diff --git a/Package.swift b/Package.swift index f1d035e..9f29bf8 100644 --- a/Package.swift +++ b/Package.swift @@ -37,6 +37,7 @@ let package = Package( ), .testTarget( name: "AckGenTests", - dependencies: ["AckGenCore"]), + dependencies: ["AckGenCore"], + resources: [.copy("Fixtures")]), ] ) diff --git a/Tests/AckGenTests/AcknowledgementAllTests.swift b/Tests/AckGenTests/AcknowledgementAllTests.swift new file mode 100644 index 0000000..08cb8de --- /dev/null +++ b/Tests/AckGenTests/AcknowledgementAllTests.swift @@ -0,0 +1,66 @@ +// +// AcknowledgementAllTests.swift +// AckGenTests +// +// Created by Martin Pfundmair on 2026-01-13. +// + +import XCTest +@testable import AckGenCore + +final class AcknowledgementAllTests: XCTestCase { + + func testAllDecodesFixturePlist() { + // Given: A fixture plist in the test bundle's Fixtures directory + // When: Loading acknowledgements from the fixture + let acks = Acknowledgement.all(fromPlist: "Fixtures/Acknowledgements", in: Bundle.module) + + // Then: All entries should be decoded correctly + XCTAssertEqual(acks.count, 3) + + // Verify the content is decoded properly + let titles = acks.map(\.title) + XCTAssertTrue(titles.contains("Zebra")) + XCTAssertTrue(titles.contains("apple")) + XCTAssertTrue(titles.contains("Banana")) + + // Verify license content is present + let zebra = acks.first { $0.title == "Zebra" } + XCTAssertEqual(zebra?.license, "MIT License for Zebra package") + } + + func testAllSortsCaseInsensitively() { + // Given: A fixture plist with mixed case titles (Zebra, apple, Banana) + // When: Loading acknowledgements (which applies case-insensitive sorting) + let acks = Acknowledgement.all(fromPlist: "Fixtures/Acknowledgements", in: Bundle.module) + + // Then: Should be sorted case-insensitively: apple, Banana, Zebra + XCTAssertEqual(acks.count, 3) + XCTAssertEqual(acks[0].title, "apple") // 'a' comes first + XCTAssertEqual(acks[1].title, "Banana") // 'B' (as 'b') comes second + XCTAssertEqual(acks[2].title, "Zebra") // 'Z' (as 'z') comes last + } + + func testAllReturnsEmptyArrayForMissingPlist() { + // Given: A non-existent plist name + let bundle = Bundle.module + + // When: Loading from a non-existent plist + let acks = Acknowledgement.all(fromPlist: "NonExistent", in: bundle) + + // Then: Should return empty array instead of crashing + XCTAssertTrue(acks.isEmpty) + } + + func testAllReturnsEmptyArrayForInvalidPlist() { + // Given: An invalid plist file (the invalid-utf8-license fixture) + // Note: This test verifies graceful handling of invalid data + // The all() method should return empty array for any decode failure + + // When: Attempting to decode a plist with invalid UTF-8 content + let acks = Acknowledgement.all(fromPlist: "Fixtures/invalid-utf8-license", in: Bundle.module) + + // Then: Should return empty array instead of crashing + XCTAssertTrue(acks.isEmpty) + } +} diff --git a/Tests/AckGenTests/Fixtures/Acknowledgements.plist b/Tests/AckGenTests/Fixtures/Acknowledgements.plist new file mode 100644 index 0000000..151e246 --- /dev/null +++ b/Tests/AckGenTests/Fixtures/Acknowledgements.plist @@ -0,0 +1,30 @@ + + + + + + Title + Zebra + FooterText + MIT License for Zebra package + Type + PSGroupSpecifier + + + Title + apple + FooterText + Apache 2.0 License for apple package + Type + PSGroupSpecifier + + + Title + Banana + FooterText + BSD License for Banana package + Type + PSGroupSpecifier + + + diff --git a/Tests/AckGenTests/Fixtures/invalid-utf8-license.plist b/Tests/AckGenTests/Fixtures/invalid-utf8-license.plist new file mode 100644 index 0000000..503ecb8 --- /dev/null +++ b/Tests/AckGenTests/Fixtures/invalid-utf8-license.plist @@ -0,0 +1 @@ + \ No newline at end of file