diff --git a/Tests/TestSWCompression/GzipTests.swift b/Tests/TestSWCompression/GzipTests.swift index 2ec1f17b..409e49d9 100644 --- a/Tests/TestSWCompression/GzipTests.swift +++ b/Tests/TestSWCompression/GzipTests.swift @@ -3,10 +3,11 @@ // // See LICENSE for license information -import XCTest +import Foundation +import Testing import SWCompression -class GzipTests: XCTestCase { +struct GzipTests { private static let testType: String = "gz" @@ -14,12 +15,12 @@ class GzipTests: XCTestCase { let testData = try Constants.data(forTest: testName, withType: GzipTests.testType) let testGzipHeader = try GzipHeader(archive: testData) - XCTAssertEqual(testGzipHeader.compressionMethod, .deflate) - XCTAssertEqual(testGzipHeader.modificationTime, Date(timeIntervalSince1970: TimeInterval(mtime))) - XCTAssertEqual(testGzipHeader.osType, .unix) - XCTAssertEqual(testGzipHeader.fileName, "\(testName).answer") - XCTAssertEqual(testGzipHeader.comment, nil) - XCTAssertTrue(testGzipHeader.extraFields.isEmpty) + #expect(testGzipHeader.compressionMethod == .deflate) + #expect(testGzipHeader.modificationTime == Date(timeIntervalSince1970: TimeInterval(mtime))) + #expect(testGzipHeader.osType == .unix) + #expect(testGzipHeader.fileName == "\(testName).answer") + #expect(testGzipHeader.comment == nil) + #expect(testGzipHeader.extraFields.isEmpty) } func unarchive(test testName: String) throws { @@ -27,7 +28,7 @@ class GzipTests: XCTestCase { let decompressedData = try GzipArchive.unarchive(archive: testData) let answerData = try Constants.data(forAnswer: testName) - XCTAssertEqual(decompressedData, answerData) + #expect(decompressedData == answerData) } func archive(test testName: String) throws { @@ -56,197 +57,213 @@ class GzipTests: XCTestCase { // Test output GZip header. let testGzipHeader = try GzipHeader(archive: archiveData) - XCTAssertEqual(testGzipHeader.compressionMethod, .deflate) - XCTAssertEqual(testGzipHeader.modificationTime?.timeIntervalSince1970, mtime) - XCTAssertEqual(testGzipHeader.osType, .macintosh) - XCTAssertEqual(testGzipHeader.fileName, "\(testName).answer") - XCTAssertEqual(testGzipHeader.comment, "some file comment") - XCTAssertTrue(testGzipHeader.isTextFile) - XCTAssertEqual(testGzipHeader.extraFields.count, 1) - XCTAssertEqual(testGzipHeader.extraFields.first?.si1, si1) - XCTAssertEqual(testGzipHeader.extraFields.first?.si2, si2) - XCTAssertEqual(testGzipHeader.extraFields.first?.bytes, extraFieldBytes) + #expect(testGzipHeader.compressionMethod == .deflate) + #expect(testGzipHeader.modificationTime?.timeIntervalSince1970 == mtime) + #expect(testGzipHeader.osType == .macintosh) + #expect(testGzipHeader.fileName == "\(testName).answer") + #expect(testGzipHeader.comment == "some file comment") + #expect(testGzipHeader.isTextFile) + #expect(testGzipHeader.extraFields.count == 1) + #expect(testGzipHeader.extraFields.first?.si1 == si1) + #expect(testGzipHeader.extraFields.first?.si2 == si2) + #expect(testGzipHeader.extraFields.first?.bytes == extraFieldBytes) // Test output GZip archive content. let decompressedData = try GzipArchive.unarchive(archive: archiveData) - XCTAssertEqual(decompressedData, answerData) + #expect(decompressedData == answerData) } - func testGzip1() throws { + @Test func test1() throws { try self.header(test: "test1", mtime: 1482698300) try self.unarchive(test: "test1") } - func testGzip2() throws { + @Test func test2() throws { try self.header(test: "test2", mtime: 1482698300) try self.unarchive(test: "test2") } - func testGzip3() throws { + @Test func test3() throws { try self.header(test: "test3", mtime: 1482698301) try self.unarchive(test: "test3") } - func testGzip4() throws { + @Test func test4() throws { try self.header(test: "test4", mtime: 1482698301) try self.unarchive(test: "test4") } - func testGzip4ExtraField() throws { + @Test func test4ExtraField() throws { let testData = try Constants.data(forTest: "test4_extra_field", withType: GzipTests.testType) let testGzipHeader = try GzipHeader(archive: testData) - XCTAssertEqual(testGzipHeader.compressionMethod, .deflate) - XCTAssertEqual(testGzipHeader.modificationTime?.timeIntervalSince1970, 1665760462) - XCTAssertEqual(testGzipHeader.osType, .macintosh) - XCTAssertEqual(testGzipHeader.fileName, "test4.answer") - XCTAssertEqual(testGzipHeader.comment, "some file comment") - XCTAssertTrue(testGzipHeader.isTextFile) - XCTAssertEqual(testGzipHeader.extraFields.count, 1) - XCTAssertEqual(testGzipHeader.extraFields.first?.si1, 0x54) - XCTAssertEqual(testGzipHeader.extraFields.first?.si2, 0x53) - XCTAssertEqual(testGzipHeader.extraFields.first?.bytes, [0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, - 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, 0x33, - 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, - 0xDD, 0xEE, 0xFF]) + #expect(testGzipHeader.compressionMethod == .deflate) + #expect(testGzipHeader.modificationTime?.timeIntervalSince1970 == 1665760462) + #expect(testGzipHeader.osType == .macintosh) + #expect(testGzipHeader.fileName == "test4.answer") + #expect(testGzipHeader.comment == "some file comment") + #expect(testGzipHeader.isTextFile) + #expect(testGzipHeader.extraFields.count == 1) + #expect(testGzipHeader.extraFields.first?.si1 == 0x54) + #expect(testGzipHeader.extraFields.first?.si2 == 0x53) + #expect(testGzipHeader.extraFields.first?.bytes == [0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, + 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, 0x33, 0x44, 0x55, + 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF]) } - func testGzip5() throws { + @Test func test5() throws { try self.header(test: "test5", mtime: 1482698242) try self.unarchive(test: "test5") } - func testGzip6() throws { + @Test func test6() throws { try self.header(test: "test6", mtime: 1511554495) try self.unarchive(test: "test6") } - func testGzip7() throws { + @Test func test7() throws { try self.header(test: "test7", mtime: 1511554611) try self.unarchive(test: "test7") } - func testGzip8() throws { + @Test func test8() throws { try self.header(test: "test8", mtime: 1483040005) try self.unarchive(test: "test8") } - func testGzip9() throws { + @Test func test9() throws { try self.header(test: "test9", mtime: 1483040005) try self.unarchive(test: "test9") } - func testGzipArchive4() throws { + @Test func archive4() throws { try self.archive(test: "test4") } - func testMultiUnarchive() throws { + @Test func multiUnarchive() throws { let testData = try Constants.data(forTest: "test_multi", withType: GzipTests.testType) let members = try GzipArchive.multiUnarchive(archive: testData) - XCTAssertEqual(members.count, 4) + try #require(members.count == 4) for i in 1...4 { let header = members[i - 1].header - XCTAssertEqual(header.fileName, "test\(i).answer") + #expect(header.fileName == "test\(i).answer") let data = members[i - 1].data let answerData = try Constants.data(forAnswer: "test\(i)") - XCTAssertEqual(data, answerData) + #expect(data == answerData) } } - func testMultiUnarchiveRedundant() throws { + @Test func multiUnarchiveRedundant() throws { let testData = try Constants.data(forTest: "test1", withType: GzipTests.testType) let members = try GzipArchive.multiUnarchive(archive: testData) - XCTAssertEqual(members.count, 1) + try #require(members.count == 1) let header = members[0].header - XCTAssertEqual(header.fileName, "test1.answer") + #expect(header.fileName == "test1.answer") let data = members[0].data let answerData = try Constants.data(forAnswer: "test1") - XCTAssertEqual(data, answerData) + #expect(data == answerData) } - func testBadFile_short() { - XCTAssertThrowsError(try GzipArchive.unarchive(archive: Data([0]))) - XCTAssertThrowsError(try GzipArchive.multiUnarchive(archive: Data([0]))) - XCTAssertThrowsError(try GzipHeader(archive: Data([0]))) + @Test func shortInput() { + #expect(throws: (any Error).self) { try GzipArchive.unarchive(archive: Data([0])) } + #expect(throws: (any Error).self) { try GzipArchive.multiUnarchive(archive: Data([0])) } + #expect(throws: (any Error).self) { try GzipHeader(archive: Data([0])) } } - func testBadFile_invalid() throws { + @Test func invalidInput() throws { let testData = try Constants.data(forAnswer: "test6") - XCTAssertThrowsError(try GzipArchive.unarchive(archive: testData)) - XCTAssertThrowsError(try GzipArchive.multiUnarchive(archive: testData)) + #expect(throws: (any Error).self) { try GzipArchive.unarchive(archive: testData) } + #expect(throws: (any Error).self) { try GzipArchive.multiUnarchive(archive: testData) } } - func testEmptyData() throws { - XCTAssertThrowsError(try GzipArchive.unarchive(archive: Data())) + @Test func emptyInput() throws { + #expect(throws: (any Error).self) { try GzipArchive.unarchive(archive: Data()) } } - func testChecksumMismatch() throws { + @Test func checksumMismatch() throws { // Here we test that an error for checksum mismatch is thrown correctly and its associated value contains // expected data. We do this by programmatically adjusting the input: we change one of the bytes for the checkum, // which makes it incorrect. var testData = try Constants.data(forTest: "test1", withType: GzipTests.testType) // Here we modify the stored value of crc32. testData[41] &+= 1 - var thrownError: Error? = nil - XCTAssertThrowsError(try GzipArchive.unarchive(archive: testData)) { thrownError = $0 } - XCTAssertTrue(thrownError is GzipError, "Unexpected error type: \(type(of: thrownError))") - if case let .some(.wrongCRC(members)) = thrownError as? GzipError { - XCTAssertEqual(members.count, 1) - let answerData = try Constants.data(forAnswer: "test1") - XCTAssertEqual(members.first?.data, answerData) - } else { - XCTFail("Unexpected error: \(String(describing: thrownError))") - } + #if compiler(>=6.1) + let error = #expect(throws: GzipError.self) { try GzipArchive.unarchive(archive: testData) } + if case let .some(.wrongCRC(members)) = error { + try #require(members.count == 1) + let answerData = try Constants.data(forAnswer: "test1") + #expect(members.first!.data == answerData) + } else { + Issue.record("Unexpected error: \(error)") + } + #else + #expect { try GzipArchive.unarchive(archive: testData) } throws: { error in + if case let .some(.wrongCRC(members)) = error as? GzipError { + let answerData = try Constants.data(forAnswer: "test1") + return members.count == 1 && members.first!.data == answerData + } + return false + } + #endif } - func testMultiUnarchiveChecksumMismatch() throws { + @Test func multiUnarchiveChecksumMismatch() throws { // Here we test that an error for checksum mismatch is thrown correctly and its associated value contains // expected data. We do this by programmatically adjusting the input: we change one of the bytes for the checkum, // which makes it incorrect. var testData = try Constants.data(forTest: "test_multi", withType: GzipTests.testType) // Here we modify the stored value of crc32. testData[2289] &+= 1 - var thrownError: Error? = nil - XCTAssertThrowsError(try GzipArchive.multiUnarchive(archive: testData)) { thrownError = $0 } - XCTAssertTrue(thrownError is GzipError, "Unexpected error type: \(type(of: thrownError))") - if case let .some(.wrongCRC(members)) = thrownError as? GzipError { - XCTAssertEqual(members.count, 2) - var answerData = try Constants.data(forAnswer: "test1") - XCTAssertEqual(members[0].data, answerData) - answerData = try Constants.data(forAnswer: "test2") - XCTAssertEqual(members[1].data, answerData) - } else { - XCTFail("Unexpected error: \(String(describing: thrownError))") - } + #if compiler(>=6.1) + let error = #expect(throws: GzipError.self) { try GzipArchive.multiUnarchive(archive: testData) } + if case let .some(.wrongCRC(members)) = error { + try #require(members.count == 2) + var answerData = try Constants.data(forAnswer: "test1") + #expect(members[0].data == answerData) + answerData = try Constants.data(forAnswer: "test2") + #expect(members[1].data == answerData) + } else { + Issue.record("Unexpected error: \(error)") + } + #else + #expect { try GzipArchive.multiUnarchive(archive: testData) } throws: { error in + if case let .some(.wrongCRC(members)) = error as? GzipError { + let answer1Data = try Constants.data(forAnswer: "test1") + let answer2Data = try Constants.data(forAnswer: "test2") + return members.count == 2 && members[0].data == answer1Data && members[1].data == answer2Data + } + return false + } + #endif } - func testMinimal() throws { + @Test func minimal() throws { // In this test we test several things: // - that the archive consisting only of the minimal header is successfully processed, // - that the mtime field with the value 0 correctly results in a `GzipHeader.modificationTime == nil`, // - that the `GzipArchive.multiUnarchive(archive:)` works on a single member archive. let testData = try Constants.data(forTest: "minimal", withType: GzipTests.testType) let members = try GzipArchive.multiUnarchive(archive: testData) - XCTAssertEqual(members.count, 1) + try #require(members.count == 1) if let member = members.first { - XCTAssertEqual(member.header.compressionMethod, .deflate) - XCTAssertNil(member.header.modificationTime) - XCTAssertEqual(member.header.osType, .unix) - XCTAssertNil(member.header.fileName) - XCTAssertNil(member.header.comment) - XCTAssertFalse(member.header.isTextFile) - XCTAssertEqual(member.data, Data()) + #expect(member.header.compressionMethod == .deflate) + #expect(member.header.modificationTime == nil) + #expect(member.header.osType == .unix) + #expect(member.header.fileName == nil) + #expect(member.header.comment == nil) + #expect(!member.header.isTextFile) + #expect(member.data == Data()) } } - func testGzipTruncation() throws { + @Test func headerFooterTruncation() throws { // In this test we check the handling of truncation inside the optional elements (name, comment, "extra field", // crc) of a GZip header, as well as in the "checksum" information of the archive (last 8 bytes). The sample // file used is "test4_extra_field" since it contains a header which utilizes all format features. @@ -255,28 +272,20 @@ class GzipTests: XCTestCase { // We test all possible truncation points since there are very few of them. // The header takes first 79 bytes. for truncationIndex in 1..<79 { - var thrownError: Error? = nil - XCTAssertThrowsError(try GzipArchive.unarchive(archive: testData[..