diff --git a/Tests/FoundationEssentialsTests/DataIOTests.swift b/Tests/FoundationEssentialsTests/DataIOTests.swift index fdaca9b56..e9d2d8e15 100644 --- a/Tests/FoundationEssentialsTests/DataIOTests.swift +++ b/Tests/FoundationEssentialsTests/DataIOTests.swift @@ -10,13 +10,7 @@ // //===----------------------------------------------------------------------===// -#if canImport(TestSupport) -import TestSupport -#endif - -#if canImport(Glibc) -@preconcurrency import Glibc -#endif +import Testing #if FOUNDATION_FRAMEWORK @testable import Foundation @@ -24,38 +18,40 @@ import TestSupport @testable import FoundationEssentials #endif // FOUNDATION_FRAMEWORK -class DataIOTests : XCTestCase { +private func generateTestData(count: Int = 16_777_216) -> Data { + // Set a few bytes so we're sure to not be all zeros + let buf = UnsafeMutableBufferPointer.allocate(capacity: count) + for i in 0..<15 { + for j in 0..<128 { + buf[j * 1024 + i] = UInt8.random(in: 1..<42) + } + } + + return Data(bytesNoCopy: buf.baseAddress!, count: count, deallocator: .custom({ ptr, _ in + ptr.deallocate() + })) +} + +@Suite("Data I/O") +private final class DataIOTests { // MARK: - Helpers - func testURL() -> URL { - // Generate a random file name - URL(fileURLWithPath: NSTemporaryDirectory(), isDirectory: true).appendingPathComponent("testfile-\(UUID().uuidString)") - } + let url: URL - func generateTestData(count: Int = 16_777_216) -> Data { - let memory = malloc(count)! - let ptr = memory.bindMemory(to: UInt8.self, capacity: count) - - // Set a few bytes so we're sure to not be all zeros - let buf = UnsafeMutableBufferPointer(start: ptr, count: count) - for i in 0..<15 { - for j in 0..<128 { - buf[j * 1024 + i] = UInt8.random(in: 1..<42) - } - } - - return Data(bytesNoCopy: ptr, count: count, deallocator: .free) + init() { + // Generate a random file name + url = URL.temporaryDirectory.appendingPathComponent("testfile-\(UUID().uuidString)") } - func writeAndVerifyTestData(to url: URL, writeOptions: Data.WritingOptions = [], readOptions: Data.ReadingOptions = []) throws { + func writeAndVerifyTestData(to url: URL, writeOptions: Data.WritingOptions = [], readOptions: Data.ReadingOptions = [], sourceLocation: SourceLocation = #_sourceLocation) throws { let data = generateTestData() try data.write(to: url, options: writeOptions) let readData = try Data(contentsOf: url, options: readOptions) - XCTAssertEqual(data, readData) + #expect(data == readData, sourceLocation: sourceLocation) } - func cleanup(at url: URL) { + deinit { do { try FileManager.default.removeItem(at: url) } catch { @@ -63,18 +59,14 @@ class DataIOTests : XCTestCase { } } - // MARK: - Tests - func test_basicReadWrite() throws { - let url = testURL() + @Test func basicReadWrite() throws { try writeAndVerifyTestData(to: url) - cleanup(at: url) } - func test_slicedReadWrite() throws { + @Test func slicedReadWrite() throws { // Be sure to use progress reporting so we get tests of the chunking - let url = testURL() let data = generateTestData() let slice = data[data.startIndex.advanced(by: 1 * 1024 * 1024)..= 2 }) - XCTAssertEqual(2, data2.count) + #expect(2 == data2.count) let data3 = Data([1, 2, 3, 4, 5][1..<3]) - XCTAssertEqual(2, data3.count) + #expect(2 == data3.count) } - func testInitializationWithBufferPointer() { + @Test func initializationWithBufferPointer() { let nilBuffer = UnsafeBufferPointer(start: nil, count: 0) let data = Data(buffer: nilBuffer) - XCTAssertEqual(data, Data()) + #expect(data == Data()) let validPointer = UnsafeMutablePointer.allocate(capacity: 2) validPointer[0] = 0xCA @@ -109,29 +114,29 @@ class DataTests : XCTestCase { let emptyBuffer = UnsafeBufferPointer(start: validPointer, count: 0) let data2 = Data(buffer: emptyBuffer) - XCTAssertEqual(data2, Data()) + #expect(data2 == Data()) let shortBuffer = UnsafeBufferPointer(start: validPointer, count: 1) let data3 = Data(buffer: shortBuffer) - XCTAssertEqual(data3, Data([0xCA])) + #expect(data3 == Data([0xCA])) let fullBuffer = UnsafeBufferPointer(start: validPointer, count: 2) let data4 = Data(buffer: fullBuffer) - XCTAssertEqual(data4, Data([0xCA, 0xFE])) + #expect(data4 == Data([0xCA, 0xFE])) let tuple: (UInt16, UInt16, UInt16, UInt16) = (0xFF, 0xFE, 0xFD, 0xFC) withUnsafeBytes(of: tuple) { // If necessary, port this to big-endian. let tupleBuffer: UnsafeBufferPointer = $0.bindMemory(to: UInt8.self) let data5 = Data(buffer: tupleBuffer) - XCTAssertEqual(data5, Data([0xFF, 0x00, 0xFE, 0x00, 0xFD, 0x00, 0xFC, 0x00])) + #expect(data5 == Data([0xFF, 0x00, 0xFE, 0x00, 0xFD, 0x00, 0xFC, 0x00])) } } - func testInitializationWithMutableBufferPointer() { + @Test func initializationWithMutableBufferPointer() { let nilBuffer = UnsafeMutableBufferPointer(start: nil, count: 0) let data = Data(buffer: nilBuffer) - XCTAssertEqual(data, Data()) + #expect(data == Data()) let validPointer = UnsafeMutablePointer.allocate(capacity: 2) validPointer[0] = 0xCA @@ -140,59 +145,59 @@ class DataTests : XCTestCase { let emptyBuffer = UnsafeMutableBufferPointer(start: validPointer, count: 0) let data2 = Data(buffer: emptyBuffer) - XCTAssertEqual(data2, Data()) + #expect(data2 == Data()) let shortBuffer = UnsafeMutableBufferPointer(start: validPointer, count: 1) let data3 = Data(buffer: shortBuffer) - XCTAssertEqual(data3, Data([0xCA])) + #expect(data3 == Data([0xCA])) let fullBuffer = UnsafeMutableBufferPointer(start: validPointer, count: 2) let data4 = Data(buffer: fullBuffer) - XCTAssertEqual(data4, Data([0xCA, 0xFE])) + #expect(data4 == Data([0xCA, 0xFE])) var tuple: (UInt16, UInt16, UInt16, UInt16) = (0xFF, 0xFE, 0xFD, 0xFC) withUnsafeMutableBytes(of: &tuple) { // If necessary, port this to big-endian. let tupleBuffer: UnsafeMutableBufferPointer = $0.bindMemory(to: UInt8.self) let data5 = Data(buffer: tupleBuffer) - XCTAssertEqual(data5, Data([0xFF, 0x00, 0xFE, 0x00, 0xFD, 0x00, 0xFC, 0x00])) + #expect(data5 == Data([0xFF, 0x00, 0xFE, 0x00, 0xFD, 0x00, 0xFC, 0x00])) } } - func testMutableData() { + @Test func mutableData() { let hello = dataFrom("hello") let helloLength = hello.count - XCTAssertEqual(hello[0], 0x68, "Unexpected first byte") + #expect(hello[0] == 0x68, "Unexpected first byte") // Double the length var mutatingHello = hello mutatingHello.count *= 2 - XCTAssertEqual(hello.count, helloLength, "The length of the initial data should not have changed") - XCTAssertEqual(mutatingHello.count, helloLength * 2, "The length should have changed") + #expect(hello.count == helloLength, "The length of the initial data should not have changed") + #expect(mutatingHello.count == helloLength * 2, "The length should have changed") // Get the underlying data for hello2 mutatingHello.withUnsafeMutableUInt8Bytes { (bytes : UnsafeMutablePointer) in - XCTAssertEqual(bytes.pointee, 0x68, "First byte should be 0x68") + #expect(bytes.pointee == 0x68, "First byte should be 0x68") // Mutate it bytes.pointee = 0x67 - XCTAssertEqual(bytes.pointee, 0x67, "First byte should be 0x67") + #expect(bytes.pointee == 0x67, "First byte should be 0x67") // Verify that the first data is still correct - XCTAssertEqual(hello[0], 0x68, "The first byte should still be 0x68") + #expect(hello[0] == 0x68, "The first byte should still be 0x68") } } - func testEquality() { + @Test func equality() { let d1 = dataFrom("hello") let d2 = dataFrom("hello") // Use == explicitly here to make sure we're calling the right methods - XCTAssertTrue(d1 == d2, "Data should be equal") + #expect(d1 == d2, "Data should be equal") } - func testDataInSet() { + @Test func dataInSet() { let d1 = dataFrom("Hello") let d2 = dataFrom("Hello") let d3 = dataFrom("World") @@ -202,25 +207,25 @@ class DataTests : XCTestCase { s.insert(d2) s.insert(d3) - XCTAssertEqual(s.count, 2, "Expected only two entries in the Set") + #expect(s.count == 2, "Expected only two entries in the Set") } - func testReplaceSubrange() { + @Test func replaceSubrange() { var hello = dataFrom("Hello") let world = dataFrom("World") hello[0] = world[0] - XCTAssertEqual(hello[0], world[0]) + #expect(hello[0] == world[0]) var goodbyeWorld = dataFrom("Hello World") let goodbye = dataFrom("Goodbye") let expected = dataFrom("Goodbye World") goodbyeWorld.replaceSubrange(0..<5, with: goodbye) - XCTAssertEqual(goodbyeWorld, expected) + #expect(goodbyeWorld == expected) } - func testReplaceSubrange3() { + @Test func replaceSubrange3() { // The expected result let expectedBytes : [UInt8] = [1, 2, 9, 10, 11, 12, 13] let expected = expectedBytes.withUnsafeBufferPointer { @@ -238,10 +243,10 @@ class DataTests : XCTestCase { b.withUnsafeBufferPointer { a.replaceSubrange(2..<5, with: $0) } - XCTAssertEqual(expected, a) + #expect(expected == a) } - func testReplaceSubrange4() { + @Test func replaceSubrange4() { let expectedBytes : [UInt8] = [1, 2, 9, 10, 11, 12, 13] let expected = Data(expectedBytes) @@ -252,31 +257,31 @@ class DataTests : XCTestCase { // The bytes we'll insert let b : [UInt8] = [9, 10, 11, 12, 13] a.replaceSubrange(2..<5, with: b) - XCTAssertEqual(expected, a) + #expect(expected == a) } - func testReplaceSubrange5() { + @Test func replaceSubrange5() { var d = Data([1, 2, 3]) d.replaceSubrange(0..<0, with: [4]) - XCTAssertEqual(Data([4, 1, 2, 3]), d) + #expect(Data([4, 1, 2, 3]) == d) d.replaceSubrange(0..<4, with: [9]) - XCTAssertEqual(Data([9]), d) + #expect(Data([9]) == d) d.replaceSubrange(0..= 65 && byte <= 90 } let allCaps = hello.filter(isCapital) - XCTAssertEqual(allCaps.count, 2) + #expect(allCaps.count == 2) let capCount = hello.reduce(0) { isCapital($1) ? $0 + 1 : $0 } - XCTAssertEqual(capCount, 2) + #expect(capCount == 2) let allLower = hello.map { isCapital($0) ? $0 + 31 : $0 } - XCTAssertEqual(allLower.count, hello.count) + #expect(allLower.count == hello.count) } - func testCopyBytes() { + @Test func copyBytes() { let c = 10 let underlyingBuffer = malloc(c * MemoryLayout.stride)! let u16Ptr = underlyingBuffer.bindMemory(to: UInt16.self, capacity: c) @@ -326,50 +331,50 @@ class DataTests : XCTestCase { data[0] = 0xFF data[1] = 0xFF let copiedCount = data.copyBytes(to: buffer) - XCTAssertEqual(copiedCount, c * MemoryLayout.stride) + #expect(copiedCount == c * MemoryLayout.stride) - XCTAssertEqual(buffer[0], 0xFFFF) + #expect(buffer[0] == 0xFFFF) free(underlyingBuffer) } - func testCopyBytes_undersized() { + @Test func copyBytes_undersized() { let a : [UInt8] = [1, 2, 3, 4, 5] let data = a.withUnsafeBufferPointer { return Data(buffer: $0) } let expectedSize = MemoryLayout.stride * a.count - XCTAssertEqual(expectedSize, data.count) + #expect(expectedSize == data.count) let buffer = UnsafeMutableRawBufferPointer.allocate(byteCount: expectedSize - 1, alignment: MemoryLayout.size) // We should only copy in enough bytes that can fit in the buffer let copiedCount = data.copyBytes(to: buffer) - XCTAssertEqual(expectedSize - 1, copiedCount) + #expect(expectedSize - 1 == copiedCount) var index = 0 for v in a[0...stride * a.count - XCTAssertEqual(expectedSize, data.count) + #expect(expectedSize == data.count) let buffer = UnsafeMutableRawBufferPointer.allocate(byteCount: expectedSize, alignment: MemoryLayout.size) let copiedCount = data.copyBytes(to: buffer) - XCTAssertEqual(expectedSize, copiedCount) + #expect(expectedSize == copiedCount) buffer.deallocate() } - func testCopyBytes_ranges() { + @Test func copyBytes_ranges() { do { // Equal sized buffer, data @@ -383,17 +388,17 @@ class DataTests : XCTestCase { var copiedCount : Int copiedCount = data.copyBytes(to: buffer, from: 0..<0) - XCTAssertEqual(0, copiedCount) + #expect(0 == copiedCount) copiedCount = data.copyBytes(to: buffer, from: 1..<1) - XCTAssertEqual(0, copiedCount) + #expect(0 == copiedCount) copiedCount = data.copyBytes(to: buffer, from: 0..<3) - XCTAssertEqual((0..<3).count, copiedCount) + #expect((0..<3).count == copiedCount) var index = 0 for v in a[0..<3] { - XCTAssertEqual(v, buffer[index]) + #expect(v == buffer[index]) index += 1 } buffer.deallocate() @@ -410,11 +415,11 @@ class DataTests : XCTestCase { var copiedCount : Int copiedCount = data.copyBytes(to: buffer, from: 0..<3) - XCTAssertEqual((0..<3).count, copiedCount) + #expect((0..<3).count == copiedCount) var index = 0 for v in a[0..<3] { - XCTAssertEqual(v, buffer[index]) + #expect(v == buffer[index]) index += 1 } buffer.deallocate() @@ -432,11 +437,11 @@ class DataTests : XCTestCase { var copiedCount : Int copiedCount = data.copyBytes(to: buffer, from: 0..(repeating: 8, count: 4) destination.withUnsafeMutableBufferPointer { let count = source.copyBytes(to: $0) - XCTAssertEqual(count, 2) + #expect(count == 2) } - XCTAssertEqual(destination, [3, 5, 8, 8]) + #expect(destination == [3, 5, 8, 8]) } - func test_genericBuffers() { + @Test func genericBuffers() { let a : [Int32] = [1, 0, 1, 0, 1] var data = a.withUnsafeBufferPointer { return Data(buffer: $0) } var expectedSize = MemoryLayout.stride * a.count - XCTAssertEqual(expectedSize, data.count) + #expect(expectedSize == data.count) [false, true].withUnsafeBufferPointer { data.append($0) } expectedSize += MemoryLayout.stride * 2 - XCTAssertEqual(expectedSize, data.count) + #expect(expectedSize == data.count) let buffer = UnsafeMutableRawBufferPointer.allocate(byteCount: expectedSize, alignment: MemoryLayout.size) let copiedCount = data.copyBytes(to: buffer) - XCTAssertEqual(copiedCount, expectedSize) + #expect(copiedCount == expectedSize) buffer.deallocate() } @@ -492,7 +497,7 @@ class DataTests : XCTestCase { } } - func test_bufferSizeCalculation() { + @Test func bufferSizeCalculation() { // Make sure that Data is correctly using strideof instead of sizeof. // n.b. if sizeof(MyStruct) == strideof(MyStruct), this test is not as useful as it could be @@ -502,7 +507,7 @@ class DataTests : XCTestCase { return Data(buffer: $0) } - XCTAssertEqual(data.count, MemoryLayout.stride * 3) + #expect(data.count == MemoryLayout.stride * 3) // append @@ -510,7 +515,7 @@ class DataTests : XCTestCase { data.append($0) } - XCTAssertEqual(data.count, MemoryLayout.stride * 6) + #expect(data.count == MemoryLayout.stride * 6) // copyBytes do { @@ -522,7 +527,7 @@ class DataTests : XCTestCase { let buffer = UnsafeMutableBufferPointer(start: ptr, count: 6) let byteCount = data.copyBytes(to: buffer) - XCTAssertEqual(6 * MemoryLayout.stride, byteCount) + #expect(6 * MemoryLayout.stride == byteCount) } do { @@ -534,7 +539,7 @@ class DataTests : XCTestCase { let buffer = UnsafeMutableBufferPointer(start: ptr, count: 3) let byteCount = data.copyBytes(to: buffer) - XCTAssertEqual(3 * MemoryLayout.stride, byteCount) + #expect(3 * MemoryLayout.stride == byteCount) } do { @@ -546,47 +551,47 @@ class DataTests : XCTestCase { let buffer = UnsafeMutableBufferPointer(start: ptr, count: 6) let byteCount = data.copyBytes(to: buffer) - XCTAssertEqual(6 * MemoryLayout.stride, byteCount) + #expect(6 * MemoryLayout.stride == byteCount) } } // MARK: - - func test_repeatingValueInitialization() { + @Test func repeatingValueInitialization() { var d = Data(repeating: 0x01, count: 3) let elements = repeatElement(UInt8(0x02), count: 3) // ensure we fall into the sequence case d.append(contentsOf: elements) - XCTAssertEqual(d[0], 0x01) - XCTAssertEqual(d[1], 0x01) - XCTAssertEqual(d[2], 0x01) + #expect(d[0] == 0x01) + #expect(d[1] == 0x01) + #expect(d[2] == 0x01) - XCTAssertEqual(d[3], 0x02) - XCTAssertEqual(d[4], 0x02) - XCTAssertEqual(d[5], 0x02) + #expect(d[3] == 0x02) + #expect(d[4] == 0x02) + #expect(d[5] == 0x02) } - func test_rangeSlice() { + @Test func rangeSlice() { let a: [UInt8] = [0, 1, 2, 3, 4, 5, 6, 7] let d = Data(a) for i in 0..? = nil, expectedStartIndex: Int?, - _ message: @autoclosure () -> String = "", - file: StaticString = #filePath, line: UInt = #line) { + _ message: @autoclosure () -> Comment? = nil, + sourceLocation: SourceLocation = #_sourceLocation) { if let index = expectedStartIndex { let expectedRange: Range = index..<(index + fragment.count) if let someRange = range { - XCTAssertEqual(data.firstRange(of: fragment, in: someRange), expectedRange, message(), file: file, line: line) + #expect(data.firstRange(of: fragment, in: someRange) == expectedRange, message(), sourceLocation: sourceLocation) } else { - XCTAssertEqual(data.firstRange(of: fragment), expectedRange, message(), file: file, line: line) + #expect(data.firstRange(of: fragment) == expectedRange, message(), sourceLocation: sourceLocation) } } else { if let someRange = range { - XCTAssertNil(data.firstRange(of: fragment, in: someRange), message(), file: file, line: line) + #expect(data.firstRange(of: fragment, in: someRange) == nil, message(), sourceLocation: sourceLocation) } else { - XCTAssertNil(data.firstRange(of: fragment), message(), file: file, line: line) + #expect(data.firstRange(of: fragment) == nil, message(), sourceLocation: sourceLocation) } } } @@ -656,20 +661,20 @@ class DataTests : XCTestCase { do { // lastRange(of:in:) func assertLastRange(_ data: Data, _ fragment: Data, range: ClosedRange? = nil, expectedStartIndex: Int?, - _ message: @autoclosure () -> String = "", - file: StaticString = #filePath, line: UInt = #line) { + _ message: @autoclosure () -> Comment? = nil, + sourceLocation: SourceLocation = #_sourceLocation) { if let index = expectedStartIndex { let expectedRange: Range = index..<(index + fragment.count) if let someRange = range { - XCTAssertEqual(data.lastRange(of: fragment, in: someRange), expectedRange, file: file, line: line) + #expect(data.lastRange(of: fragment, in: someRange) == expectedRange, message(), sourceLocation: sourceLocation) } else { - XCTAssertEqual(data.lastRange(of: fragment), expectedRange, message(), file: file, line: line) + #expect(data.lastRange(of: fragment) == expectedRange, message(), sourceLocation: sourceLocation) } } else { if let someRange = range { - XCTAssertNil(data.lastRange(of: fragment, in: someRange), message(), file: file, line: line) + #expect(data.lastRange(of: fragment, in: someRange) == nil, message(), sourceLocation: sourceLocation) } else { - XCTAssertNil(data.lastRange(of: fragment), message(), file: file, line: line) + #expect(data.lastRange(of: fragment) == nil, message(), sourceLocation: sourceLocation) } } } @@ -696,98 +701,98 @@ class DataTests : XCTestCase { } } - func test_sliceAppending() { + @Test func sliceAppending() { // https://bugs.swift.org/browse/SR-4473 var fooData = Data() let barData = Data([0, 1, 2, 3, 4, 5]) let slice = barData.suffix(from: 3) fooData.append(slice) - XCTAssertEqual(fooData[0], 0x03) - XCTAssertEqual(fooData[1], 0x04) - XCTAssertEqual(fooData[2], 0x05) + #expect(fooData[0] == 0x03) + #expect(fooData[1] == 0x04) + #expect(fooData[2] == 0x05) } - func test_sliceWithUnsafeBytes() { + @Test func sliceWithUnsafeBytes() { let base = Data([0, 1, 2, 3, 4, 5]) let slice = base[2..<4] let segment = slice.withUnsafeUInt8Bytes { (ptr: UnsafePointer) -> [UInt8] in return [ptr.pointee, ptr.advanced(by: 1).pointee] } - XCTAssertEqual(segment, [UInt8(2), UInt8(3)]) + #expect(segment == [UInt8(2), UInt8(3)]) } - func test_sliceIteration() { + @Test func sliceIteration() { let base = Data([0, 1, 2, 3, 4, 5]) let slice = base[2..<4] var found = [UInt8]() for byte in slice { found.append(byte) } - XCTAssertEqual(found[0], 2) - XCTAssertEqual(found[1], 3) + #expect(found[0] == 2) + #expect(found[1] == 3) } - func test_sliceIndexing() { + @Test func sliceIndexing() { let d = Data([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]) let slice = d[5..<10] - XCTAssertEqual(slice[5], d[5]) + #expect(slice[5] == d[5]) } - func test_sliceEquality() { + @Test func sliceEquality() { let d = Data([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]) let slice = d[5..<7] let expected = Data([5, 6]) - XCTAssertEqual(expected, slice) + #expect(expected == slice) } - func test_sliceEquality2() { + @Test func sliceEquality2() { let d = Data([5, 6, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]) let slice1 = d[0..<2] let slice2 = d[5..<7] - XCTAssertEqual(slice1, slice2) + #expect(slice1 == slice2) } - func test_map() { + @Test func map() { let d1 = Data([81, 0, 0, 0, 14]) let d2 = d1[1...4] - XCTAssertEqual(4, d2.count) + #expect(4 == d2.count) let expected: [UInt8] = [0, 0, 0, 14] let actual = d2.map { $0 } - XCTAssertEqual(expected, actual) + #expect(expected == actual) } - func test_dropFirst() { + @Test func dropFirst() { let data = Data([0, 1, 2, 3, 4, 5]) let sliced = data.dropFirst() - XCTAssertEqual(data.count - 1, sliced.count) - XCTAssertEqual(UInt8(1), sliced[1]) - XCTAssertEqual(UInt8(2), sliced[2]) - XCTAssertEqual(UInt8(3), sliced[3]) - XCTAssertEqual(UInt8(4), sliced[4]) - XCTAssertEqual(UInt8(5), sliced[5]) + #expect(data.count - 1 == sliced.count) + #expect(UInt8(1) == sliced[1]) + #expect(UInt8(2) == sliced[2]) + #expect(UInt8(3) == sliced[3]) + #expect(UInt8(4) == sliced[4]) + #expect(UInt8(5) == sliced[5]) } - func test_dropFirst2() { + @Test func dropFirst2() { let data = Data([0, 1, 2, 3, 4, 5]) let sliced = data.dropFirst(2) - XCTAssertEqual(data.count - 2, sliced.count) - XCTAssertEqual(UInt8(2), sliced[2]) - XCTAssertEqual(UInt8(3), sliced[3]) - XCTAssertEqual(UInt8(4), sliced[4]) - XCTAssertEqual(UInt8(5), sliced[5]) + #expect(data.count - 2 == sliced.count) + #expect(UInt8(2) == sliced[2]) + #expect(UInt8(3) == sliced[3]) + #expect(UInt8(4) == sliced[4]) + #expect(UInt8(5) == sliced[5]) } - func test_copyBytes1() { + @Test func copyBytes1() { var array: [UInt8] = [0, 1, 2, 3] let data = Data(array) array.withUnsafeMutableBufferPointer { data[1..<3].copyBytes(to: $0.baseAddress!, from: 1..<3) } - XCTAssertEqual([UInt8(1), UInt8(2), UInt8(2), UInt8(3)], array) + #expect([UInt8(1), UInt8(2), UInt8(2), UInt8(3)] == array) } - func test_copyBytes2() { + @Test func copyBytes2() { let array: [UInt8] = [0, 1, 2, 3] let data = Data(array) @@ -797,10 +802,10 @@ class DataTests : XCTestCase { let end = data.index(before: data.endIndex) let slice = data[start..(_:)` -- a discontiguous sequence of unknown length. - func test_appendingNonContiguousSequence_underestimatedCount() { + @Test func appendingNonContiguousSequence_underestimatedCount() { var d = Data() // d should go from .empty representation to .inline. // Appending a small enough sequence to fit in .inline should actually be copied. d.append(contentsOf: (0x00...0x01).makeIterator()) // `.makeIterator()` produces a sequence whose `.underestimatedCount` is 0. - XCTAssertEqual(Data([0x00, 0x01]), d) + #expect(Data([0x00, 0x01]) == d) // Appending another small sequence should similarly still work. d.append(contentsOf: (0x02...0x02).makeIterator()) // `.makeIterator()` produces a sequence whose `.underestimatedCount` is 0. - XCTAssertEqual(Data([0x00, 0x01, 0x02]), d) + #expect(Data([0x00, 0x01, 0x02]) == d) // If we append a sequence of elements larger than a single InlineData, the internal append here should buffer. // We want to make sure that buffering in this way does not accidentally drop trailing elements on the floor. d.append(contentsOf: (0x03...0x2F).makeIterator()) // `.makeIterator()` produces a sequence whose `.underestimatedCount` is 0. - XCTAssertEqual(Data([0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, - 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, - 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F]), d) + #expect(Data([0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F]) == d) } - func test_sequenceInitializers() { + @Test func sequenceInitializers() { let seq = repeatElement(UInt8(0x02), count: 3) // ensure we fall into the sequence case let dataFromSeq = Data(seq) - XCTAssertEqual(3, dataFromSeq.count) - XCTAssertEqual(UInt8(0x02), dataFromSeq[0]) - XCTAssertEqual(UInt8(0x02), dataFromSeq[1]) - XCTAssertEqual(UInt8(0x02), dataFromSeq[2]) + #expect(3 == dataFromSeq.count) + #expect(UInt8(0x02) == dataFromSeq[0]) + #expect(UInt8(0x02) == dataFromSeq[1]) + #expect(UInt8(0x02) == dataFromSeq[2]) let array: [UInt8] = [0, 1, 2, 3, 4, 5, 6] let dataFromArray = Data(array) - XCTAssertEqual(array.count, dataFromArray.count) - XCTAssertEqual(array[0], dataFromArray[0]) - XCTAssertEqual(array[1], dataFromArray[1]) - XCTAssertEqual(array[2], dataFromArray[2]) - XCTAssertEqual(array[3], dataFromArray[3]) + #expect(array.count == dataFromArray.count) + #expect(array[0] == dataFromArray[0]) + #expect(array[1] == dataFromArray[1]) + #expect(array[2] == dataFromArray[2]) + #expect(array[3] == dataFromArray[3]) let slice = array[1..<4] let dataFromSlice = Data(slice) - XCTAssertEqual(slice.count, dataFromSlice.count) - XCTAssertEqual(slice.first, dataFromSlice.first) - XCTAssertEqual(slice.last, dataFromSlice.last) + #expect(slice.count == dataFromSlice.count) + #expect(slice.first == dataFromSlice.first) + #expect(slice.last == dataFromSlice.last) let data = Data([1, 2, 3, 4, 5, 6, 7, 8, 9]) let dataFromData = Data(data) - XCTAssertEqual(data, dataFromData) + #expect(data == dataFromData) let sliceOfData = data[1..<3] let dataFromSliceOfData = Data(sliceOfData) - XCTAssertEqual(sliceOfData, dataFromSliceOfData) + #expect(sliceOfData == dataFromSliceOfData) } - func test_reversedDataInit() { + @Test func reversedDataInit() { let data = Data([1, 2, 3, 4, 5, 6, 7, 8, 9]) let reversedData = Data(data.reversed()) let expected = Data([9, 8, 7, 6, 5, 4, 3, 2, 1]) - XCTAssertEqual(expected, reversedData) + #expect(expected == reversedData) } - func test_validateMutation_withUnsafeMutableBytes() { + @Test func validateMutation_withUnsafeMutableBytes() { var data = Data([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) data.withUnsafeMutableUInt8Bytes { (ptr: UnsafeMutablePointer) in ptr.advanced(by: 5).pointee = 0xFF } - XCTAssertEqual(data, Data([0, 1, 2, 3, 4, 0xFF, 6, 7, 8, 9])) + #expect(data == Data([0, 1, 2, 3, 4, 0xFF, 6, 7, 8, 9])) } - func test_validateMutation_appendBytes() { + @Test func validateMutation_appendBytes() { var data = Data([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) data.append("hello", count: 5) - XCTAssertEqual(data[data.startIndex.advanced(by: 5)], 0x5) + #expect(data[data.startIndex.advanced(by: 5)] == 0x5) } - func test_validateMutation_appendData() { + @Test func validateMutation_appendData() { var data = Data([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) let other = Data([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) data.append(other) - XCTAssertEqual(data[data.startIndex.advanced(by: 9)], 9) - XCTAssertEqual(data[data.startIndex.advanced(by: 10)], 0) + #expect(data[data.startIndex.advanced(by: 9)] == 9) + #expect(data[data.startIndex.advanced(by: 10)] == 0) } - func test_validateMutation_appendBuffer() { + @Test func validateMutation_appendBuffer() { var data = Data([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) let bytes: [UInt8] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] bytes.withUnsafeBufferPointer { data.append($0) } - XCTAssertEqual(data[data.startIndex.advanced(by: 9)], 9) - XCTAssertEqual(data[data.startIndex.advanced(by: 10)], 0) + #expect(data[data.startIndex.advanced(by: 9)] == 9) + #expect(data[data.startIndex.advanced(by: 10)] == 0) } - func test_validateMutation_appendSequence() { + @Test func validateMutation_appendSequence() { var data = Data([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) let seq = repeatElement(UInt8(1), count: 10) data.append(contentsOf: seq) - XCTAssertEqual(data[data.startIndex.advanced(by: 9)], 9) - XCTAssertEqual(data[data.startIndex.advanced(by: 10)], 1) + #expect(data[data.startIndex.advanced(by: 9)] == 9) + #expect(data[data.startIndex.advanced(by: 10)] == 1) } - func test_validateMutation_appendContentsOf() { + @Test func validateMutation_appendContentsOf() { var data = Data([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) let bytes: [UInt8] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] data.append(contentsOf: bytes) - XCTAssertEqual(data[data.startIndex.advanced(by: 9)], 9) - XCTAssertEqual(data[data.startIndex.advanced(by: 10)], 0) + #expect(data[data.startIndex.advanced(by: 9)] == 9) + #expect(data[data.startIndex.advanced(by: 10)] == 0) } - func test_validateMutation_resetBytes() { + @Test func validateMutation_resetBytes() { var data = Data([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) data.resetBytes(in: 5..<8) - XCTAssertEqual(data, Data([0, 1, 2, 3, 4, 0, 0, 0, 8, 9])) + #expect(data == Data([0, 1, 2, 3, 4, 0, 0, 0, 8, 9])) } - func test_validateMutation_replaceSubrange() { + @Test func validateMutation_replaceSubrange() { var data = Data([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) let range: Range = data.startIndex.advanced(by: 4).. = data.startIndex.advanced(by: 4).. = data.startIndex.advanced(by: 4).. = data.startIndex.advanced(by: 4).. = data.startIndex.advanced(by: 4)..) in ptr.advanced(by: 1).pointee = 0xFF } - XCTAssertEqual(data, Data([4, 0xFF, 6, 7, 8])) + #expect(data == Data([4, 0xFF, 6, 7, 8])) } - func test_validateMutation_slice_appendBytes() { + @Test func validateMutation_slice_appendBytes() { var data = Data([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])[4..<9] let bytes: [UInt8] = [0xFF, 0xFF] bytes.withUnsafeBufferPointer { data.append($0.baseAddress!, count: $0.count) } - XCTAssertEqual(data, Data([4, 5, 6, 7, 8, 0xFF, 0xFF])) + #expect(data == Data([4, 5, 6, 7, 8, 0xFF, 0xFF])) } - func test_validateMutation_slice_appendData() { + @Test func validateMutation_slice_appendData() { var data = Data([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])[4..<9] let other = Data([0xFF, 0xFF]) data.append(other) - XCTAssertEqual(data, Data([4, 5, 6, 7, 8, 0xFF, 0xFF])) + #expect(data == Data([4, 5, 6, 7, 8, 0xFF, 0xFF])) } - func test_validateMutation_slice_appendBuffer() { + @Test func validateMutation_slice_appendBuffer() { var data = Data([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])[4..<9] let bytes: [UInt8] = [0xFF, 0xFF] bytes.withUnsafeBufferPointer { data.append($0) } - XCTAssertEqual(data, Data([4, 5, 6, 7, 8, 0xFF, 0xFF])) + #expect(data == Data([4, 5, 6, 7, 8, 0xFF, 0xFF])) } - func test_validateMutation_slice_appendSequence() { + @Test func validateMutation_slice_appendSequence() { var data = Data([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])[4..<9] let seq = repeatElement(UInt8(0xFF), count: 2) data.append(contentsOf: seq) - XCTAssertEqual(data, Data([4, 5, 6, 7, 8, 0xFF, 0xFF])) + #expect(data == Data([4, 5, 6, 7, 8, 0xFF, 0xFF])) } - func test_validateMutation_slice_appendContentsOf() { + @Test func validateMutation_slice_appendContentsOf() { var data = Data([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])[4..<9] let bytes: [UInt8] = [0xFF, 0xFF] data.append(contentsOf: bytes) - XCTAssertEqual(data, Data([4, 5, 6, 7, 8, 0xFF, 0xFF])) + #expect(data == Data([4, 5, 6, 7, 8, 0xFF, 0xFF])) } - func test_validateMutation_slice_resetBytes() { + @Test func validateMutation_slice_resetBytes() { var data = Data([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])[4..<9] data.resetBytes(in: 5..<8) - XCTAssertEqual(data, Data([4, 0, 0, 0, 8])) + #expect(data == Data([4, 0, 0, 0, 8])) } - func test_validateMutation_slice_replaceSubrange() { + @Test func validateMutation_slice_replaceSubrange() { var data = Data([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])[4..<9] let range: Range = data.startIndex.advanced(by: 1).. = data.startIndex.advanced(by: 1).. = data.startIndex.advanced(by: 1).. = data.startIndex.advanced(by: 1).. = data.startIndex.advanced(by: 1)..) in ptr.advanced(by: 5).pointee = 0xFF } - XCTAssertEqual(data, Data([0, 1, 2, 3, 4, 0xFF, 6, 7, 8, 9])) + #expect(data == Data([0, 1, 2, 3, 4, 0xFF, 6, 7, 8, 9])) } } - func test_validateMutation_cow_appendBytes() { + @Test func validateMutation_cow_appendBytes() { var data = Data([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) holdReference(data) { data.append("hello", count: 5) - XCTAssertEqual(data[data.startIndex.advanced(by: 9)], 0x9) - XCTAssertEqual(data[data.startIndex.advanced(by: 10)], 0x68) + #expect(data[data.startIndex.advanced(by: 9)] == 0x9) + #expect(data[data.startIndex.advanced(by: 10)] == 0x68) } } - func test_validateMutation_cow_appendData() { + @Test func validateMutation_cow_appendData() { var data = Data([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) holdReference(data) { let other = Data([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) data.append(other) - XCTAssertEqual(data[data.startIndex.advanced(by: 9)], 9) - XCTAssertEqual(data[data.startIndex.advanced(by: 10)], 0) + #expect(data[data.startIndex.advanced(by: 9)] == 9) + #expect(data[data.startIndex.advanced(by: 10)] == 0) } } - func test_validateMutation_cow_appendBuffer() { + @Test func validateMutation_cow_appendBuffer() { var data = Data([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) holdReference(data) { let bytes: [UInt8] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] bytes.withUnsafeBufferPointer { data.append($0) } - XCTAssertEqual(data[data.startIndex.advanced(by: 9)], 9) - XCTAssertEqual(data[data.startIndex.advanced(by: 10)], 0) + #expect(data[data.startIndex.advanced(by: 9)] == 9) + #expect(data[data.startIndex.advanced(by: 10)] == 0) } } - func test_validateMutation_cow_appendSequence() { + @Test func validateMutation_cow_appendSequence() { var data = Data([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) holdReference(data) { let seq = repeatElement(UInt8(1), count: 10) data.append(contentsOf: seq) - XCTAssertEqual(data[data.startIndex.advanced(by: 9)], 9) - XCTAssertEqual(data[data.startIndex.advanced(by: 10)], 1) + #expect(data[data.startIndex.advanced(by: 9)] == 9) + #expect(data[data.startIndex.advanced(by: 10)] == 1) } } - func test_validateMutation_cow_appendContentsOf() { + @Test func validateMutation_cow_appendContentsOf() { var data = Data([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) holdReference(data) { let bytes: [UInt8] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] data.append(contentsOf: bytes) - XCTAssertEqual(data[data.startIndex.advanced(by: 9)], 9) - XCTAssertEqual(data[data.startIndex.advanced(by: 10)], 0) + #expect(data[data.startIndex.advanced(by: 9)] == 9) + #expect(data[data.startIndex.advanced(by: 10)] == 0) } } - func test_validateMutation_cow_resetBytes() { + @Test func validateMutation_cow_resetBytes() { var data = Data([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) holdReference(data) { data.resetBytes(in: 5..<8) - XCTAssertEqual(data, Data([0, 1, 2, 3, 4, 0, 0, 0, 8, 9])) + #expect(data == Data([0, 1, 2, 3, 4, 0, 0, 0, 8, 9])) } } - func test_validateMutation_cow_replaceSubrange() { + @Test func validateMutation_cow_replaceSubrange() { var data = Data([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) holdReference(data) { let range: Range = data.startIndex.advanced(by: 4).. = data.startIndex.advanced(by: 4).. = data.startIndex.advanced(by: 4).. = data.startIndex.advanced(by: 4).. = data.startIndex.advanced(by: 4)..) in ptr.advanced(by: 1).pointee = 0xFF } - XCTAssertEqual(data, Data([4, 0xFF, 6, 7, 8])) + #expect(data == Data([4, 0xFF, 6, 7, 8])) } } - func test_validateMutation_slice_cow_appendBytes() { + @Test func validateMutation_slice_cow_appendBytes() { var data = Data([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])[4..<9] holdReference(data) { data.append("hello", count: 5) - XCTAssertEqual(data[data.startIndex.advanced(by: 4)], 0x8) - XCTAssertEqual(data[data.startIndex.advanced(by: 5)], 0x68) + #expect(data[data.startIndex.advanced(by: 4)] == 0x8) + #expect(data[data.startIndex.advanced(by: 5)] == 0x68) } } - func test_validateMutation_slice_cow_appendData() { + @Test func validateMutation_slice_cow_appendData() { var data = Data([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])[4..<9] holdReference(data) { let other = Data([0xFF, 0xFF]) data.append(other) - XCTAssertEqual(data, Data([4, 5, 6, 7, 8, 0xFF, 0xFF])) + #expect(data == Data([4, 5, 6, 7, 8, 0xFF, 0xFF])) } } - func test_validateMutation_slice_cow_appendBuffer() { + @Test func validateMutation_slice_cow_appendBuffer() { var data = Data([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])[4..<9] holdReference(data) { let bytes: [UInt8] = [0xFF, 0xFF] bytes.withUnsafeBufferPointer { data.append($0) } - XCTAssertEqual(data, Data([4, 5, 6, 7, 8, 0xFF, 0xFF])) + #expect(data == Data([4, 5, 6, 7, 8, 0xFF, 0xFF])) } } - func test_validateMutation_slice_cow_appendSequence() { + @Test func validateMutation_slice_cow_appendSequence() { var data = Data([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])[4..<9] holdReference(data) { let seq = repeatElement(UInt8(0xFF), count: 2) data.append(contentsOf: seq) - XCTAssertEqual(data, Data([4, 5, 6, 7, 8, 0xFF, 0xFF])) + #expect(data == Data([4, 5, 6, 7, 8, 0xFF, 0xFF])) } } - func test_validateMutation_slice_cow_appendContentsOf() { + @Test func validateMutation_slice_cow_appendContentsOf() { var data = Data([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])[4..<9] holdReference(data) { let bytes: [UInt8] = [0xFF, 0xFF] data.append(contentsOf: bytes) - XCTAssertEqual(data, Data([4, 5, 6, 7, 8, 0xFF, 0xFF])) + #expect(data == Data([4, 5, 6, 7, 8, 0xFF, 0xFF])) } } - func test_validateMutation_slice_cow_resetBytes() { + @Test func validateMutation_slice_cow_resetBytes() { var data = Data([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])[4..<9] holdReference(data) { data.resetBytes(in: 5..<8) - XCTAssertEqual(data, Data([4, 0, 0, 0, 8])) + #expect(data == Data([4, 0, 0, 0, 8])) } } - func test_validateMutation_slice_cow_replaceSubrange() { + @Test func validateMutation_slice_cow_replaceSubrange() { var data = Data([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])[4..<9] holdReference(data) { let range: Range = data.startIndex.advanced(by: 1).. = data.startIndex.advanced(by: 1).. = data.startIndex.advanced(by: 1).. = data.startIndex.advanced(by: 1).. = data.startIndex.advanced(by: 1)..) in ptr.advanced(by: 1).pointee = 0xFF } - XCTAssertEqual(data, Data([4, 0xFF])) + #expect(data == Data([4, 0xFF])) } - func test_increaseCount() { + @Test func increaseCount() { let initials: [Range] = [ 0..<0, 0..<2, @@ -1478,14 +1483,14 @@ class DataTests : XCTestCase { for diff in diffs { var data = Data(initial) data.count += diff - XCTAssertEqual( - Data(Array(initial) + Array(repeating: 0, count: diff)), + #expect( + Data(Array(initial) + Array(repeating: 0, count: diff)) == data) } } } - func test_decreaseCount() { + @Test func decreaseCount() { let initials: [Range] = [ 0..<0, 0..<2, @@ -1501,25 +1506,25 @@ class DataTests : XCTestCase { guard initial.count >= diff else { continue } var data = Data(initial) data.count -= diff - XCTAssertEqual( - Data(initial.dropLast(diff)), + #expect( + Data(initial.dropLast(diff)) == data) } } } - func test_decrease_increase_count() { + @Test func decrease_increase_count() { var data = Data(Array(repeating: 0, count: 8) + [42]) data.count -= 1 - XCTAssertEqual(Data(Array(repeating: 0, count: 8)), data) + #expect(Data(Array(repeating: 0, count: 8)) == data) data.count += 1 - XCTAssertEqual(Data(Array(repeating: 0, count: 9)), data) + #expect(Data(Array(repeating: 0, count: 9)) == data) data = Data(Array(repeating: 0, count: 64) + [42]) data.count -= 1 - XCTAssertEqual(Data(Array(repeating: 0, count: 64)), data) + #expect(Data(Array(repeating: 0, count: 64)) == data) data.count += 1 - XCTAssertEqual(Data(Array(repeating: 0, count: 65)), data) + #expect(Data(Array(repeating: 0, count: 65)) == data) } // This is a (potentially invalid) sequence that produces a configurable number of 42s and has a freely customizable `underestimatedCount`. @@ -1544,26 +1549,26 @@ class DataTests : XCTestCase { } } - func test_init_TestSequence() { + @Test func init_TestSequence() { // Underestimated count do { let d = Data(TestSequence(underestimatedCount: 0, count: 10)) - XCTAssertEqual(10, d.count) - XCTAssertEqual(Array(repeating: 42 as UInt8, count: 10), Array(d)) + #expect(10 == d.count) + #expect(Array(repeating: 42 as UInt8, count: 10) == Array(d)) } // Very underestimated count (to exercise realloc path) do { let d = Data(TestSequence(underestimatedCount: 0, count: 1000)) - XCTAssertEqual(1000, d.count) - XCTAssertEqual(Array(repeating: 42 as UInt8, count: 1000), Array(d)) + #expect(1000 == d.count) + #expect(Array(repeating: 42 as UInt8, count: 1000) == Array(d)) } // Exact count do { let d = Data(TestSequence(underestimatedCount: 10, count: 10)) - XCTAssertEqual(10, d.count) - XCTAssertEqual(Array(repeating: 42 as UInt8, count: 10), Array(d)) + #expect(10 == d.count) + #expect(Array(repeating: 42 as UInt8, count: 10) == Array(d)) } // Overestimated count. This is an illegal case, so trapping would be fine. @@ -1571,37 +1576,36 @@ class DataTests : XCTestCase { // handles this case by simply truncating itself to the actual size. do { let d = Data(TestSequence(underestimatedCount: 20, count: 10)) - XCTAssertEqual(10, d.count) - XCTAssertEqual(Array(repeating: 42 as UInt8, count: 10), Array(d)) + #expect(10 == d.count) + #expect(Array(repeating: 42 as UInt8, count: 10) == Array(d)) } } - func test_append_TestSequence() { + @Test func append_TestSequence() { let base = Data(Array(repeating: 23 as UInt8, count: 10)) // Underestimated count do { var d = base d.append(contentsOf: TestSequence(underestimatedCount: 0, count: 10)) - XCTAssertEqual(20, d.count) - XCTAssertEqual(Array(base) + Array(repeating: 42 as UInt8, count: 10), - Array(d)) + #expect(20 == d.count) + #expect(Array(base) + Array(repeating: 42 as UInt8, count: 10) == Array(d)) } // Very underestimated count (to exercise realloc path) do { var d = base d.append(contentsOf: TestSequence(underestimatedCount: 0, count: 1000)) - XCTAssertEqual(1010, d.count) - XCTAssertEqual(Array(base) + Array(repeating: 42 as UInt8, count: 1000), Array(d)) + #expect(1010 == d.count) + #expect(Array(base) + Array(repeating: 42 as UInt8, count: 1000) == Array(d)) } // Exact count do { var d = base d.append(contentsOf: TestSequence(underestimatedCount: 10, count: 10)) - XCTAssertEqual(20, d.count) - XCTAssertEqual(Array(base) + Array(repeating: 42 as UInt8, count: 10), Array(d)) + #expect(20 == d.count) + #expect(Array(base) + Array(repeating: 42 as UInt8, count: 10) == Array(d)) } // Overestimated count. This is an illegal case, so trapping would be fine. @@ -1610,270 +1614,209 @@ class DataTests : XCTestCase { do { var d = base d.append(contentsOf: TestSequence(underestimatedCount: 20, count: 10)) - XCTAssertEqual(20, d.count) - XCTAssertEqual(Array(base) + Array(repeating: 42 as UInt8, count: 10), Array(d)) + #expect(20 == d.count) + #expect(Array(base) + Array(repeating: 42 as UInt8, count: 10) == Array(d)) } } - func testAdvancedBy() { + @Test func advancedBy() async { let source: Data = Data([1, 42, 64, 8]) - XCTAssertEqual(source.advanced(by: 0), Data([1, 42, 64, 8])) - XCTAssertEqual(source.advanced(by: 2), Data([64, 8])) - XCTAssertEqual(source.advanced(by: 4), Data()) + #expect(source.advanced(by: 0) == Data([1, 42, 64, 8])) + #expect(source.advanced(by: 2) == Data([64, 8])) + #expect(source.advanced(by: 4) == Data()) // Make sure .advanced creates a new data - XCTAssert(source.advanced(by: 3).startIndex == 0) + #expect(source.advanced(by: 3).startIndex == 0) // Make sure .advanced works on Data whose `startIndex` isn't 0 let offsetData: Data = Data([1, 42, 64, 8, 90, 80])[1..<5] - XCTAssertEqual(offsetData.advanced(by: 0), Data([42, 64, 8, 90])) - XCTAssertEqual(offsetData.advanced(by: 2), Data([8, 90])) - XCTAssertEqual(offsetData.advanced(by: 4), Data()) - XCTAssert(offsetData.advanced(by: 3).startIndex == 0) + #expect(offsetData.advanced(by: 0) == Data([42, 64, 8, 90])) + #expect(offsetData.advanced(by: 2) == Data([8, 90])) + #expect(offsetData.advanced(by: 4) == Data()) + #expect(offsetData.advanced(by: 3).startIndex == 0) - // FIXME: XCTest doesn't support crash tests yet rdar://20195010&22387653 - // source.advanced(by: -1) - // source.advanced(by: 5) + #if FOUNDATION_EXIT_TESTS + await #expect(processExitsWith: .failure) { + let source: Data = Data([1, 42, 64, 8]) + _ = source.advanced(by: -1) + } + await #expect(processExitsWith: .failure) { + let source: Data = Data([1, 42, 64, 8]) + _ = source.advanced(by: 5) + } + #endif } - func test_InlineDataSpan() throws { - guard #available(FoundationSpan 6.2, *) else { throw XCTSkip("Span not available") } - + @available(FoundationSpan 6.2, *) + @Test func inlineDataSpan() throws { var source = Data() var span = source.span - XCTAssertTrue(span.isEmpty) + var isEmpty = span.isEmpty + #expect(isEmpty) source.append(contentsOf: [1, 2, 3]) span = source.span - XCTAssertFalse(span.isEmpty) - XCTAssertEqual(span.count, source.count) - XCTAssertEqual(span[0], 1) + isEmpty = span.isEmpty + #expect(!isEmpty) + #expect(span.count == source.count) + let firstElement = span[0] + #expect(firstElement == 1) } - func test_InlineSliceDataSpan() throws { - guard #available(FoundationSpan 6.2, *) else { throw XCTSkip("Span not available") } - + @available(FoundationSpan 6.2, *) + @Test func inlineSliceDataSpan() throws { let source = Data(0 ... .max) let span = source.span - XCTAssertEqual(span.count, source.count) - XCTAssertEqual(span[span.indices.last!], .max) + #expect(span.count == source.count) + #expect(span[span.indices.last!] == .max) } - func test_LargeSliceDataSpan() throws { - guard #available(FoundationSpan 6.2, *) else { throw XCTSkip("Span not available") } - -#if _pointerBitWidth(_64) - let count = Int(Int32.max) -#elseif _pointerBitWidth(_32) - let count = Int(Int16.max) -#else - #error("This test needs updating") -#endif - - let source = Data(repeating: 0, count: count).dropFirst() - XCTAssertNotEqual(source.startIndex, 0) - let span = source.span - XCTAssertFalse(span.isEmpty) - } - - func test_InlineDataMutableSpan() throws { - guard #available(FoundationSpan 6.2, *) else { throw XCTSkip("Span not available") } - + @available(FoundationSpan 6.2, *) + @Test func inlineDataMutableSpan() throws { #if !canImport(Darwin) || FOUNDATION_FRAMEWORK var source = Data() var span = source.mutableSpan - XCTAssertTrue(span.isEmpty) + var isEmpty = span.isEmpty + #expect(isEmpty) source.append(contentsOf: [1, 2, 3]) let count = source.count span = source.mutableSpan - let i = try XCTUnwrap(span.indices.randomElement()) - XCTAssertFalse(span.isEmpty) - XCTAssertEqual(span.count, count) + let indices = span.indices + let i = try #require(indices.randomElement()) + isEmpty = span.isEmpty + #expect(!isEmpty) + #expect(span.count == count) let v = UInt8.random(in: 10..<100) span[i] = v var sub = span.extracting(i ..< i+1) sub.update(repeating: v) - XCTAssertEqual(source[i], v) + #expect(source[i] == v) #endif } - func test_InlineSliceDataMutableSpan() throws { - guard #available(FoundationSpan 6.2, *) else { throw XCTSkip("Span not available") } - + @available(FoundationSpan 6.2, *) + @Test func inlineSliceDataMutableSpan() throws { #if !canImport(Darwin) || FOUNDATION_FRAMEWORK var source = Data(0..<100) let count = source.count var span = source.mutableSpan - XCTAssertEqual(span.count, count) - let i = try XCTUnwrap(span.indices.randomElement()) + #expect(span.count == count) + let i = try #require(span.indices.randomElement()) var sub = span.extracting(i.. length + data.replaceSubrange(2..<4, with: $0) + } } } - #endif - - #if false // FIXME: XCTest doesn't support crash tests yet rdar://20195010&22387653 - func test_bounding_failure_replace3() { - var data = "a".data(using: .utf8)! - var bytes : [UInt8] = [1, 2, 3] - expectCrashLater() - bytes.withUnsafeBufferPointer { + + @Test func bounding_failure_replace4() async { + await #expect(processExitsWith: .failure) { + var data = try #require("a".data(using: .utf8)) + let bytes : [UInt8] = [1, 2, 3] // lowerBound is > length - data.replaceSubrange(2..<4, with: $0) + data.replaceSubrange(2..<4, with: bytes) } } - #endif - - #if false // FIXME: XCTest doesn't support crash tests yet rdar://20195010&22387653 - func test_bounding_failure_replace4() { - var data = "a".data(using: .utf8)! - var bytes : [UInt8] = [1, 2, 3] - expectCrashLater() - // lowerBound is > length - data.replaceSubrange(2..<4, with: bytes) - } - #endif - - #if false // FIXME: XCTest doesn't support crash tests yet rdar://20195010&22387653 - func test_bounding_failure_reset_range() { - var data = "Hello World".data(using: .utf8)! - expectCrashLater() - data.resetBytes(in: 100..<200) + + @Test func bounding_failure_reset_range() async { + await #expect(processExitsWith: .failure) { + var data = try #require("Hello World".data(using: .utf8)) + data.resetBytes(in: 100..<200) + } } - #endif - - #if false // FIXME: XCTest doesn't support crash tests yet rdar://20195010&22387653 - func test_bounding_failure_append_bad_length() { - var data = "Hello World".data(using: .utf8)! - expectCrashLater() - data.append("hello", count: -2) + + @Test func bounding_failure_append_bad_length() async { + await #expect(processExitsWith: .failure) { + var data = try #require("Hello World".data(using: .utf8)) + data.append("hello", count: -2) + } } - #endif - - #if false // FIXME: XCTest doesn't support crash tests yet rdar://20195010&22387653 - func test_bounding_failure_append_absurd_length() { - var data = "Hello World".data(using: .utf8)! - expectCrashLater() - data.append("hello", count: Int.min) + + @Test func bounding_failure_append_absurd_length() async { + await #expect(processExitsWith: .failure) { + var data = try #require("Hello World".data(using: .utf8)) + data.append("hello", count: Int.min) + } } - #endif - - #if false // FIXME: XCTest doesn't support crash tests yet rdar://20195010&22387653 - func test_bounding_failure_subscript() { - var data = "Hello World".data(using: .utf8)! - expectCrashLater() - data[100] = 4 + + @Test func bounding_failure_subscript() async { + await #expect(processExitsWith: .failure) { + var data = try #require("Hello World".data(using: .utf8)) + data[100] = 4 + } } #endif -} - -#if FOUNDATION_FRAMEWORK // FIXME: Re-enable test after String.data(using:) is implemented -extension DataTests { - func test_splittingHttp() { + + @Test func splittingHttp() throws { func split(_ data: Data, on delimiter: String) -> [Data] { let dataDelimiter = delimiter.data(using: .utf8)! var found = [Data]() @@ -1895,26 +1838,27 @@ extension DataTests { if index < data.endIndex { found.append(data[index..) -> Int in let slice = Data(bytesNoCopy: UnsafeMutablePointer(mutating: bytes), count: 1, deallocator: .none) return slice.count } - XCTAssertEqual(len, 1) + #expect(len == 1) } - func test_discontiguousEnumerateBytes() { + #if FOUNDATION_FRAMEWORK + @Test func discontiguousEnumerateBytes() { let dataToEncode = "Hello World".data(using: .utf8)! let subdata1 = dataToEncode.withUnsafeBytes { bytes in @@ -1933,54 +1877,46 @@ extension DataTests { offsets.append(offset) } - XCTAssertEqual(2, numChunks, "composing two dispatch_data should enumerate as structural data as 2 chunks") - XCTAssertEqual(0, offsets[0], "composing two dispatch_data should enumerate as structural data with the first offset as the location of the region") - XCTAssertEqual(dataToEncode.count, offsets[1], "composing two dispatch_data should enumerate as structural data with the first offset as the location of the region") - } - - func test_rangeOfSlice() { - let data = "FooBar".data(using: .ascii)! - let slice = data[3...] // Bar - - let range = slice.range(of: "a".data(using: .ascii)!) - XCTAssertEqual(range, 4..<5 as Range) + #expect(2 == numChunks, "composing two dispatch_data should enumerate as structural data as 2 chunks") + #expect(0 == offsets[0], "composing two dispatch_data should enumerate as structural data with the first offset as the location of the region") + #expect(dataToEncode.count == offsets[1], "composing two dispatch_data should enumerate as structural data with the first offset as the location of the region") } + #endif } -#endif // MARK: - Base64 Encode/Decode Tests extension DataTests { - func test_base64Encode_emptyData() { - XCTAssertEqual(Data().base64EncodedString(), "") - XCTAssertEqual(Data().base64EncodedData(), Data()) + @Test func base64Encode_emptyData() { + #expect(Data().base64EncodedString() == "") + #expect(Data().base64EncodedData() == Data()) } - func test_base64Encode_arrayOfNulls() { + @Test func base64Encode_arrayOfNulls() { let input = Data(repeating: 0, count: 10) - XCTAssertEqual(input.base64EncodedString(), "AAAAAAAAAAAAAA==") - XCTAssertEqual(input.base64EncodedData(), Data("AAAAAAAAAAAAAA==".utf8)) + #expect(input.base64EncodedString() == "AAAAAAAAAAAAAA==") + #expect(input.base64EncodedData() == Data("AAAAAAAAAAAAAA==".utf8)) } - func test_base64Encode_differentPaddingNeeds() { - XCTAssertEqual(Data([1, 2, 3, 4]).base64EncodedString(), "AQIDBA==") - XCTAssertEqual(Data([1, 2, 3, 4, 5]).base64EncodedString(), "AQIDBAU=") - XCTAssertEqual(Data([1, 2, 3, 4, 5, 6]).base64EncodedString(), "AQIDBAUG") + @Test func base64Encode_differentPaddingNeeds() { + #expect(Data([1, 2, 3, 4]).base64EncodedString() == "AQIDBA==") + #expect(Data([1, 2, 3, 4, 5]).base64EncodedString() == "AQIDBAU=") + #expect(Data([1, 2, 3, 4, 5, 6]).base64EncodedString() == "AQIDBAUG") - XCTAssertEqual(Data([1, 2, 3, 4]).base64EncodedString(options: [.lineLength64Characters]), "AQIDBA==") - XCTAssertEqual(Data([1, 2, 3, 4, 5]).base64EncodedString(options: [.lineLength64Characters]), "AQIDBAU=") - XCTAssertEqual(Data([1, 2, 3, 4, 5, 6]).base64EncodedString(options: [.lineLength64Characters]), "AQIDBAUG") + #expect(Data([1, 2, 3, 4]).base64EncodedString(options: [.lineLength64Characters]) == "AQIDBA==") + #expect(Data([1, 2, 3, 4, 5]).base64EncodedString(options: [.lineLength64Characters]) == "AQIDBAU=") + #expect(Data([1, 2, 3, 4, 5, 6]).base64EncodedString(options: [.lineLength64Characters]) == "AQIDBAUG") } - func test_base64Encode_addingLinebreaks() { + @Test func base64Encode_addingLinebreaks() { let input = """ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut at tincidunt arcu. Suspendisse nec sodales erat, sit amet imperdiet ipsum. Etiam sed ornare felis. """ // using .endLineWithLineFeed - XCTAssertEqual( - Data(input.utf8).base64EncodedString(options: [.lineLength64Characters, .endLineWithLineFeed]), + #expect( + Data(input.utf8).base64EncodedString(options: [.lineLength64Characters, .endLineWithLineFeed]) == """ TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVyIGFkaXBpc2Np\n\ bmcgZWxpdC4gVXQgYXQgdGluY2lkdW50IGFyY3UuIFN1c3BlbmRpc3NlIG5lYyBz\n\ @@ -1988,8 +1924,8 @@ extension DataTests { IG9ybmFyZSBmZWxpcy4= """ ) - XCTAssertEqual( - Data(input.utf8).base64EncodedString(options: [.lineLength76Characters, .endLineWithLineFeed]), + #expect( + Data(input.utf8).base64EncodedString(options: [.lineLength76Characters, .endLineWithLineFeed]) == """ TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVyIGFkaXBpc2NpbmcgZWxpdC4g\n\ VXQgYXQgdGluY2lkdW50IGFyY3UuIFN1c3BlbmRpc3NlIG5lYyBzb2RhbGVzIGVyYXQsIHNpdCBh\n\ @@ -1998,8 +1934,8 @@ extension DataTests { ) // using .endLineWithCarriageReturn - XCTAssertEqual( - Data(input.utf8).base64EncodedString(options: [.lineLength64Characters, .endLineWithCarriageReturn]), + #expect( + Data(input.utf8).base64EncodedString(options: [.lineLength64Characters, .endLineWithCarriageReturn]) == """ TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVyIGFkaXBpc2Np\r\ bmcgZWxpdC4gVXQgYXQgdGluY2lkdW50IGFyY3UuIFN1c3BlbmRpc3NlIG5lYyBz\r\ @@ -2007,8 +1943,8 @@ extension DataTests { IG9ybmFyZSBmZWxpcy4= """ ) - XCTAssertEqual( - Data(input.utf8).base64EncodedString(options: [.lineLength76Characters, .endLineWithCarriageReturn]), + #expect( + Data(input.utf8).base64EncodedString(options: [.lineLength76Characters, .endLineWithCarriageReturn]) == """ TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVyIGFkaXBpc2NpbmcgZWxpdC4g\r\ VXQgYXQgdGluY2lkdW50IGFyY3UuIFN1c3BlbmRpc3NlIG5lYyBzb2RhbGVzIGVyYXQsIHNpdCBh\r\ @@ -2017,8 +1953,8 @@ extension DataTests { ) // using .endLineWithLineFeed, .endLineWithCarriageReturn - XCTAssertEqual( - Data(input.utf8).base64EncodedString(options: [.lineLength64Characters, .endLineWithLineFeed, .endLineWithCarriageReturn]), + #expect( + Data(input.utf8).base64EncodedString(options: [.lineLength64Characters, .endLineWithLineFeed, .endLineWithCarriageReturn]) == """ TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVyIGFkaXBpc2Np\r\n\ bmcgZWxpdC4gVXQgYXQgdGluY2lkdW50IGFyY3UuIFN1c3BlbmRpc3NlIG5lYyBz\r\n\ @@ -2026,8 +1962,8 @@ extension DataTests { IG9ybmFyZSBmZWxpcy4= """ ) - XCTAssertEqual( - Data(input.utf8).base64EncodedString(options: [.lineLength76Characters, .endLineWithLineFeed, .endLineWithCarriageReturn]), + #expect( + Data(input.utf8).base64EncodedString(options: [.lineLength76Characters, .endLineWithLineFeed, .endLineWithCarriageReturn]) == """ TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVyIGFkaXBpc2NpbmcgZWxpdC4g\r\n\ VXQgYXQgdGluY2lkdW50IGFyY3UuIFN1c3BlbmRpc3NlIG5lYyBzb2RhbGVzIGVyYXQsIHNpdCBh\r\n\ @@ -2036,8 +1972,8 @@ extension DataTests { ) // using no explicit endLine option - XCTAssertEqual( - Data(input.utf8).base64EncodedString(options: [.lineLength64Characters]), + #expect( + Data(input.utf8).base64EncodedString(options: [.lineLength64Characters]) == """ TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVyIGFkaXBpc2Np\r\n\ bmcgZWxpdC4gVXQgYXQgdGluY2lkdW50IGFyY3UuIFN1c3BlbmRpc3NlIG5lYyBz\r\n\ @@ -2045,8 +1981,8 @@ extension DataTests { IG9ybmFyZSBmZWxpcy4= """ ) - XCTAssertEqual( - Data(input.utf8).base64EncodedString(options: [.lineLength76Characters]), + #expect( + Data(input.utf8).base64EncodedString(options: [.lineLength76Characters]) == """ TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVyIGFkaXBpc2NpbmcgZWxpdC4g\r\n\ VXQgYXQgdGluY2lkdW50IGFyY3UuIFN1c3BlbmRpc3NlIG5lYyBzb2RhbGVzIGVyYXQsIHNpdCBh\r\n\ @@ -2055,28 +1991,27 @@ extension DataTests { ) } - func test_base64Encode_DoesNotAddLineSeparatorsInLastLineWhenStringFitsInLine() { - XCTAssertEqual( - Data(repeating: 0, count: 48).base64EncodedString(options: .lineLength64Characters), + @Test func base64Encode_DoesNotAddLineSeparatorsInLastLineWhenStringFitsInLine() { + #expect( + Data(repeating: 0, count: 48).base64EncodedString(options: .lineLength64Characters) == "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" ) - XCTAssertEqual( - Data(repeating: 0, count: 96).base64EncodedString(options: .lineLength64Characters), + #expect( + Data(repeating: 0, count: 96).base64EncodedString(options: .lineLength64Characters) == """ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\r\n\ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA """ ) - print([UInt8](Data(repeating: 0, count: 96).base64EncodedString(options: .lineLength64Characters).utf8)) - XCTAssertEqual( - Data(repeating: 0, count: 57).base64EncodedString(options: .lineLength76Characters), + #expect( + Data(repeating: 0, count: 57).base64EncodedString(options: .lineLength76Characters) == "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" ) - XCTAssertEqual( - Data(repeating: 0, count: 114).base64EncodedString(options: .lineLength76Characters), + #expect( + Data(repeating: 0, count: 114).base64EncodedString(options: .lineLength76Characters) == """ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\r\n\ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA @@ -2085,25 +2020,25 @@ extension DataTests { } - func test_base64Decode_emptyString() { - XCTAssertEqual(Data(), Data(base64Encoded: "")) + @Test func base64Decode_emptyString() { + #expect(Data() == Data(base64Encoded: "")) } - func test_base64Decode_emptyData() { - XCTAssertEqual(Data(), Data(base64Encoded: Data())) + @Test func base64Decode_emptyData() { + #expect(Data() == Data(base64Encoded: Data())) } - func test_base64Decode_arrayOfNulls() { - XCTAssertEqual(Data(repeating: 0, count: 10), Data(base64Encoded: "AAAAAAAAAAAAAA==")) + @Test func base64Decode_arrayOfNulls() { + #expect(Data(repeating: 0, count: 10) == Data(base64Encoded: "AAAAAAAAAAAAAA==")) } - func test_base64Decode_AllTheBytesSequentially() { + @Test func base64Decode_AllTheBytesSequentially() { let base64 = "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWltcXV5fYGFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6e3x9fn+AgYKDhIWGh4iJiouMjY6PkJGSk5SVlpeYmZqbnJ2en6ChoqOkpaanqKmqq6ytrq+wsbKztLW2t7i5uru8vb6/wMHCw8TFxsfIycrLzM3Oz9DR0tPU1dbX2Nna29zd3t/g4eLj5OXm5+jp6uvs7e7v8PHy8/T19vf4+fr7/P3+/w==" - XCTAssertEqual(Data(UInt8(0) ... UInt8(255)), Data(base64Encoded: base64)) + #expect(Data(UInt8(0) ... UInt8(255)) == Data(base64Encoded: base64)) } - func test_base64Decode_ignoringLineBreaks() { + @Test func base64Decode_ignoringLineBreaks() { let base64 = """ TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVyIGFkaXBpc2Np\r\n\ bmcgZWxpdC4gVXQgYXQgdGluY2lkdW50IGFyY3UuIFN1c3BlbmRpc3NlIG5lYyBz\r\n\ @@ -2114,143 +2049,143 @@ extension DataTests { Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut at tincidunt arcu. Suspendisse nec sodales erat, sit amet imperdiet ipsum. Etiam sed ornare felis. """ - XCTAssertEqual(Data(expected.utf8), Data(base64Encoded: base64, options: .ignoreUnknownCharacters)) - } - - func test_base64Decode_invalidLength() { - XCTAssertNil(Data(base64Encoded: "AAAAA")) - XCTAssertNil(Data(base64Encoded: "AAAAA", options: .ignoreUnknownCharacters)) - } - - func test_base64Decode_variousPaddingNeeds() { - XCTAssertEqual(Data([1, 2, 3, 4]), Data(base64Encoded: "AQIDBA==")) - XCTAssertEqual(Data([1, 2, 3, 4, 5]), Data(base64Encoded: "AQIDBAU=")) - XCTAssertEqual(Data([1, 2, 3, 4, 5, 6]), Data(base64Encoded: "AQIDBAUG")) - } - - func test_base64Decode_ignoreWhitespaceAtVariousPlaces() { - XCTAssertEqual(Data([1, 2, 3, 4]), Data(base64Encoded: " AQIDBA==", options: .ignoreUnknownCharacters)) - XCTAssertEqual(Data([1, 2, 3, 4]), Data(base64Encoded: "A QIDBA==", options: .ignoreUnknownCharacters)) - XCTAssertEqual(Data([1, 2, 3, 4]), Data(base64Encoded: "AQ IDBA==", options: .ignoreUnknownCharacters)) - XCTAssertEqual(Data([1, 2, 3, 4]), Data(base64Encoded: "AQI DBA==", options: .ignoreUnknownCharacters)) - XCTAssertEqual(Data([1, 2, 3, 4]), Data(base64Encoded: "AQID BA==", options: .ignoreUnknownCharacters)) - XCTAssertEqual(Data([1, 2, 3, 4]), Data(base64Encoded: "AQIDB A==", options: .ignoreUnknownCharacters)) - XCTAssertEqual(Data([1, 2, 3, 4]), Data(base64Encoded: "AQIDBA ==", options: .ignoreUnknownCharacters)) - XCTAssertEqual(Data([1, 2, 3, 4]), Data(base64Encoded: "AQIDBA= =", options: .ignoreUnknownCharacters)) - XCTAssertEqual(Data([1, 2, 3, 4]), Data(base64Encoded: "AQIDBA== ", options: .ignoreUnknownCharacters)) - - XCTAssertEqual(Data([1, 2, 3, 4]), Data(base64Encoded: " AQIDBA==", options: .ignoreUnknownCharacters)) - XCTAssertEqual(Data([1, 2, 3, 4]), Data(base64Encoded: "A QIDBA==", options: .ignoreUnknownCharacters)) - XCTAssertEqual(Data([1, 2, 3, 4]), Data(base64Encoded: "AQ IDBA==", options: .ignoreUnknownCharacters)) - XCTAssertEqual(Data([1, 2, 3, 4]), Data(base64Encoded: "AQI DBA==", options: .ignoreUnknownCharacters)) - XCTAssertEqual(Data([1, 2, 3, 4]), Data(base64Encoded: "AQID BA==", options: .ignoreUnknownCharacters)) - XCTAssertEqual(Data([1, 2, 3, 4]), Data(base64Encoded: "AQIDB A==", options: .ignoreUnknownCharacters)) - XCTAssertEqual(Data([1, 2, 3, 4]), Data(base64Encoded: "AQIDBA ==", options: .ignoreUnknownCharacters)) - XCTAssertEqual(Data([1, 2, 3, 4]), Data(base64Encoded: "AQIDBA= =", options: .ignoreUnknownCharacters)) - XCTAssertEqual(Data([1, 2, 3, 4]), Data(base64Encoded: "AQIDBA== ", options: .ignoreUnknownCharacters)) - - XCTAssertEqual(Data([1, 2, 3, 4]), Data(base64Encoded: " AQIDBA==", options: .ignoreUnknownCharacters)) - XCTAssertEqual(Data([1, 2, 3, 4]), Data(base64Encoded: "A QIDBA==", options: .ignoreUnknownCharacters)) - XCTAssertEqual(Data([1, 2, 3, 4]), Data(base64Encoded: "AQ IDBA==", options: .ignoreUnknownCharacters)) - XCTAssertEqual(Data([1, 2, 3, 4]), Data(base64Encoded: "AQI DBA==", options: .ignoreUnknownCharacters)) - XCTAssertEqual(Data([1, 2, 3, 4]), Data(base64Encoded: "AQID BA==", options: .ignoreUnknownCharacters)) - XCTAssertEqual(Data([1, 2, 3, 4]), Data(base64Encoded: "AQIDB A==", options: .ignoreUnknownCharacters)) - XCTAssertEqual(Data([1, 2, 3, 4]), Data(base64Encoded: "AQIDBA ==", options: .ignoreUnknownCharacters)) - XCTAssertEqual(Data([1, 2, 3, 4]), Data(base64Encoded: "AQIDBA= =", options: .ignoreUnknownCharacters)) - XCTAssertEqual(Data([1, 2, 3, 4]), Data(base64Encoded: "AQIDBA== ", options: .ignoreUnknownCharacters)) - - XCTAssertEqual(Data([1, 2, 3, 4]), Data(base64Encoded: " AQIDBA==", options: .ignoreUnknownCharacters)) - XCTAssertEqual(Data([1, 2, 3, 4]), Data(base64Encoded: "A QIDBA==", options: .ignoreUnknownCharacters)) - XCTAssertEqual(Data([1, 2, 3, 4]), Data(base64Encoded: "AQ IDBA==", options: .ignoreUnknownCharacters)) - XCTAssertEqual(Data([1, 2, 3, 4]), Data(base64Encoded: "AQI DBA==", options: .ignoreUnknownCharacters)) - XCTAssertEqual(Data([1, 2, 3, 4]), Data(base64Encoded: "AQID BA==", options: .ignoreUnknownCharacters)) - XCTAssertEqual(Data([1, 2, 3, 4]), Data(base64Encoded: "AQIDB A==", options: .ignoreUnknownCharacters)) - XCTAssertEqual(Data([1, 2, 3, 4]), Data(base64Encoded: "AQIDBA ==", options: .ignoreUnknownCharacters)) - XCTAssertEqual(Data([1, 2, 3, 4]), Data(base64Encoded: "AQIDBA= =", options: .ignoreUnknownCharacters)) - XCTAssertEqual(Data([1, 2, 3, 4]), Data(base64Encoded: "AQIDBA== ", options: .ignoreUnknownCharacters)) - - XCTAssertEqual(Data([1, 2, 3, 4, 5]), Data(base64Encoded: " AQIDBAU=", options: .ignoreUnknownCharacters)) - XCTAssertEqual(Data([1, 2, 3, 4, 5]), Data(base64Encoded: "A QIDBAU=", options: .ignoreUnknownCharacters)) - XCTAssertEqual(Data([1, 2, 3, 4, 5]), Data(base64Encoded: "AQ IDBAU=", options: .ignoreUnknownCharacters)) - XCTAssertEqual(Data([1, 2, 3, 4, 5]), Data(base64Encoded: "AQI DBAU=", options: .ignoreUnknownCharacters)) - XCTAssertEqual(Data([1, 2, 3, 4, 5]), Data(base64Encoded: "AQID BAU=", options: .ignoreUnknownCharacters)) - XCTAssertEqual(Data([1, 2, 3, 4, 5]), Data(base64Encoded: "AQIDB AU=", options: .ignoreUnknownCharacters)) - XCTAssertEqual(Data([1, 2, 3, 4, 5]), Data(base64Encoded: "AQIDBA U=", options: .ignoreUnknownCharacters)) - XCTAssertEqual(Data([1, 2, 3, 4, 5]), Data(base64Encoded: "AQIDBAU =", options: .ignoreUnknownCharacters)) - XCTAssertEqual(Data([1, 2, 3, 4, 5]), Data(base64Encoded: "AQIDBAU= ", options: .ignoreUnknownCharacters)) - - XCTAssertEqual(Data([1, 2, 3, 4, 5]), Data(base64Encoded: " AQIDBAU=", options: .ignoreUnknownCharacters)) - XCTAssertEqual(Data([1, 2, 3, 4, 5]), Data(base64Encoded: "A QIDBAU=", options: .ignoreUnknownCharacters)) - XCTAssertEqual(Data([1, 2, 3, 4, 5]), Data(base64Encoded: "AQ IDBAU=", options: .ignoreUnknownCharacters)) - XCTAssertEqual(Data([1, 2, 3, 4, 5]), Data(base64Encoded: "AQI DBAU=", options: .ignoreUnknownCharacters)) - XCTAssertEqual(Data([1, 2, 3, 4, 5]), Data(base64Encoded: "AQID BAU=", options: .ignoreUnknownCharacters)) - XCTAssertEqual(Data([1, 2, 3, 4, 5]), Data(base64Encoded: "AQIDB AU=", options: .ignoreUnknownCharacters)) - XCTAssertEqual(Data([1, 2, 3, 4, 5]), Data(base64Encoded: "AQIDBA U=", options: .ignoreUnknownCharacters)) - XCTAssertEqual(Data([1, 2, 3, 4, 5]), Data(base64Encoded: "AQIDBAU =", options: .ignoreUnknownCharacters)) - XCTAssertEqual(Data([1, 2, 3, 4, 5]), Data(base64Encoded: "AQIDBAU= ", options: .ignoreUnknownCharacters)) - - XCTAssertEqual(Data([1, 2, 3, 4, 5]), Data(base64Encoded: " AQIDBAU=", options: .ignoreUnknownCharacters)) - XCTAssertEqual(Data([1, 2, 3, 4, 5]), Data(base64Encoded: "A QIDBAU=", options: .ignoreUnknownCharacters)) - XCTAssertEqual(Data([1, 2, 3, 4, 5]), Data(base64Encoded: "AQ IDBAU=", options: .ignoreUnknownCharacters)) - XCTAssertEqual(Data([1, 2, 3, 4, 5]), Data(base64Encoded: "AQI DBAU=", options: .ignoreUnknownCharacters)) - XCTAssertEqual(Data([1, 2, 3, 4, 5]), Data(base64Encoded: "AQID BAU=", options: .ignoreUnknownCharacters)) - XCTAssertEqual(Data([1, 2, 3, 4, 5]), Data(base64Encoded: "AQIDB AU=", options: .ignoreUnknownCharacters)) - XCTAssertEqual(Data([1, 2, 3, 4, 5]), Data(base64Encoded: "AQIDBA U=", options: .ignoreUnknownCharacters)) - XCTAssertEqual(Data([1, 2, 3, 4, 5]), Data(base64Encoded: "AQIDBAU =", options: .ignoreUnknownCharacters)) - XCTAssertEqual(Data([1, 2, 3, 4, 5]), Data(base64Encoded: "AQIDBAU= ", options: .ignoreUnknownCharacters)) - - XCTAssertEqual(Data([1, 2, 3, 4, 5]), Data(base64Encoded: " AQIDBAU=", options: .ignoreUnknownCharacters)) - XCTAssertEqual(Data([1, 2, 3, 4, 5]), Data(base64Encoded: "A QIDBAU=", options: .ignoreUnknownCharacters)) - XCTAssertEqual(Data([1, 2, 3, 4, 5]), Data(base64Encoded: "AQ IDBAU=", options: .ignoreUnknownCharacters)) - XCTAssertEqual(Data([1, 2, 3, 4, 5]), Data(base64Encoded: "AQI DBAU=", options: .ignoreUnknownCharacters)) - XCTAssertEqual(Data([1, 2, 3, 4, 5]), Data(base64Encoded: "AQID BAU=", options: .ignoreUnknownCharacters)) - XCTAssertEqual(Data([1, 2, 3, 4, 5]), Data(base64Encoded: "AQIDB AU=", options: .ignoreUnknownCharacters)) - XCTAssertEqual(Data([1, 2, 3, 4, 5]), Data(base64Encoded: "AQIDBA U=", options: .ignoreUnknownCharacters)) - XCTAssertEqual(Data([1, 2, 3, 4, 5]), Data(base64Encoded: "AQIDBAU =", options: .ignoreUnknownCharacters)) - XCTAssertEqual(Data([1, 2, 3, 4, 5]), Data(base64Encoded: "AQIDBAU= ", options: .ignoreUnknownCharacters)) - - XCTAssertEqual(Data([1, 2, 3, 4, 5, 6]), Data(base64Encoded: " AQIDBAUG", options: .ignoreUnknownCharacters)) - XCTAssertEqual(Data([1, 2, 3, 4, 5, 6]), Data(base64Encoded: "A QIDBAUG", options: .ignoreUnknownCharacters)) - XCTAssertEqual(Data([1, 2, 3, 4, 5, 6]), Data(base64Encoded: "AQ IDBAUG", options: .ignoreUnknownCharacters)) - XCTAssertEqual(Data([1, 2, 3, 4, 5, 6]), Data(base64Encoded: "AQI DBAUG", options: .ignoreUnknownCharacters)) - XCTAssertEqual(Data([1, 2, 3, 4, 5, 6]), Data(base64Encoded: "AQID BAUG", options: .ignoreUnknownCharacters)) - XCTAssertEqual(Data([1, 2, 3, 4, 5, 6]), Data(base64Encoded: "AQIDB AUG", options: .ignoreUnknownCharacters)) - XCTAssertEqual(Data([1, 2, 3, 4, 5, 6]), Data(base64Encoded: "AQIDBA UG", options: .ignoreUnknownCharacters)) - XCTAssertEqual(Data([1, 2, 3, 4, 5, 6]), Data(base64Encoded: "AQIDBAU G", options: .ignoreUnknownCharacters)) - XCTAssertEqual(Data([1, 2, 3, 4, 5, 6]), Data(base64Encoded: "AQIDBAUG ", options: .ignoreUnknownCharacters)) - - XCTAssertEqual(Data([1, 2, 3, 4, 5, 6]), Data(base64Encoded: " AQIDBAUG", options: .ignoreUnknownCharacters)) - XCTAssertEqual(Data([1, 2, 3, 4, 5, 6]), Data(base64Encoded: "A QIDBAUG", options: .ignoreUnknownCharacters)) - XCTAssertEqual(Data([1, 2, 3, 4, 5, 6]), Data(base64Encoded: "AQ IDBAUG", options: .ignoreUnknownCharacters)) - XCTAssertEqual(Data([1, 2, 3, 4, 5, 6]), Data(base64Encoded: "AQI DBAUG", options: .ignoreUnknownCharacters)) - XCTAssertEqual(Data([1, 2, 3, 4, 5, 6]), Data(base64Encoded: "AQID BAUG", options: .ignoreUnknownCharacters)) - XCTAssertEqual(Data([1, 2, 3, 4, 5, 6]), Data(base64Encoded: "AQIDB AUG", options: .ignoreUnknownCharacters)) - XCTAssertEqual(Data([1, 2, 3, 4, 5, 6]), Data(base64Encoded: "AQIDBA UG", options: .ignoreUnknownCharacters)) - XCTAssertEqual(Data([1, 2, 3, 4, 5, 6]), Data(base64Encoded: "AQIDBAU G", options: .ignoreUnknownCharacters)) - XCTAssertEqual(Data([1, 2, 3, 4, 5, 6]), Data(base64Encoded: "AQIDBAUG ", options: .ignoreUnknownCharacters)) - - XCTAssertEqual(Data([1, 2, 3, 4, 5, 6]), Data(base64Encoded: " AQIDBAUG", options: .ignoreUnknownCharacters)) - XCTAssertEqual(Data([1, 2, 3, 4, 5, 6]), Data(base64Encoded: "A QIDBAUG", options: .ignoreUnknownCharacters)) - XCTAssertEqual(Data([1, 2, 3, 4, 5, 6]), Data(base64Encoded: "AQ IDBAUG", options: .ignoreUnknownCharacters)) - XCTAssertEqual(Data([1, 2, 3, 4, 5, 6]), Data(base64Encoded: "AQI DBAUG", options: .ignoreUnknownCharacters)) - XCTAssertEqual(Data([1, 2, 3, 4, 5, 6]), Data(base64Encoded: "AQID BAUG", options: .ignoreUnknownCharacters)) - XCTAssertEqual(Data([1, 2, 3, 4, 5, 6]), Data(base64Encoded: "AQIDB AUG", options: .ignoreUnknownCharacters)) - XCTAssertEqual(Data([1, 2, 3, 4, 5, 6]), Data(base64Encoded: "AQIDBA UG", options: .ignoreUnknownCharacters)) - XCTAssertEqual(Data([1, 2, 3, 4, 5, 6]), Data(base64Encoded: "AQIDBAU G", options: .ignoreUnknownCharacters)) - XCTAssertEqual(Data([1, 2, 3, 4, 5, 6]), Data(base64Encoded: "AQIDBAUG ", options: .ignoreUnknownCharacters)) - - XCTAssertEqual(Data([1, 2, 3, 4, 5, 6]), Data(base64Encoded: " AQIDBAUG", options: .ignoreUnknownCharacters)) - XCTAssertEqual(Data([1, 2, 3, 4, 5, 6]), Data(base64Encoded: "A QIDBAUG", options: .ignoreUnknownCharacters)) - XCTAssertEqual(Data([1, 2, 3, 4, 5, 6]), Data(base64Encoded: "AQ IDBAUG", options: .ignoreUnknownCharacters)) - XCTAssertEqual(Data([1, 2, 3, 4, 5, 6]), Data(base64Encoded: "AQI DBAUG", options: .ignoreUnknownCharacters)) - XCTAssertEqual(Data([1, 2, 3, 4, 5, 6]), Data(base64Encoded: "AQID BAUG", options: .ignoreUnknownCharacters)) - XCTAssertEqual(Data([1, 2, 3, 4, 5, 6]), Data(base64Encoded: "AQIDB AUG", options: .ignoreUnknownCharacters)) - XCTAssertEqual(Data([1, 2, 3, 4, 5, 6]), Data(base64Encoded: "AQIDBA UG", options: .ignoreUnknownCharacters)) - XCTAssertEqual(Data([1, 2, 3, 4, 5, 6]), Data(base64Encoded: "AQIDBAU G", options: .ignoreUnknownCharacters)) - XCTAssertEqual(Data([1, 2, 3, 4, 5, 6]), Data(base64Encoded: "AQIDBAUG ", options: .ignoreUnknownCharacters)) - } - - func test_base64Decode_test1MBDataGoing0to255OverAndOver() { + #expect(Data(expected.utf8) == Data(base64Encoded: base64, options: .ignoreUnknownCharacters)) + } + + @Test func base64Decode_invalidLength() { + #expect(Data(base64Encoded: "AAAAA") == nil) + #expect(Data(base64Encoded: "AAAAA", options: .ignoreUnknownCharacters) == nil) + } + + @Test func base64Decode_variousPaddingNeeds() { + #expect(Data([1, 2, 3, 4]) == Data(base64Encoded: "AQIDBA==")) + #expect(Data([1, 2, 3, 4, 5]) == Data(base64Encoded: "AQIDBAU=")) + #expect(Data([1, 2, 3, 4, 5, 6]) == Data(base64Encoded: "AQIDBAUG")) + } + + @Test func base64Decode_ignoreWhitespaceAtVariousPlaces() { + #expect(Data([1, 2, 3, 4]) == Data(base64Encoded: " AQIDBA==", options: .ignoreUnknownCharacters)) + #expect(Data([1, 2, 3, 4]) == Data(base64Encoded: "A QIDBA==", options: .ignoreUnknownCharacters)) + #expect(Data([1, 2, 3, 4]) == Data(base64Encoded: "AQ IDBA==", options: .ignoreUnknownCharacters)) + #expect(Data([1, 2, 3, 4]) == Data(base64Encoded: "AQI DBA==", options: .ignoreUnknownCharacters)) + #expect(Data([1, 2, 3, 4]) == Data(base64Encoded: "AQID BA==", options: .ignoreUnknownCharacters)) + #expect(Data([1, 2, 3, 4]) == Data(base64Encoded: "AQIDB A==", options: .ignoreUnknownCharacters)) + #expect(Data([1, 2, 3, 4]) == Data(base64Encoded: "AQIDBA ==", options: .ignoreUnknownCharacters)) + #expect(Data([1, 2, 3, 4]) == Data(base64Encoded: "AQIDBA= =", options: .ignoreUnknownCharacters)) + #expect(Data([1, 2, 3, 4]) == Data(base64Encoded: "AQIDBA== ", options: .ignoreUnknownCharacters)) + + #expect(Data([1, 2, 3, 4]) == Data(base64Encoded: " AQIDBA==", options: .ignoreUnknownCharacters)) + #expect(Data([1, 2, 3, 4]) == Data(base64Encoded: "A QIDBA==", options: .ignoreUnknownCharacters)) + #expect(Data([1, 2, 3, 4]) == Data(base64Encoded: "AQ IDBA==", options: .ignoreUnknownCharacters)) + #expect(Data([1, 2, 3, 4]) == Data(base64Encoded: "AQI DBA==", options: .ignoreUnknownCharacters)) + #expect(Data([1, 2, 3, 4]) == Data(base64Encoded: "AQID BA==", options: .ignoreUnknownCharacters)) + #expect(Data([1, 2, 3, 4]) == Data(base64Encoded: "AQIDB A==", options: .ignoreUnknownCharacters)) + #expect(Data([1, 2, 3, 4]) == Data(base64Encoded: "AQIDBA ==", options: .ignoreUnknownCharacters)) + #expect(Data([1, 2, 3, 4]) == Data(base64Encoded: "AQIDBA= =", options: .ignoreUnknownCharacters)) + #expect(Data([1, 2, 3, 4]) == Data(base64Encoded: "AQIDBA== ", options: .ignoreUnknownCharacters)) + + #expect(Data([1, 2, 3, 4]) == Data(base64Encoded: " AQIDBA==", options: .ignoreUnknownCharacters)) + #expect(Data([1, 2, 3, 4]) == Data(base64Encoded: "A QIDBA==", options: .ignoreUnknownCharacters)) + #expect(Data([1, 2, 3, 4]) == Data(base64Encoded: "AQ IDBA==", options: .ignoreUnknownCharacters)) + #expect(Data([1, 2, 3, 4]) == Data(base64Encoded: "AQI DBA==", options: .ignoreUnknownCharacters)) + #expect(Data([1, 2, 3, 4]) == Data(base64Encoded: "AQID BA==", options: .ignoreUnknownCharacters)) + #expect(Data([1, 2, 3, 4]) == Data(base64Encoded: "AQIDB A==", options: .ignoreUnknownCharacters)) + #expect(Data([1, 2, 3, 4]) == Data(base64Encoded: "AQIDBA ==", options: .ignoreUnknownCharacters)) + #expect(Data([1, 2, 3, 4]) == Data(base64Encoded: "AQIDBA= =", options: .ignoreUnknownCharacters)) + #expect(Data([1, 2, 3, 4]) == Data(base64Encoded: "AQIDBA== ", options: .ignoreUnknownCharacters)) + + #expect(Data([1, 2, 3, 4]) == Data(base64Encoded: " AQIDBA==", options: .ignoreUnknownCharacters)) + #expect(Data([1, 2, 3, 4]) == Data(base64Encoded: "A QIDBA==", options: .ignoreUnknownCharacters)) + #expect(Data([1, 2, 3, 4]) == Data(base64Encoded: "AQ IDBA==", options: .ignoreUnknownCharacters)) + #expect(Data([1, 2, 3, 4]) == Data(base64Encoded: "AQI DBA==", options: .ignoreUnknownCharacters)) + #expect(Data([1, 2, 3, 4]) == Data(base64Encoded: "AQID BA==", options: .ignoreUnknownCharacters)) + #expect(Data([1, 2, 3, 4]) == Data(base64Encoded: "AQIDB A==", options: .ignoreUnknownCharacters)) + #expect(Data([1, 2, 3, 4]) == Data(base64Encoded: "AQIDBA ==", options: .ignoreUnknownCharacters)) + #expect(Data([1, 2, 3, 4]) == Data(base64Encoded: "AQIDBA= =", options: .ignoreUnknownCharacters)) + #expect(Data([1, 2, 3, 4]) == Data(base64Encoded: "AQIDBA== ", options: .ignoreUnknownCharacters)) + + #expect(Data([1, 2, 3, 4, 5]) == Data(base64Encoded: " AQIDBAU=", options: .ignoreUnknownCharacters)) + #expect(Data([1, 2, 3, 4, 5]) == Data(base64Encoded: "A QIDBAU=", options: .ignoreUnknownCharacters)) + #expect(Data([1, 2, 3, 4, 5]) == Data(base64Encoded: "AQ IDBAU=", options: .ignoreUnknownCharacters)) + #expect(Data([1, 2, 3, 4, 5]) == Data(base64Encoded: "AQI DBAU=", options: .ignoreUnknownCharacters)) + #expect(Data([1, 2, 3, 4, 5]) == Data(base64Encoded: "AQID BAU=", options: .ignoreUnknownCharacters)) + #expect(Data([1, 2, 3, 4, 5]) == Data(base64Encoded: "AQIDB AU=", options: .ignoreUnknownCharacters)) + #expect(Data([1, 2, 3, 4, 5]) == Data(base64Encoded: "AQIDBA U=", options: .ignoreUnknownCharacters)) + #expect(Data([1, 2, 3, 4, 5]) == Data(base64Encoded: "AQIDBAU =", options: .ignoreUnknownCharacters)) + #expect(Data([1, 2, 3, 4, 5]) == Data(base64Encoded: "AQIDBAU= ", options: .ignoreUnknownCharacters)) + + #expect(Data([1, 2, 3, 4, 5]) == Data(base64Encoded: " AQIDBAU=", options: .ignoreUnknownCharacters)) + #expect(Data([1, 2, 3, 4, 5]) == Data(base64Encoded: "A QIDBAU=", options: .ignoreUnknownCharacters)) + #expect(Data([1, 2, 3, 4, 5]) == Data(base64Encoded: "AQ IDBAU=", options: .ignoreUnknownCharacters)) + #expect(Data([1, 2, 3, 4, 5]) == Data(base64Encoded: "AQI DBAU=", options: .ignoreUnknownCharacters)) + #expect(Data([1, 2, 3, 4, 5]) == Data(base64Encoded: "AQID BAU=", options: .ignoreUnknownCharacters)) + #expect(Data([1, 2, 3, 4, 5]) == Data(base64Encoded: "AQIDB AU=", options: .ignoreUnknownCharacters)) + #expect(Data([1, 2, 3, 4, 5]) == Data(base64Encoded: "AQIDBA U=", options: .ignoreUnknownCharacters)) + #expect(Data([1, 2, 3, 4, 5]) == Data(base64Encoded: "AQIDBAU =", options: .ignoreUnknownCharacters)) + #expect(Data([1, 2, 3, 4, 5]) == Data(base64Encoded: "AQIDBAU= ", options: .ignoreUnknownCharacters)) + + #expect(Data([1, 2, 3, 4, 5]) == Data(base64Encoded: " AQIDBAU=", options: .ignoreUnknownCharacters)) + #expect(Data([1, 2, 3, 4, 5]) == Data(base64Encoded: "A QIDBAU=", options: .ignoreUnknownCharacters)) + #expect(Data([1, 2, 3, 4, 5]) == Data(base64Encoded: "AQ IDBAU=", options: .ignoreUnknownCharacters)) + #expect(Data([1, 2, 3, 4, 5]) == Data(base64Encoded: "AQI DBAU=", options: .ignoreUnknownCharacters)) + #expect(Data([1, 2, 3, 4, 5]) == Data(base64Encoded: "AQID BAU=", options: .ignoreUnknownCharacters)) + #expect(Data([1, 2, 3, 4, 5]) == Data(base64Encoded: "AQIDB AU=", options: .ignoreUnknownCharacters)) + #expect(Data([1, 2, 3, 4, 5]) == Data(base64Encoded: "AQIDBA U=", options: .ignoreUnknownCharacters)) + #expect(Data([1, 2, 3, 4, 5]) == Data(base64Encoded: "AQIDBAU =", options: .ignoreUnknownCharacters)) + #expect(Data([1, 2, 3, 4, 5]) == Data(base64Encoded: "AQIDBAU= ", options: .ignoreUnknownCharacters)) + + #expect(Data([1, 2, 3, 4, 5]) == Data(base64Encoded: " AQIDBAU=", options: .ignoreUnknownCharacters)) + #expect(Data([1, 2, 3, 4, 5]) == Data(base64Encoded: "A QIDBAU=", options: .ignoreUnknownCharacters)) + #expect(Data([1, 2, 3, 4, 5]) == Data(base64Encoded: "AQ IDBAU=", options: .ignoreUnknownCharacters)) + #expect(Data([1, 2, 3, 4, 5]) == Data(base64Encoded: "AQI DBAU=", options: .ignoreUnknownCharacters)) + #expect(Data([1, 2, 3, 4, 5]) == Data(base64Encoded: "AQID BAU=", options: .ignoreUnknownCharacters)) + #expect(Data([1, 2, 3, 4, 5]) == Data(base64Encoded: "AQIDB AU=", options: .ignoreUnknownCharacters)) + #expect(Data([1, 2, 3, 4, 5]) == Data(base64Encoded: "AQIDBA U=", options: .ignoreUnknownCharacters)) + #expect(Data([1, 2, 3, 4, 5]) == Data(base64Encoded: "AQIDBAU =", options: .ignoreUnknownCharacters)) + #expect(Data([1, 2, 3, 4, 5]) == Data(base64Encoded: "AQIDBAU= ", options: .ignoreUnknownCharacters)) + + #expect(Data([1, 2, 3, 4, 5, 6]) == Data(base64Encoded: " AQIDBAUG", options: .ignoreUnknownCharacters)) + #expect(Data([1, 2, 3, 4, 5, 6]) == Data(base64Encoded: "A QIDBAUG", options: .ignoreUnknownCharacters)) + #expect(Data([1, 2, 3, 4, 5, 6]) == Data(base64Encoded: "AQ IDBAUG", options: .ignoreUnknownCharacters)) + #expect(Data([1, 2, 3, 4, 5, 6]) == Data(base64Encoded: "AQI DBAUG", options: .ignoreUnknownCharacters)) + #expect(Data([1, 2, 3, 4, 5, 6]) == Data(base64Encoded: "AQID BAUG", options: .ignoreUnknownCharacters)) + #expect(Data([1, 2, 3, 4, 5, 6]) == Data(base64Encoded: "AQIDB AUG", options: .ignoreUnknownCharacters)) + #expect(Data([1, 2, 3, 4, 5, 6]) == Data(base64Encoded: "AQIDBA UG", options: .ignoreUnknownCharacters)) + #expect(Data([1, 2, 3, 4, 5, 6]) == Data(base64Encoded: "AQIDBAU G", options: .ignoreUnknownCharacters)) + #expect(Data([1, 2, 3, 4, 5, 6]) == Data(base64Encoded: "AQIDBAUG ", options: .ignoreUnknownCharacters)) + + #expect(Data([1, 2, 3, 4, 5, 6]) == Data(base64Encoded: " AQIDBAUG", options: .ignoreUnknownCharacters)) + #expect(Data([1, 2, 3, 4, 5, 6]) == Data(base64Encoded: "A QIDBAUG", options: .ignoreUnknownCharacters)) + #expect(Data([1, 2, 3, 4, 5, 6]) == Data(base64Encoded: "AQ IDBAUG", options: .ignoreUnknownCharacters)) + #expect(Data([1, 2, 3, 4, 5, 6]) == Data(base64Encoded: "AQI DBAUG", options: .ignoreUnknownCharacters)) + #expect(Data([1, 2, 3, 4, 5, 6]) == Data(base64Encoded: "AQID BAUG", options: .ignoreUnknownCharacters)) + #expect(Data([1, 2, 3, 4, 5, 6]) == Data(base64Encoded: "AQIDB AUG", options: .ignoreUnknownCharacters)) + #expect(Data([1, 2, 3, 4, 5, 6]) == Data(base64Encoded: "AQIDBA UG", options: .ignoreUnknownCharacters)) + #expect(Data([1, 2, 3, 4, 5, 6]) == Data(base64Encoded: "AQIDBAU G", options: .ignoreUnknownCharacters)) + #expect(Data([1, 2, 3, 4, 5, 6]) == Data(base64Encoded: "AQIDBAUG ", options: .ignoreUnknownCharacters)) + + #expect(Data([1, 2, 3, 4, 5, 6]) == Data(base64Encoded: " AQIDBAUG", options: .ignoreUnknownCharacters)) + #expect(Data([1, 2, 3, 4, 5, 6]) == Data(base64Encoded: "A QIDBAUG", options: .ignoreUnknownCharacters)) + #expect(Data([1, 2, 3, 4, 5, 6]) == Data(base64Encoded: "AQ IDBAUG", options: .ignoreUnknownCharacters)) + #expect(Data([1, 2, 3, 4, 5, 6]) == Data(base64Encoded: "AQI DBAUG", options: .ignoreUnknownCharacters)) + #expect(Data([1, 2, 3, 4, 5, 6]) == Data(base64Encoded: "AQID BAUG", options: .ignoreUnknownCharacters)) + #expect(Data([1, 2, 3, 4, 5, 6]) == Data(base64Encoded: "AQIDB AUG", options: .ignoreUnknownCharacters)) + #expect(Data([1, 2, 3, 4, 5, 6]) == Data(base64Encoded: "AQIDBA UG", options: .ignoreUnknownCharacters)) + #expect(Data([1, 2, 3, 4, 5, 6]) == Data(base64Encoded: "AQIDBAU G", options: .ignoreUnknownCharacters)) + #expect(Data([1, 2, 3, 4, 5, 6]) == Data(base64Encoded: "AQIDBAUG ", options: .ignoreUnknownCharacters)) + + #expect(Data([1, 2, 3, 4, 5, 6]) == Data(base64Encoded: " AQIDBAUG", options: .ignoreUnknownCharacters)) + #expect(Data([1, 2, 3, 4, 5, 6]) == Data(base64Encoded: "A QIDBAUG", options: .ignoreUnknownCharacters)) + #expect(Data([1, 2, 3, 4, 5, 6]) == Data(base64Encoded: "AQ IDBAUG", options: .ignoreUnknownCharacters)) + #expect(Data([1, 2, 3, 4, 5, 6]) == Data(base64Encoded: "AQI DBAUG", options: .ignoreUnknownCharacters)) + #expect(Data([1, 2, 3, 4, 5, 6]) == Data(base64Encoded: "AQID BAUG", options: .ignoreUnknownCharacters)) + #expect(Data([1, 2, 3, 4, 5, 6]) == Data(base64Encoded: "AQIDB AUG", options: .ignoreUnknownCharacters)) + #expect(Data([1, 2, 3, 4, 5, 6]) == Data(base64Encoded: "AQIDBA UG", options: .ignoreUnknownCharacters)) + #expect(Data([1, 2, 3, 4, 5, 6]) == Data(base64Encoded: "AQIDBAU G", options: .ignoreUnknownCharacters)) + #expect(Data([1, 2, 3, 4, 5, 6]) == Data(base64Encoded: "AQIDBAUG ", options: .ignoreUnknownCharacters)) + } + + @Test func base64Decode_test1MBDataGoing0to255OverAndOver() { let oneMBTestData = createTestData(count: 1000 * 1024) func createTestData(count: Int) -> Data { var data = Data(count: count) @@ -2261,144 +2196,142 @@ extension DataTests { } let base64DataString = oneMBTestData.base64EncodedString(options: .lineLength64Characters) - XCTAssertEqual(oneMBTestData, Data(base64Encoded: base64DataString, options: .ignoreUnknownCharacters)) + #expect(oneMBTestData == Data(base64Encoded: base64DataString, options: .ignoreUnknownCharacters)) } - func test_base64Data_small() { + @Test func base64Data_small() { let data = Data("Hello World".utf8) let base64 = data.base64EncodedString() - XCTAssertEqual("SGVsbG8gV29ybGQ=", base64, "trivial base64 conversion should work") + #expect("SGVsbG8gV29ybGQ=" == base64, "trivial base64 conversion should work") } - func test_base64Data_bad() { - XCTAssertNil(Data(base64Encoded: "signature-not-base64-encoded")) + @Test func base64Data_bad() { + #expect(Data(base64Encoded: "signature-not-base64-encoded") == nil) } - func test_base64Decode_MorePaddingThanNecessary() { - XCTAssertNil(Data(base64Encoded: "=")) - XCTAssertNil(Data(base64Encoded: "==")) - XCTAssertNil(Data(base64Encoded: "===")) + @Test func base64Decode_MorePaddingThanNecessary() { + #expect(Data(base64Encoded: "=") == nil) + #expect(Data(base64Encoded: "==") == nil) + #expect(Data(base64Encoded: "===") == nil) for x in 4..<1000 { - XCTAssertEqual(Data(base64Encoded: String(repeating: "=", count: x)), Data([0])) - } - - XCTAssertEqual(Data(base64Encoded: "AAAA"), Data([0, 0, 0])) - XCTAssertEqual(Data(base64Encoded: "AAAA="), Data([0, 0, 0])) - XCTAssertEqual(Data(base64Encoded: "AAAA=="), Data([0, 0, 0])) - XCTAssertEqual(Data(base64Encoded: "AAAA==="), Data([0, 0, 0])) - XCTAssertEqual(Data(base64Encoded: "AAAA===="), Data([0, 0, 0])) - XCTAssertEqual(Data(base64Encoded: "AAA="), Data([0, 0])) - XCTAssertEqual(Data(base64Encoded: "AAA=="), Data([0, 0])) - XCTAssertEqual(Data(base64Encoded: "AAA==="), Data([0, 0])) - XCTAssertEqual(Data(base64Encoded: "AAA===="), Data([0, 0])) - XCTAssertNil(Data(base64Encoded: "AA=")) - XCTAssertEqual(Data(base64Encoded: "AA=="), Data([0])) - XCTAssertEqual(Data(base64Encoded: "AA==="), Data([0])) - XCTAssertEqual(Data(base64Encoded: "AA===="), Data([0])) - XCTAssertNil(Data(base64Encoded: "A=")) - XCTAssertNil(Data(base64Encoded: "A==")) - XCTAssertNil(Data(base64Encoded: "A===")) - XCTAssertNil(Data(base64Encoded: "A====")) - } - - func test_base64Decode_MorePaddingThanNecessaryIgnoreWhitespace() { - XCTAssertEqual(Data(base64Encoded: "", options: .ignoreUnknownCharacters), Data()) - XCTAssertNil(Data(base64Encoded: "=", options: .ignoreUnknownCharacters)) - XCTAssertNil(Data(base64Encoded: "==", options: .ignoreUnknownCharacters)) - XCTAssertNil(Data(base64Encoded: "===", options: .ignoreUnknownCharacters)) - XCTAssertNil(Data(base64Encoded: "====", options: .ignoreUnknownCharacters)) + #expect(Data(base64Encoded: String(repeating: "=", count: x)) == Data([0])) + } + + #expect(Data(base64Encoded: "AAAA") == Data([0, 0, 0])) + #expect(Data(base64Encoded: "AAAA=") == Data([0, 0, 0])) + #expect(Data(base64Encoded: "AAAA==") == Data([0, 0, 0])) + #expect(Data(base64Encoded: "AAAA===") == Data([0, 0, 0])) + #expect(Data(base64Encoded: "AAAA====") == Data([0, 0, 0])) + #expect(Data(base64Encoded: "AAA=") == Data([0, 0])) + #expect(Data(base64Encoded: "AAA==") == Data([0, 0])) + #expect(Data(base64Encoded: "AAA===") == Data([0, 0])) + #expect(Data(base64Encoded: "AAA====") == Data([0, 0])) + #expect(Data(base64Encoded: "AA=") == nil) + #expect(Data(base64Encoded: "AA==") == Data([0])) + #expect(Data(base64Encoded: "AA===") == Data([0])) + #expect(Data(base64Encoded: "AA====") == Data([0])) + #expect(Data(base64Encoded: "A=") == nil) + #expect(Data(base64Encoded: "A==") == nil) + #expect(Data(base64Encoded: "A===") == nil) + #expect(Data(base64Encoded: "A====") == nil) + } + + @Test func base64Decode_MorePaddingThanNecessaryIgnoreWhitespace() { + #expect(Data(base64Encoded: "", options: .ignoreUnknownCharacters) == Data()) + #expect(Data(base64Encoded: "=", options: .ignoreUnknownCharacters) == nil) + #expect(Data(base64Encoded: "==", options: .ignoreUnknownCharacters) == nil) + #expect(Data(base64Encoded: "===", options: .ignoreUnknownCharacters) == nil) + #expect(Data(base64Encoded: "====", options: .ignoreUnknownCharacters) == nil) for x in 5..<1000 { - XCTAssertNil(Data(base64Encoded: String(repeating: "=", count: x), options: .ignoreUnknownCharacters)) - } - - XCTAssertEqual(Data(base64Encoded: "AAAA", options: .ignoreUnknownCharacters), Data([0, 0, 0])) - XCTAssertEqual(Data(base64Encoded: "AAAA=", options: .ignoreUnknownCharacters), Data([0, 0, 0])) - XCTAssertEqual(Data(base64Encoded: "AAAA =", options: .ignoreUnknownCharacters), Data([0, 0, 0])) - XCTAssertEqual(Data(base64Encoded: "AAAA==", options: .ignoreUnknownCharacters), Data([0, 0, 0])) - XCTAssertEqual(Data(base64Encoded: "AAAA = =", options: .ignoreUnknownCharacters), Data([0, 0, 0])) - XCTAssertEqual(Data(base64Encoded: "AAAA===", options: .ignoreUnknownCharacters), Data([0, 0, 0])) - XCTAssertEqual(Data(base64Encoded: "AAAA = = = ", options: .ignoreUnknownCharacters), Data([0, 0, 0])) - XCTAssertEqual(Data(base64Encoded: "AAAA====", options: .ignoreUnknownCharacters), Data([0, 0, 0])) - XCTAssertEqual(Data(base64Encoded: "AAAA = = = =", options: .ignoreUnknownCharacters), Data([0, 0, 0])) - XCTAssertEqual(Data(base64Encoded: "AAA=", options: .ignoreUnknownCharacters), Data([0, 0])) - XCTAssertEqual(Data(base64Encoded: "AAA==", options: .ignoreUnknownCharacters), Data([0, 0])) - XCTAssertEqual(Data(base64Encoded: "AAA===", options: .ignoreUnknownCharacters), Data([0, 0])) - XCTAssertEqual(Data(base64Encoded: "AAA====", options: .ignoreUnknownCharacters), Data([0, 0])) - XCTAssertNil(Data(base64Encoded: "AA=", options: .ignoreUnknownCharacters)) - XCTAssertEqual(Data(base64Encoded: "AA==", options: .ignoreUnknownCharacters), Data([0])) - XCTAssertEqual(Data(base64Encoded: "AA===", options: .ignoreUnknownCharacters), Data([0])) - XCTAssertEqual(Data(base64Encoded: "AA====", options: .ignoreUnknownCharacters), Data([0])) - XCTAssertNil(Data(base64Encoded: "A=", options: .ignoreUnknownCharacters)) - XCTAssertNil(Data(base64Encoded: "A==", options: .ignoreUnknownCharacters)) - XCTAssertNil(Data(base64Encoded: "A===", options: .ignoreUnknownCharacters)) - XCTAssertNil(Data(base64Encoded: "A====", options: .ignoreUnknownCharacters)) - } - - - func test_base64Data_medium() { + #expect(Data(base64Encoded: String(repeating: "=", count: x), options: .ignoreUnknownCharacters) == nil) + } + + #expect(Data(base64Encoded: "AAAA", options: .ignoreUnknownCharacters) == Data([0, 0, 0])) + #expect(Data(base64Encoded: "AAAA=", options: .ignoreUnknownCharacters) == Data([0, 0, 0])) + #expect(Data(base64Encoded: "AAAA =", options: .ignoreUnknownCharacters) == Data([0, 0, 0])) + #expect(Data(base64Encoded: "AAAA==", options: .ignoreUnknownCharacters) == Data([0, 0, 0])) + #expect(Data(base64Encoded: "AAAA = =", options: .ignoreUnknownCharacters) == Data([0, 0, 0])) + #expect(Data(base64Encoded: "AAAA===", options: .ignoreUnknownCharacters) == Data([0, 0, 0])) + #expect(Data(base64Encoded: "AAAA = = = ", options: .ignoreUnknownCharacters) == Data([0, 0, 0])) + #expect(Data(base64Encoded: "AAAA====", options: .ignoreUnknownCharacters) == Data([0, 0, 0])) + #expect(Data(base64Encoded: "AAAA = = = =", options: .ignoreUnknownCharacters) == Data([0, 0, 0])) + #expect(Data(base64Encoded: "AAA=", options: .ignoreUnknownCharacters) == Data([0, 0])) + #expect(Data(base64Encoded: "AAA==", options: .ignoreUnknownCharacters) == Data([0, 0])) + #expect(Data(base64Encoded: "AAA===", options: .ignoreUnknownCharacters) == Data([0, 0])) + #expect(Data(base64Encoded: "AAA====", options: .ignoreUnknownCharacters) == Data([0, 0])) + #expect(Data(base64Encoded: "AA=", options: .ignoreUnknownCharacters) == nil) + #expect(Data(base64Encoded: "AA==", options: .ignoreUnknownCharacters) == Data([0])) + #expect(Data(base64Encoded: "AA===", options: .ignoreUnknownCharacters) == Data([0])) + #expect(Data(base64Encoded: "AA====", options: .ignoreUnknownCharacters) == Data([0])) + #expect(Data(base64Encoded: "A=", options: .ignoreUnknownCharacters) == nil) + #expect(Data(base64Encoded: "A==", options: .ignoreUnknownCharacters) == nil) + #expect(Data(base64Encoded: "A===", options: .ignoreUnknownCharacters) == nil) + #expect(Data(base64Encoded: "A====", options: .ignoreUnknownCharacters) == nil) + } + + + @Test func base64Data_medium() { let data = Data("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut at tincidunt arcu. Suspendisse nec sodales erat, sit amet imperdiet ipsum. Etiam sed ornare felis. Nunc mauris turpis, bibendum non lectus quis, malesuada placerat turpis. Nam adipiscing non massa et semper. Nulla convallis semper bibendum. Aliquam dictum nulla cursus mi ultricies, at tincidunt mi sagittis. Nulla faucibus at dui quis sodales. Morbi rutrum, dui id ultrices venenatis, arcu urna egestas felis, vel suscipit mauris arcu quis risus. Nunc venenatis ligula at orci tristique, et mattis purus pulvinar. Etiam ultricies est odio. Nunc eleifend malesuada justo, nec euismod sem ultrices quis. Etiam nec nibh sit amet lorem faucibus dapibus quis nec leo. Praesent sit amet mauris vel lacus hendrerit porta mollis consectetur mi. Donec eget tortor dui. Morbi imperdiet, arcu sit amet elementum interdum, quam nisl tempor quam, vitae feugiat augue purus sed lacus. In ac urna adipiscing purus venenatis volutpat vel et metus. Nullam nec auctor quam. Phasellus porttitor felis ac nibh gravida suscipit tempus at ante. Nunc pellentesque iaculis sapien a mattis. Aenean eleifend dolor non nunc laoreet, non dictum massa aliquam. Aenean quis turpis augue. Praesent augue lectus, mollis nec elementum eu, dignissim at velit. Ut congue neque id ullamcorper pellentesque. Maecenas euismod in elit eu vehicula. Nullam tristique dui nulla, nec convallis metus suscipit eget. Cras semper augue nec cursus blandit. Nulla rhoncus et odio quis blandit. Praesent lobortis dignissim velit ut pulvinar. Duis interdum quam adipiscing dolor semper semper. Nunc bibendum convallis dui, eget mollis magna hendrerit et. Morbi facilisis, augue eu fringilla convallis, mauris est cursus dolor, eu posuere odio nunc quis orci. Ut eu justo sem. Phasellus ut erat rhoncus, faucibus arcu vitae, vulputate erat. Aliquam nec magna viverra, interdum est vitae, rhoncus sapien. Duis tincidunt tempor ipsum ut dapibus. Nullam commodo varius metus, sed sollicitudin eros. Etiam nec odio et dui tempor blandit posuere.".utf8) let base64 = data.base64EncodedString() - XCTAssertEqual("TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVyIGFkaXBpc2NpbmcgZWxpdC4gVXQgYXQgdGluY2lkdW50IGFyY3UuIFN1c3BlbmRpc3NlIG5lYyBzb2RhbGVzIGVyYXQsIHNpdCBhbWV0IGltcGVyZGlldCBpcHN1bS4gRXRpYW0gc2VkIG9ybmFyZSBmZWxpcy4gTnVuYyBtYXVyaXMgdHVycGlzLCBiaWJlbmR1bSBub24gbGVjdHVzIHF1aXMsIG1hbGVzdWFkYSBwbGFjZXJhdCB0dXJwaXMuIE5hbSBhZGlwaXNjaW5nIG5vbiBtYXNzYSBldCBzZW1wZXIuIE51bGxhIGNvbnZhbGxpcyBzZW1wZXIgYmliZW5kdW0uIEFsaXF1YW0gZGljdHVtIG51bGxhIGN1cnN1cyBtaSB1bHRyaWNpZXMsIGF0IHRpbmNpZHVudCBtaSBzYWdpdHRpcy4gTnVsbGEgZmF1Y2lidXMgYXQgZHVpIHF1aXMgc29kYWxlcy4gTW9yYmkgcnV0cnVtLCBkdWkgaWQgdWx0cmljZXMgdmVuZW5hdGlzLCBhcmN1IHVybmEgZWdlc3RhcyBmZWxpcywgdmVsIHN1c2NpcGl0IG1hdXJpcyBhcmN1IHF1aXMgcmlzdXMuIE51bmMgdmVuZW5hdGlzIGxpZ3VsYSBhdCBvcmNpIHRyaXN0aXF1ZSwgZXQgbWF0dGlzIHB1cnVzIHB1bHZpbmFyLiBFdGlhbSB1bHRyaWNpZXMgZXN0IG9kaW8uIE51bmMgZWxlaWZlbmQgbWFsZXN1YWRhIGp1c3RvLCBuZWMgZXVpc21vZCBzZW0gdWx0cmljZXMgcXVpcy4gRXRpYW0gbmVjIG5pYmggc2l0IGFtZXQgbG9yZW0gZmF1Y2lidXMgZGFwaWJ1cyBxdWlzIG5lYyBsZW8uIFByYWVzZW50IHNpdCBhbWV0IG1hdXJpcyB2ZWwgbGFjdXMgaGVuZHJlcml0IHBvcnRhIG1vbGxpcyBjb25zZWN0ZXR1ciBtaS4gRG9uZWMgZWdldCB0b3J0b3IgZHVpLiBNb3JiaSBpbXBlcmRpZXQsIGFyY3Ugc2l0IGFtZXQgZWxlbWVudHVtIGludGVyZHVtLCBxdWFtIG5pc2wgdGVtcG9yIHF1YW0sIHZpdGFlIGZldWdpYXQgYXVndWUgcHVydXMgc2VkIGxhY3VzLiBJbiBhYyB1cm5hIGFkaXBpc2NpbmcgcHVydXMgdmVuZW5hdGlzIHZvbHV0cGF0IHZlbCBldCBtZXR1cy4gTnVsbGFtIG5lYyBhdWN0b3IgcXVhbS4gUGhhc2VsbHVzIHBvcnR0aXRvciBmZWxpcyBhYyBuaWJoIGdyYXZpZGEgc3VzY2lwaXQgdGVtcHVzIGF0IGFudGUuIE51bmMgcGVsbGVudGVzcXVlIGlhY3VsaXMgc2FwaWVuIGEgbWF0dGlzLiBBZW5lYW4gZWxlaWZlbmQgZG9sb3Igbm9uIG51bmMgbGFvcmVldCwgbm9uIGRpY3R1bSBtYXNzYSBhbGlxdWFtLiBBZW5lYW4gcXVpcyB0dXJwaXMgYXVndWUuIFByYWVzZW50IGF1Z3VlIGxlY3R1cywgbW9sbGlzIG5lYyBlbGVtZW50dW0gZXUsIGRpZ25pc3NpbSBhdCB2ZWxpdC4gVXQgY29uZ3VlIG5lcXVlIGlkIHVsbGFtY29ycGVyIHBlbGxlbnRlc3F1ZS4gTWFlY2VuYXMgZXVpc21vZCBpbiBlbGl0IGV1IHZlaGljdWxhLiBOdWxsYW0gdHJpc3RpcXVlIGR1aSBudWxsYSwgbmVjIGNvbnZhbGxpcyBtZXR1cyBzdXNjaXBpdCBlZ2V0LiBDcmFzIHNlbXBlciBhdWd1ZSBuZWMgY3Vyc3VzIGJsYW5kaXQuIE51bGxhIHJob25jdXMgZXQgb2RpbyBxdWlzIGJsYW5kaXQuIFByYWVzZW50IGxvYm9ydGlzIGRpZ25pc3NpbSB2ZWxpdCB1dCBwdWx2aW5hci4gRHVpcyBpbnRlcmR1bSBxdWFtIGFkaXBpc2NpbmcgZG9sb3Igc2VtcGVyIHNlbXBlci4gTnVuYyBiaWJlbmR1bSBjb252YWxsaXMgZHVpLCBlZ2V0IG1vbGxpcyBtYWduYSBoZW5kcmVyaXQgZXQuIE1vcmJpIGZhY2lsaXNpcywgYXVndWUgZXUgZnJpbmdpbGxhIGNvbnZhbGxpcywgbWF1cmlzIGVzdCBjdXJzdXMgZG9sb3IsIGV1IHBvc3VlcmUgb2RpbyBudW5jIHF1aXMgb3JjaS4gVXQgZXUganVzdG8gc2VtLiBQaGFzZWxsdXMgdXQgZXJhdCByaG9uY3VzLCBmYXVjaWJ1cyBhcmN1IHZpdGFlLCB2dWxwdXRhdGUgZXJhdC4gQWxpcXVhbSBuZWMgbWFnbmEgdml2ZXJyYSwgaW50ZXJkdW0gZXN0IHZpdGFlLCByaG9uY3VzIHNhcGllbi4gRHVpcyB0aW5jaWR1bnQgdGVtcG9yIGlwc3VtIHV0IGRhcGlidXMuIE51bGxhbSBjb21tb2RvIHZhcml1cyBtZXR1cywgc2VkIHNvbGxpY2l0dWRpbiBlcm9zLiBFdGlhbSBuZWMgb2RpbyBldCBkdWkgdGVtcG9yIGJsYW5kaXQgcG9zdWVyZS4=", base64, "medium base64 conversion should work") + #expect("TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVyIGFkaXBpc2NpbmcgZWxpdC4gVXQgYXQgdGluY2lkdW50IGFyY3UuIFN1c3BlbmRpc3NlIG5lYyBzb2RhbGVzIGVyYXQsIHNpdCBhbWV0IGltcGVyZGlldCBpcHN1bS4gRXRpYW0gc2VkIG9ybmFyZSBmZWxpcy4gTnVuYyBtYXVyaXMgdHVycGlzLCBiaWJlbmR1bSBub24gbGVjdHVzIHF1aXMsIG1hbGVzdWFkYSBwbGFjZXJhdCB0dXJwaXMuIE5hbSBhZGlwaXNjaW5nIG5vbiBtYXNzYSBldCBzZW1wZXIuIE51bGxhIGNvbnZhbGxpcyBzZW1wZXIgYmliZW5kdW0uIEFsaXF1YW0gZGljdHVtIG51bGxhIGN1cnN1cyBtaSB1bHRyaWNpZXMsIGF0IHRpbmNpZHVudCBtaSBzYWdpdHRpcy4gTnVsbGEgZmF1Y2lidXMgYXQgZHVpIHF1aXMgc29kYWxlcy4gTW9yYmkgcnV0cnVtLCBkdWkgaWQgdWx0cmljZXMgdmVuZW5hdGlzLCBhcmN1IHVybmEgZWdlc3RhcyBmZWxpcywgdmVsIHN1c2NpcGl0IG1hdXJpcyBhcmN1IHF1aXMgcmlzdXMuIE51bmMgdmVuZW5hdGlzIGxpZ3VsYSBhdCBvcmNpIHRyaXN0aXF1ZSwgZXQgbWF0dGlzIHB1cnVzIHB1bHZpbmFyLiBFdGlhbSB1bHRyaWNpZXMgZXN0IG9kaW8uIE51bmMgZWxlaWZlbmQgbWFsZXN1YWRhIGp1c3RvLCBuZWMgZXVpc21vZCBzZW0gdWx0cmljZXMgcXVpcy4gRXRpYW0gbmVjIG5pYmggc2l0IGFtZXQgbG9yZW0gZmF1Y2lidXMgZGFwaWJ1cyBxdWlzIG5lYyBsZW8uIFByYWVzZW50IHNpdCBhbWV0IG1hdXJpcyB2ZWwgbGFjdXMgaGVuZHJlcml0IHBvcnRhIG1vbGxpcyBjb25zZWN0ZXR1ciBtaS4gRG9uZWMgZWdldCB0b3J0b3IgZHVpLiBNb3JiaSBpbXBlcmRpZXQsIGFyY3Ugc2l0IGFtZXQgZWxlbWVudHVtIGludGVyZHVtLCBxdWFtIG5pc2wgdGVtcG9yIHF1YW0sIHZpdGFlIGZldWdpYXQgYXVndWUgcHVydXMgc2VkIGxhY3VzLiBJbiBhYyB1cm5hIGFkaXBpc2NpbmcgcHVydXMgdmVuZW5hdGlzIHZvbHV0cGF0IHZlbCBldCBtZXR1cy4gTnVsbGFtIG5lYyBhdWN0b3IgcXVhbS4gUGhhc2VsbHVzIHBvcnR0aXRvciBmZWxpcyBhYyBuaWJoIGdyYXZpZGEgc3VzY2lwaXQgdGVtcHVzIGF0IGFudGUuIE51bmMgcGVsbGVudGVzcXVlIGlhY3VsaXMgc2FwaWVuIGEgbWF0dGlzLiBBZW5lYW4gZWxlaWZlbmQgZG9sb3Igbm9uIG51bmMgbGFvcmVldCwgbm9uIGRpY3R1bSBtYXNzYSBhbGlxdWFtLiBBZW5lYW4gcXVpcyB0dXJwaXMgYXVndWUuIFByYWVzZW50IGF1Z3VlIGxlY3R1cywgbW9sbGlzIG5lYyBlbGVtZW50dW0gZXUsIGRpZ25pc3NpbSBhdCB2ZWxpdC4gVXQgY29uZ3VlIG5lcXVlIGlkIHVsbGFtY29ycGVyIHBlbGxlbnRlc3F1ZS4gTWFlY2VuYXMgZXVpc21vZCBpbiBlbGl0IGV1IHZlaGljdWxhLiBOdWxsYW0gdHJpc3RpcXVlIGR1aSBudWxsYSwgbmVjIGNvbnZhbGxpcyBtZXR1cyBzdXNjaXBpdCBlZ2V0LiBDcmFzIHNlbXBlciBhdWd1ZSBuZWMgY3Vyc3VzIGJsYW5kaXQuIE51bGxhIHJob25jdXMgZXQgb2RpbyBxdWlzIGJsYW5kaXQuIFByYWVzZW50IGxvYm9ydGlzIGRpZ25pc3NpbSB2ZWxpdCB1dCBwdWx2aW5hci4gRHVpcyBpbnRlcmR1bSBxdWFtIGFkaXBpc2NpbmcgZG9sb3Igc2VtcGVyIHNlbXBlci4gTnVuYyBiaWJlbmR1bSBjb252YWxsaXMgZHVpLCBlZ2V0IG1vbGxpcyBtYWduYSBoZW5kcmVyaXQgZXQuIE1vcmJpIGZhY2lsaXNpcywgYXVndWUgZXUgZnJpbmdpbGxhIGNvbnZhbGxpcywgbWF1cmlzIGVzdCBjdXJzdXMgZG9sb3IsIGV1IHBvc3VlcmUgb2RpbyBudW5jIHF1aXMgb3JjaS4gVXQgZXUganVzdG8gc2VtLiBQaGFzZWxsdXMgdXQgZXJhdCByaG9uY3VzLCBmYXVjaWJ1cyBhcmN1IHZpdGFlLCB2dWxwdXRhdGUgZXJhdC4gQWxpcXVhbSBuZWMgbWFnbmEgdml2ZXJyYSwgaW50ZXJkdW0gZXN0IHZpdGFlLCByaG9uY3VzIHNhcGllbi4gRHVpcyB0aW5jaWR1bnQgdGVtcG9yIGlwc3VtIHV0IGRhcGlidXMuIE51bGxhbSBjb21tb2RvIHZhcml1cyBtZXR1cywgc2VkIHNvbGxpY2l0dWRpbiBlcm9zLiBFdGlhbSBuZWMgb2RpbyBldCBkdWkgdGVtcG9yIGJsYW5kaXQgcG9zdWVyZS4=" == base64, "medium base64 conversion should work") } - func test_AnyHashableContainingData() { + @Test func anyHashableContainingData() { let values: [Data] = [ Data(base64Encoded: "AAAA")!, Data(base64Encoded: "AAAB")!, Data(base64Encoded: "AAAB")!, ] let anyHashables = values.map(AnyHashable.init) - expectEqual(Data.self, type(of: anyHashables[0].base)) - expectEqual(Data.self, type(of: anyHashables[1].base)) - expectEqual(Data.self, type(of: anyHashables[2].base)) - XCTAssertNotEqual(anyHashables[0], anyHashables[1]) - XCTAssertEqual(anyHashables[1], anyHashables[2]) + #expect(Data.self == type(of: anyHashables[0].base)) + #expect(Data.self == type(of: anyHashables[1].base)) + #expect(Data.self == type(of: anyHashables[2].base)) + #expect(anyHashables[0] != anyHashables[1]) + #expect(anyHashables[1] == anyHashables[2]) } - func test_replaceSubrange() { + @Test func replaceSubrangeBase64Roundtrip() { // https://bugs.swift.org/browse/SR-4462 let data = Data([0x01, 0x02]) var dataII = Data(base64Encoded: data.base64EncodedString())! dataII.replaceSubrange(0..<1, with: Data()) - XCTAssertEqual(dataII[0], 0x02) + #expect(dataII[0] == 0x02) } - func testEOPNOTSUPP() throws { - #if !canImport(Darwin) && !os(Linux) && !os(Android) - throw XCTSkip("POSIXError.Code is not supported on this platform") - #else + #if canImport(Darwin) || os(Linux) || os(Android) + @Test func cocoaErrorEOPNOTSUPP() throws { // Opening a socket via open(2) on Darwin can result in the EOPNOTSUPP error code // Validate that this does not crash despite missing a case in POSIXError.Code let error = CocoaError.errorWithFilePath("/foo/bar", errno: EOPNOTSUPP, reading: true) - XCTAssertEqual(error.filePath, "/foo/bar") - #endif + #expect(error.filePath == "/foo/bar") } + #endif } #if FOUNDATION_FRAMEWORK // FIXME: Re-enable tests once range(of:) is implemented extension DataTests { - func testRange() { + @Test func range() { let helloWorld = dataFrom("Hello World") let goodbye = dataFrom("Goodbye") let hello = dataFrom("Hello") do { let found = helloWorld.range(of: goodbye) - XCTAssertNil(found) + #expect(found == nil) } do { let found = helloWorld.range(of: goodbye, options: .anchored) - XCTAssertNil(found) + #expect(found == nil) } do { let found = helloWorld.range(of: hello, in: 7..) } } #endif // FOUNDATION_FRAMEWORK #if FOUNDATION_FRAMEWORK // Bridging is not available in the FoundationPreview package extension DataTests { - func test_noCustomDealloc_bridge() { + @Test func noCustomDealloc_bridge() { let bytes = UnsafeMutableRawBufferPointer.allocate(byteCount: 1024, alignment: MemoryLayout.alignment) let data: Data = Data(bytesNoCopy: bytes.baseAddress!, count: bytes.count, deallocator: .free) let copy = data._bridgeToObjectiveC().copy() as! NSData data.withUnsafeBytes { buffer in - XCTAssertEqual(buffer.baseAddress, copy.bytes) + #expect(buffer.baseAddress == copy.bytes) } } - func test_noCopy_uaf_bridge() { + @Test func noCopy_uaf_bridge() { // this can only really be tested (modulo ASAN) via comparison of the pointer address of the storage. let bytes = UnsafeMutableRawBufferPointer.allocate(byteCount: 1024, alignment: MemoryLayout.alignment) let data: Data = Data(bytesNoCopy: bytes.baseAddress!, count: bytes.count, deallocator: .none) let copy = data._bridgeToObjectiveC().copy() as! NSData data.withUnsafeBytes { buffer in - XCTAssertNotEqual(buffer.baseAddress, copy.bytes) + #expect(buffer.baseAddress != copy.bytes) } bytes.deallocate() } } #endif + +// These tests require allocating an extremely large amount of data and are serialized to prevent the test runner from using all available memory at once +@Suite("Large Data Tests", .serialized) +struct LargeDataTests { + @Test + @available(FoundationSpan 6.2, *) + func largeSliceDataSpan() throws { +#if _pointerBitWidth(_64) + let count = Int(Int32.max) +#elseif _pointerBitWidth(_32) + let count = Int(Int16.max) +#else +#error("This test needs updating") +#endif + + let source = Data(repeating: 0, count: count).dropFirst() + #expect(source.startIndex != 0) + let span = source.span + let isEmpty = span.isEmpty + #expect(!isEmpty) + } + + @Test + @available(FoundationSpan 6.2, *) + func largeSliceDataMutableSpan() throws { +#if _pointerBitWidth(_64) + var count = Int(Int32.max) +#elseif _pointerBitWidth(_32) + var count = Int(Int16.max) +#else +#error("This test needs updating") +#endif + +#if !canImport(Darwin) || FOUNDATION_FRAMEWORK + var source = Data(repeating: 0, count: count).dropFirst() + #expect(source.startIndex != 0) + count = source.count + var span = source.mutableSpan + #expect(span.count == count) + let i = try #require(span.indices.dropFirst().randomElement()) + span[i] = .max + #expect(source[i] == 0) + #expect(source[i+1] == .max) +#endif + } + + @Test + @available(FoundationSpan 6.2, *) + func largeSliceDataMutableRawSpan() throws { +#if _pointerBitWidth(_64) + var count = Int(Int32.max) +#elseif _pointerBitWidth(_32) + var count = Int(Int16.max) +#else +#error("This test needs updating") +#endif + + var source = Data(repeating: 0, count: count).dropFirst() + #expect(source.startIndex != 0) + count = source.count + var span = source.mutableBytes + let byteCount = span.byteCount + #expect(byteCount == count) + let i = try #require(span.byteOffsets.dropFirst().randomElement()) + span.storeBytes(of: -1, toByteOffset: i, as: Int8.self) + #expect(source[i] == 0) + #expect(source[i+1] == .max) + } +} diff --git a/Tests/FoundationEssentialsTests/StringTests.swift b/Tests/FoundationEssentialsTests/StringTests.swift index 06ecd170c..1a06c6c43 100644 --- a/Tests/FoundationEssentialsTests/StringTests.swift +++ b/Tests/FoundationEssentialsTests/StringTests.swift @@ -424,6 +424,14 @@ private struct StringTests { #expect("/////".lastPathComponent == "/") #expect("/./..//./..//".lastPathComponent == "..") #expect("/😎/😂/❤️/".lastPathComponent == "❤️") + + #expect("/a/b/c".lastPathComponent == "c") + #expect("/aaa".lastPathComponent == "aaa") + #expect("/a/b/c/".lastPathComponent == "c") + #expect("hello".lastPathComponent == "hello") + #expect("hello/".lastPathComponent == "hello") + #expect("hello///".lastPathComponent == "hello") + #expect("//a//".lastPathComponent == "a") } @Test func testRemovingDotSegments() { @@ -893,6 +901,47 @@ private struct StringTests { #expect(result == expected) } } + + @Test func deletingLastPathComponent() { + #expect("/a/b/c".deletingLastPathComponent() == "/a/b") + #expect("".deletingLastPathComponent() == "") + #expect("/".deletingLastPathComponent() == "/") + #expect("q".deletingLastPathComponent() == "") + #expect("/aaa".deletingLastPathComponent() == "/") + #expect("/aaa/".deletingLastPathComponent() == "/") + #expect("/a/b/c/".deletingLastPathComponent() == "/a/b") + #expect("hello".deletingLastPathComponent() == "") + #expect("hello/".deletingLastPathComponent() == "") + #expect("/hello/".deletingLastPathComponent() == "/") + #expect("hello///".deletingLastPathComponent() == "") + #expect("a/".deletingLastPathComponent() == "") + #expect("a/b".deletingLastPathComponent() == "a") + #expect("a/b/".deletingLastPathComponent() == "a") + #expect("a//b//".deletingLastPathComponent() == "a") + } + + @Test func appendingPathComponent() { + let comp = "test" + #expect("/a/b/c".appendingPathComponent(comp) == "/a/b/c/test") + #expect("".appendingPathComponent(comp) == "test") + #expect("/".appendingPathComponent(comp) == "/test") + #expect("q".appendingPathComponent(comp) == "q/test") + #expect("/aaa".appendingPathComponent(comp) == "/aaa/test") + #expect("/a/b/c/".appendingPathComponent(comp) == "/a/b/c/test") + #expect("hello".appendingPathComponent(comp) == "hello/test") + #expect("hello/".appendingPathComponent(comp) == "hello/test") + + #expect("hello/".appendingPathComponent("/test") == "hello/test") + #expect("hello".appendingPathComponent("/test") == "hello/test") + #expect("hello///".appendingPathComponent("///test") == "hello/test") + #expect("hello".appendingPathComponent("test/") == "hello/test") + #expect("hello".appendingPathComponent("test/test2") == "hello/test/test2") + #expect("hello".appendingPathComponent("test/test2/") == "hello/test/test2") + #expect("hello".appendingPathComponent("test///test2/") == "hello/test/test2") + #expect("hello".appendingPathComponent("/") == "hello") + #expect("//".appendingPathComponent("/") == "/") + #expect("".appendingPathComponent("") == "") + } @Test func dataUsingEncoding() { let s = "hello 🧮"