From 021d42ddab1f3bb149ddfda5cd7417f47052bb39 Mon Sep 17 00:00:00 2001 From: Jeremy Schonfeld Date: Mon, 16 Jun 2025 15:48:33 -0700 Subject: [PATCH 1/7] Convert DataIO tests --- .../DataIOTests.swift | 268 ++++++++---------- 1 file changed, 117 insertions(+), 151 deletions(-) diff --git a/Tests/FoundationEssentialsTests/DataIOTests.swift b/Tests/FoundationEssentialsTests/DataIOTests.swift index fdaca9b56..1198c1a01 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 { +@Suite("Data I/O") +private final class DataIOTests { // MARK: - Helpers - func testURL() -> URL { + let url: URL + + init() { // Generate a random file name - URL(fileURLWithPath: NSTemporaryDirectory(), isDirectory: true).appendingPathComponent("testfile-\(UUID().uuidString)") + url = URL.temporaryDirectory.appendingPathComponent("testfile-\(UUID().uuidString)") } 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) + 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: ptr, count: count, deallocator: .free) + return Data(bytesNoCopy: buf.baseAddress!, count: count, deallocator: .custom({ ptr, _ in + ptr.deallocate() + })) } - 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).. Date: Tue, 17 Jun 2025 14:52:28 -0700 Subject: [PATCH 2/7] Convert Data tests --- .../FoundationEssentialsTests/DataTests.swift | 1643 +++++++++-------- 1 file changed, 828 insertions(+), 815 deletions(-) diff --git a/Tests/FoundationEssentialsTests/DataTests.swift b/Tests/FoundationEssentialsTests/DataTests.swift index 0a639fbe6..fd2300e31 100644 --- a/Tests/FoundationEssentialsTests/DataTests.swift +++ b/Tests/FoundationEssentialsTests/DataTests.swift @@ -10,12 +10,16 @@ // //===----------------------------------------------------------------------===// -#if canImport(TestSupport) -import TestSupport -#endif +import Testing -#if canImport(Glibc) +#if canImport(Darwin) +import Darwin +#elseif canImport(Android) +@preconcurrency import Android +#elseif canImport(Glibc) @preconcurrency import Glibc +#elseif canImport(Musl) +@preconcurrency import Musl #endif #if FOUNDATION_FRAMEWORK @@ -42,7 +46,8 @@ extension Data { } } -class DataTests : XCTestCase { +@Suite("Data") +private final class DataTests { var heldData: Data? @@ -68,12 +73,12 @@ class DataTests : XCTestCase { // MARK: - - func testBasicConstruction() { + @Test func basicConstruction() { // Make sure that we were able to create some data let hello = dataFrom("hello") let helloLength = hello.count - XCTAssertEqual(hello[0], 0x68, "Unexpected first byte") + #expect(hello[0] == 0x68, "Unexpected first byte") let world = dataFrom(" world") var helloWorld = hello @@ -81,26 +86,26 @@ class DataTests : XCTestCase { helloWorld.append($0, count: world.count) } - XCTAssertEqual(hello[0], 0x68, "First byte should not have changed") - XCTAssertEqual(hello.count, helloLength, "Length of first data should not have changed") - XCTAssertEqual(helloWorld.count, hello.count + world.count, "The total length should include both buffers") + #expect(hello[0] == 0x68, "First byte should not have changed") + #expect(hello.count == helloLength, "Length of first data should not have changed") + #expect(helloWorld.count == hello.count + world.count, "The total length should include both buffers") } - func testInitializationWithArray() { + @Test func initializationWithArray() { let data = Data([1, 2, 3]) - XCTAssertEqual(3, data.count) + #expect(3 == data.count) let data2 = Data([1, 2, 3].filter { $0 >= 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,56 +1614,64 @@ 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) + let count = span.count + #expect(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") } - + @available(FoundationSpan 6.2, *) + @Test func largeSliceDataSpan() throws { #if _pointerBitWidth(_64) let count = Int(Int32.max) #elseif _pointerBitWidth(_32) @@ -1669,51 +1681,53 @@ class DataTests : XCTestCase { #endif let source = Data(repeating: 0, count: count).dropFirst() - XCTAssertNotEqual(source.startIndex, 0) + #expect(source.startIndex != 0) let span = source.span - XCTAssertFalse(span.isEmpty) + let isEmpty = span.isEmpty + #expect(!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 + var 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) + count = span.count + #expect(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) + + @Test func bounding_failure_replace3() async { + await #expect(processExitsWith: .failure) { + var data = try #require("a".data(using: .utf8)) + let bytes : [UInt8] = [1, 2, 3] + bytes.withUnsafeBufferPointer { + // lowerBound is > 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_replace4() { - var data = "a".data(using: .utf8)! - var bytes : [UInt8] = [1, 2, 3] - expectCrashLater() - // lowerBound is > length - data.replaceSubrange(2..<4, with: bytes) + + @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: 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 +1902,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 +1941,54 @@ 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") + #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") } - func test_rangeOfSlice() { + @Test func 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(range == 4..<5 as Range) } + #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 +1996,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 +2006,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 +2015,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 +2025,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 +2034,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 +2044,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 +2053,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 +2063,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 +2092,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 +2121,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 +2268,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() } From 085bd5c18046c7927ccd52a8f7d11d8957f14243 Mon Sep 17 00:00:00 2001 From: Jeremy Schonfeld Date: Tue, 17 Jun 2025 14:56:01 -0700 Subject: [PATCH 3/7] Move string path tests from Data IO suite to String suite --- .../DataIOTests.swift | 56 ------------------- .../StringTests.swift | 49 ++++++++++++++++ 2 files changed, 49 insertions(+), 56 deletions(-) diff --git a/Tests/FoundationEssentialsTests/DataIOTests.swift b/Tests/FoundationEssentialsTests/DataIOTests.swift index 1198c1a01..ddfff6208 100644 --- a/Tests/FoundationEssentialsTests/DataIOTests.swift +++ b/Tests/FoundationEssentialsTests/DataIOTests.swift @@ -217,61 +217,5 @@ private final class DataIOTests { let maps = try String(contentsOfFile: "/proc/self/maps", encoding: .utf8) #expect(!maps.isEmpty) } - - // MARK: - String Path Tests - // TODO: Move these to string tests - @Test func stringDeletingLastPathComponent() { - #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 stringLastPathComponent() { - #expect("/a/b/c".lastPathComponent == "c") - #expect("".lastPathComponent == "") - #expect("/".lastPathComponent == "/") - #expect("q".lastPathComponent == "q") - #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") - } } 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 🧮" From 2dede55c69e26209c35429bbbf6feb387322a509 Mon Sep 17 00:00:00 2001 From: Jeremy Schonfeld Date: Wed, 18 Jun 2025 09:14:38 -0700 Subject: [PATCH 4/7] Cleanup span expectations --- Tests/FoundationEssentialsTests/DataTests.swift | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/Tests/FoundationEssentialsTests/DataTests.swift b/Tests/FoundationEssentialsTests/DataTests.swift index fd2300e31..0cacf2b80 100644 --- a/Tests/FoundationEssentialsTests/DataTests.swift +++ b/Tests/FoundationEssentialsTests/DataTests.swift @@ -1656,8 +1656,7 @@ private final class DataTests { span = source.span isEmpty = span.isEmpty #expect(!isEmpty) - let count = span.count - #expect(count == source.count) + #expect(span.count == source.count) let firstElement = span[0] #expect(firstElement == 1) } @@ -1702,8 +1701,7 @@ private final class DataTests { let i = try #require(indices.randomElement()) isEmpty = span.isEmpty #expect(!isEmpty) - count = span.count - #expect(count == count) + #expect(span.count == count) let v = UInt8.random(in: 10..<100) span[i] = v var sub = span.extracting(i ..< i+1) From ab5fecb494b76c9d832c993d03195c05208f4b53 Mon Sep 17 00:00:00 2001 From: Jeremy Schonfeld Date: Wed, 18 Jun 2025 11:35:17 -0700 Subject: [PATCH 5/7] Fix build failure --- Tests/FoundationEssentialsTests/DataTests.swift | 8 -------- 1 file changed, 8 deletions(-) diff --git a/Tests/FoundationEssentialsTests/DataTests.swift b/Tests/FoundationEssentialsTests/DataTests.swift index 0cacf2b80..d7f26e1f7 100644 --- a/Tests/FoundationEssentialsTests/DataTests.swift +++ b/Tests/FoundationEssentialsTests/DataTests.swift @@ -1943,14 +1943,6 @@ private final class DataTests { #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") } - - @Test func rangeOfSlice() { - let data = "FooBar".data(using: .ascii)! - let slice = data[3...] // Bar - - let range = slice.range(of: "a".data(using: .ascii)!) - #expect(range == 4..<5 as Range) - } #endif } From 5ceae50bc5d0052d35ca46c33593ebc92323dc4c Mon Sep 17 00:00:00 2001 From: Jeremy Schonfeld Date: Wed, 18 Jun 2025 13:18:59 -0700 Subject: [PATCH 6/7] Fix watchOS build failure --- Tests/FoundationEssentialsTests/DataIOTests.swift | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/Tests/FoundationEssentialsTests/DataIOTests.swift b/Tests/FoundationEssentialsTests/DataIOTests.swift index ddfff6208..a63dbeac6 100644 --- a/Tests/FoundationEssentialsTests/DataIOTests.swift +++ b/Tests/FoundationEssentialsTests/DataIOTests.swift @@ -166,11 +166,7 @@ private final class DataIOTests { } #endif - #if os(watchOS) - @Test(.disabled("This test is not supported on this platform")) - #else - @Test - #endif +#if !os(watchOS) func largeFile() throws { // More than 2 GB let size = 0x80010000 @@ -189,6 +185,7 @@ private final class DataIOTests { #expect(data.count == readNS.count) #endif } +#endif #if os(Linux) || os(Windows) @Test From 48066b1adda2a59f46377a37c7518577b3280554 Mon Sep 17 00:00:00 2001 From: Jeremy Schonfeld Date: Wed, 18 Jun 2025 14:00:19 -0700 Subject: [PATCH 7/7] Move large data allocation tests into separate serialized suite --- .../DataIOTests.swift | 75 +++++----- .../FoundationEssentialsTests/DataTests.swift | 133 +++++++++--------- 2 files changed, 110 insertions(+), 98 deletions(-) diff --git a/Tests/FoundationEssentialsTests/DataIOTests.swift b/Tests/FoundationEssentialsTests/DataIOTests.swift index a63dbeac6..e9d2d8e15 100644 --- a/Tests/FoundationEssentialsTests/DataIOTests.swift +++ b/Tests/FoundationEssentialsTests/DataIOTests.swift @@ -18,6 +18,20 @@ import Testing @testable import FoundationEssentials #endif // FOUNDATION_FRAMEWORK +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 { @@ -29,20 +43,6 @@ private final class DataIOTests { // Generate a random file name url = URL.temporaryDirectory.appendingPathComponent("testfile-\(UUID().uuidString)") } - - 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() - })) - } func writeAndVerifyTestData(to url: URL, writeOptions: Data.WritingOptions = [], readOptions: Data.ReadingOptions = [], sourceLocation: SourceLocation = #_sourceLocation) throws { let data = generateTestData() @@ -166,27 +166,6 @@ private final class DataIOTests { } #endif -#if !os(watchOS) - func largeFile() throws { - // More than 2 GB - let size = 0x80010000 - - let data = generateTestData(count: size) - - try data.write(to: url) - let read = try Data(contentsOf: url, options: .mappedIfSafe) - - // No need to compare the contents, but do compare the size - #expect(data.count == read.count) - -#if FOUNDATION_FRAMEWORK - // Try the NSData path - let readNS = try NSData(contentsOf: url, options: .mappedIfSafe) as Data - #expect(data.count == readNS.count) -#endif - } -#endif - #if os(Linux) || os(Windows) @Test #else @@ -216,3 +195,29 @@ private final class DataIOTests { } } +extension LargeDataTests { + // This test is placed in the LargeDataTests suite since it allocates an extremely large amount of memory for some devices +#if !os(watchOS) + @Test func readLargeFile() throws { + let url = URL.temporaryDirectory.appendingPathComponent("testfile-\(UUID().uuidString)") + defer { try? FileManager.default.removeItem(at: url) } + // More than 2 GB + let size = 0x80010000 + + let data = generateTestData(count: size) + + try data.write(to: url) + let read = try Data(contentsOf: url, options: .mappedIfSafe) + + // No need to compare the contents, but do compare the size + #expect(data.count == read.count) + +#if FOUNDATION_FRAMEWORK + // Try the NSData path + let readNS = try NSData(contentsOf: url, options: .mappedIfSafe) as Data + #expect(data.count == readNS.count) +#endif + } +#endif +} + diff --git a/Tests/FoundationEssentialsTests/DataTests.swift b/Tests/FoundationEssentialsTests/DataTests.swift index d7f26e1f7..a2333f567 100644 --- a/Tests/FoundationEssentialsTests/DataTests.swift +++ b/Tests/FoundationEssentialsTests/DataTests.swift @@ -1669,23 +1669,6 @@ private final class DataTests { #expect(span[span.indices.last!] == .max) } - @available(FoundationSpan 6.2, *) - @Test 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) - } - @available(FoundationSpan 6.2, *) @Test func inlineDataMutableSpan() throws { #if !canImport(Darwin) || FOUNDATION_FRAMEWORK @@ -1695,7 +1678,7 @@ private final class DataTests { #expect(isEmpty) source.append(contentsOf: [1, 2, 3]) - var count = source.count + let count = source.count span = source.mutableSpan let indices = span.indices let i = try #require(indices.randomElement()) @@ -1724,29 +1707,6 @@ private final class DataTests { #endif } - @available(FoundationSpan 6.2, *) - @Test 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 - } - @available(FoundationSpan 6.2, *) @Test func inlineDataMutableRawSpan() throws { var source = Data() @@ -1781,28 +1741,6 @@ private final class DataTests { #expect(source[i] == .max) } - @available(FoundationSpan 6.2, *) - @Test 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) - } - #if FOUNDATION_EXIT_TESTS @Test func bounding_failure_subdata() async { await #expect(processExitsWith: .failure) { @@ -2443,3 +2381,72 @@ extension DataTests { } } #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) + } +}