diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 4513e40..15c7c9c 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -7,7 +7,7 @@ jobs: runs-on: macos-14 steps: - uses: actions/checkout@v4 - - run: sudo xcode-select -switch /Applications/Xcode_15.3.app + - run: sudo xcode-select -switch /Applications/Xcode_16.app - run: swift test lint: runs-on: ubuntu-latest diff --git a/Package.swift b/Package.swift index fe3d4bf..0be8de6 100644 --- a/Package.swift +++ b/Package.swift @@ -1,4 +1,4 @@ -// swift-tools-version:5.10 +// swift-tools-version:5.11 import PackageDescription let package = Package( diff --git a/Sources/Defaults/Defaults+Extensions.swift b/Sources/Defaults/Defaults+Extensions.swift index 027ba73..8d1c009 100644 --- a/Sources/Defaults/Defaults+Extensions.swift +++ b/Sources/Defaults/Defaults+Extensions.swift @@ -179,11 +179,13 @@ extension UserDefaults: DefaultsKeyValueStore {} extension DefaultsLockProtocol { @discardableResult - func with(_ body: @Sendable () throws -> R) rethrows -> R where R: Sendable { + func with(_ body: @Sendable () throws(E) -> R) throws(E) -> R where R: Sendable { lock() + defer { - self.unlock() + unlock() } + return try body() } } diff --git a/Sources/Defaults/Defaults+Protocol.swift b/Sources/Defaults/Defaults+Protocol.swift index f6d08dc..9057a04 100644 --- a/Sources/Defaults/Defaults+Protocol.swift +++ b/Sources/Defaults/Defaults+Protocol.swift @@ -169,5 +169,5 @@ protocol DefaultsLockProtocol { func unlock() - func with(_ body: @Sendable () throws -> R) rethrows -> R where R: Sendable + func with(_ body: @Sendable () throws(E) -> R) throws(E) -> R where R: Sendable } diff --git a/Tests/DefaultsTests/Defaults+iCloudTests.swift b/Tests/DefaultsTests/Defaults+iCloudTests.swift index 2f1d451..c09a49a 100644 --- a/Tests/DefaultsTests/Defaults+iCloudTests.swift +++ b/Tests/DefaultsTests/Defaults+iCloudTests.swift @@ -1,8 +1,8 @@ -@testable import Defaults import SwiftUI -import XCTest +import Testing +@testable import Defaults -final class MockStorage: DefaultsKeyValueStore { +private final class MockStorage: DefaultsKeyValueStore { private var pairs: [String: Any] = [:] private let queue = DispatchQueue(label: "a") @@ -51,9 +51,7 @@ final class MockStorage: DefaultsKeyValueStore { @discardableResult func synchronize() -> Bool { - let pairs = queue.sync { - Array(self.pairs.keys) - } + let pairs = queue.sync { Array(self.pairs.keys) } NotificationCenter.default.post(Notification(name: NSUbiquitousKeyValueStore.didChangeExternallyNotification, userInfo: [NSUbiquitousKeyValueStoreChangedKeysKey: pairs])) return true } @@ -61,39 +59,34 @@ final class MockStorage: DefaultsKeyValueStore { private let mockStorage = MockStorage() -@available(iOS 15, tvOS 15, watchOS 8, visionOS 1.0, *) -final class DefaultsICloudTests: XCTestCase { - override final class func setUp() { +@Suite(.serialized) +final class DefaultsICloudTests { + private let suite = createSuite() + + init() { Defaults.iCloud.isDebug = true Defaults.iCloud.syncOnChange = true Defaults.iCloud.synchronizer = iCloudSynchronizer(remoteStorage: mockStorage) } - override func setUp() { - super.setUp() + deinit { mockStorage.removeAll() Defaults.iCloud.removeAll() - Defaults.removeAll() - } - - override func tearDown() { - super.tearDown() - mockStorage.removeAll() - Defaults.iCloud.removeAll() - Defaults.removeAll() + Defaults.removeAll(suite: suite) } private func updateMockStorage(key: String, value: some Any, _ date: Date? = nil) { mockStorage.set([date ?? Date(), value], forKey: key) } + @Test func testICloudInitialize() async { - let name = Defaults.Key("testICloudInitialize_name", default: "0", iCloud: true) - let quality = Defaults.Key("testICloudInitialize_quality", default: 0.0, iCloud: true) + let name = Defaults.Key("testICloudInitialize_name", default: "0", suite: suite, iCloud: true) + let quality = Defaults.Key("testICloudInitialize_quality", default: 0.0, suite: suite, iCloud: true) await Defaults.iCloud.waitForSyncCompletion() - XCTAssertNil(mockStorage.data(forKey: name.name)) - XCTAssertNil(mockStorage.data(forKey: quality.name)) + #expect(mockStorage.data(forKey: name.name) == nil) + #expect(mockStorage.data(forKey: quality.name) == nil) let name_expected = ["1", "2", "3", "4", "5", "6", "7"] let quality_expected = [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0] @@ -101,39 +94,40 @@ final class DefaultsICloudTests: XCTestCase { Defaults[name] = name_expected[index] Defaults[quality] = quality_expected[index] await Defaults.iCloud.waitForSyncCompletion() - XCTAssertEqual(mockStorage.data(forKey: name.name), name_expected[index]) - XCTAssertEqual(mockStorage.data(forKey: quality.name), quality_expected[index]) + #expect(mockStorage.data(forKey: name.name) == name_expected[index]) + #expect(mockStorage.data(forKey: quality.name) == quality_expected[index]) } updateMockStorage(key: quality.name, value: 8.0) updateMockStorage(key: name.name, value: "8") mockStorage.synchronize() await Defaults.iCloud.waitForSyncCompletion() - XCTAssertEqual(Defaults[quality], 8.0) - XCTAssertEqual(Defaults[name], "8") + #expect(Defaults[quality] == 8.0) + #expect(Defaults[name] == "8") Defaults[name] = "9" Defaults[quality] = 9.0 await Defaults.iCloud.waitForSyncCompletion() - XCTAssertEqual(mockStorage.data(forKey: name.name), "9") - XCTAssertEqual(mockStorage.data(forKey: quality.name), 9.0) + #expect(mockStorage.data(forKey: name.name) == "9") + #expect(mockStorage.data(forKey: quality.name) == 9.0) updateMockStorage(key: quality.name, value: 10) updateMockStorage(key: name.name, value: "10") mockStorage.synchronize() await Defaults.iCloud.waitForSyncCompletion() - XCTAssertEqual(Defaults[quality], 10.0) - XCTAssertEqual(Defaults[name], "10") + #expect(Defaults[quality] == 10.0) + #expect(Defaults[name] == "10") } + @Test func testDidChangeExternallyNotification() async { updateMockStorage(key: "testDidChangeExternallyNotification_name", value: "0") updateMockStorage(key: "testDidChangeExternallyNotification_quality", value: 0.0) - let name = Defaults.Key("testDidChangeExternallyNotification_name", iCloud: true) - let quality = Defaults.Key("testDidChangeExternallyNotification_quality", iCloud: true) + let name = Defaults.Key("testDidChangeExternallyNotification_name", suite: suite, iCloud: true) + let quality = Defaults.Key("testDidChangeExternallyNotification_quality", suite: suite, iCloud: true) await Defaults.iCloud.waitForSyncCompletion() - XCTAssertEqual(Defaults[name], "0") - XCTAssertEqual(Defaults[quality], 0.0) + #expect(Defaults[name] == "0") + #expect(Defaults[quality] == 0.0) let name_expected = ["1", "2", "3", "4", "5", "6", "7"] let quality_expected = [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0] @@ -143,60 +137,63 @@ final class DefaultsICloudTests: XCTestCase { mockStorage.synchronize() } await Defaults.iCloud.waitForSyncCompletion() - XCTAssertEqual(Defaults[name], "7") - XCTAssertEqual(Defaults[quality], 7.0) + #expect(Defaults[name] == "7") + #expect(Defaults[quality] == 7.0) Defaults[name] = "8" Defaults[quality] = 8.0 await Defaults.iCloud.waitForSyncCompletion() - XCTAssertEqual(mockStorage.data(forKey: name.name), "8") - XCTAssertEqual(mockStorage.data(forKey: quality.name), 8.0) + #expect(mockStorage.data(forKey: name.name) == "8") + #expect(mockStorage.data(forKey: quality.name) == 8.0) Defaults[name] = nil Defaults[quality] = nil await Defaults.iCloud.waitForSyncCompletion() - XCTAssertNil(mockStorage.data(forKey: name.name)) - XCTAssertNil(mockStorage.data(forKey: quality.name)) + #expect(mockStorage.data(forKey: name.name) == nil) + #expect(mockStorage.data(forKey: quality.name) == nil) } + @Test func testICloudInitializeSyncLast() async { - let name = Defaults.Key("testICloudInitializeSyncLast_name", default: "0", iCloud: true) - let quality = Defaults.Key("testICloudInitializeSyncLast_quality", default: 0.0, iCloud: true) + let name = Defaults.Key("testICloudInitializeSyncLast_name", default: "0", suite: suite, iCloud: true) + let quality = Defaults.Key("testICloudInitializeSyncLast_quality", default: 0.0, suite: suite, iCloud: true) let name_expected = ["1", "2", "3", "4", "5", "6", "7"] let quality_expected = [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0] for index in 0..("testRemoveKey_name", default: "0", iCloud: true) - let quality = Defaults.Key("testRemoveKey_quality", default: 0.0, iCloud: true) + let name = Defaults.Key("testRemoveKey_name", default: "0", suite: suite, iCloud: true) + let quality = Defaults.Key("testRemoveKey_quality", default: 0.0, suite: suite, iCloud: true) Defaults[name] = "1" Defaults[quality] = 1.0 await Defaults.iCloud.waitForSyncCompletion() - XCTAssertEqual(mockStorage.data(forKey: name.name), "1") - XCTAssertEqual(mockStorage.data(forKey: quality.name), 1.0) + #expect(mockStorage.data(forKey: name.name) == "1") + #expect(mockStorage.data(forKey: quality.name) == 1.0) Defaults.iCloud.remove(quality) Defaults[name] = "2" Defaults[quality] = 1.0 await Defaults.iCloud.waitForSyncCompletion() - XCTAssertEqual(mockStorage.data(forKey: name.name), "2") - XCTAssertEqual(mockStorage.data(forKey: quality.name), 1.0) + #expect(mockStorage.data(forKey: name.name) == "2") + #expect(mockStorage.data(forKey: quality.name) == 1.0) } + @Test func testSyncKeysFromLocal() async { - let name = Defaults.Key("testSyncKeysFromLocal_name", default: "0") - let quality = Defaults.Key("testSyncKeysFromLocal_quality", default: 0.0) + let name = Defaults.Key("testSyncKeysFromLocal_name", default: "0", suite: suite) + let quality = Defaults.Key("testSyncKeysFromLocal_quality", default: 0.0, suite: suite) let name_expected = ["1", "2", "3", "4", "5", "6", "7"] let quality_expected = [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0] @@ -205,21 +202,22 @@ final class DefaultsICloudTests: XCTestCase { Defaults[quality] = quality_expected[index] Defaults.iCloud.syncWithoutWaiting(name, quality, source: .local) await Defaults.iCloud.waitForSyncCompletion() - XCTAssertEqual(mockStorage.data(forKey: name.name), name_expected[index]) - XCTAssertEqual(mockStorage.data(forKey: quality.name), quality_expected[index]) + #expect(mockStorage.data(forKey: name.name) == name_expected[index]) + #expect(mockStorage.data(forKey: quality.name) == quality_expected[index]) } updateMockStorage(key: name.name, value: "8") updateMockStorage(key: quality.name, value: 8) Defaults.iCloud.syncWithoutWaiting(name, quality, source: .remote) await Defaults.iCloud.waitForSyncCompletion() - XCTAssertEqual(Defaults[quality], 8.0) - XCTAssertEqual(Defaults[name], "8") + #expect(Defaults[quality] == 8.0) + #expect(Defaults[name] == "8") } + @Test func testSyncKeysFromRemote() async { - let name = Defaults.Key("testSyncKeysFromRemote_name") - let quality = Defaults.Key("testSyncKeysFromRemote_quality") + let name = Defaults.Key("testSyncKeysFromRemote_name", suite: suite) + let quality = Defaults.Key("testSyncKeysFromRemote_quality", suite: suite) let name_expected = ["1", "2", "3", "4", "5", "6", "7"] let quality_expected = [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0] @@ -228,47 +226,47 @@ final class DefaultsICloudTests: XCTestCase { updateMockStorage(key: quality.name, value: quality_expected[index]) Defaults.iCloud.syncWithoutWaiting(name, quality, source: .remote) await Defaults.iCloud.waitForSyncCompletion() - XCTAssertEqual(Defaults[name], name_expected[index]) - XCTAssertEqual(Defaults[quality], quality_expected[index]) + #expect(Defaults[name] == name_expected[index]) + #expect(Defaults[quality] == quality_expected[index]) } Defaults[name] = "8" Defaults[quality] = 8.0 Defaults.iCloud.syncWithoutWaiting(name, quality, source: .local) await Defaults.iCloud.waitForSyncCompletion() - XCTAssertEqual(mockStorage.data(forKey: name.name), "8") - XCTAssertEqual(mockStorage.data(forKey: quality.name), 8.0) + #expect(mockStorage.data(forKey: name.name) == "8") + #expect(mockStorage.data(forKey: quality.name) == 8.0) Defaults[name] = nil Defaults[quality] = nil Defaults.iCloud.syncWithoutWaiting(name, quality, source: .local) await Defaults.iCloud.waitForSyncCompletion() - XCTAssertNil(mockStorage.object(forKey: name.name)) - XCTAssertNil(mockStorage.object(forKey: quality.name)) + #expect(mockStorage.object(forKey: name.name) == nil) + #expect(mockStorage.object(forKey: quality.name) == nil) } + @Test func testAddFromDetached() async { - let name = Defaults.Key("testInitAddFromDetached_name", default: "0") - let quantity = Defaults.Key("testInitAddFromDetached_quantity", default: false) - let task = Task.detached { + let name = Defaults.Key("testInitAddFromDetached_name", default: "0", suite: suite) + let quantity = Defaults.Key("testInitAddFromDetached_quantity", default: false, suite: suite) + await Task.detached { Defaults.iCloud.add(name, quantity) Defaults.iCloud.syncWithoutWaiting() await Defaults.iCloud.waitForSyncCompletion() - } - await task.value - XCTAssertEqual(mockStorage.data(forKey: name.name), "0") + }.value + #expect(mockStorage.data(forKey: name.name) == "0") Defaults[name] = "1" await Defaults.iCloud.waitForSyncCompletion() - XCTAssertEqual(mockStorage.data(forKey: name.name), "1") + #expect(mockStorage.data(forKey: name.name) == "1") } + @Test func testICloudInitializeFromDetached() async { - let task = Task.detached { - let name = Defaults.Key("testICloudInitializeFromDetached_name", default: "0", iCloud: true) + await Task.detached { + let name = Defaults.Key("testICloudInitializeFromDetached_name", default: "0", suite: self.suite, iCloud: true) await Defaults.iCloud.waitForSyncCompletion() - XCTAssertNil(mockStorage.data(forKey: name.name)) - } - await task.value + #expect(mockStorage.data(forKey: name.name) == nil) + }.value } } diff --git a/Tests/DefaultsTests/DefaultsAnySeriliazableTests.swift b/Tests/DefaultsTests/DefaultsAnySeriliazableTests.swift index 051d1a4..bd00fd5 100644 --- a/Tests/DefaultsTests/DefaultsAnySeriliazableTests.swift +++ b/Tests/DefaultsTests/DefaultsAnySeriliazableTests.swift @@ -1,6 +1,8 @@ +import SwiftUI +import Testing import Defaults -import Foundation -import XCTest + +private let suite_ = createSuite() private enum mime: String, Defaults.Serializable { case JSON = "application/json" @@ -30,347 +32,360 @@ private struct UnicornBridge: Defaults.Bridge { } extension Defaults.Keys { - fileprivate static let magic = Key<[String: Defaults.AnySerializable]>("magic", default: [:]) - fileprivate static let anyKey = Key("anyKey", default: "🦄") - fileprivate static let anyArrayKey = Key<[Defaults.AnySerializable]>("anyArrayKey", default: ["No.1 🦄", "No.2 🦄"]) - fileprivate static let anyDictionaryKey = Key<[String: Defaults.AnySerializable]>("anyDictionaryKey", default: ["unicorn": "🦄"]) + fileprivate static let magic = Key<[String: Defaults.AnySerializable]>("magic", default: [:], suite: suite_) + fileprivate static let anyKey = Key("anyKey", default: "🦄", suite: suite_) + fileprivate static let anyArrayKey = Key<[Defaults.AnySerializable]>("anyArrayKey", default: ["No.1 🦄", "No.2 🦄"], suite: suite_) + fileprivate static let anyDictionaryKey = Key<[String: Defaults.AnySerializable]>("anyDictionaryKey", default: ["unicorn": "🦄"], suite: suite_) } -final class DefaultsAnySerializableTests: XCTestCase { - override func setUp() { - super.setUp() - Defaults.removeAll() +@Suite(.serialized) +final class DefaultsAnySerializableTests { + init() { + Defaults.removeAll(suite: suite_) } - override func tearDown() { - super.tearDown() - Defaults.removeAll() + deinit { + Defaults.removeAll(suite: suite_) } + @Test func testReadMeExample() { - let any = Defaults.Key("anyKey", default: Defaults.AnySerializable(mime.JSON)) + let any = Defaults.Key("anyKey", default: Defaults.AnySerializable(mime.JSON), suite: suite_) if let mimeType: mime = Defaults[any].get() { - XCTAssertEqual(mimeType, mime.JSON) + #expect(mimeType == mime.JSON) } Defaults[any].set(mime.STREAM) if let mimeType: mime = Defaults[any].get() { - XCTAssertEqual(mimeType, mime.STREAM) + #expect(mimeType == mime.STREAM) } Defaults[any].set(mime.JSON) if let mimeType: mime = Defaults[any].get() { - XCTAssertEqual(mimeType, mime.JSON) + #expect(mimeType == mime.JSON) } Defaults[.magic]["unicorn"] = "🦄" Defaults[.magic]["number"] = 3 Defaults[.magic]["boolean"] = true Defaults[.magic]["enum"] = Defaults.AnySerializable(mime.JSON) - XCTAssertEqual(Defaults[.magic]["unicorn"], "🦄") - XCTAssertEqual(Defaults[.magic]["number"], 3) + #expect(Defaults[.magic]["unicorn"] == "🦄") + #expect(Defaults[.magic]["number"] == 3) if let bool: Bool = Defaults[.magic]["unicorn"]?.get() { - XCTAssertTrue(bool) + #expect(bool) } - XCTAssertEqual(Defaults[.magic]["enum"]?.get(), mime.JSON) + #expect(Defaults[.magic]["enum"]?.get() == mime.JSON) Defaults[.magic]["enum"]?.set(mime.STREAM) if let value: String = Defaults[.magic]["unicorn"]?.get() { - XCTAssertEqual(value, "🦄") + #expect(value == "🦄") } if let mimeType: mime = Defaults[.magic]["enum"]?.get() { - XCTAssertEqual(mimeType, mime.STREAM) + #expect(mimeType == mime.STREAM) } Defaults[any].set(mime.JSON) if let mimeType: mime = Defaults[any].get() { - XCTAssertEqual(mime.JSON, mimeType) + #expect(mime.JSON == mimeType) } Defaults[any].set(mime.STREAM) if let mimeType: mime = Defaults[any].get() { - XCTAssertEqual(mime.STREAM, mimeType) + #expect(mime.STREAM == mimeType) } } + @Test func testKey() { // Test Int - let any = Defaults.Key("independentAnyKey", default: 121_314) - XCTAssertEqual(Defaults[any], 121_314) + let any = Defaults.Key("independentAnyKey", default: 121_314, suite: suite_) + #expect(Defaults[any] == 121_314) // Test Int8 let int8 = Int8.max Defaults[any].set(int8) - XCTAssertEqual(Defaults[any].get(), int8) + #expect(Defaults[any].get() == int8) // Test Int16 let int16 = Int16.max Defaults[any].set(int16) - XCTAssertEqual(Defaults[any].get(), int16) + #expect(Defaults[any].get() == int16) // Test Int32 let int32 = Int32.max Defaults[any].set(int32) - XCTAssertEqual(Defaults[any].get(), int32) + #expect(Defaults[any].get() == int32) // Test Int64 let int64 = Int64.max Defaults[any].set(int64) - XCTAssertEqual(Defaults[any].get(), int64) + #expect(Defaults[any].get() == int64) // Test UInt let uint = UInt.max Defaults[any].set(uint) - XCTAssertEqual(Defaults[any].get(), uint) + #expect(Defaults[any].get() == uint) // Test UInt8 let uint8 = UInt8.max Defaults[any].set(uint8) - XCTAssertEqual(Defaults[any].get(), uint8) + #expect(Defaults[any].get() == uint8) // Test UInt16 let uint16 = UInt16.max Defaults[any].set(uint16) - XCTAssertEqual(Defaults[any].get(), uint16) + #expect(Defaults[any].get() == uint16) // Test UInt32 let uint32 = UInt32.max Defaults[any].set(uint32) - XCTAssertEqual(Defaults[any].get(), uint32) + #expect(Defaults[any].get() == uint32) // Test UInt64 let uint64 = UInt64.max Defaults[any].set(uint64) - XCTAssertEqual(Defaults[any].get(), uint64) + #expect(Defaults[any].get() == uint64) // Test Double Defaults[any] = 12_131.4 - XCTAssertEqual(Defaults[any], 12_131.4) + #expect(Defaults[any] == 12_131.4) // Test Bool Defaults[any] = true - XCTAssertTrue(Defaults[any].get(Bool.self)!) + #expect(Defaults[any].get(Bool.self)!) // Test String Defaults[any] = "121314" - XCTAssertEqual(Defaults[any], "121314") + #expect(Defaults[any] == "121314") // Test Float Defaults[any].set(12_131.456, type: Float.self) - XCTAssertEqual(Defaults[any].get(Float.self), 12_131.456) + #expect(Defaults[any].get(Float.self) == 12_131.456) // Test Date let date = Date() Defaults[any].set(date) - XCTAssertEqual(Defaults[any].get(Date.self), date) + #expect(Defaults[any].get(Date.self) == date) // Test Data let data = "121314".data(using: .utf8) Defaults[any].set(data) - XCTAssertEqual(Defaults[any].get(Data.self), data) + #expect(Defaults[any].get(Data.self) == data) // Test Array Defaults[any] = [1, 2, 3] if let array: [Int] = Defaults[any].get() { - XCTAssertEqual(array[0], 1) - XCTAssertEqual(array[1], 2) - XCTAssertEqual(array[2], 3) + #expect(array[0] == 1) + #expect(array[1] == 2) + #expect(array[2] == 3) } // Test Dictionary Defaults[any] = ["unicorn": "🦄", "boolean": true, "number": 3] if let dictionary = Defaults[any].get([String: Defaults.AnySerializable].self) { - XCTAssertEqual(dictionary["unicorn"], "🦄") - XCTAssertTrue(dictionary["boolean"]!.get(Bool.self)!) - XCTAssertEqual(dictionary["number"], 3) + #expect(dictionary["unicorn"] == "🦄") + #expect(dictionary["boolean"]?.get(Bool.self) == true) + #expect(dictionary["number"] == 3) } // Test Set Defaults[any].set(Set([1])) - XCTAssertEqual(Defaults[any].get(Set.self)?.first, 1) + #expect(Defaults[any].get(Set.self)?.first == 1) // Test URL Defaults[any].set(URL(string: "https://example.com")!) - XCTAssertEqual(Defaults[any].get()!, URL(string: "https://example.com")!) + #expect(Defaults[any].get()! == URL(string: "https://example.com")!) #if os(macOS) // Test NSColor Defaults[any].set(NSColor(red: Double(103) / Double(0xFF), green: Double(132) / Double(0xFF), blue: Double(255) / Double(0xFF), alpha: 0.987)) - XCTAssertEqual(Defaults[any].get(NSColor.self)?.alphaComponent, 0.987) + #expect(Defaults[any].get(NSColor.self)?.alphaComponent == 0.987) #else // Test UIColor Defaults[any].set(UIColor(red: Double(103) / Double(0xFF), green: Double(132) / Double(0xFF), blue: Double(255) / Double(0xFF), alpha: 0.654)) - XCTAssertEqual(Defaults[any].get(UIColor.self)?.cgColor.alpha, 0.654) + #expect(Defaults[any].get(UIColor.self)?.cgColor.alpha == 0.654) #endif // Test Codable type Defaults[any].set(CodableUnicorn(is_missing: false)) - XCTAssertFalse(Defaults[any].get(CodableUnicorn.self)!.is_missing) + #expect(Defaults[any].get(CodableUnicorn.self)!.is_missing == false) // Test Custom type Defaults[any].set(Unicorn(is_missing: true)) - XCTAssertTrue(Defaults[any].get(Unicorn.self)!.is_missing) + #expect(Defaults[any].get(Unicorn.self)!.is_missing) // Test nil Defaults[any] = nil - XCTAssertEqual(Defaults[any], 121_314) + #expect(Defaults[any] == 121_314) } + @Test func testOptionalKey() { - let key = Defaults.Key("independentOptionalAnyKey") - XCTAssertNil(Defaults[key]) + let key = Defaults.Key("independentOptionalAnyKey", suite: suite_) + #expect(Defaults[key] == nil) Defaults[key] = 12_131.4 - XCTAssertEqual(Defaults[key], 12_131.4) + #expect(Defaults[key] == 12_131.4) Defaults[key]?.set(mime.JSON) - XCTAssertEqual(Defaults[key]?.get(mime.self), mime.JSON) + #expect(Defaults[key]?.get(mime.self) == mime.JSON) Defaults[key] = nil - XCTAssertNil(Defaults[key]) + #expect(Defaults[key] == nil) } + @Test func testArrayKey() { - let key = Defaults.Key<[Defaults.AnySerializable]>("independentArrayAnyKey", default: [123, 456]) - XCTAssertEqual(Defaults[key][0], 123) - XCTAssertEqual(Defaults[key][1], 456) + let key = Defaults.Key<[Defaults.AnySerializable]>("independentArrayAnyKey", default: [123, 456], suite: suite_) + #expect(Defaults[key][0] == 123) + #expect(Defaults[key][1] == 456) Defaults[key][0] = 12_131.4 - XCTAssertEqual(Defaults[key][0], 12_131.4) + #expect(Defaults[key][0] == 12_131.4) } + @Test func testSetKey() { - let key = Defaults.Key>("independentArrayAnyKey", default: [123]) - XCTAssertEqual(Defaults[key].first, 123) + let key = Defaults.Key>("independentArrayAnyKey", default: [123], suite: suite_) + #expect(Defaults[key].first == 123) Defaults[key].insert(12_131.4) - XCTAssertTrue(Defaults[key].contains(12_131.4)) + #expect(Defaults[key].contains(12_131.4)) let date = Defaults.AnySerializable(Date()) Defaults[key].insert(date) - XCTAssertTrue(Defaults[key].contains(date)) + #expect(Defaults[key].contains(date)) let data = Defaults.AnySerializable("Hello World!".data(using: .utf8)) Defaults[key].insert(data) - XCTAssertTrue(Defaults[key].contains(data)) + #expect(Defaults[key].contains(data)) let int = Defaults.AnySerializable(Int.max) Defaults[key].insert(int) - XCTAssertTrue(Defaults[key].contains(int)) + #expect(Defaults[key].contains(int)) let int8 = Defaults.AnySerializable(Int8.max) Defaults[key].insert(int8) - XCTAssertTrue(Defaults[key].contains(int8)) + #expect(Defaults[key].contains(int8)) let int16 = Defaults.AnySerializable(Int16.max) Defaults[key].insert(int16) - XCTAssertTrue(Defaults[key].contains(int16)) + #expect(Defaults[key].contains(int16)) let int32 = Defaults.AnySerializable(Int32.max) Defaults[key].insert(int32) - XCTAssertTrue(Defaults[key].contains(int32)) + #expect(Defaults[key].contains(int32)) let int64 = Defaults.AnySerializable(Int64.max) Defaults[key].insert(int64) - XCTAssertTrue(Defaults[key].contains(int64)) + #expect(Defaults[key].contains(int64)) let uint = Defaults.AnySerializable(UInt.max) Defaults[key].insert(uint) - XCTAssertTrue(Defaults[key].contains(uint)) + #expect(Defaults[key].contains(uint)) let uint8 = Defaults.AnySerializable(UInt8.max) Defaults[key].insert(uint8) - XCTAssertTrue(Defaults[key].contains(uint8)) + #expect(Defaults[key].contains(uint8)) let uint16 = Defaults.AnySerializable(UInt16.max) Defaults[key].insert(uint16) - XCTAssertTrue(Defaults[key].contains(uint16)) + #expect(Defaults[key].contains(uint16)) let uint32 = Defaults.AnySerializable(UInt32.max) Defaults[key].insert(uint32) - XCTAssertTrue(Defaults[key].contains(uint32)) + #expect(Defaults[key].contains(uint32)) let uint64 = Defaults.AnySerializable(UInt64.max) Defaults[key].insert(uint64) - XCTAssertTrue(Defaults[key].contains(uint64)) + #expect(Defaults[key].contains(uint64)) let bool: Defaults.AnySerializable = false Defaults[key].insert(bool) - XCTAssertTrue(Defaults[key].contains(bool)) + #expect(Defaults[key].contains(bool)) let float = Defaults.AnySerializable(Float(1213.14)) Defaults[key].insert(float) - XCTAssertTrue(Defaults[key].contains(float)) + #expect(Defaults[key].contains(float)) let cgFloat = Defaults.AnySerializable(CGFloat(12_131.415)) // swiftlint:disable:this no_cgfloat2 Defaults[key].insert(cgFloat) - XCTAssertTrue(Defaults[key].contains(cgFloat)) + #expect(Defaults[key].contains(cgFloat)) let string = Defaults.AnySerializable("Hello World!") Defaults[key].insert(string) - XCTAssertTrue(Defaults[key].contains(string)) + #expect(Defaults[key].contains(string)) let array: Defaults.AnySerializable = [1, 2, 3, 4] Defaults[key].insert(array) - XCTAssertTrue(Defaults[key].contains(array)) + #expect(Defaults[key].contains(array)) let dictionary: Defaults.AnySerializable = ["Hello": "World!"] Defaults[key].insert(dictionary) - XCTAssertTrue(Defaults[key].contains(dictionary)) + #expect(Defaults[key].contains(dictionary)) let unicorn = Defaults.AnySerializable(Unicorn(is_missing: true)) Defaults[key].insert(unicorn) - XCTAssertTrue(Defaults[key].contains(unicorn)) + #expect(Defaults[key].contains(unicorn)) } + @Test func testArrayOptionalKey() { - let key = Defaults.Key<[Defaults.AnySerializable]?>("testArrayOptionalAnyKey") // swiftlint:disable:this discouraged_optional_collection - XCTAssertNil(Defaults[key]) + let key = Defaults.Key<[Defaults.AnySerializable]?>("testArrayOptionalAnyKey", suite: suite_) // swiftlint:disable:this discouraged_optional_collection + #expect(Defaults[key] == nil) Defaults[key] = [123] Defaults[key]?.append(456) - XCTAssertEqual(Defaults[key]![0], 123) - XCTAssertEqual(Defaults[key]![1], 456) + #expect(Defaults[key]![0] == 123) + #expect(Defaults[key]![1] == 456) Defaults[key]![0] = 12_131.4 - XCTAssertEqual(Defaults[key]![0], 12_131.4) + #expect(Defaults[key]![0] == 12_131.4) } + @Test func testNestedArrayKey() { - let key = Defaults.Key<[[Defaults.AnySerializable]]>("testNestedArrayAnyKey", default: [[123]]) + let key = Defaults.Key<[[Defaults.AnySerializable]]>("testNestedArrayAnyKey", default: [[123]], suite: suite_) Defaults[key][0].append(456) - XCTAssertEqual(Defaults[key][0][0], 123) - XCTAssertEqual(Defaults[key][0][1], 456) + #expect(Defaults[key][0][0] == 123) + #expect(Defaults[key][0][1] == 456) Defaults[key].append([12_131.4]) - XCTAssertEqual(Defaults[key][1][0], 12_131.4) + #expect(Defaults[key][1][0] == 12_131.4) } + @Test func testDictionaryKey() { - let key = Defaults.Key<[String: Defaults.AnySerializable]>("independentDictionaryAnyKey", default: ["unicorn": ""]) - XCTAssertEqual(Defaults[key]["unicorn"], "") + let key = Defaults.Key<[String: Defaults.AnySerializable]>("independentDictionaryAnyKey", default: ["unicorn": ""], suite: suite_) + #expect(Defaults[key]["unicorn"] == "") Defaults[key]["unicorn"] = "🦄" - XCTAssertEqual(Defaults[key]["unicorn"], "🦄") + #expect(Defaults[key]["unicorn"] == "🦄") Defaults[key]["number"] = 3 Defaults[key]["boolean"] = true - XCTAssertEqual(Defaults[key]["number"], 3) + #expect(Defaults[key]["number"] == 3) if let bool: Bool = Defaults[.magic]["unicorn"]?.get() { - XCTAssertTrue(bool) + #expect(bool) } Defaults[key]["set"] = Defaults.AnySerializable(Set([1])) - XCTAssertEqual(Defaults[key]["set"]!.get(Set.self)!.first, 1) + #expect(Defaults[key]["set"]!.get(Set.self)!.first == 1) Defaults[key]["nil"] = nil - XCTAssertNil(Defaults[key]["nil"]) + #expect(Defaults[key]["nil"] == nil) } + @Test func testDictionaryOptionalKey() { - let key = Defaults.Key<[String: Defaults.AnySerializable]?>("independentDictionaryOptionalAnyKey") // swiftlint:disable:this discouraged_optional_collection - XCTAssertNil(Defaults[key]) + let key = Defaults.Key<[String: Defaults.AnySerializable]?>("independentDictionaryOptionalAnyKey", suite: suite_) // swiftlint:disable:this discouraged_optional_collection + #expect(Defaults[key] == nil) Defaults[key] = ["unicorn": "🦄"] - XCTAssertEqual(Defaults[key]?["unicorn"], "🦄") + #expect(Defaults[key]?["unicorn"] == "🦄") Defaults[key]?["number"] = 3 Defaults[key]?["boolean"] = true - XCTAssertEqual(Defaults[key]?["number"], 3) - XCTAssertEqual(Defaults[key]?["boolean"], true) + #expect(Defaults[key]?["number"] == 3) + #expect(Defaults[key]?["boolean"] == true) } + @Test func testDictionaryArrayKey() { - let key = Defaults.Key<[String: [Defaults.AnySerializable]]>("independentDictionaryArrayAnyKey", default: ["number": [1]]) - XCTAssertEqual(Defaults[key]["number"]?[0], 1) + let key = Defaults.Key<[String: [Defaults.AnySerializable]]>("independentDictionaryArrayAnyKey", default: ["number": [1]], suite: suite_) + #expect(Defaults[key]["number"]?[0] == 1) Defaults[key]["number"]?.append(2) Defaults[key]["unicorn"] = ["No.1 🦄"] Defaults[key]["unicorn"]?.append("No.2 🦄") Defaults[key]["unicorn"]?.append("No.3 🦄") Defaults[key]["boolean"] = [true] Defaults[key]["boolean"]?.append(false) - XCTAssertEqual(Defaults[key]["number"]?[1], 2) - XCTAssertEqual(Defaults[key]["unicorn"]?[0], "No.1 🦄") - XCTAssertEqual(Defaults[key]["unicorn"]?[1], "No.2 🦄") - XCTAssertEqual(Defaults[key]["unicorn"]?[2], "No.3 🦄") - XCTAssertTrue(Defaults[key]["boolean"]![0].get(Bool.self)!) - XCTAssertFalse(Defaults[key]["boolean"]![1].get(Bool.self)!) + #expect(Defaults[key]["number"]?[1] == 2) + #expect(Defaults[key]["unicorn"]?[0] == "No.1 🦄") + #expect(Defaults[key]["unicorn"]?[1] == "No.2 🦄") + #expect(Defaults[key]["unicorn"]?[2] == "No.3 🦄") +// #expect(#require(Defaults[key]["boolean"]?[0].get(Bool.self)) == true) + #expect(Defaults[key]["boolean"]?[1].get(Bool.self) == false) } + @Test func testType() { - XCTAssertEqual(Defaults[.anyKey], "🦄") + #expect(Defaults[.anyKey] == "🦄") Defaults[.anyKey] = 123 - XCTAssertEqual(Defaults[.anyKey], 123) + #expect(Defaults[.anyKey] == 123) } + @Test func testArrayType() { - XCTAssertEqual(Defaults[.anyArrayKey][0], "No.1 🦄") - XCTAssertEqual(Defaults[.anyArrayKey][1], "No.2 🦄") + #expect(Defaults[.anyArrayKey][0] == "No.1 🦄") + #expect(Defaults[.anyArrayKey][1] == "No.2 🦄") Defaults[.anyArrayKey].append(123) - XCTAssertEqual(Defaults[.anyArrayKey][2], 123) + #expect(Defaults[.anyArrayKey][2] == 123) } + @Test func testDictionaryType() { - XCTAssertEqual(Defaults[.anyDictionaryKey]["unicorn"], "🦄") + #expect(Defaults[.anyDictionaryKey]["unicorn"] == "🦄") Defaults[.anyDictionaryKey]["number"] = 3 - XCTAssertEqual(Defaults[.anyDictionaryKey]["number"], 3) + #expect(Defaults[.anyDictionaryKey]["number"] == 3) Defaults[.anyDictionaryKey]["boolean"] = true - XCTAssertTrue(Defaults[.anyDictionaryKey]["boolean"]!.get(Bool.self)!) + #expect(Defaults[.anyDictionaryKey]["boolean"]!.get(Bool.self)!) Defaults[.anyDictionaryKey]["array"] = [1, 2] if let array = Defaults[.anyDictionaryKey]["array"]?.get([Int].self) { - XCTAssertEqual(array[0], 1) - XCTAssertEqual(array[1], 2) + #expect(array[0] == 1) + #expect(array[1] == 2) } } - func testObserveKeyCombine() { - let key = Defaults.Key("observeAnyKeyCombine", default: 123) - let expect = expectation(description: "Observation closure being called") + @available(iOS 16.0, macOS 13.0, tvOS 16.0, watchOS 9.0, visionOS 1.0, *) + @Test + func testObserveKeyCombine() async { + let key = Defaults.Key("observeAnyKeyCombine", default: 123, suite: suite_) let publisher = Defaults .publisher(key, options: []) @@ -379,25 +394,26 @@ final class DefaultsAnySerializableTests: XCTestCase { let expectedValue: [(Defaults.AnySerializable, Defaults.AnySerializable)] = [(123, "🦄"), ("🦄", 123)] - let cancellable = publisher.sink { tuples in - for (index, expected) in expectedValue.enumerated() { - XCTAssertEqual(expected.0, tuples[index].0) - XCTAssertEqual(expected.1, tuples[index].1) - } - - expect.fulfill() + Task { + try? await Task.sleep(for: .seconds(0.1)) + Defaults[key] = "🦄" + Defaults.reset(key) } - Defaults[key] = "🦄" - Defaults.reset(key) - cancellable.cancel() + for await tuples in publisher.values { + for (index, expected) in expectedValue.enumerated() { + #expect(expected.0 == tuples[index].0) + #expect(expected.1 == tuples[index].1) + } - waitForExpectations(timeout: 10) + break + } } - func testObserveOptionalKeyCombine() { - let key = Defaults.Key("observeAnyOptionalKeyCombine") - let expect = expectation(description: "Observation closure being called") + @available(iOS 16.0, macOS 13.0, tvOS 16.0, watchOS 9.0, visionOS 1.0, *) + @Test + func testObserveOptionalKeyCombine() async { + let key = Defaults.Key("observeAnyOptionalKeyCombine", suite: suite_) let publisher = Defaults .publisher(key, options: []) @@ -406,70 +422,34 @@ final class DefaultsAnySerializableTests: XCTestCase { let expectedValue: [(Defaults.AnySerializable?, Defaults.AnySerializable?)] = [(nil, 123), (123, "🦄"), ("🦄", nil)] - let cancellable = publisher.sink { tuples in + Task { + try? await Task.sleep(for: .seconds(0.1)) + Defaults[key] = 123 + Defaults[key] = "🦄" + Defaults.reset(key) + } + + for await tuples in publisher.values { for (index, expected) in expectedValue.enumerated() { if tuples[index].0?.get(Int.self) != nil { - XCTAssertEqual(expected.0, tuples[index].0) - XCTAssertEqual(expected.1, tuples[index].1) + #expect(expected.0 == tuples[index].0) + #expect(expected.1 == tuples[index].1) } else if tuples[index].0?.get(String.self) != nil { - XCTAssertEqual(expected.0, tuples[index].0) - XCTAssertNil(tuples[index].1) + #expect(expected.0 == tuples[index].0) + #expect(tuples[index].1 == nil) } else { - XCTAssertNil(tuples[index].0) - XCTAssertEqual(expected.1, tuples[index].1) + #expect(tuples[index].0 == nil) + #expect(expected.1 == tuples[index].1) } } - - expect.fulfill() + break } - - Defaults[key] = 123 - Defaults[key] = "🦄" - Defaults.reset(key) - cancellable.cancel() - - waitForExpectations(timeout: 10) - } - - func testObserveKey() { - let key = Defaults.Key("observeAnyKey", default: 123) - let expect = expectation(description: "Observation closure being called") - - var observation: Defaults.Observation! - observation = Defaults.observe(key, options: []) { change in - XCTAssertEqual(change.oldValue, 123) - XCTAssertEqual(change.newValue, "🦄") - observation.invalidate() - expect.fulfill() - } - - Defaults[key] = "🦄" - observation.invalidate() - - waitForExpectations(timeout: 10) - } - - func testObserveOptionalKey() { - let key = Defaults.Key("observeAnyOptionalKey") - let expect = expectation(description: "Observation closure being called") - - var observation: Defaults.Observation! - observation = Defaults.observe(key, options: []) { change in - XCTAssertNil(change.oldValue) - XCTAssertEqual(change.newValue, "🦄") - observation.invalidate() - expect.fulfill() - } - - Defaults[key] = "🦄" - observation.invalidate() - - waitForExpectations(timeout: 10) } + @Test func testWrongCast() { let value = Defaults.AnySerializable(false) - XCTAssertEqual(value.get(Bool.self), false) // swiftlint:disable:this xct_specific_matcher - XCTAssertNil(value.get(String.self)) + #expect(value.get(Bool.self) == false) + #expect(value.get(String.self) == nil) } } diff --git a/Tests/DefaultsTests/DefaultsArrayTests.swift b/Tests/DefaultsTests/DefaultsArrayTests.swift index a0bc03d..4484080 100644 --- a/Tests/DefaultsTests/DefaultsArrayTests.swift +++ b/Tests/DefaultsTests/DefaultsArrayTests.swift @@ -1,116 +1,127 @@ import Foundation +import Testing import Defaults -import XCTest + +private let suite_ = createSuite() private let fixtureArray = ["Hank", "Chen"] extension Defaults.Keys { - fileprivate static let array = Key<[String]>("array", default: fixtureArray) + fileprivate static let array = Key<[String]>("array", default: fixtureArray, suite: suite_) } -final class DefaultsArrayTests: XCTestCase { - override func setUp() { - super.setUp() - Defaults.removeAll() +@Suite(.serialized) +final class DefaultsArrayTests { + init() { + Defaults.removeAll(suite: suite_) } - override func tearDown() { - super.tearDown() - Defaults.removeAll() + deinit { + Defaults.removeAll(suite: suite_) } + @Test func testKey() { - let key = Defaults.Key<[String]>("independentArrayStringKey", default: fixtureArray) - XCTAssertEqual(Defaults[key][0], fixtureArray[0]) + let key = Defaults.Key<[String]>("independentArrayStringKey", default: fixtureArray, suite: suite_) + #expect(Defaults[key][0] == fixtureArray[0]) let newValue = "John" Defaults[key][0] = newValue - XCTAssertEqual(Defaults[key][0], newValue) + #expect(Defaults[key][0] == newValue) } + @Test func testOptionalKey() { - let key = Defaults.Key<[String]?>("independentArrayOptionalStringKey") // swiftlint:disable:this discouraged_optional_collection - XCTAssertNil(Defaults[key]) + let key = Defaults.Key<[String]?>("independentArrayOptionalStringKey", suite: suite_) // swiftlint:disable:this discouraged_optional_collection + #expect(Defaults[key] == nil) Defaults[key] = fixtureArray - XCTAssertEqual(Defaults[key]?[0], fixtureArray[0]) + #expect(Defaults[key]?[0] == fixtureArray[0]) Defaults[key] = nil - XCTAssertNil(Defaults[key]) + #expect(Defaults[key] == nil) let newValue = ["John", "Chen"] Defaults[key] = newValue - XCTAssertEqual(Defaults[key]?[0], newValue[0]) + #expect(Defaults[key]?[0] == newValue[0]) } + @Test func testNestedKey() { let defaultValue = ["Hank", "Chen"] - let key = Defaults.Key<[[String]]>("independentArrayNestedKey", default: [defaultValue]) - XCTAssertEqual(Defaults[key][0][0], "Hank") + let key = Defaults.Key<[[String]]>("independentArrayNestedKey", default: [defaultValue], suite: suite_) + #expect(Defaults[key][0][0] == "Hank") let newValue = ["Sindre", "Sorhus"] Defaults[key][0] = newValue Defaults[key].append(defaultValue) - XCTAssertEqual(Defaults[key][0][0], newValue[0]) - XCTAssertEqual(Defaults[key][0][1], newValue[1]) - XCTAssertEqual(Defaults[key][1][0], defaultValue[0]) - XCTAssertEqual(Defaults[key][1][1], defaultValue[1]) + #expect(Defaults[key][0][0] == newValue[0]) + #expect(Defaults[key][0][1] == newValue[1]) + #expect(Defaults[key][1][0] == defaultValue[0]) + #expect(Defaults[key][1][1] == defaultValue[1]) } + @Test func testDictionaryKey() { let defaultValue = ["0": "HankChen"] - let key = Defaults.Key<[[String: String]]>("independentArrayDictionaryKey", default: [defaultValue]) - XCTAssertEqual(Defaults[key][0]["0"], defaultValue["0"]) + let key = Defaults.Key<[[String: String]]>("independentArrayDictionaryKey", default: [defaultValue], suite: suite_) + #expect(Defaults[key][0]["0"] == defaultValue["0"]) let newValue = ["0": "SindreSorhus"] Defaults[key][0] = newValue Defaults[key].append(defaultValue) - XCTAssertEqual(Defaults[key][0]["0"], newValue["0"]) - XCTAssertEqual(Defaults[key][1]["0"], defaultValue["0"]) + #expect(Defaults[key][0]["0"] == newValue["0"]) + #expect(Defaults[key][1]["0"] == defaultValue["0"]) } + @Test func testNestedDictionaryKey() { let defaultValue = ["0": [["0": 0]]] - let key = Defaults.Key<[[String: [[String: Int]]]]>("independentArrayNestedDictionaryKey", default: [defaultValue]) - XCTAssertEqual(Defaults[key][0]["0"]![0]["0"], 0) + let key = Defaults.Key<[[String: [[String: Int]]]]>("independentArrayNestedDictionaryKey", default: [defaultValue], suite: suite_) + #expect(Defaults[key][0]["0"]?[0]["0"] == 0) let newValue = 1 - Defaults[key][0]["0"]![0]["0"] = newValue + Defaults[key][0]["0"]?[0]["0"] = newValue Defaults[key].append(defaultValue) - XCTAssertEqual(Defaults[key][1]["0"]![0]["0"], 0) - XCTAssertEqual(Defaults[key][0]["0"]![0]["0"], newValue) + #expect(Defaults[key][1]["0"]?[0]["0"] == 0) + #expect(Defaults[key][0]["0"]?[0]["0"] == newValue) } + @Test func testType() { - XCTAssertEqual(Defaults[.array][0], fixtureArray[0]) + #expect(Defaults[.array][0] == fixtureArray[0]) let newName = "Hank121314" Defaults[.array][0] = newName - XCTAssertEqual(Defaults[.array][0], newName) + #expect(Defaults[.array][0] == newName) } - func testObserveKeyCombine() { - let key = Defaults.Key<[String]>("observeArrayKeyCombine", default: fixtureArray) + @available(iOS 16.0, macOS 13.0, tvOS 16.0, watchOS 9.0, visionOS 1.0, *) + @Test + func testObserveKeyCombine() async { + let key = Defaults.Key<[String]>("observeArrayKeyCombine", default: fixtureArray, suite: suite_) let newName = "Chen" - let expect = expectation(description: "Observation closure being called") let publisher = Defaults .publisher(key, options: []) .map { ($0.oldValue, $0.newValue) } .collect(2) - let cancellable = publisher.sink { tuples in - for (index, expected) in [(fixtureArray[0], newName), (newName, fixtureArray[0])].enumerated() { - XCTAssertEqual(expected.0, tuples[index].0[0]) - XCTAssertEqual(expected.1, tuples[index].1[0]) - } + let expectedValues = [(fixtureArray[0], newName), (newName, fixtureArray[0])] - expect.fulfill() + Task { + try? await Task.sleep(for: .seconds(0.1)) + Defaults[key][0] = newName + Defaults.reset(key) } - Defaults[key][0] = newName - Defaults.reset(key) - cancellable.cancel() + for await tuples in publisher.values { + for (index, expected) in expectedValues.enumerated() { + #expect(expected.0 == tuples[index].0[0]) + #expect(expected.1 == tuples[index].1[0]) + } - waitForExpectations(timeout: 10) + break + } } - func testObserveOptionalKeyCombine() { - let key = Defaults.Key<[String]?>("observeArrayOptionalKeyCombine") // swiftlint:disable:this discouraged_optional_collection + @available(iOS 16.0, macOS 13.0, tvOS 16.0, watchOS 9.0, visionOS 1.0, *) + @Test + func testObserveOptionalKeyCombine() async { + let key = Defaults.Key<[String]?>("observeArrayOptionalKeyCombine", suite: suite_) // swiftlint:disable:this discouraged_optional_collection let newName = ["Chen"] - let expect = expectation(description: "Observation closure being called") let publisher = Defaults .publisher(key, options: []) @@ -120,57 +131,20 @@ final class DefaultsArrayTests: XCTestCase { // swiftlint:disable:next discouraged_optional_collection let expectedValues: [([String]?, [String]?)] = [(nil, fixtureArray), (fixtureArray, newName), (newName, nil)] - let cancellable = publisher.sink { actualValues in + Task { + try? await Task.sleep(for: .seconds(0.1)) + Defaults[key] = fixtureArray + Defaults[key] = newName + Defaults.reset(key) + } + + for await actualValues in publisher.values { for (expected, actual) in zip(expectedValues, actualValues) { - XCTAssertEqual(expected.0, actual.0) - XCTAssertEqual(expected.1, actual.1) + #expect(expected.0 == actual.0) + #expect(expected.1 == actual.1) } - expect.fulfill() + break } - - Defaults[key] = fixtureArray - Defaults[key] = newName - Defaults.reset(key) - cancellable.cancel() - - waitForExpectations(timeout: 10) - } - - func testObserveKey() { - let key = Defaults.Key<[String]>("observeArrayKey", default: fixtureArray) - let newName = "John" - let expect = expectation(description: "Observation closure being called") - - var observation: Defaults.Observation! - observation = Defaults.observe(key, options: []) { change in - XCTAssertEqual(change.oldValue, fixtureArray) - XCTAssertEqual(change.newValue, [fixtureArray[0], newName]) - observation.invalidate() - expect.fulfill() - } - - Defaults[key][1] = newName - observation.invalidate() - - waitForExpectations(timeout: 10) - } - - func testObserveOptionalKey() { - let key = Defaults.Key<[String]?>("observeArrayOptionalKey") // swiftlint:disable:this discouraged_optional_collection - let expect = expectation(description: "Observation closure being called") - - var observation: Defaults.Observation! - observation = Defaults.observe(key, options: []) { change in - XCTAssertNil(change.oldValue) - XCTAssertEqual(change.newValue!, fixtureArray) - observation.invalidate() - expect.fulfill() - } - - Defaults[key] = fixtureArray - observation.invalidate() - - waitForExpectations(timeout: 10) } } diff --git a/Tests/DefaultsTests/DefaultsCodableEnumTests.swift b/Tests/DefaultsTests/DefaultsCodableEnumTests.swift index 70e66bb..8bfc150 100644 --- a/Tests/DefaultsTests/DefaultsCodableEnumTests.swift +++ b/Tests/DefaultsTests/DefaultsCodableEnumTests.swift @@ -1,6 +1,8 @@ import Foundation +import Testing import Defaults -import XCTest + +private let suite_ = createSuite() private enum FixtureCodableEnum: String, Hashable, Codable, Defaults.Serializable { case tenMinutes = "10 Minutes" @@ -15,300 +17,131 @@ private enum FixtureCodableEnumPreferRawRepresentable: Int, Hashable, Codable, D } extension Defaults.Keys { - fileprivate static let codableEnum = Key("codable_enum", default: .oneHour) - fileprivate static let codableEnumArray = Key<[FixtureCodableEnum]>("codable_enum", default: [.oneHour]) - fileprivate static let codableEnumDictionary = Key<[String: FixtureCodableEnum]>("codable_enum", default: ["0": .oneHour]) + fileprivate static let codableEnum = Key("codable_enum", default: .oneHour, suite: suite_) + fileprivate static let codableEnumArray = Key<[FixtureCodableEnum]>("codable_enum", default: [.oneHour], suite: suite_) + fileprivate static let codableEnumDictionary = Key<[String: FixtureCodableEnum]>("codable_enum", default: ["0": .oneHour], suite: suite_) } -final class DefaultsCodableEnumTests: XCTestCase { - override func setUp() { - super.setUp() - Defaults.removeAll() +@Suite(.serialized) +final class DefaultsCodableEnumTests { + init() { + Defaults.removeAll(suite: suite_) } - override func tearDown() { - super.tearDown() - Defaults.removeAll() + deinit { + Defaults.removeAll(suite: suite_) } + @Test func testKey() { - let key = Defaults.Key("independentCodableEnumKey", default: .tenMinutes) - XCTAssertEqual(Defaults[key], .tenMinutes) + let key = Defaults.Key("independentCodableEnumKey", default: .tenMinutes, suite: suite_) + #expect(Defaults[key] == .tenMinutes) Defaults[key] = .halfHour - XCTAssertEqual(Defaults[key], .halfHour) + #expect(Defaults[key] == .halfHour) } + @Test func testOptionalKey() { - let key = Defaults.Key("independentCodableEnumOptionalKey") - XCTAssertNil(Defaults[key]) + let key = Defaults.Key("independentCodableEnumOptionalKey", suite: suite_) + #expect(Defaults[key] == nil) Defaults[key] = .tenMinutes - XCTAssertEqual(Defaults[key], .tenMinutes) + #expect(Defaults[key] == .tenMinutes) } + @Test func testArrayKey() { - let key = Defaults.Key<[FixtureCodableEnum]>("independentCodableEnumArrayKey", default: [.tenMinutes]) - XCTAssertEqual(Defaults[key][0], .tenMinutes) + let key = Defaults.Key<[FixtureCodableEnum]>("independentCodableEnumArrayKey", default: [.tenMinutes], suite: suite_) + #expect(Defaults[key][0] == .tenMinutes) Defaults[key][0] = .halfHour - XCTAssertEqual(Defaults[key][0], .halfHour) + #expect(Defaults[key][0] == .halfHour) } + @Test func testArrayOptionalKey() { - let key = Defaults.Key<[FixtureCodableEnum]?>("independentCodableEnumArrayOptionalKey") // swiftlint:disable:this discouraged_optional_collection - XCTAssertNil(Defaults[key]) + let key = Defaults.Key<[FixtureCodableEnum]?>("independentCodableEnumArrayOptionalKey", suite: suite_) // swiftlint:disable:this discouraged_optional_collection + #expect(Defaults[key] == nil) Defaults[key] = [.halfHour] } + @Test func testNestedArrayKey() { - let key = Defaults.Key<[[FixtureCodableEnum]]>("independentCodableEnumNestedArrayKey", default: [[.tenMinutes]]) - XCTAssertEqual(Defaults[key][0][0], .tenMinutes) + let key = Defaults.Key<[[FixtureCodableEnum]]>("independentCodableEnumNestedArrayKey", default: [[.tenMinutes]], suite: suite_) + #expect(Defaults[key][0][0] == .tenMinutes) Defaults[key].append([.halfHour]) Defaults[key][0].append(.oneHour) - XCTAssertEqual(Defaults[key][1][0], .halfHour) - XCTAssertEqual(Defaults[key][0][1], .oneHour) + #expect(Defaults[key][1][0] == .halfHour) + #expect(Defaults[key][0][1] == .oneHour) } + @Test func testArrayDictionaryKey() { - let key = Defaults.Key<[[String: FixtureCodableEnum]]>("independentCodableEnumArrayDictionaryKey", default: [["0": .tenMinutes]]) - XCTAssertEqual(Defaults[key][0]["0"], .tenMinutes) + let key = Defaults.Key<[[String: FixtureCodableEnum]]>("independentCodableEnumArrayDictionaryKey", default: [["0": .tenMinutes]], suite: suite_) + #expect(Defaults[key][0]["0"] == .tenMinutes) Defaults[key][0]["1"] = .halfHour Defaults[key].append(["0": .oneHour]) - XCTAssertEqual(Defaults[key][0]["1"], .halfHour) - XCTAssertEqual(Defaults[key][1]["0"], .oneHour) + #expect(Defaults[key][0]["1"] == .halfHour) + #expect(Defaults[key][1]["0"] == .oneHour) } + @Test func testDictionaryKey() { - let key = Defaults.Key<[String: FixtureCodableEnum]>("independentCodableEnumDictionaryKey", default: ["0": .tenMinutes]) - XCTAssertEqual(Defaults[key]["0"], .tenMinutes) + let key = Defaults.Key<[String: FixtureCodableEnum]>("independentCodableEnumDictionaryKey", default: ["0": .tenMinutes], suite: suite_) + #expect(Defaults[key]["0"] == .tenMinutes) Defaults[key]["1"] = .halfHour Defaults[key]["0"] = .oneHour - XCTAssertEqual(Defaults[key]["0"], .oneHour) - XCTAssertEqual(Defaults[key]["1"], .halfHour) + #expect(Defaults[key]["0"] == .oneHour) + #expect(Defaults[key]["1"] == .halfHour) } + @Test func testDictionaryOptionalKey() { - let key = Defaults.Key<[String: FixtureCodableEnum]?>("independentCodableEnumDictionaryOptionalKey") // swiftlint:disable:this discouraged_optional_collection - XCTAssertNil(Defaults[key]) + let key = Defaults.Key<[String: FixtureCodableEnum]?>("independentCodableEnumDictionaryOptionalKey", suite: suite_) // swiftlint:disable:this discouraged_optional_collection + #expect(Defaults[key] == nil) Defaults[key] = ["0": .tenMinutes] Defaults[key]?["1"] = .halfHour - XCTAssertEqual(Defaults[key]?["0"], .tenMinutes) - XCTAssertEqual(Defaults[key]?["1"], .halfHour) + #expect(Defaults[key]?["0"] == .tenMinutes) + #expect(Defaults[key]?["1"] == .halfHour) } + @Test func testDictionaryArrayKey() { - let key = Defaults.Key<[String: [FixtureCodableEnum]]>("independentCodableEnumDictionaryArrayKey", default: ["0": [.tenMinutes]]) - XCTAssertEqual(Defaults[key]["0"]?[0], .tenMinutes) + let key = Defaults.Key<[String: [FixtureCodableEnum]]>("independentCodableEnumDictionaryArrayKey", default: ["0": [.tenMinutes]], suite: suite_) + #expect(Defaults[key]["0"]?[0] == .tenMinutes) Defaults[key]["0"]?.append(.halfHour) Defaults[key]["1"] = [.oneHour] - XCTAssertEqual(Defaults[key]["0"]?[0], .tenMinutes) - XCTAssertEqual(Defaults[key]["0"]?[1], .halfHour) - XCTAssertEqual(Defaults[key]["1"]?[0], .oneHour) + #expect(Defaults[key]["0"]?[0] == .tenMinutes) + #expect(Defaults[key]["0"]?[1] == .halfHour) + #expect(Defaults[key]["1"]?[0] == .oneHour) } + @Test func testType() { - XCTAssertEqual(Defaults[.codableEnum], .oneHour) + #expect(Defaults[.codableEnum] == .oneHour) Defaults[.codableEnum] = .tenMinutes - XCTAssertEqual(Defaults[.codableEnum], .tenMinutes) + #expect(Defaults[.codableEnum] == .tenMinutes) } + @Test func testArrayType() { - XCTAssertEqual(Defaults[.codableEnumArray][0], .oneHour) + #expect(Defaults[.codableEnumArray][0] == .oneHour) Defaults[.codableEnumArray].append(.halfHour) - XCTAssertEqual(Defaults[.codableEnumArray][0], .oneHour) - XCTAssertEqual(Defaults[.codableEnumArray][1], .halfHour) + #expect(Defaults[.codableEnumArray][0] == .oneHour) + #expect(Defaults[.codableEnumArray][1] == .halfHour) } + @Test func testDictionaryType() { - XCTAssertEqual(Defaults[.codableEnumDictionary]["0"], .oneHour) + #expect(Defaults[.codableEnumDictionary]["0"] == .oneHour) Defaults[.codableEnumDictionary]["1"] = .halfHour - XCTAssertEqual(Defaults[.codableEnumDictionary]["0"], .oneHour) - XCTAssertEqual(Defaults[.codableEnumDictionary]["1"], .halfHour) + #expect(Defaults[.codableEnumDictionary]["0"] == .oneHour) + #expect(Defaults[.codableEnumDictionary]["1"] == .halfHour) } + @Test func testFixtureCodableEnumPreferRawRepresentable() { let fixture: FixtureCodableEnumPreferRawRepresentable = .tenMinutes let keyName = "testFixtureCodableEnumPreferRawRepresentable" - _ = Defaults.Key(keyName, default: fixture) - XCTAssertNotNil(UserDefaults.standard.integer(forKey: keyName)) - } - - func testObserveKeyCombine() { - let key = Defaults.Key("observeCodableEnumKeyCombine", default: .tenMinutes) - let expect = expectation(description: "Observation closure being called") - - let publisher = Defaults - .publisher(key, options: []) - .map { ($0.oldValue, $0.newValue) } - .collect(2) - - let expectedValue: [(FixtureCodableEnum, FixtureCodableEnum)] = [(.tenMinutes, .oneHour), (.oneHour, .tenMinutes)] - - let cancellable = publisher.sink { tuples in - for (index, expected) in expectedValue.enumerated() { - XCTAssertEqual(expected.0, tuples[index].0) - XCTAssertEqual(expected.1, tuples[index].1) - } - - expect.fulfill() - } - - Defaults[key] = .oneHour - Defaults.reset(key) - cancellable.cancel() - - waitForExpectations(timeout: 10) - } - - func testObserveOptionalKeyCombine() { - let key = Defaults.Key("observeCodableEnumOptionalKeyCombine") - let expect = expectation(description: "Observation closure being called") - - let publisher = Defaults - .publisher(key, options: []) - .map { ($0.oldValue, $0.newValue) } - .collect(3) - - let expectedValue: [(FixtureCodableEnum?, FixtureCodableEnum?)] = [(nil, .tenMinutes), (.tenMinutes, .halfHour), (.halfHour, nil)] - - let cancellable = publisher.sink { tuples in - for (index, expected) in expectedValue.enumerated() { - XCTAssertEqual(expected.0, tuples[index].0) - XCTAssertEqual(expected.1, tuples[index].1) - } - - expect.fulfill() - } - - Defaults[key] = .tenMinutes - Defaults[key] = .halfHour - Defaults.reset(key) - cancellable.cancel() - - waitForExpectations(timeout: 10) - } - - func testObserveArrayKeyCombine() { - let key = Defaults.Key<[FixtureCodableEnum]>("observeCodableEnumArrayKeyCombine", default: [.tenMinutes]) - let expect = expectation(description: "Observation closure being called") - - let publisher = Defaults - .publisher(key, options: []) - .map { ($0.oldValue, $0.newValue) } - .collect(2) - - let expectedValue: [(FixtureCodableEnum?, FixtureCodableEnum?)] = [(.tenMinutes, .halfHour), (.halfHour, .tenMinutes)] - - let cancellable = publisher.sink { tuples in - for (index, expected) in expectedValue.enumerated() { - XCTAssertEqual(expected.0, tuples[index].0[0]) - XCTAssertEqual(expected.1, tuples[index].1[0]) - } - - expect.fulfill() - } - - Defaults[key][0] = .halfHour - Defaults.reset(key) - cancellable.cancel() - - waitForExpectations(timeout: 10) - } - - func testObserveDictionaryKeyCombine() { - let key = Defaults.Key<[String: FixtureCodableEnum]>("observeCodableEnumDictionaryKeyCombine", default: ["0": .tenMinutes]) - let expect = expectation(description: "Observation closure being called") - - let publisher = Defaults - .publisher(key, options: []) - .map { ($0.oldValue, $0.newValue) } - .collect(2) - - let expectedValue: [(FixtureCodableEnum?, FixtureCodableEnum?)] = [(.tenMinutes, .halfHour), (.halfHour, .tenMinutes)] - - let cancellable = publisher.sink { tuples in - for (index, expected) in expectedValue.enumerated() { - XCTAssertEqual(expected.0, tuples[index].0["0"]) - XCTAssertEqual(expected.1, tuples[index].1["0"]) - } - - expect.fulfill() - } - - Defaults[key]["0"] = .halfHour - Defaults.reset(key) - cancellable.cancel() - - waitForExpectations(timeout: 10) - } - - func testObserveKey() { - let key = Defaults.Key("observeCodableEnumKey", default: .tenMinutes) - let expect = expectation(description: "Observation closure being called") - - var observation: Defaults.Observation! - observation = Defaults.observe(key, options: []) { change in - XCTAssertEqual(change.oldValue, .tenMinutes) - XCTAssertEqual(change.newValue, .halfHour) - observation.invalidate() - expect.fulfill() - } - - Defaults[key] = .halfHour - observation.invalidate() - - waitForExpectations(timeout: 10) - } - - func testObserveOptionalKey() { - let key = Defaults.Key("observeCodableEnumOptionalKey") - let expect = expectation(description: "Observation closure being called") - - var observation: Defaults.Observation! - observation = Defaults.observe(key, options: []) { change in - XCTAssertNil(change.oldValue) - XCTAssertEqual(change.newValue, .halfHour) - observation.invalidate() - expect.fulfill() - } - - Defaults[key] = .halfHour - observation.invalidate() - - waitForExpectations(timeout: 10) - } - - func testObserveArrayKey() { - let key = Defaults.Key<[FixtureCodableEnum]>("observeCodableEnumArrayKey", default: [.tenMinutes]) - let expect = expectation(description: "Observation closure being called") - - var observation: Defaults.Observation! - observation = Defaults.observe(key, options: []) { change in - XCTAssertEqual(change.oldValue[0], .tenMinutes) - XCTAssertEqual(change.newValue[1], .halfHour) - observation.invalidate() - expect.fulfill() - } - - Defaults[key].append(.halfHour) - observation.invalidate() - - waitForExpectations(timeout: 10) - } - - func testObserveDictionaryKey() { - let key = Defaults.Key<[String: FixtureCodableEnum]>("observeCodableEnumDictionaryKey", default: ["0": .tenMinutes]) - let expect = expectation(description: "Observation closure being called") - - var observation: Defaults.Observation! - observation = Defaults.observe(key, options: []) { change in - XCTAssertEqual(change.oldValue["0"], .tenMinutes) - XCTAssertEqual(change.newValue["1"], .halfHour) - observation.invalidate() - expect.fulfill() - } - - Defaults[key]["1"] = .halfHour - observation.invalidate() - - waitForExpectations(timeout: 10) + _ = Defaults.Key(keyName, default: fixture, suite: suite_) + #expect(UserDefaults.standard.integer(forKey: keyName) != 0) } } diff --git a/Tests/DefaultsTests/DefaultsCodableTests.swift b/Tests/DefaultsTests/DefaultsCodableTests.swift index 4dced9d..2fdb0be 100644 --- a/Tests/DefaultsTests/DefaultsCodableTests.swift +++ b/Tests/DefaultsTests/DefaultsCodableTests.swift @@ -1,7 +1,9 @@ import Foundation -import XCTest +import Testing import Defaults +private let suite_ = createSuite() + private struct Unicorn: Codable, Defaults.Serializable { var isUnicorn: Bool } @@ -35,99 +37,109 @@ private final class UnicornCodableAndPreferNSSecureCoding: NSObject, NSSecureCod } extension Defaults.Keys { - fileprivate static let codable = Key("codable", default: fixtureCodable) - fileprivate static let codableArray = Key<[Unicorn]>("codable", default: [fixtureCodable]) - fileprivate static let codableDictionary = Key<[String: Unicorn]>("codable", default: ["0": fixtureCodable]) + fileprivate static let codable = Key("codable", default: fixtureCodable, suite: suite_) + fileprivate static let codableArray = Key<[Unicorn]>("codable", default: [fixtureCodable], suite: suite_) + fileprivate static let codableDictionary = Key<[String: Unicorn]>("codable", default: ["0": fixtureCodable], suite: suite_) } -final class DefaultsCodableTests: XCTestCase { - override func setUp() { - super.setUp() - Defaults.removeAll() +@Suite(.serialized) +final class DefaultsCodableTests { + init() { + // TODO: Convert all the keys to use a prefix and then remove based on the prefix. + Defaults.removeAll(suite: suite_) } - override func tearDown() { - super.tearDown() - Defaults.removeAll() + deinit { + Defaults.removeAll(suite: suite_) } + @Test func testKey() { - let key = Defaults.Key("independentCodableKey", default: fixtureCodable) - XCTAssertTrue(Defaults[key].isUnicorn) + let key = Defaults.Key("independentCodableKey", default: fixtureCodable, suite: suite_) + #expect(Defaults[key].isUnicorn) Defaults[key].isUnicorn = false - XCTAssertFalse(Defaults[key].isUnicorn) + #expect(!Defaults[key].isUnicorn) } + @Test func testOptionalKey() { - let key = Defaults.Key("independentCodableOptionalKey") - XCTAssertNil(Defaults[key]) + let key = Defaults.Key("independentCodableOptionalKey", suite: suite_) + #expect(Defaults[key] == nil) Defaults[key] = Unicorn(isUnicorn: true) - XCTAssertTrue(Defaults[key]?.isUnicorn ?? false) + #expect(Defaults[key]?.isUnicorn ?? false) } + @Test func testArrayKey() { - let key = Defaults.Key<[Unicorn]>("independentCodableArrayKey", default: [fixtureCodable]) - XCTAssertTrue(Defaults[key][0].isUnicorn) + let key = Defaults.Key<[Unicorn]>("independentCodableArrayKey", default: [fixtureCodable], suite: suite_) + #expect(Defaults[key][0].isUnicorn) Defaults[key].append(Unicorn(isUnicorn: false)) - XCTAssertTrue(Defaults[key][0].isUnicorn) - XCTAssertFalse(Defaults[key][1].isUnicorn) + #expect(Defaults[key][0].isUnicorn) + #expect(!Defaults[key][1].isUnicorn) } + @Test func testArrayOptionalKey() { - let key = Defaults.Key<[Unicorn]?>("independentCodableArrayOptionalKey") // swiftlint:disable:this discouraged_optional_collection - XCTAssertNil(Defaults[key]) + let key = Defaults.Key<[Unicorn]?>("independentCodableArrayOptionalKey", suite: suite_) // swiftlint:disable:this discouraged_optional_collection + #expect(Defaults[key] == nil) Defaults[key] = [fixtureCodable] Defaults[key]?.append(Unicorn(isUnicorn: false)) - XCTAssertTrue(Defaults[key]?[0].isUnicorn ?? false) - XCTAssertFalse(Defaults[key]?[1].isUnicorn ?? false) + #expect(Defaults[key]?[0].isUnicorn ?? false) + #expect(!(Defaults[key]?[1].isUnicorn ?? false)) } + @Test func testNestedArrayKey() { - let key = Defaults.Key<[[Unicorn]]>("independentCodableNestedArrayKey", default: [[fixtureCodable]]) - XCTAssertTrue(Defaults[key][0][0].isUnicorn) + let key = Defaults.Key<[[Unicorn]]>("independentCodableNestedArrayKey", default: [[fixtureCodable]], suite: suite_) + #expect(Defaults[key][0][0].isUnicorn) Defaults[key].append([fixtureCodable]) Defaults[key][0].append(Unicorn(isUnicorn: false)) - XCTAssertTrue(Defaults[key][0][0].isUnicorn) - XCTAssertTrue(Defaults[key][1][0].isUnicorn) - XCTAssertFalse(Defaults[key][0][1].isUnicorn) + #expect(Defaults[key][0][0].isUnicorn) + #expect(Defaults[key][1][0].isUnicorn) + #expect(!Defaults[key][0][1].isUnicorn) } + @Test func testArrayDictionaryKey() { - let key = Defaults.Key<[[String: Unicorn]]>("independentCodableArrayDictionaryKey", default: [["0": fixtureCodable]]) - XCTAssertTrue(Defaults[key][0]["0"]?.isUnicorn ?? false) + let key = Defaults.Key<[[String: Unicorn]]>("independentCodableArrayDictionaryKey", default: [["0": fixtureCodable]], suite: suite_) + #expect(Defaults[key][0]["0"]?.isUnicorn ?? false) Defaults[key].append(["0": fixtureCodable]) Defaults[key][0]["1"] = Unicorn(isUnicorn: false) - XCTAssertTrue(Defaults[key][0]["0"]?.isUnicorn ?? false) - XCTAssertTrue(Defaults[key][1]["0"]?.isUnicorn ?? false) - XCTAssertFalse(Defaults[key][0]["1"]?.isUnicorn ?? true) + #expect(Defaults[key][0]["0"]?.isUnicorn ?? false) + #expect(Defaults[key][1]["0"]?.isUnicorn ?? false) + #expect(!(Defaults[key][0]["1"]?.isUnicorn ?? true)) } + @Test func testDictionaryKey() { - let key = Defaults.Key<[String: Unicorn]>("independentCodableDictionaryKey", default: ["0": fixtureCodable]) - XCTAssertTrue(Defaults[key]["0"]?.isUnicorn ?? false) + let key = Defaults.Key<[String: Unicorn]>("independentCodableDictionaryKey", default: ["0": fixtureCodable], suite: suite_) + #expect(Defaults[key]["0"]?.isUnicorn ?? false) Defaults[key]["1"] = Unicorn(isUnicorn: false) - XCTAssertTrue(Defaults[key]["0"]?.isUnicorn ?? false) - XCTAssertFalse(Defaults[key]["1"]?.isUnicorn ?? true) + #expect(Defaults[key]["0"]?.isUnicorn ?? false) + #expect(!(Defaults[key]["1"]?.isUnicorn ?? true)) } + @Test func testDictionaryOptionalKey() { - let key = Defaults.Key<[String: Unicorn]?>("independentCodableDictionaryOptionalKey") // swiftlint:disable:this discouraged_optional_collection - XCTAssertNil(Defaults[key]) + let key = Defaults.Key<[String: Unicorn]?>("independentCodableDictionaryOptionalKey", suite: suite_) // swiftlint:disable:this discouraged_optional_collection + #expect(Defaults[key] == nil) Defaults[key] = ["0": fixtureCodable] Defaults[key]?["1"] = Unicorn(isUnicorn: false) - XCTAssertTrue(Defaults[key]?["0"]?.isUnicorn ?? false) - XCTAssertFalse(Defaults[key]?["1"]?.isUnicorn ?? true) + #expect(Defaults[key]?["0"]?.isUnicorn ?? false) + #expect(!(Defaults[key]?["1"]?.isUnicorn ?? true)) } + @Test func testDictionaryArrayKey() { - let key = Defaults.Key<[String: [Unicorn]]>("independentCodableDictionaryArrayKey", default: ["0": [fixtureCodable]]) - XCTAssertTrue(Defaults[key]["0"]?[0].isUnicorn ?? false) + let key = Defaults.Key<[String: [Unicorn]]>("independentCodableDictionaryArrayKey", default: ["0": [fixtureCodable]], suite: suite_) + #expect(Defaults[key]["0"]?[0].isUnicorn ?? false) Defaults[key]["1"] = [fixtureCodable] Defaults[key]["0"]?.append(Unicorn(isUnicorn: false)) - XCTAssertTrue(Defaults[key]["1"]?[0].isUnicorn ?? false) - XCTAssertFalse(Defaults[key]["0"]?[1].isUnicorn ?? true) + #expect(Defaults[key]["1"]?[0].isUnicorn ?? false) + #expect(!(Defaults[key]["0"]?[1].isUnicorn ?? true)) } + @Test func testCodableAndRawRepresentable() { struct Unicorn: Codable, RawRepresentable, Defaults.Serializable { var rawValue: String @@ -135,217 +147,48 @@ final class DefaultsCodableTests: XCTestCase { let fixture = Unicorn(rawValue: "x") - let key = Defaults.Key("independentKey_codableAndRawRepresentable") + let key = Defaults.Key("independentKey_codableAndRawRepresentable", suite: suite_) Defaults[key] = fixture - XCTAssertEqual(Defaults[key]?.rawValue, fixture.rawValue) - XCTAssertEqual(UserDefaults.standard.string(forKey: key.name), #""\#(fixture.rawValue)""#) + #expect(Defaults[key]?.rawValue == fixture.rawValue) + #expect(suite_.string(forKey: key.name) == #""\#(fixture.rawValue)""#) } + @Test func testType() { - XCTAssertTrue(Defaults[.codable].isUnicorn) + #expect(Defaults[.codable].isUnicorn) Defaults[.codable] = Unicorn(isUnicorn: false) - XCTAssertFalse(Defaults[.codable].isUnicorn) + #expect(!Defaults[.codable].isUnicorn) } + @Test func testArrayType() { - XCTAssertTrue(Defaults[.codableArray][0].isUnicorn) + #expect(Defaults[.codableArray][0].isUnicorn) Defaults[.codableArray][0] = Unicorn(isUnicorn: false) - XCTAssertFalse(Defaults[.codableArray][0].isUnicorn) + #expect(!Defaults[.codableArray][0].isUnicorn) } + @Test func testDictionaryType() { - XCTAssertTrue(Defaults[.codableDictionary]["0"]?.isUnicorn ?? false) + #expect(Defaults[.codableDictionary]["0"]?.isUnicorn ?? false) Defaults[.codableDictionary]["0"] = Unicorn(isUnicorn: false) - XCTAssertFalse(Defaults[.codableDictionary]["0"]?.isUnicorn ?? true) + #expect(!(Defaults[.codableDictionary]["0"]?.isUnicorn ?? true)) } + @Test func testCodableAndNSSecureCoding() { let fixture = UnicornCodableAndNSSecureCoding() let keyName = "testCodableAndNSSecureCoding" - _ = Defaults.Key(keyName, default: fixture) - XCTAssertNil(UserDefaults.standard.data(forKey: keyName)) - XCTAssertNotNil(UserDefaults.standard.string(forKey: keyName)) + _ = Defaults.Key(keyName, default: fixture, suite: suite_) + #expect(UserDefaults.standard.data(forKey: keyName) == nil) + #expect(UserDefaults.standard.string(forKey: keyName) != nil) } + @Test func testCodableAndPreferNSSecureCoding() { let fixture = UnicornCodableAndPreferNSSecureCoding() let keyName = "testCodableAndPreferNSSecureCoding" - _ = Defaults.Key(keyName, default: fixture) - XCTAssertNil(UserDefaults.standard.string(forKey: keyName)) - XCTAssertNotNil(UserDefaults.standard.data(forKey: keyName)) - } - - func testObserveKeyCombine() { - let key = Defaults.Key("observeCodableKeyCombine", default: fixtureCodable) - let expect = expectation(description: "Observation closure being called") - - let publisher = Defaults - .publisher(key, options: []) - .map { ($0.oldValue.isUnicorn, $0.newValue.isUnicorn) } - .collect(2) - - let cancellable = publisher.sink { tuples in - for (index, expected) in [(true, false), (false, true)].enumerated() { - XCTAssertEqual(expected.0, tuples[index].0) - XCTAssertEqual(expected.1, tuples[index].1) - } - - expect.fulfill() - } - - Defaults[key] = Unicorn(isUnicorn: false) - Defaults.reset(key) - cancellable.cancel() - - waitForExpectations(timeout: 10) - } - - func testObserveOptionalKeyCombine() { - let key = Defaults.Key("observeCodableOptionalKeyCombine") - let expect = expectation(description: "Observation closure being called") - - let publisher = Defaults - .publisher(key, options: []) - .map { ($0.oldValue?.isUnicorn, $0.newValue?.isUnicorn) } - .collect(2) - - let expectedValue: [(Bool?, Bool?)] = [(nil, true), (true, nil)] // swiftlint:disable:this discouraged_optional_boolean - - let cancellable = publisher.sink { tuples in - for (index, expected) in expectedValue.enumerated() { - XCTAssertEqual(expected.0, tuples[index].0) - XCTAssertEqual(expected.1, tuples[index].1) - } - - expect.fulfill() - } - - Defaults[key] = fixtureCodable - Defaults.reset(key) - cancellable.cancel() - - waitForExpectations(timeout: 10) - } - - func testObserveArrayKeyCombine() { - let key = Defaults.Key<[Unicorn]>("observeCodableArrayKeyCombine", default: [fixtureCodable]) - let expect = expectation(description: "Observation closure being called") - - let publisher = Defaults - .publisher(key, options: []) - .map { ($0.oldValue, $0.newValue) } - .collect(2) - - let cancellable = publisher.sink { tuples in - for (index, expected) in [(true, false), (false, true)].enumerated() { - XCTAssertEqual(expected.0, tuples[index].0[0].isUnicorn) - XCTAssertEqual(expected.1, tuples[index].1[0].isUnicorn) - } - - expect.fulfill() - } - - Defaults[key][0] = Unicorn(isUnicorn: false) - Defaults.reset(key) - cancellable.cancel() - - waitForExpectations(timeout: 10) - } - - func testObserveDictionaryKeyCombine() { - let key = Defaults.Key<[String: Unicorn]>("observeCodableDictionaryKeyCombine", default: ["0": fixtureCodable]) - let expect = expectation(description: "Observation closure being called") - - let publisher = Defaults - .publisher(key, options: []) - .map { ($0.oldValue, $0.newValue) } - .collect(2) - - let cancellable = publisher.sink { tuples in - for (index, expected) in [(true, false), (false, true)].enumerated() { - XCTAssertEqual(expected.0, tuples[index].0["0"]?.isUnicorn) - XCTAssertEqual(expected.1, tuples[index].1["0"]?.isUnicorn) - } - - expect.fulfill() - } - - Defaults[key]["0"] = Unicorn(isUnicorn: false) - Defaults.reset(key) - cancellable.cancel() - - waitForExpectations(timeout: 10) - } - - func testObserveKey() { - let key = Defaults.Key("observeCodableKey", default: fixtureCodable) - let expect = expectation(description: "Observation closure being called") - - var observation: Defaults.Observation! - observation = Defaults.observe(key, options: []) { change in - XCTAssertTrue(change.oldValue.isUnicorn) - XCTAssertFalse(change.newValue.isUnicorn) - observation.invalidate() - expect.fulfill() - } - - Defaults[key] = Unicorn(isUnicorn: false) - observation.invalidate() - - waitForExpectations(timeout: 10) - } - - func testObserveOptionalKey() { - let key = Defaults.Key("observeCodableOptionalKey") - let expect = expectation(description: "Observation closure being called") - - var observation: Defaults.Observation! - observation = Defaults.observe(key, options: []) { change in - XCTAssertNil(change.oldValue) - XCTAssertTrue(change.newValue?.isUnicorn ?? false) - observation.invalidate() - expect.fulfill() - } - - Defaults[key] = fixtureCodable - observation.invalidate() - - waitForExpectations(timeout: 10) - } - - func testObserveArrayKey() { - let key = Defaults.Key<[Unicorn]>("observeCodableArrayKey", default: [fixtureCodable]) - let expect = expectation(description: "Observation closure being called") - - var observation: Defaults.Observation! - observation = Defaults.observe(key, options: []) { change in - XCTAssertTrue(change.oldValue[0].isUnicorn) - XCTAssertFalse(change.newValue[0].isUnicorn) - observation.invalidate() - expect.fulfill() - } - - Defaults[key][0] = Unicorn(isUnicorn: false) - observation.invalidate() - - waitForExpectations(timeout: 10) - } - - func testObserveDictionaryKey() { - let key = Defaults.Key<[String: Unicorn]>("observeCodableDictionaryKey", default: ["0": fixtureCodable]) - let expect = expectation(description: "Observation closure being called") - - var observation: Defaults.Observation! - observation = Defaults.observe(key, options: []) { change in - XCTAssertTrue(change.oldValue["0"]?.isUnicorn ?? false) - XCTAssertFalse(change.newValue["0"]?.isUnicorn ?? true) - observation.invalidate() - expect.fulfill() - } - - Defaults[key]["0"] = Unicorn(isUnicorn: false) - observation.invalidate() - - waitForExpectations(timeout: 10) + _ = Defaults.Key(keyName, default: fixture, suite: suite_) + #expect(UserDefaults.standard.string(forKey: keyName) == nil) + #expect(UserDefaults.standard.data(forKey: keyName) != nil) } } diff --git a/Tests/DefaultsTests/DefaultsCollectionCustomElementTests.swift b/Tests/DefaultsTests/DefaultsCollectionCustomElementTests.swift index 99f21ef..207992d 100644 --- a/Tests/DefaultsTests/DefaultsCollectionCustomElementTests.swift +++ b/Tests/DefaultsTests/DefaultsCollectionCustomElementTests.swift @@ -1,7 +1,9 @@ import Foundation -import XCTest +import Testing import Defaults +private let suite_ = createSuite() + private struct Item: Equatable { let name: String let count: UInt @@ -40,308 +42,144 @@ private let fixtureCustomCollection1 = Item(name: "Banana", count: 20) private let fixtureCustomCollection2 = Item(name: "Grape", count: 30) extension Defaults.Keys { - fileprivate static let collectionCustomElement = Key>("collectionCustomElement", default: .init(items: [fixtureCustomCollection])) - fileprivate static let collectionCustomElementArray = Key<[Bag]>("collectionCustomElementArray", default: [.init(items: [fixtureCustomCollection])]) - fileprivate static let collectionCustomElementDictionary = Key<[String: Bag]>("collectionCustomElementDictionary", default: ["0": .init(items: [fixtureCustomCollection])]) + fileprivate static let collectionCustomElement = Key>("collectionCustomElement", default: .init(items: [fixtureCustomCollection]), suite: suite_) + fileprivate static let collectionCustomElementArray = Key<[Bag]>("collectionCustomElementArray", default: [.init(items: [fixtureCustomCollection])], suite: suite_) + fileprivate static let collectionCustomElementDictionary = Key<[String: Bag]>("collectionCustomElementDictionary", default: ["0": .init(items: [fixtureCustomCollection])], suite: suite_) } -final class DefaultsCollectionCustomElementTests: XCTestCase { - override func setUp() { - super.setUp() - Defaults.removeAll() +@Suite(.serialized) +final class DefaultsCollectionCustomElementTests { + init() { + Defaults.removeAll(suite: suite_) } - override func tearDown() { - super.tearDown() - Defaults.removeAll() + deinit { + Defaults.removeAll(suite: suite_) } + @Test func testKey() { - let key = Defaults.Key>("independentCollectionCustomElementKey", default: .init(items: [fixtureCustomCollection])) + let key = Defaults.Key>("independentCollectionCustomElementKey", default: .init(items: [fixtureCustomCollection]), suite: suite_) Defaults[key].insert(element: fixtureCustomCollection1, at: 1) Defaults[key].insert(element: fixtureCustomCollection2, at: 2) - XCTAssertEqual(Defaults[key][0], fixtureCustomCollection) - XCTAssertEqual(Defaults[key][1], fixtureCustomCollection1) - XCTAssertEqual(Defaults[key][2], fixtureCustomCollection2) + #expect(Defaults[key][0] == fixtureCustomCollection) + #expect(Defaults[key][1] == fixtureCustomCollection1) + #expect(Defaults[key][2] == fixtureCustomCollection2) } + @Test func testOptionalKey() { - let key = Defaults.Key?>("independentCollectionCustomElementOptionalKey") + let key = Defaults.Key?>("independentCollectionCustomElementOptionalKey", suite: suite_) Defaults[key] = .init(items: [fixtureCustomCollection]) Defaults[key]?.insert(element: fixtureCustomCollection1, at: 1) Defaults[key]?.insert(element: fixtureCustomCollection2, at: 2) - XCTAssertEqual(Defaults[key]?[0], fixtureCustomCollection) - XCTAssertEqual(Defaults[key]?[1], fixtureCustomCollection1) - XCTAssertEqual(Defaults[key]?[2], fixtureCustomCollection2) + #expect(Defaults[key]?[0] == fixtureCustomCollection) + #expect(Defaults[key]?[1] == fixtureCustomCollection1) + #expect(Defaults[key]?[2] == fixtureCustomCollection2) } + @Test func testArrayKey() { - let key = Defaults.Key<[Bag]>("independentCollectionCustomElementArrayKey", default: [.init(items: [fixtureCustomCollection])]) + let key = Defaults.Key<[Bag]>("independentCollectionCustomElementArrayKey", default: [.init(items: [fixtureCustomCollection])], suite: suite_) Defaults[key][0].insert(element: fixtureCustomCollection1, at: 1) Defaults[key].append(.init(items: [fixtureCustomCollection2])) - XCTAssertEqual(Defaults[key][0][0], fixtureCustomCollection) - XCTAssertEqual(Defaults[key][0][1], fixtureCustomCollection1) - XCTAssertEqual(Defaults[key][1][0], fixtureCustomCollection2) + #expect(Defaults[key][0][0] == fixtureCustomCollection) + #expect(Defaults[key][0][1] == fixtureCustomCollection1) + #expect(Defaults[key][1][0] == fixtureCustomCollection2) } + @Test func testArrayOptionalKey() { - let key = Defaults.Key<[Bag]?>("independentCollectionCustomElementArrayOptionalKey") // swiftlint:disable:this discouraged_optional_collection + let key = Defaults.Key<[Bag]?>("independentCollectionCustomElementArrayOptionalKey", suite: suite_) // swiftlint:disable:this discouraged_optional_collection Defaults[key] = [.init(items: [fixtureCustomCollection])] Defaults[key]?[0].insert(element: fixtureCustomCollection1, at: 1) Defaults[key]?.append(Bag(items: [fixtureCustomCollection2])) - XCTAssertEqual(Defaults[key]?[0][0], fixtureCustomCollection) - XCTAssertEqual(Defaults[key]?[0][1], fixtureCustomCollection1) - XCTAssertEqual(Defaults[key]?[1][0], fixtureCustomCollection2) + #expect(Defaults[key]?[0][0] == fixtureCustomCollection) + #expect(Defaults[key]?[0][1] == fixtureCustomCollection1) + #expect(Defaults[key]?[1][0] == fixtureCustomCollection2) } + @Test func testNestedArrayKey() { - let key = Defaults.Key<[[Bag]]>("independentCollectionCustomElementNestedArrayKey", default: [[.init(items: [fixtureCustomCollection])]]) + let key = Defaults.Key<[[Bag]]>("independentCollectionCustomElementNestedArrayKey", default: [[.init(items: [fixtureCustomCollection])]], suite: suite_) Defaults[key][0][0].insert(element: fixtureCustomCollection, at: 1) Defaults[key][0].append(.init(items: [fixtureCustomCollection1])) Defaults[key].append([.init(items: [fixtureCustomCollection2])]) - XCTAssertEqual(Defaults[key][0][0][0], fixtureCustomCollection) - XCTAssertEqual(Defaults[key][0][0][1], fixtureCustomCollection) - XCTAssertEqual(Defaults[key][0][1][0], fixtureCustomCollection1) - XCTAssertEqual(Defaults[key][1][0][0], fixtureCustomCollection2) + #expect(Defaults[key][0][0][0] == fixtureCustomCollection) + #expect(Defaults[key][0][0][1] == fixtureCustomCollection) + #expect(Defaults[key][0][1][0] == fixtureCustomCollection1) + #expect(Defaults[key][1][0][0] == fixtureCustomCollection2) } + @Test func testArrayDictionaryKey() { - let key = Defaults.Key<[[String: Bag]]>("independentCollectionCustomElementArrayDictionaryKey", default: [["0": .init(items: [fixtureCustomCollection])]]) + let key = Defaults.Key<[[String: Bag]]>("independentCollectionCustomElementArrayDictionaryKey", default: [["0": .init(items: [fixtureCustomCollection])]], suite: suite_) Defaults[key][0]["0"]?.insert(element: fixtureCustomCollection, at: 1) Defaults[key][0]["1"] = .init(items: [fixtureCustomCollection1]) Defaults[key].append(["0": .init(items: [fixtureCustomCollection2])]) - XCTAssertEqual(Defaults[key][0]["0"]?[0], fixtureCustomCollection) - XCTAssertEqual(Defaults[key][0]["0"]?[1], fixtureCustomCollection) - XCTAssertEqual(Defaults[key][0]["1"]?[0], fixtureCustomCollection1) - XCTAssertEqual(Defaults[key][1]["0"]?[0], fixtureCustomCollection2) + #expect(Defaults[key][0]["0"]?[0] == fixtureCustomCollection) + #expect(Defaults[key][0]["0"]?[1] == fixtureCustomCollection) + #expect(Defaults[key][0]["1"]?[0] == fixtureCustomCollection1) + #expect(Defaults[key][1]["0"]?[0] == fixtureCustomCollection2) } + @Test func testDictionaryKey() { - let key = Defaults.Key<[String: Bag]>("independentCollectionCustomElementDictionaryKey", default: ["0": .init(items: [fixtureCustomCollection])]) + let key = Defaults.Key<[String: Bag]>("independentCollectionCustomElementDictionaryKey", default: ["0": .init(items: [fixtureCustomCollection])], suite: suite_) Defaults[key]["0"]?.insert(element: fixtureCustomCollection1, at: 1) Defaults[key]["1"] = .init(items: [fixtureCustomCollection2]) - XCTAssertEqual(Defaults[key]["0"]?[0], fixtureCustomCollection) - XCTAssertEqual(Defaults[key]["0"]?[1], fixtureCustomCollection1) - XCTAssertEqual(Defaults[key]["1"]?[0], fixtureCustomCollection2) + #expect(Defaults[key]["0"]?[0] == fixtureCustomCollection) + #expect(Defaults[key]["0"]?[1] == fixtureCustomCollection1) + #expect(Defaults[key]["1"]?[0] == fixtureCustomCollection2) } + @Test func testDictionaryOptionalKey() { - let key = Defaults.Key<[String: Bag]?>("independentCollectionCustomElementDictionaryOptionalKey") // swiftlint:disable:this discouraged_optional_collection + let key = Defaults.Key<[String: Bag]?>("independentCollectionCustomElementDictionaryOptionalKey", suite: suite_) // swiftlint:disable:this discouraged_optional_collection Defaults[key] = ["0": .init(items: [fixtureCustomCollection])] Defaults[key]?["0"]?.insert(element: fixtureCustomCollection1, at: 1) Defaults[key]?["1"] = .init(items: [fixtureCustomCollection2]) - XCTAssertEqual(Defaults[key]?["0"]?[0], fixtureCustomCollection) - XCTAssertEqual(Defaults[key]?["0"]?[1], fixtureCustomCollection1) - XCTAssertEqual(Defaults[key]?["1"]?[0], fixtureCustomCollection2) + #expect(Defaults[key]?["0"]?[0] == fixtureCustomCollection) + #expect(Defaults[key]?["0"]?[1] == fixtureCustomCollection1) + #expect(Defaults[key]?["1"]?[0] == fixtureCustomCollection2) } + @Test func testDictionaryArrayKey() { - let key = Defaults.Key<[String: [Bag]]>("independentCollectionCustomElementDictionaryArrayKey", default: ["0": [.init(items: [fixtureCustomCollection])]]) + let key = Defaults.Key<[String: [Bag]]>("independentCollectionCustomElementDictionaryArrayKey", default: ["0": [.init(items: [fixtureCustomCollection])]], suite: suite_) Defaults[key]["0"]?[0].insert(element: fixtureCustomCollection, at: 1) Defaults[key]["0"]?.append(.init(items: [fixtureCustomCollection1])) Defaults[key]["1"] = [.init(items: [fixtureCustomCollection2])] - XCTAssertEqual(Defaults[key]["0"]?[0][0], fixtureCustomCollection) - XCTAssertEqual(Defaults[key]["0"]?[0][1], fixtureCustomCollection) - XCTAssertEqual(Defaults[key]["0"]?[1][0], fixtureCustomCollection1) - XCTAssertEqual(Defaults[key]["1"]?[0][0], fixtureCustomCollection2) + #expect(Defaults[key]["0"]?[0][0] == fixtureCustomCollection) + #expect(Defaults[key]["0"]?[0][1] == fixtureCustomCollection) + #expect(Defaults[key]["0"]?[1][0] == fixtureCustomCollection1) + #expect(Defaults[key]["1"]?[0][0] == fixtureCustomCollection2) } + @Test func testType() { Defaults[.collectionCustomElement].insert(element: fixtureCustomCollection1, at: 1) Defaults[.collectionCustomElement].insert(element: fixtureCustomCollection2, at: 2) - XCTAssertEqual(Defaults[.collectionCustomElement][0], fixtureCustomCollection) - XCTAssertEqual(Defaults[.collectionCustomElement][1], fixtureCustomCollection1) - XCTAssertEqual(Defaults[.collectionCustomElement][2], fixtureCustomCollection2) + #expect(Defaults[.collectionCustomElement][0] == fixtureCustomCollection) + #expect(Defaults[.collectionCustomElement][1] == fixtureCustomCollection1) + #expect(Defaults[.collectionCustomElement][2] == fixtureCustomCollection2) } + @Test func testArrayType() { Defaults[.collectionCustomElementArray][0].insert(element: fixtureCustomCollection1, at: 1) Defaults[.collectionCustomElementArray].append(.init(items: [fixtureCustomCollection2])) - XCTAssertEqual(Defaults[.collectionCustomElementArray][0][0], fixtureCustomCollection) - XCTAssertEqual(Defaults[.collectionCustomElementArray][0][1], fixtureCustomCollection1) - XCTAssertEqual(Defaults[.collectionCustomElementArray][1][0], fixtureCustomCollection2) + #expect(Defaults[.collectionCustomElementArray][0][0] == fixtureCustomCollection) + #expect(Defaults[.collectionCustomElementArray][0][1] == fixtureCustomCollection1) + #expect(Defaults[.collectionCustomElementArray][1][0] == fixtureCustomCollection2) } + @Test func testDictionaryType() { Defaults[.collectionCustomElementDictionary]["0"]?.insert(element: fixtureCustomCollection1, at: 1) Defaults[.collectionCustomElementDictionary]["1"] = .init(items: [fixtureCustomCollection2]) - XCTAssertEqual(Defaults[.collectionCustomElementDictionary]["0"]?[0], fixtureCustomCollection) - XCTAssertEqual(Defaults[.collectionCustomElementDictionary]["0"]?[1], fixtureCustomCollection1) - XCTAssertEqual(Defaults[.collectionCustomElementDictionary]["1"]?[0], fixtureCustomCollection2) - } - - func testObserveKeyCombine() { - let key = Defaults.Key>("observeCollectionCustomElementKeyCombine", default: .init(items: [fixtureCustomCollection])) - let expect = expectation(description: "Observation closure being called") - - let publisher = Defaults - .publisher(key, options: []) - .map { ($0.oldValue, $0.newValue) } - .collect(2) - - let cancellable = publisher.sink { tuples in - for (index, expected) in [(fixtureCustomCollection, fixtureCustomCollection1), (fixtureCustomCollection1, fixtureCustomCollection)].enumerated() { - XCTAssertEqual(expected.0, tuples[index].0[0]) - XCTAssertEqual(expected.1, tuples[index].1[0]) - } - - expect.fulfill() - } - - Defaults[key].insert(element: fixtureCustomCollection1, at: 0) - Defaults.reset(key) - cancellable.cancel() - - waitForExpectations(timeout: 10) - } - - func testObserveOptionalKeyCombine() { - let key = Defaults.Key?>("observeCollectionCustomElementOptionalKeyCombine") - let expect = expectation(description: "Observation closure being called") - - let publisher = Defaults - .publisher(key, options: []) - .map { ($0.oldValue, $0.newValue) } - .collect(3) - - let expectedValue: [(Item?, Item?)] = [(nil, fixtureCustomCollection), (fixtureCustomCollection, fixtureCustomCollection1), (fixtureCustomCollection1, nil)] - - let cancellable = publisher.sink { tuples in - for (index, expected) in expectedValue.enumerated() { - XCTAssertEqual(expected.0, tuples[index].0?[0]) - XCTAssertEqual(expected.1, tuples[index].1?[0]) - } - - expect.fulfill() - } - - Defaults[key] = .init(items: [fixtureCustomCollection]) - Defaults[key]?.insert(element: fixtureCustomCollection1, at: 0) - Defaults.reset(key) - cancellable.cancel() - - waitForExpectations(timeout: 10) - } - - func testObserveArrayKeyCombine() { - let key = Defaults.Key<[Bag]>("observeCollectionCustomElementArrayKeyCombine", default: [.init(items: [fixtureCustomCollection])]) - let expect = expectation(description: "Observation closure being called") - - let publisher = Defaults - .publisher(key, options: []) - .map { ($0.oldValue, $0.newValue) } - .collect(2) - - let cancellable = publisher.sink { tuples in - for (index, expected) in [(fixtureCustomCollection, fixtureCustomCollection1), (fixtureCustomCollection1, fixtureCustomCollection)].enumerated() { - XCTAssertEqual(expected.0, tuples[index].0[0][0]) - XCTAssertEqual(expected.1, tuples[index].1[0][0]) - } - - expect.fulfill() - } - - Defaults[key][0].insert(element: fixtureCustomCollection1, at: 0) - Defaults.reset(key) - cancellable.cancel() - - waitForExpectations(timeout: 10) - } - - func testObserveDictionaryKeyCombine() { - let key = Defaults.Key<[String: Bag]>("observeCollectionCustomElementDictionaryKeyCombine", default: ["0": .init(items: [fixtureCustomCollection])]) - let expect = expectation(description: "Observation closure being called") - - let publisher = Defaults - .publisher(key, options: []) - .map { ($0.oldValue, $0.newValue) } - .collect(2) - - let cancellable = publisher.sink { tuples in - for (index, expected) in [(fixtureCustomCollection, fixtureCustomCollection1), (fixtureCustomCollection1, fixtureCustomCollection)].enumerated() { - XCTAssertEqual(expected.0, tuples[index].0["0"]?[0]) - XCTAssertEqual(expected.1, tuples[index].1["0"]?[0]) - } - - expect.fulfill() - } - - Defaults[key]["0"]?.insert(element: fixtureCustomCollection1, at: 0) - Defaults.reset(key) - cancellable.cancel() - - waitForExpectations(timeout: 10) - } - - func testObserveKey() { - let key = Defaults.Key>("observeCollectionCustomElementKey", default: .init(items: [fixtureCustomCollection])) - let expect = expectation(description: "Observation closure being called") - - var observation: Defaults.Observation! - observation = Defaults.observe(key, options: []) { change in - XCTAssertEqual(change.oldValue[0], fixtureCustomCollection) - XCTAssertEqual(change.newValue[0], fixtureCustomCollection1) - observation.invalidate() - expect.fulfill() - } - - Defaults[key].insert(element: fixtureCustomCollection1, at: 0) - observation.invalidate() - - waitForExpectations(timeout: 10) - } - - func testObserveOptionalKey() { - let key = Defaults.Key?>("observeCollectionCustomElementOptionalKey") - let expect = expectation(description: "Observation closure being called") - - var observation: Defaults.Observation! - observation = Defaults.observe(key, options: []) { change in - XCTAssertNil(change.oldValue) - XCTAssertEqual(change.newValue?[0], fixtureCustomCollection) - observation.invalidate() - expect.fulfill() - } - - Defaults[key] = .init(items: [fixtureCustomCollection]) - observation.invalidate() - - waitForExpectations(timeout: 10) - } - - func testObserveArrayKey() { - let key = Defaults.Key<[Bag]>("observeCollectionCustomElementArrayKey", default: [.init(items: [fixtureCustomCollection])]) - let expect = expectation(description: "Observation closure being called") - - var observation: Defaults.Observation! - observation = Defaults.observe(key, options: []) { change in - XCTAssertEqual(change.oldValue[0][0], fixtureCustomCollection) - XCTAssertEqual(change.newValue[0][0], fixtureCustomCollection1) - observation.invalidate() - expect.fulfill() - } - - Defaults[key][0].insert(element: fixtureCustomCollection1, at: 0) - observation.invalidate() - - waitForExpectations(timeout: 10) - } - - func testObserveDictionaryKey() { - let key = Defaults.Key<[String: Bag]>("observeCollectionCustomElementArrayKey", default: ["0": .init(items: [fixtureCustomCollection])]) - let expect = expectation(description: "Observation closure being called") - - var observation: Defaults.Observation! - observation = Defaults.observe(key, options: []) { change in - XCTAssertEqual(change.oldValue["0"]?[0], fixtureCustomCollection) - XCTAssertEqual(change.newValue["0"]?[0], fixtureCustomCollection1) - observation.invalidate() - expect.fulfill() - } - - Defaults[key]["0"]?.insert(element: fixtureCustomCollection1, at: 0) - observation.invalidate() - - waitForExpectations(timeout: 10) + #expect(Defaults[.collectionCustomElementDictionary]["0"]?[0] == fixtureCustomCollection) + #expect(Defaults[.collectionCustomElementDictionary]["0"]?[1] == fixtureCustomCollection1) + #expect(Defaults[.collectionCustomElementDictionary]["1"]?[0] == fixtureCustomCollection2) } } diff --git a/Tests/DefaultsTests/DefaultsCollectionTests.swift b/Tests/DefaultsTests/DefaultsCollectionTests.swift index 33eb191..31327d0 100644 --- a/Tests/DefaultsTests/DefaultsCollectionTests.swift +++ b/Tests/DefaultsTests/DefaultsCollectionTests.swift @@ -1,7 +1,9 @@ import Foundation -import XCTest +import Testing import Defaults +private let suite_ = createSuite() + struct Bag: Collection { var items: [Element] @@ -36,305 +38,133 @@ extension Bag: Defaults.CollectionSerializable { } } - private let fixtureCollection = ["Juice", "Apple", "Banana"] extension Defaults.Keys { - fileprivate static let collection = Key>("collection", default: Bag(items: fixtureCollection)) - fileprivate static let collectionArray = Key<[Bag]>("collectionArray", default: [Bag(items: fixtureCollection)]) - fileprivate static let collectionDictionary = Key<[String: Bag]>("collectionDictionary", default: ["0": Bag(items: fixtureCollection)]) + fileprivate static let collection = Key>("collection", default: Bag(items: fixtureCollection), suite: suite_) + fileprivate static let collectionArray = Key<[Bag]>("collectionArray", default: [Bag(items: fixtureCollection)], suite: suite_) + fileprivate static let collectionDictionary = Key<[String: Bag]>("collectionDictionary", default: ["0": Bag(items: fixtureCollection)], suite: suite_) } -final class DefaultsCollectionTests: XCTestCase { - override func setUp() { - super.setUp() - Defaults.removeAll() +@Suite(.serialized) +final class DefaultsCollectionTests { + init() { + Defaults.removeAll(suite: suite_) } - override func tearDown() { - super.tearDown() - Defaults.removeAll() + deinit { + Defaults.removeAll(suite: suite_) } + @Test func testKey() { - let key = Defaults.Key>("independentCollectionKey", default: Bag(items: fixtureCollection)) + let key = Defaults.Key>("independentCollectionKey", default: Bag(items: fixtureCollection), suite: suite_) Defaults[key].insert(element: "123", at: 0) - XCTAssertEqual(Defaults[key][0], "123") + #expect(Defaults[key][0] == "123") } + @Test func testOptionalKey() { - let key = Defaults.Key?>("independentCollectionOptionalKey") - XCTAssertNil(Defaults[key]) + let key = Defaults.Key?>("independentCollectionOptionalKey", suite: suite_) + #expect(Defaults[key] == nil) Defaults[key] = Bag(items: []) Defaults[key]?.insert(element: fixtureCollection[0], at: 0) - XCTAssertEqual(Defaults[key]?[0], fixtureCollection[0]) + #expect(Defaults[key]?[0] == fixtureCollection[0]) Defaults[key]?.insert(element: fixtureCollection[1], at: 1) - XCTAssertEqual(Defaults[key]?[1], fixtureCollection[1]) + #expect(Defaults[key]?[1] == fixtureCollection[1]) } + @Test func testArrayKey() { - let key = Defaults.Key<[Bag]>("independentCollectionArrayKey", default: [Bag(items: [fixtureCollection[0]])]) + let key = Defaults.Key<[Bag]>("independentCollectionArrayKey", default: [Bag(items: [fixtureCollection[0]])], suite: suite_) Defaults[key].append(Bag(items: [fixtureCollection[1]])) - XCTAssertEqual(Defaults[key][1][0], fixtureCollection[1]) + #expect(Defaults[key][1][0] == fixtureCollection[1]) Defaults[key][0].insert(element: fixtureCollection[2], at: 1) - XCTAssertEqual(Defaults[key][0][1], fixtureCollection[2]) + #expect(Defaults[key][0][1] == fixtureCollection[2]) } + @Test func testArrayOptionalKey() { - let key = Defaults.Key<[Bag]?>("independentCollectionArrayOptionalKey") // swiftlint:disable:this discouraged_optional_collection - XCTAssertNil(Defaults[key]) + let key = Defaults.Key<[Bag]?>("independentCollectionArrayOptionalKey", suite: suite_) // swiftlint:disable:this discouraged_optional_collection + #expect(Defaults[key] == nil) Defaults[key] = [Bag(items: [fixtureCollection[0]])] Defaults[key]?.append(Bag(items: [fixtureCollection[1]])) - XCTAssertEqual(Defaults[key]?[1][0], fixtureCollection[1]) + #expect(Defaults[key]?[1][0] == fixtureCollection[1]) Defaults[key]?[0].insert(element: fixtureCollection[2], at: 1) - XCTAssertEqual(Defaults[key]?[0][1], fixtureCollection[2]) + #expect(Defaults[key]?[0][1] == fixtureCollection[2]) } + @Test func testNestedArrayKey() { - let key = Defaults.Key<[[Bag]]>("independentCollectionNestedArrayKey", default: [[Bag(items: [fixtureCollection[0]])]]) + let key = Defaults.Key<[[Bag]]>("independentCollectionNestedArrayKey", default: [[Bag(items: [fixtureCollection[0]])]], suite: suite_) Defaults[key][0].append(Bag(items: [fixtureCollection[1]])) Defaults[key].append([Bag(items: [fixtureCollection[2]])]) - XCTAssertEqual(Defaults[key][0][0][0], fixtureCollection[0]) - XCTAssertEqual(Defaults[key][0][1][0], fixtureCollection[1]) - XCTAssertEqual(Defaults[key][1][0][0], fixtureCollection[2]) + #expect(Defaults[key][0][0][0] == fixtureCollection[0]) + #expect(Defaults[key][0][1][0] == fixtureCollection[1]) + #expect(Defaults[key][1][0][0] == fixtureCollection[2]) } + @Test func testArrayDictionaryKey() { - let key = Defaults.Key<[[String: Bag]]>("independentCollectionArrayDictionaryKey", default: [["0": Bag(items: [fixtureCollection[0]])]]) + let key = Defaults.Key<[[String: Bag]]>("independentCollectionArrayDictionaryKey", default: [["0": Bag(items: [fixtureCollection[0]])]], suite: suite_) Defaults[key][0]["1"] = Bag(items: [fixtureCollection[1]]) Defaults[key].append(["0": Bag(items: [fixtureCollection[2]])]) - XCTAssertEqual(Defaults[key][0]["0"]?[0], fixtureCollection[0]) - XCTAssertEqual(Defaults[key][0]["1"]?[0], fixtureCollection[1]) - XCTAssertEqual(Defaults[key][1]["0"]?[0], fixtureCollection[2]) + #expect(Defaults[key][0]["0"]?[0] == fixtureCollection[0]) + #expect(Defaults[key][0]["1"]?[0] == fixtureCollection[1]) + #expect(Defaults[key][1]["0"]?[0] == fixtureCollection[2]) } + @Test func testDictionaryKey() { - let key = Defaults.Key<[String: Bag]>("independentCollectionDictionaryKey", default: ["0": Bag(items: [fixtureCollection[0]])]) + let key = Defaults.Key<[String: Bag]>("independentCollectionDictionaryKey", default: ["0": Bag(items: [fixtureCollection[0]])], suite: suite_) Defaults[key]["0"]?.insert(element: fixtureCollection[1], at: 1) Defaults[key]["1"] = Bag(items: [fixtureCollection[2]]) - XCTAssertEqual(Defaults[key]["0"]?[0], fixtureCollection[0]) - XCTAssertEqual(Defaults[key]["0"]?[1], fixtureCollection[1]) - XCTAssertEqual(Defaults[key]["1"]?[0], fixtureCollection[2]) + #expect(Defaults[key]["0"]?[0] == fixtureCollection[0]) + #expect(Defaults[key]["0"]?[1] == fixtureCollection[1]) + #expect(Defaults[key]["1"]?[0] == fixtureCollection[2]) } + @Test func testDictionaryOptionalKey() { - let key = Defaults.Key<[String: Bag]?>("independentCollectionDictionaryOptionalKey") // swiftlint:disable:this discouraged_optional_collection - XCTAssertNil(Defaults[key]) + let key = Defaults.Key<[String: Bag]?>("independentCollectionDictionaryOptionalKey", suite: suite_) // swiftlint:disable:this discouraged_optional_collection + #expect(Defaults[key] == nil) Defaults[key] = ["0": Bag(items: [fixtureCollection[0]])] Defaults[key]?["0"]?.insert(element: fixtureCollection[1], at: 1) Defaults[key]?["1"] = Bag(items: [fixtureCollection[2]]) - XCTAssertEqual(Defaults[key]?["0"]?[0], fixtureCollection[0]) - XCTAssertEqual(Defaults[key]?["0"]?[1], fixtureCollection[1]) - XCTAssertEqual(Defaults[key]?["1"]?[0], fixtureCollection[2]) + #expect(Defaults[key]?["0"]?[0] == fixtureCollection[0]) + #expect(Defaults[key]?["0"]?[1] == fixtureCollection[1]) + #expect(Defaults[key]?["1"]?[0] == fixtureCollection[2]) } + @Test func testDictionaryArrayKey() { - let key = Defaults.Key<[String: [Bag]]>("independentCollectionDictionaryArrayKey", default: ["0": [Bag(items: [fixtureCollection[0]])]]) + let key = Defaults.Key<[String: [Bag]]>("independentCollectionDictionaryArrayKey", default: ["0": [Bag(items: [fixtureCollection[0]])]], suite: suite_) Defaults[key]["0"]?[0].insert(element: fixtureCollection[1], at: 1) Defaults[key]["1"] = [Bag(items: [fixtureCollection[2]])] - XCTAssertEqual(Defaults[key]["0"]?[0][0], fixtureCollection[0]) - XCTAssertEqual(Defaults[key]["0"]?[0][1], fixtureCollection[1]) - XCTAssertEqual(Defaults[key]["1"]?[0][0], fixtureCollection[2]) + #expect(Defaults[key]["0"]?[0][0] == fixtureCollection[0]) + #expect(Defaults[key]["0"]?[0][1] == fixtureCollection[1]) + #expect(Defaults[key]["1"]?[0][0] == fixtureCollection[2]) } + @Test func testType() { Defaults[.collection].insert(element: "123", at: 0) - XCTAssertEqual(Defaults[.collection][0], "123") + #expect(Defaults[.collection][0] == "123") } + @Test func testArrayType() { Defaults[.collectionArray].append(Bag(items: [fixtureCollection[0]])) Defaults[.collectionArray][0].insert(element: "123", at: 0) - XCTAssertEqual(Defaults[.collectionArray][0][0], "123") - XCTAssertEqual(Defaults[.collectionArray][1][0], fixtureCollection[0]) + #expect(Defaults[.collectionArray][0][0] == "123") + #expect(Defaults[.collectionArray][1][0] == fixtureCollection[0]) } + @Test func testDictionaryType() { Defaults[.collectionDictionary]["1"] = Bag(items: [fixtureCollection[0]]) Defaults[.collectionDictionary]["0"]?.insert(element: "123", at: 0) - XCTAssertEqual(Defaults[.collectionDictionary]["0"]?[0], "123") - XCTAssertEqual(Defaults[.collectionDictionary]["1"]?[0], fixtureCollection[0]) - } - - func testObserveKeyCombine() { - let key = Defaults.Key>("observeCollectionKeyCombine", default: .init(items: fixtureCollection)) - let item = "Grape" - let expect = expectation(description: "Observation closure being called") - - let publisher = Defaults - .publisher(key, options: []) - .map { ($0.oldValue, $0.newValue) } - .collect(2) - - let cancellable = publisher.sink { tuples in - for (index, expected) in [(fixtureCollection[0], item), (item, fixtureCollection[0])].enumerated() { - XCTAssertEqual(expected.0, tuples[index].0[0]) - XCTAssertEqual(expected.1, tuples[index].1[0]) - } - - expect.fulfill() - } - - Defaults[key].insert(element: item, at: 0) - Defaults.reset(key) - cancellable.cancel() - - waitForExpectations(timeout: 10) - } - - func testObserveOptionalKeyCombine() { - let key = Defaults.Key?>("observeCollectionOptionalKeyCombine") - let item = "Grape" - let expect = expectation(description: "Observation closure being called") - - let publisher = Defaults - .publisher(key, options: []) - .map { ($0.oldValue, $0.newValue) } - .collect(3) - - let expectedValue: [(String?, String?)] = [(nil, fixtureCollection[0]), (fixtureCollection[0], item), (item, nil)] - - let cancellable = publisher.sink { tuples in - for (index, expected) in expectedValue.enumerated() { - XCTAssertEqual(expected.0, tuples[index].0?[0]) - XCTAssertEqual(expected.1, tuples[index].1?[0]) - } - - expect.fulfill() - } - - Defaults[key] = Bag(items: fixtureCollection) - Defaults[key]?.insert(element: item, at: 0) - Defaults.reset(key) - cancellable.cancel() - - waitForExpectations(timeout: 10) - } - - func testObserveArrayKeyCombine() { - let key = Defaults.Key<[Bag]>("observeCollectionArrayKeyCombine", default: [.init(items: fixtureCollection)]) - let item = "Grape" - let expect = expectation(description: "Observation closure being called") - - let publisher = Defaults - .publisher(key, options: []) - .map { ($0.oldValue, $0.newValue) } - .collect(2) - - let cancellable = publisher.sink { tuples in - for (index, expected) in [(fixtureCollection[0], item), (item, fixtureCollection[0])].enumerated() { - XCTAssertEqual(expected.0, tuples[index].0[0][0]) - XCTAssertEqual(expected.1, tuples[index].1[0][0]) - } - - expect.fulfill() - } - - Defaults[key][0].insert(element: item, at: 0) - Defaults.reset(key) - cancellable.cancel() - - waitForExpectations(timeout: 10) - } - - func testObserveDictionaryKeyCombine() { - let key = Defaults.Key<[String: Bag]>("observeCollectionArrayKeyCombine", default: ["0": .init(items: fixtureCollection)]) - let item = "Grape" - let expect = expectation(description: "Observation closure being called") - - let publisher = Defaults - .publisher(key, options: []) - .map { ($0.oldValue, $0.newValue) } - .collect(2) - - let cancellable = publisher.sink { tuples in - for (index, expected) in [(fixtureCollection[0], item), (item, fixtureCollection[0])].enumerated() { - XCTAssertEqual(expected.0, tuples[index].0["0"]?[0]) - XCTAssertEqual(expected.1, tuples[index].1["0"]?[0]) - } - - expect.fulfill() - } - - Defaults[key]["0"]?.insert(element: item, at: 0) - Defaults.reset(key) - cancellable.cancel() - - waitForExpectations(timeout: 10) - } - - func testObserveKey() { - let key = Defaults.Key>("observeCollectionKey", default: .init(items: fixtureCollection)) - let item = "Grape" - let expect = expectation(description: "Observation closure being called") - - var observation: Defaults.Observation! - observation = Defaults.observe(key, options: []) { change in - XCTAssertEqual(change.oldValue[0], fixtureCollection[0]) - XCTAssertEqual(change.newValue[0], item) - observation.invalidate() - expect.fulfill() - } - - Defaults[key].insert(element: item, at: 0) - observation.invalidate() - - waitForExpectations(timeout: 10) - } - - func testObserveOptionalKey() { - let key = Defaults.Key?>("observeCollectionOptionalKey") - let expect = expectation(description: "Observation closure being called") - - var observation: Defaults.Observation! - observation = Defaults.observe(key, options: []) { change in - XCTAssertNil(change.oldValue) - XCTAssertEqual(change.newValue?[0], fixtureCollection[0]) - observation.invalidate() - expect.fulfill() - } - - Defaults[key] = .init(items: fixtureCollection) - observation.invalidate() - - waitForExpectations(timeout: 10) - } - - func testObserveArrayKey() { - let key = Defaults.Key<[Bag]>("observeCollectionArrayKey", default: [.init(items: fixtureCollection)]) - let item = "Grape" - let expect = expectation(description: "Observation closure being called") - - var observation: Defaults.Observation! - observation = Defaults.observe(key, options: []) { change in - XCTAssertEqual(change.oldValue[0][0], fixtureCollection[0]) - XCTAssertEqual(change.newValue[0][0], item) - observation.invalidate() - expect.fulfill() - } - - Defaults[key][0].insert(element: item, at: 0) - observation.invalidate() - - waitForExpectations(timeout: 10) - } - - func testObserveDictionaryKey() { - let key = Defaults.Key<[String: Bag]>("observeCollectionDictionaryKey", default: ["0": .init(items: fixtureCollection)]) - let item = "Grape" - let expect = expectation(description: "Observation closure being called") - - var observation: Defaults.Observation! - observation = Defaults.observe(key, options: []) { change in - XCTAssertEqual(change.oldValue["0"]?[0], fixtureCollection[0]) - XCTAssertEqual(change.newValue["0"]?[0], item) - observation.invalidate() - expect.fulfill() - } - - Defaults[key]["0"]?.insert(element: item, at: 0) - observation.invalidate() - - waitForExpectations(timeout: 10) + #expect(Defaults[.collectionDictionary]["0"]?[0] == "123") + #expect(Defaults[.collectionDictionary]["1"]?[0] == fixtureCollection[0]) } } diff --git a/Tests/DefaultsTests/DefaultsColorTests.swift b/Tests/DefaultsTests/DefaultsColorTests.swift index 89ce5e3..c0280f7 100644 --- a/Tests/DefaultsTests/DefaultsColorTests.swift +++ b/Tests/DefaultsTests/DefaultsColorTests.swift @@ -1,44 +1,47 @@ import SwiftUI +import Testing import Defaults -import XCTest -@available(macOS 12, iOS 15, tvOS 15, watchOS 8, visionOS 1.0, *) -final class DefaultsColorTests: XCTestCase { - override func setUp() { - super.setUp() - Defaults.removeAll() +private let suite_ = createSuite() + +@Suite(.serialized) +final class DefaultsColorTests { + init() { + Defaults.removeAll(suite: suite_) } - override func tearDown() { - super.tearDown() - Defaults.removeAll() + deinit { + Defaults.removeAll(suite: suite_) } + @available(macOS 12, iOS 15, tvOS 15, watchOS 8, visionOS 1.0, *) + @Test func testPreservesColorSpace() { let fixture = Color(.displayP3, red: 1, green: 0.3, blue: 0.7, opacity: 1) - let key = Defaults.Key("independentColorPreservesColorSpaceKey") + let key = Defaults.Key("independentColorPreservesColorSpaceKey", suite: suite_) Defaults[key] = fixture - XCTAssertEqual(Defaults[key]?.cgColor?.colorSpace, fixture.cgColor?.colorSpace) - XCTAssertEqual(Defaults[key]?.cgColor, fixture.cgColor) + #expect(Defaults[key]?.cgColor != nil) + #expect(Defaults[key]?.cgColor?.colorSpace == fixture.cgColor?.colorSpace) + #expect(Defaults[key]?.cgColor == fixture.cgColor) } } -@available(macOS 14, iOS 17, tvOS 17, watchOS 10, visionOS 1, *) -final class DefaultsColorResolvedTests: XCTestCase { - override func setUp() { - super.setUp() - Defaults.removeAll() +@Suite(.serialized) +final class DefaultsColorResolvedTests { + init() { + Defaults.removeAll(suite: suite_) } - override func tearDown() { - super.tearDown() - Defaults.removeAll() + deinit { + Defaults.removeAll(suite: suite_) } + @available(macOS 14, iOS 17, tvOS 17, watchOS 10, visionOS 1, *) + @Test func test() { let fixture = Color(.displayP3, red: 1, green: 0.3, blue: 0.7, opacity: 1).resolve(in: .init()) - let key = Defaults.Key("independentColorResolvedKey") + let key = Defaults.Key("independentColorResolvedKey", suite: suite_) Defaults[key] = fixture - XCTAssertEqual(Defaults[key]?.cgColor, fixture.cgColor) + #expect(Defaults[key]?.cgColor == fixture.cgColor) } } diff --git a/Tests/DefaultsTests/DefaultsCustomBridgeTests.swift b/Tests/DefaultsTests/DefaultsCustomBridgeTests.swift index f203fd9..2ed693e 100644 --- a/Tests/DefaultsTests/DefaultsCustomBridgeTests.swift +++ b/Tests/DefaultsTests/DefaultsCustomBridgeTests.swift @@ -1,6 +1,8 @@ import Foundation +import Testing import Defaults -import XCTest + +private let suite_ = createSuite() public struct User: Hashable, Equatable { var username: String @@ -84,343 +86,176 @@ extension Collection { } extension Defaults.Keys { - fileprivate static let customBridge = Key("customBridge", default: fixtureCustomBridge) - fileprivate static let customBridgeArray = Key<[User]>("array_customBridge", default: [fixtureCustomBridge]) - fileprivate static let customBridgeDictionary = Key<[String: User]>("dictionary_customBridge", default: ["0": fixtureCustomBridge]) + fileprivate static let customBridge = Key("customBridge", default: fixtureCustomBridge, suite: suite_) + fileprivate static let customBridgeArray = Key<[User]>("array_customBridge", default: [fixtureCustomBridge], suite: suite_) + fileprivate static let customBridgeDictionary = Key<[String: User]>("dictionary_customBridge", default: ["0": fixtureCustomBridge], suite: suite_) } -final class DefaultsCustomBridge: XCTestCase { - override func setUp() { - super.setUp() - Defaults.removeAll() +@Suite(.serialized) +final class DefaultsCustomBridge { + init() { + Defaults.removeAll(suite: suite_) } - override func tearDown() { - super.tearDown() - Defaults.removeAll() + deinit { + Defaults.removeAll(suite: suite_) } + @Test func testKey() { - let key = Defaults.Key("independentCustomBridgeKey", default: fixtureCustomBridge) - XCTAssertEqual(Defaults[key], fixtureCustomBridge) + let key = Defaults.Key("independentCustomBridgeKey", default: fixtureCustomBridge, suite: suite_) + #expect(Defaults[key] == fixtureCustomBridge) let newUser = User(username: "sindresorhus", password: "123456789") Defaults[key] = newUser - XCTAssertEqual(Defaults[key], newUser) + #expect(Defaults[key] == newUser) } + @Test func testOptionalKey() { - let key = Defaults.Key("independentCustomBridgeOptionalKey") - XCTAssertNil(Defaults[key]) + let key = Defaults.Key("independentCustomBridgeOptionalKey", suite: suite_) + #expect(Defaults[key] == nil) Defaults[key] = fixtureCustomBridge - XCTAssertEqual(Defaults[key], fixtureCustomBridge) + #expect(Defaults[key] == fixtureCustomBridge) } + @Test func testArrayKey() { let user = User(username: "hank121314", password: "123456") - let key = Defaults.Key<[User]>("independentCustomBridgeArrayKey", default: [user]) - XCTAssertEqual(Defaults[key][0], user) + let key = Defaults.Key<[User]>("independentCustomBridgeArrayKey", default: [user], suite: suite_) + #expect(Defaults[key][0] == user) let newUser = User(username: "sindresorhus", password: "123456789") Defaults[key][0] = newUser - XCTAssertEqual(Defaults[key][0], newUser) + #expect(Defaults[key][0] == newUser) } + @Test func testArrayOptionalKey() { - let key = Defaults.Key<[User]?>("independentCustomBridgeArrayOptionalKey") // swiftlint:disable:this discouraged_optional_collection - XCTAssertNil(Defaults[key]) + let key = Defaults.Key<[User]?>("independentCustomBridgeArrayOptionalKey", suite: suite_) // swiftlint:disable:this discouraged_optional_collection + #expect(Defaults[key] == nil) let newUser = User(username: "hank121314", password: "123456") Defaults[key] = [newUser] - XCTAssertEqual(Defaults[key]?[0], newUser) + #expect(Defaults[key]?[0] == newUser) Defaults[key] = nil - XCTAssertNil(Defaults[key]) + #expect(Defaults[key] == nil) } + @Test func testNestedArrayKey() { - let key = Defaults.Key<[[User]]>("independentCustomBridgeNestedArrayKey", default: [[fixtureCustomBridge], [fixtureCustomBridge]]) - XCTAssertEqual(Defaults[key][0][0].username, fixtureCustomBridge.username) + let key = Defaults.Key<[[User]]>("independentCustomBridgeNestedArrayKey", default: [[fixtureCustomBridge], [fixtureCustomBridge]], suite: suite_) + #expect(Defaults[key][0][0].username == fixtureCustomBridge.username) let newUsername = "John" let newPassword = "7891011" Defaults[key][0][0] = User(username: newUsername, password: newPassword) - XCTAssertEqual(Defaults[key][0][0].username, newUsername) - XCTAssertEqual(Defaults[key][0][0].password, newPassword) - XCTAssertEqual(Defaults[key][1][0].username, fixtureCustomBridge.username) - XCTAssertEqual(Defaults[key][1][0].password, fixtureCustomBridge.password) + #expect(Defaults[key][0][0].username == newUsername) + #expect(Defaults[key][0][0].password == newPassword) + #expect(Defaults[key][1][0].username == fixtureCustomBridge.username) + #expect(Defaults[key][1][0].password == fixtureCustomBridge.password) } + @Test func testArrayDictionaryKey() { - let key = Defaults.Key<[[String: User]]>("independentCustomBridgeArrayDictionaryKey", default: [["0": fixtureCustomBridge], ["0": fixtureCustomBridge]]) - XCTAssertEqual(Defaults[key][0]["0"]?.username, fixtureCustomBridge.username) + let key = Defaults.Key<[[String: User]]>("independentCustomBridgeArrayDictionaryKey", default: [["0": fixtureCustomBridge], ["0": fixtureCustomBridge]], suite: suite_) + #expect(Defaults[key][0]["0"]?.username == fixtureCustomBridge.username) let newUser = User(username: "sindresorhus", password: "123456789") Defaults[key][0]["0"] = newUser - XCTAssertEqual(Defaults[key][0]["0"], newUser) - XCTAssertEqual(Defaults[key][1]["0"], fixtureCustomBridge) + #expect(Defaults[key][0]["0"] == newUser) + #expect(Defaults[key][1]["0"] == fixtureCustomBridge) } + @Test func testSetKey() { - let key = Defaults.Key>("independentCustomBridgeSetKey", default: [fixtureCustomBridge]) - XCTAssertEqual(Defaults[key].first, fixtureCustomBridge) + let key = Defaults.Key>("independentCustomBridgeSetKey", default: [fixtureCustomBridge], suite: suite_) + #expect(Defaults[key].first == fixtureCustomBridge) Defaults[key].insert(fixtureCustomBridge) - XCTAssertEqual(Defaults[key].count, 1) + #expect(Defaults[key].count == 1) let newUser = User(username: "sindresorhus", password: "123456789") Defaults[key].insert(newUser) - XCTAssertTrue(Defaults[key].contains(newUser)) + #expect(Defaults[key].contains(newUser)) } + @Test func testDictionaryKey() { - let key = Defaults.Key<[String: User]>("independentCustomBridgeDictionaryKey", default: ["0": fixtureCustomBridge]) - XCTAssertEqual(Defaults[key]["0"], fixtureCustomBridge) + let key = Defaults.Key<[String: User]>("independentCustomBridgeDictionaryKey", default: ["0": fixtureCustomBridge], suite: suite_) + #expect(Defaults[key]["0"] == fixtureCustomBridge) let newUser = User(username: "sindresorhus", password: "123456789") Defaults[key]["0"] = newUser - XCTAssertEqual(Defaults[key]["0"], newUser) + #expect(Defaults[key]["0"] == newUser) } + @Test func testDictionaryOptionalKey() { - let key = Defaults.Key<[String: User]?>("independentCustomBridgeDictionaryOptionalKey") // swiftlint:disable:this discouraged_optional_collection - XCTAssertNil(Defaults[key]) + let key = Defaults.Key<[String: User]?>("independentCustomBridgeDictionaryOptionalKey", suite: suite_) // swiftlint:disable:this discouraged_optional_collection + #expect(Defaults[key] == nil) Defaults[key] = ["0": fixtureCustomBridge] - XCTAssertEqual(Defaults[key]?["0"], fixtureCustomBridge) + #expect(Defaults[key]?["0"] == fixtureCustomBridge) } + @Test func testDictionaryArrayKey() { - let key = Defaults.Key<[String: [User]]>("independentCustomBridgeDictionaryArrayKey", default: ["0": [fixtureCustomBridge]]) - XCTAssertEqual(Defaults[key]["0"]?[0], fixtureCustomBridge) + let key = Defaults.Key<[String: [User]]>("independentCustomBridgeDictionaryArrayKey", default: ["0": [fixtureCustomBridge]], suite: suite_) + #expect(Defaults[key]["0"]?[0] == fixtureCustomBridge) let newUser = User(username: "sindresorhus", password: "123456789") Defaults[key]["0"]?[0] = newUser Defaults[key]["0"]?.append(fixtureCustomBridge) - XCTAssertEqual(Defaults[key]["0"]?[0], newUser) - XCTAssertEqual(Defaults[key]["0"]?[0], newUser) - XCTAssertEqual(Defaults[key]["0"]?[1], fixtureCustomBridge) - XCTAssertEqual(Defaults[key]["0"]?[1], fixtureCustomBridge) + #expect(Defaults[key]["0"]?[0] == newUser) + #expect(Defaults[key]["0"]?[0] == newUser) + #expect(Defaults[key]["0"]?[1] == fixtureCustomBridge) + #expect(Defaults[key]["0"]?[1] == fixtureCustomBridge) } + @Test func testRecursiveKey() { let start = PlainHourMinuteTime(hour: 1, minute: 0) let end = PlainHourMinuteTime(hour: 2, minute: 0) let range = PlainHourMinuteTimeRange(start: start, end: end) - let key = Defaults.Key("independentCustomBridgeRecursiveKey", default: range) - XCTAssertEqual(Defaults[key].start.hour, range.start.hour) - XCTAssertEqual(Defaults[key].start.minute, range.start.minute) - XCTAssertEqual(Defaults[key].end.hour, range.end.hour) - XCTAssertEqual(Defaults[key].end.minute, range.end.minute) - guard let rawValue = UserDefaults.standard.array(forKey: key.name) as? [String] else { - XCTFail("rawValue should not be nil") + let key = Defaults.Key("independentCustomBridgeRecursiveKey", default: range, suite: suite_) + #expect(Defaults[key].start.hour == range.start.hour) + #expect(Defaults[key].start.minute == range.start.minute) + #expect(Defaults[key].end.hour == range.end.hour) + #expect(Defaults[key].end.minute == range.end.minute) + guard let rawValue = suite_.array(forKey: key.name) as? [String] else { + Issue.record("rawValue should not be nil") return } - XCTAssertEqual(rawValue, [#"{"hour":1,"minute":0}"#, #"{"hour":2,"minute":0}"#]) + #expect(rawValue == [#"{"hour":1,"minute":0}"#, #"{"hour":2,"minute":0}"#]) let next_start = PlainHourMinuteTime(hour: 3, minute: 58) let next_end = PlainHourMinuteTime(hour: 4, minute: 59) let next_range = PlainHourMinuteTimeRange(start: next_start, end: next_end) Defaults[key] = next_range - XCTAssertEqual(Defaults[key].start.hour, next_range.start.hour) - XCTAssertEqual(Defaults[key].start.minute, next_range.start.minute) - XCTAssertEqual(Defaults[key].end.hour, next_range.end.hour) - XCTAssertEqual(Defaults[key].end.minute, next_range.end.minute) - guard let nextRawValue = UserDefaults.standard.array(forKey: key.name) as? [String] else { - XCTFail("nextRawValue should not be nil") + #expect(Defaults[key].start.hour == next_range.start.hour) + #expect(Defaults[key].start.minute == next_range.start.minute) + #expect(Defaults[key].end.hour == next_range.end.hour) + #expect(Defaults[key].end.minute == next_range.end.minute) + + guard let nextRawValue = suite_.array(forKey: key.name) as? [String] else { + Issue.record("nextRawValue should not be nil") return } - XCTAssertEqual(nextRawValue, [#"{"hour":3,"minute":58}"#, #"{"hour":4,"minute":59}"#]) + + #expect(nextRawValue == [#"{"hour":3,"minute":58}"#, #"{"hour":4,"minute":59}"#]) } + @Test func testType() { - XCTAssertEqual(Defaults[.customBridge], fixtureCustomBridge) + #expect(Defaults[.customBridge] == fixtureCustomBridge) let newUser = User(username: "sindresorhus", password: "123456789") Defaults[.customBridge] = newUser - XCTAssertEqual(Defaults[.customBridge], newUser) + #expect(Defaults[.customBridge] == newUser) } + @Test func testArrayType() { - XCTAssertEqual(Defaults[.customBridgeArray][0], fixtureCustomBridge) + #expect(Defaults[.customBridgeArray][0] == fixtureCustomBridge) let newUser = User(username: "sindresorhus", password: "123456789") Defaults[.customBridgeArray][0] = newUser - XCTAssertEqual(Defaults[.customBridgeArray][0], newUser) + #expect(Defaults[.customBridgeArray][0] == newUser) } + @Test func testDictionaryType() { - XCTAssertEqual(Defaults[.customBridgeDictionary]["0"], fixtureCustomBridge) + #expect(Defaults[.customBridgeDictionary]["0"] == fixtureCustomBridge) let newUser = User(username: "sindresorhus", password: "123456789") Defaults[.customBridgeDictionary]["0"] = newUser - XCTAssertEqual(Defaults[.customBridgeDictionary]["0"], newUser) - } - - func testObserveKeyCombine() { - let key = Defaults.Key("observeCustomBridgeKeyCombine", default: fixtureCustomBridge) - let newUser = User(username: "sindresorhus", password: "123456789") - let expect = expectation(description: "Observation closure being called") - - let publisher = Defaults - .publisher(key, options: []) - .map { ($0.oldValue, $0.newValue) } - .collect(2) - - let cancellable = publisher.sink { tuples in - for (index, expected) in [(fixtureCustomBridge, newUser), (newUser, fixtureCustomBridge)].enumerated() { - XCTAssertEqual(expected.0, tuples[index].0) - XCTAssertEqual(expected.1, tuples[index].1) - } - - expect.fulfill() - } - - Defaults[key] = newUser - Defaults[key] = fixtureCustomBridge - cancellable.cancel() - - waitForExpectations(timeout: 10) - } - - func testObserveOptionalKeyCombine() { - let key = Defaults.Key("observeCustomBridgeOptionalKeyCombine") - let newUser = User(username: "sindresorhus", password: "123456789") - let expect = expectation(description: "Observation closure being called") - - let publisher = Defaults - .publisher(key, options: []) - .map { ($0.oldValue, $0.newValue) } - .collect(3) - - let expectedValue: [(User?, User?)] = [(nil, fixtureCustomBridge), (fixtureCustomBridge, newUser), (newUser, nil)] - - let cancellable = publisher.sink { tuples in - for (index, expected) in expectedValue.enumerated() { - XCTAssertEqual(expected.0, tuples[index].0) - XCTAssertEqual(expected.1, tuples[index].1) - } - - expect.fulfill() - } - - Defaults[key] = fixtureCustomBridge - Defaults[key] = newUser - Defaults.reset(key) - cancellable.cancel() - - waitForExpectations(timeout: 10) - } - - func testObserveArrayKeyCombine() { - let key = Defaults.Key<[User]>("observeCustomBridgeArrayKeyCombine", default: [fixtureCustomBridge]) - let newUser = User(username: "sindresorhus", password: "123456789") - let expect = expectation(description: "Observation closure being called") - - let publisher = Defaults - .publisher(key, options: []) - .map { ($0.oldValue, $0.newValue) } - .collect(2) - - let cancellable = publisher.sink { tuples in - for (index, expected) in [([fixtureCustomBridge], [newUser]), ([newUser], [newUser, fixtureCustomBridge])].enumerated() { - XCTAssertEqual(expected.0, tuples[index].0) - XCTAssertEqual(expected.1, tuples[index].1) - } - - expect.fulfill() - } - - Defaults[key][0] = newUser - Defaults[key].append(fixtureCustomBridge) - cancellable.cancel() - - waitForExpectations(timeout: 10) - } - - func testObserveDictionaryCombine() { - let key = Defaults.Key<[String: User]>("observeCustomBridgeDictionaryKeyCombine", default: ["0": fixtureCustomBridge]) - let newUser = User(username: "sindresorhus", password: "123456789") - let expect = expectation(description: "Observation closure being called") - - let publisher = Defaults - .publisher(key, options: []) - .map { ($0.oldValue, $0.newValue) } - .collect(2) - - let cancellable = publisher.sink { tuples in - for (index, expected) in [(fixtureCustomBridge, newUser), (newUser, fixtureCustomBridge)].enumerated() { - XCTAssertEqual(expected.0, tuples[index].0["0"]) - XCTAssertEqual(expected.1, tuples[index].1["0"]) - } - - expect.fulfill() - } - - Defaults[key]["0"] = newUser - Defaults[key]["0"] = fixtureCustomBridge - cancellable.cancel() - - waitForExpectations(timeout: 10) - } - - func testObserveKey() { - let key = Defaults.Key("observeCustomBridgeKey", default: fixtureCustomBridge) - let newUser = User(username: "sindresorhus", password: "123456789") - let expect = expectation(description: "Observation closure being called") - - var observation: Defaults.Observation! - observation = Defaults.observe(key, options: []) { change in - XCTAssertEqual(change.oldValue, fixtureCustomBridge) - XCTAssertEqual(change.newValue, newUser) - observation.invalidate() - expect.fulfill() - } - - Defaults[key] = newUser - observation.invalidate() - - waitForExpectations(timeout: 10) - } - - func testObserveOptionalKey() { - let key = Defaults.Key("observeCustomBridgeOptionalKey") - let expect = expectation(description: "Observation closure being called") - - var observation: Defaults.Observation! - observation = Defaults.observe(key, options: []) { change in - XCTAssertNil(change.oldValue) - XCTAssertEqual(change.newValue, fixtureCustomBridge) - observation.invalidate() - expect.fulfill() - } - - Defaults[key] = fixtureCustomBridge - observation.invalidate() - - waitForExpectations(timeout: 10) - } - - func testObserveArrayKey() { - let key = Defaults.Key<[User]>("observeCustomBridgeArrayKey", default: [fixtureCustomBridge]) - let newUser = User(username: "sindresorhus", password: "123456789") - let expect = expectation(description: "Observation closure being called") - - var observation: Defaults.Observation! - observation = Defaults.observe(key, options: []) { change in - XCTAssertEqual(change.oldValue[0], fixtureCustomBridge) - XCTAssertEqual(change.newValue[0], newUser) - observation.invalidate() - expect.fulfill() - } - - Defaults[key][0] = newUser - observation.invalidate() - - waitForExpectations(timeout: 10) - } - - func testObserveDictionaryKey() { - let key = Defaults.Key<[String: User]>("observeCustomBridgeDictionaryKey", default: ["0": fixtureCustomBridge]) - let newUser = User(username: "sindresorhus", password: "123456789") - let expect = expectation(description: "Observation closure being called") - - var observation: Defaults.Observation! - observation = Defaults.observe(key, options: []) { change in - XCTAssertEqual(change.oldValue["0"], fixtureCustomBridge) - XCTAssertEqual(change.newValue["0"], newUser) - observation.invalidate() - expect.fulfill() - } - - Defaults[key]["0"] = newUser - observation.invalidate() - - waitForExpectations(timeout: 10) + #expect(Defaults[.customBridgeDictionary]["0"] == newUser) } } diff --git a/Tests/DefaultsTests/DefaultsDictionaryTests.swift b/Tests/DefaultsTests/DefaultsDictionaryTests.swift index f81e4ea..9e8d35a 100644 --- a/Tests/DefaultsTests/DefaultsDictionaryTests.swift +++ b/Tests/DefaultsTests/DefaultsDictionaryTests.swift @@ -1,167 +1,82 @@ import Foundation +import Testing import Defaults -import XCTest + +private let suite_ = createSuite() private let fixtureDictionary = ["0": "Hank"] private let fixtureArray = ["Hank", "Chen"] extension Defaults.Keys { - fileprivate static let dictionary = Key<[String: String]>("dictionary", default: fixtureDictionary) + fileprivate static let dictionary = Key<[String: String]>("dictionary", default: fixtureDictionary, suite: suite_) } -final class DefaultsDictionaryTests: XCTestCase { - override func setUp() { - super.setUp() - Defaults.removeAll() +@Suite(.serialized) +final class DefaultsDictionaryTests { + init() { + Defaults.removeAll(suite: suite_) } - override func tearDown() { - super.tearDown() - Defaults.removeAll() + deinit { + Defaults.removeAll(suite: suite_) } + @Test func testKey() { - let key = Defaults.Key<[String: String]>("independentDictionaryStringKey", default: fixtureDictionary) - XCTAssertEqual(Defaults[key]["0"], fixtureDictionary["0"]) + let key = Defaults.Key<[String: String]>("independentDictionaryStringKey", default: fixtureDictionary, suite: suite_) + #expect(Defaults[key]["0"] == fixtureDictionary["0"]) let newValue = "John" Defaults[key]["0"] = newValue - XCTAssertEqual(Defaults[key]["0"], newValue) + #expect(Defaults[key]["0"] == newValue) } + @Test func testOptionalKey() { - let key = Defaults.Key<[String: String]?>("independentDictionaryOptionalKey") // swiftlint:disable:this discouraged_optional_collection - XCTAssertNil(Defaults[key]) + let key = Defaults.Key<[String: String]?>("independentDictionaryOptionalKey", suite: suite_) // swiftlint:disable:this discouraged_optional_collection + #expect(Defaults[key] == nil) Defaults[key] = fixtureDictionary - XCTAssertEqual(Defaults[key]?["0"], fixtureDictionary["0"]) + #expect(Defaults[key]?["0"] == fixtureDictionary["0"]) Defaults[key] = nil - XCTAssertNil(Defaults[key]) + #expect(Defaults[key] == nil) let newValue = ["0": "Chen"] Defaults[key] = newValue - XCTAssertEqual(Defaults[key]?["0"], newValue["0"]) + #expect(Defaults[key]?["0"] == newValue["0"]) } + @Test func testNestedKey() { - let key = Defaults.Key<[String: [String: String]]>("independentDictionaryNestedKey", default: ["0": fixtureDictionary]) - XCTAssertEqual(Defaults[key]["0"]?["0"], "Hank") + let key = Defaults.Key<[String: [String: String]]>("independentDictionaryNestedKey", default: ["0": fixtureDictionary], suite: suite_) + #expect(Defaults[key]["0"]?["0"] == "Hank") let newName = "Chen" Defaults[key]["0"]?["0"] = newName - XCTAssertEqual(Defaults[key]["0"]?["0"], newName) + #expect(Defaults[key]["0"]?["0"] == newName) } + @Test func testArrayKey() { - let key = Defaults.Key<[String: [String]]>("independentDictionaryArrayKey", default: ["0": fixtureArray]) - XCTAssertEqual(Defaults[key]["0"], fixtureArray) + let key = Defaults.Key<[String: [String]]>("independentDictionaryArrayKey", default: ["0": fixtureArray], suite: suite_) + #expect(Defaults[key]["0"] == fixtureArray) let newName = "Chen" Defaults[key]["0"]?[0] = newName - XCTAssertEqual(Defaults[key]["0"], [newName, fixtureArray[1]]) + #expect(Defaults[key]["0"] == [newName, fixtureArray[1]]) } + @Test func testIntKey() { let fixture = [1: "x"] - let key = Defaults.Key<[Int: String]>("independentDictionaryIntKey", default: fixture) - XCTAssertEqual(Defaults[key][1], fixture[1]) + let key = Defaults.Key<[Int: String]>("independentDictionaryIntKey", default: fixture, suite: suite_) + #expect(Defaults[key][1] == fixture[1]) let newValue = "John" Defaults[key][1] = newValue - XCTAssertEqual(Defaults[key][1], newValue) + #expect(Defaults[key][1] == newValue) } + @Test func testType() { - XCTAssertEqual(Defaults[.dictionary]["0"], fixtureDictionary["0"]) + #expect(Defaults[.dictionary]["0"] == fixtureDictionary["0"]) let newName = "Chen" Defaults[.dictionary]["0"] = newName - XCTAssertEqual(Defaults[.dictionary]["0"], newName) - } - - func testObserveKeyCombine() { - let key = Defaults.Key<[String: String]>("observeDictionaryKeyCombine", default: fixtureDictionary) - let expect = expectation(description: "Observation closure being called") - let newName = "John" - - let publisher = Defaults - .publisher(key, options: []) - .map { ($0.oldValue, $0.newValue) } - .collect(2) - - let cancellable = publisher.sink { tuples in - for (index, expected) in [(fixtureDictionary["0"]!, newName), (newName, fixtureDictionary["0"]!)].enumerated() { - XCTAssertEqual(expected.0, tuples[index].0["0"]) - XCTAssertEqual(expected.1, tuples[index].1["0"]) - } - - expect.fulfill() - } - - Defaults[key]["0"] = newName - Defaults.reset(key) - cancellable.cancel() - - waitForExpectations(timeout: 10) - } - - func testObserveOptionalKeyCombine() { - let key = Defaults.Key<[String: String]?>("observeDictionaryOptionalKeyCombine") // swiftlint:disable:this discouraged_optional_collection - let expect = expectation(description: "Observation closure being called") - let newName = ["0": "John"] - let publisher = Defaults - .publisher(key, options: []) - .map { ($0.oldValue, $0.newValue) } - .collect(3) - - // swiftlint:disable:next discouraged_optional_collection - let expectedValues: [([String: String]?, [String: String]?)] = [(nil, fixtureDictionary), (fixtureDictionary, newName), (newName, nil)] - - let cancellable = publisher.sink { actualValues in - for (expected, actual) in zip(expectedValues, actualValues) { - XCTAssertEqual(expected.0, actual.0) - XCTAssertEqual(expected.1, actual.1) - } - - expect.fulfill() - } - - Defaults[key] = fixtureDictionary - Defaults[key] = newName - Defaults.reset(key) - cancellable.cancel() - - waitForExpectations(timeout: 10) - } - - func testObserveKey() { - let key = Defaults.Key<[String: String]>("observeDictionaryKey", default: fixtureDictionary) - let expect = expectation(description: "Observation closure being called") - let newName = "John" - - var observation: Defaults.Observation! - observation = Defaults.observe(key, options: []) { change in - XCTAssertEqual(change.oldValue, fixtureDictionary) - XCTAssertEqual(change.newValue["1"], newName) - observation.invalidate() - expect.fulfill() - } - - Defaults[key]["1"] = newName - observation.invalidate() - - waitForExpectations(timeout: 10) - } - - func testObserveOptionalKey() { - let key = Defaults.Key<[String: String]?>("observeDictionaryOptionalKey") // swiftlint:disable:this discouraged_optional_collection - let expect = expectation(description: "Observation closure being called") - - var observation: Defaults.Observation! - observation = Defaults.observe(key, options: []) { change in - XCTAssertNil(change.oldValue) - XCTAssertEqual(change.newValue!, fixtureDictionary) - observation.invalidate() - expect.fulfill() - } - - Defaults[key] = fixtureDictionary - observation.invalidate() - - waitForExpectations(timeout: 10) + #expect(Defaults[.dictionary]["0"] == newName) } } diff --git a/Tests/DefaultsTests/DefaultsEnumTests.swift b/Tests/DefaultsTests/DefaultsEnumTests.swift index 187513a..b2f0e95 100644 --- a/Tests/DefaultsTests/DefaultsEnumTests.swift +++ b/Tests/DefaultsTests/DefaultsEnumTests.swift @@ -1,6 +1,8 @@ import Foundation +import Testing import Defaults -import XCTest + +private let suite_ = createSuite() private enum FixtureEnum: String, Defaults.Serializable { case tenMinutes = "10 Minutes" @@ -9,296 +11,121 @@ private enum FixtureEnum: String, Defaults.Serializable { } extension Defaults.Keys { - fileprivate static let `enum` = Key("enum", default: .tenMinutes) - fileprivate static let enumArray = Key<[FixtureEnum]>("array_enum", default: [.tenMinutes]) - fileprivate static let enumDictionary = Key<[String: FixtureEnum]>("dictionary_enum", default: ["0": .tenMinutes]) + fileprivate static let `enum` = Key("enum", default: .tenMinutes, suite: suite_) + fileprivate static let enumArray = Key<[FixtureEnum]>("array_enum", default: [.tenMinutes], suite: suite_) + fileprivate static let enumDictionary = Key<[String: FixtureEnum]>("dictionary_enum", default: ["0": .tenMinutes], suite: suite_) } -final class DefaultsEnumTests: XCTestCase { - override func setUp() { - super.setUp() - Defaults.removeAll() +@Suite(.serialized) +final class DefaultsEnumTests { + init() { + Defaults.removeAll(suite: suite_) } - override func tearDown() { - super.tearDown() - Defaults.removeAll() + deinit { + Defaults.removeAll(suite: suite_) } + @Test func testKey() { - let key = Defaults.Key("independentEnumKey", default: .tenMinutes) - XCTAssertEqual(Defaults[key], .tenMinutes) + let key = Defaults.Key("independentEnumKey", default: .tenMinutes, suite: suite_) + #expect(Defaults[key] == .tenMinutes) Defaults[key] = .halfHour - XCTAssertEqual(Defaults[key], .halfHour) + #expect(Defaults[key] == .halfHour) } + @Test func testOptionalKey() { - let key = Defaults.Key("independentEnumOptionalKey") - XCTAssertNil(Defaults[key]) + let key = Defaults.Key("independentEnumOptionalKey", suite: suite_) + #expect(Defaults[key] == nil) Defaults[key] = .tenMinutes - XCTAssertEqual(Defaults[key], .tenMinutes) + #expect(Defaults[key] == .tenMinutes) } + @Test func testArrayKey() { - let key = Defaults.Key<[FixtureEnum]>("independentEnumArrayKey", default: [.tenMinutes]) - XCTAssertEqual(Defaults[key][0], .tenMinutes) + let key = Defaults.Key<[FixtureEnum]>("independentEnumArrayKey", default: [.tenMinutes], suite: suite_) + #expect(Defaults[key][0] == .tenMinutes) Defaults[key].append(.halfHour) - XCTAssertEqual(Defaults[key][0], .tenMinutes) - XCTAssertEqual(Defaults[key][1], .halfHour) + #expect(Defaults[key][0] == .tenMinutes) + #expect(Defaults[key][1] == .halfHour) } + @Test func testArrayOptionalKey() { - let key = Defaults.Key<[FixtureEnum]?>("independentEnumArrayOptionalKey") // swiftlint:disable:this discouraged_optional_collection - XCTAssertNil(Defaults[key]) + let key = Defaults.Key<[FixtureEnum]?>("independentEnumArrayOptionalKey", suite: suite_) // swiftlint:disable:this discouraged_optional_collection + #expect(Defaults[key] == nil) Defaults[key] = [.tenMinutes] Defaults[key]?.append(.halfHour) - XCTAssertEqual(Defaults[key]?[0], .tenMinutes) - XCTAssertEqual(Defaults[key]?[1], .halfHour) + #expect(Defaults[key]?[0] == .tenMinutes) + #expect(Defaults[key]?[1] == .halfHour) } + @Test func testNestedArrayKey() { - let key = Defaults.Key<[[FixtureEnum]]>("independentEnumNestedArrayKey", default: [[.tenMinutes]]) - XCTAssertEqual(Defaults[key][0][0], .tenMinutes) + let key = Defaults.Key<[[FixtureEnum]]>("independentEnumNestedArrayKey", default: [[.tenMinutes]], suite: suite_) + #expect(Defaults[key][0][0] == .tenMinutes) Defaults[key][0].append(.halfHour) Defaults[key].append([.oneHour]) - XCTAssertEqual(Defaults[key][0][1], .halfHour) - XCTAssertEqual(Defaults[key][1][0], .oneHour) + #expect(Defaults[key][0][1] == .halfHour) + #expect(Defaults[key][1][0] == .oneHour) } + @Test func testArrayDictionaryKey() { - let key = Defaults.Key<[[String: FixtureEnum]]>("independentEnumArrayDictionaryKey", default: [["0": .tenMinutes]]) - XCTAssertEqual(Defaults[key][0]["0"], .tenMinutes) + let key = Defaults.Key<[[String: FixtureEnum]]>("independentEnumArrayDictionaryKey", default: [["0": .tenMinutes]], suite: suite_) + #expect(Defaults[key][0]["0"] == .tenMinutes) Defaults[key][0]["1"] = .halfHour Defaults[key].append(["0": .oneHour]) - XCTAssertEqual(Defaults[key][0]["1"], .halfHour) - XCTAssertEqual(Defaults[key][1]["0"], .oneHour) + #expect(Defaults[key][0]["1"] == .halfHour) + #expect(Defaults[key][1]["0"] == .oneHour) } + @Test func testDictionaryKey() { - let key = Defaults.Key<[String: FixtureEnum]>("independentEnumDictionaryKey", default: ["0": .tenMinutes]) - XCTAssertEqual(Defaults[key]["0"], .tenMinutes) + let key = Defaults.Key<[String: FixtureEnum]>("independentEnumDictionaryKey", default: ["0": .tenMinutes], suite: suite_) + #expect(Defaults[key]["0"] == .tenMinutes) Defaults[key]["1"] = .halfHour - XCTAssertEqual(Defaults[key]["0"], .tenMinutes) - XCTAssertEqual(Defaults[key]["1"], .halfHour) + #expect(Defaults[key]["0"] == .tenMinutes) + #expect(Defaults[key]["1"] == .halfHour) } + @Test func testDictionaryOptionalKey() { - let key = Defaults.Key<[String: FixtureEnum]?>("independentEnumDictionaryOptionalKey") // swiftlint:disable:this discouraged_optional_collection - XCTAssertNil(Defaults[key]) + let key = Defaults.Key<[String: FixtureEnum]?>("independentEnumDictionaryOptionalKey", suite: suite_) // swiftlint:disable:this discouraged_optional_collection + #expect(Defaults[key] == nil) Defaults[key] = ["0": .tenMinutes] - XCTAssertEqual(Defaults[key]?["0"], .tenMinutes) + #expect(Defaults[key]?["0"] == .tenMinutes) } + @Test func testDictionaryArrayKey() { - let key = Defaults.Key<[String: [FixtureEnum]]>("independentEnumDictionaryKey", default: ["0": [.tenMinutes]]) - XCTAssertEqual(Defaults[key]["0"]?[0], .tenMinutes) + let key = Defaults.Key<[String: [FixtureEnum]]>("independentEnumDictionaryKey", default: ["0": [.tenMinutes]], suite: suite_) + #expect(Defaults[key]["0"]?[0] == .tenMinutes) Defaults[key]["0"]?.append(.halfHour) Defaults[key]["1"] = [.oneHour] - XCTAssertEqual(Defaults[key]["0"]?[1], .halfHour) - XCTAssertEqual(Defaults[key]["1"]?[0], .oneHour) + #expect(Defaults[key]["0"]?[1] == .halfHour) + #expect(Defaults[key]["1"]?[0] == .oneHour) } + @Test func testType() { - XCTAssertEqual(Defaults[.enum], .tenMinutes) + #expect(Defaults[.enum] == .tenMinutes) Defaults[.enum] = .halfHour - XCTAssertEqual(Defaults[.enum], .halfHour) + #expect(Defaults[.enum] == .halfHour) } + @Test func testArrayType() { - XCTAssertEqual(Defaults[.enumArray][0], .tenMinutes) + #expect(Defaults[.enumArray][0] == .tenMinutes) Defaults[.enumArray][0] = .oneHour - XCTAssertEqual(Defaults[.enumArray][0], .oneHour) + #expect(Defaults[.enumArray][0] == .oneHour) } + @Test func testDictionaryType() { - XCTAssertEqual(Defaults[.enumDictionary]["0"], .tenMinutes) + #expect(Defaults[.enumDictionary]["0"] == .tenMinutes) Defaults[.enumDictionary]["0"] = .halfHour - XCTAssertEqual(Defaults[.enumDictionary]["0"], .halfHour) - } - - func testObserveKeyCombine() { - let key = Defaults.Key("observeEnumKeyCombine", default: .tenMinutes) - let expect = expectation(description: "Observation closure being called") - - let publisher = Defaults - .publisher(key, options: []) - .map { ($0.oldValue, $0.newValue) } - .collect(3) - - let expectedValue: [(FixtureEnum, FixtureEnum)] = [(.tenMinutes, .halfHour), (.halfHour, .oneHour), (.oneHour, .tenMinutes)] - - let cancellable = publisher.sink { tuples in - for (index, expected) in expectedValue.enumerated() { - XCTAssertEqual(expected.0, tuples[index].0) - XCTAssertEqual(expected.1, tuples[index].1) - } - - expect.fulfill() - } - - Defaults[key] = .tenMinutes - Defaults[key] = .halfHour - Defaults[key] = .oneHour - Defaults.reset(key) - cancellable.cancel() - - waitForExpectations(timeout: 10) - } - - func testObserveOptionalKeyCombine() { - let key = Defaults.Key("observeEnumOptionalKeyCombine") - let expect = expectation(description: "Observation closure being called") - - let publisher = Defaults - .publisher(key, options: []) - .map { ($0.oldValue, $0.newValue) } - .collect(4) - - let expectedValue: [(FixtureEnum?, FixtureEnum?)] = [(nil, .tenMinutes), (.tenMinutes, .halfHour), (.halfHour, .oneHour), (.oneHour, nil)] - - let cancellable = publisher.sink { tuples in - for (index, expected) in expectedValue.enumerated() { - XCTAssertEqual(expected.0, tuples[index].0) - XCTAssertEqual(expected.1, tuples[index].1) - } - - expect.fulfill() - } - - Defaults[key] = .tenMinutes - Defaults[key] = .halfHour - Defaults[key] = .oneHour - Defaults.reset(key) - cancellable.cancel() - - waitForExpectations(timeout: 10) - } - - func testObserveArrayKeyCombine() { - let key = Defaults.Key<[FixtureEnum]>("observeEnumArrayKeyCombine", default: [.tenMinutes]) - let expect = expectation(description: "Observation closure being called") - - let publisher = Defaults - .publisher(key, options: []) - .map { ($0.oldValue, $0.newValue) } - .collect(2) - - let expectedValue: [(FixtureEnum, FixtureEnum)] = [(.tenMinutes, .halfHour), (.halfHour, .oneHour)] - - - let cancellable = publisher.sink { tuples in - for (index, expected) in expectedValue.enumerated() { - XCTAssertEqual(expected.0, tuples[index].0[0]) - XCTAssertEqual(expected.1, tuples[index].1[0]) - } - - expect.fulfill() - } - - Defaults[key][0] = .halfHour - Defaults[key][0] = .oneHour - cancellable.cancel() - - waitForExpectations(timeout: 10) - } - - func testObserveDictionaryKeyCombine() { - let key = Defaults.Key<[String: FixtureEnum]>("observeEnumDictionaryKeyCombine", default: ["0": .tenMinutes]) - let expect = expectation(description: "Observation closure being called") - - let publisher = Defaults - .publisher(key, options: []) - .map { ($0.oldValue, $0.newValue) } - .collect(2) - - let expectedValue: [(FixtureEnum, FixtureEnum)] = [(.tenMinutes, .halfHour), (.halfHour, .oneHour)] - - - let cancellable = publisher.sink { tuples in - for (index, expected) in expectedValue.enumerated() { - XCTAssertEqual(expected.0, tuples[index].0["0"]) - XCTAssertEqual(expected.1, tuples[index].1["0"]) - } - - expect.fulfill() - } - - Defaults[key]["0"] = .halfHour - Defaults[key]["0"] = .oneHour - cancellable.cancel() - - waitForExpectations(timeout: 10) - } - - func testObserveKey() { - let key = Defaults.Key("observeEnumKey", default: .tenMinutes) - let expect = expectation(description: "Observation closure being called") - - var observation: Defaults.Observation! - observation = Defaults.observe(key, options: []) { change in - XCTAssertEqual(change.oldValue, .tenMinutes) - XCTAssertEqual(change.newValue, .halfHour) - observation.invalidate() - expect.fulfill() - } - - Defaults[key] = .halfHour - observation.invalidate() - - waitForExpectations(timeout: 10) - } - - func testObserveOptionalKey() { - let key = Defaults.Key("observeEnumOptionalKey") - let expect = expectation(description: "Observation closure being called") - - var observation: Defaults.Observation! - observation = Defaults.observe(key, options: []) { change in - XCTAssertNil(change.oldValue) - XCTAssertEqual(change.newValue, .tenMinutes) - observation.invalidate() - expect.fulfill() - } - - Defaults[key] = .tenMinutes - observation.invalidate() - - waitForExpectations(timeout: 10) - } - - func testObserveArrayKey() { - let key = Defaults.Key<[FixtureEnum]>("observeEnumArrayKey", default: [.tenMinutes]) - let expect = expectation(description: "Observation closure being called") - - var observation: Defaults.Observation! - observation = Defaults.observe(key, options: []) { change in - XCTAssertEqual(change.oldValue[0], .tenMinutes) - XCTAssertEqual(change.newValue[1], .halfHour) - observation.invalidate() - expect.fulfill() - } - - Defaults[key].append(.halfHour) - observation.invalidate() - - waitForExpectations(timeout: 10) - } - - func testObserveDictionaryKey() { - let key = Defaults.Key<[String: FixtureEnum]>("observeEnumDictionaryKey", default: ["0": .tenMinutes]) - let expect = expectation(description: "Observation closure being called") - - var observation: Defaults.Observation! - observation = Defaults.observe(key, options: []) { change in - XCTAssertEqual(change.oldValue["0"], .tenMinutes) - XCTAssertEqual(change.newValue["1"], .halfHour) - observation.invalidate() - expect.fulfill() - } - - Defaults[key]["1"] = .halfHour - observation.invalidate() - - waitForExpectations(timeout: 10) + #expect(Defaults[.enumDictionary]["0"] == .halfHour) } } diff --git a/Tests/DefaultsTests/DefaultsNSColorTests.swift b/Tests/DefaultsTests/DefaultsNSColorTests.swift index 4bb19cf..e468ca3 100644 --- a/Tests/DefaultsTests/DefaultsNSColorTests.swift +++ b/Tests/DefaultsTests/DefaultsNSColorTests.swift @@ -1,314 +1,143 @@ #if os(macOS) import Foundation -import Defaults -import XCTest import AppKit +import Testing +import Defaults + +private let suite_ = createSuite() private let fixtureColor = NSColor(red: Double(103) / Double(0xFF), green: Double(132) / Double(0xFF), blue: Double(255) / Double(0xFF), alpha: 1) private let fixtureColor1 = NSColor(red: Double(255) / Double(0xFF), green: Double(241) / Double(0xFF), blue: Double(180) / Double(0xFF), alpha: 1) private let fixtureColor2 = NSColor(red: Double(255) / Double(0xFF), green: Double(180) / Double(0xFF), blue: Double(194) / Double(0xFF), alpha: 1) extension Defaults.Keys { - fileprivate static let color = Defaults.Key("NSColor", default: fixtureColor) - fileprivate static let colorArray = Defaults.Key<[NSColor]>("NSColorArray", default: [fixtureColor]) - fileprivate static let colorDictionary = Defaults.Key<[String: NSColor]>("NSColorArray", default: ["0": fixtureColor]) + fileprivate static let color = Defaults.Key("NSColor", default: fixtureColor, suite: suite_) + fileprivate static let colorArray = Defaults.Key<[NSColor]>("NSColorArray", default: [fixtureColor], suite: suite_) + fileprivate static let colorDictionary = Defaults.Key<[String: NSColor]>("NSColorArray", default: ["0": fixtureColor], suite: suite_) } -final class DefaultsNSColorTests: XCTestCase { - override func setUp() { - super.setUp() - Defaults.removeAll() +@Suite(.serialized) +final class DefaultsNSColorTests { + init() { + Defaults.removeAll(suite: suite_) } - override func tearDown() { - super.tearDown() - Defaults.removeAll() + deinit { + Defaults.removeAll(suite: suite_) } + @Test func testKey() { - let key = Defaults.Key("independentNSColorKey", default: fixtureColor) - XCTAssertTrue(Defaults[key].isEqual(fixtureColor)) + let key = Defaults.Key("independentNSColorKey", default: fixtureColor, suite: suite_) + #expect(Defaults[key].isEqual(fixtureColor)) Defaults[key] = fixtureColor1 - XCTAssertTrue(Defaults[key].isEqual(fixtureColor1)) + #expect(Defaults[key].isEqual(fixtureColor1)) } + @Test func testPreservesColorSpace() { let fixture = NSColor(displayP3Red: 1, green: 0.3, blue: 0.7, alpha: 1) - let key = Defaults.Key("independentNSColorPreservesColorSpaceKey") + let key = Defaults.Key("independentNSColorPreservesColorSpaceKey", suite: suite_) Defaults[key] = fixture - XCTAssertEqual(Defaults[key]?.colorSpace, fixture.colorSpace) - XCTAssertEqual(Defaults[key]?.cgColor.colorSpace, fixture.cgColor.colorSpace) - XCTAssertEqual(Defaults[key], fixture) - XCTAssertEqual(Defaults[key]?.cgColor, fixture.cgColor) + #expect(Defaults[key]?.colorSpace == fixture.colorSpace) + #expect(Defaults[key]?.cgColor.colorSpace == fixture.cgColor.colorSpace) + #expect(Defaults[key] == fixture) + #expect(Defaults[key]?.cgColor == fixture.cgColor) } + @Test func testOptionalKey() { - let key = Defaults.Key("independentNSColorOptionalKey") - XCTAssertNil(Defaults[key]) + let key = Defaults.Key("independentNSColorOptionalKey", suite: suite_) + #expect(Defaults[key] == nil) Defaults[key] = fixtureColor - XCTAssertTrue(Defaults[key]?.isEqual(fixtureColor) ?? false) + #expect(Defaults[key]?.isEqual(fixtureColor) ?? false) } + @Test func testArrayKey() { - let key = Defaults.Key<[NSColor]>("independentNSColorArrayKey", default: [fixtureColor]) - XCTAssertTrue(Defaults[key][0].isEqual(fixtureColor)) + let key = Defaults.Key<[NSColor]>("independentNSColorArrayKey", default: [fixtureColor], suite: suite_) + #expect(Defaults[key][0].isEqual(fixtureColor)) Defaults[key].append(fixtureColor1) - XCTAssertTrue(Defaults[key][1].isEqual(fixtureColor1)) + #expect(Defaults[key][1].isEqual(fixtureColor1)) } + @Test func testArrayOptionalKey() { - let key = Defaults.Key<[NSColor]?>("independentNSColorOptionalKey") // swiftlint:disable:this discouraged_optional_collection - XCTAssertNil(Defaults[key]) + let key = Defaults.Key<[NSColor]?>("independentNSColorOptionalKey", suite: suite_) // swiftlint:disable:this discouraged_optional_collection + #expect(Defaults[key] == nil) Defaults[key] = [fixtureColor] Defaults[key]?.append(fixtureColor1) - XCTAssertTrue(Defaults[key]?[0].isEqual(fixtureColor) ?? false) - XCTAssertTrue(Defaults[key]?[1].isEqual(fixtureColor1) ?? false) + #expect(Defaults[key]?[0].isEqual(fixtureColor) ?? false) + #expect(Defaults[key]?[1].isEqual(fixtureColor1) ?? false) } + @Test func testNestedArrayKey() { - let key = Defaults.Key<[[NSColor]]>("independentNSColorNestedArrayKey", default: [[fixtureColor]]) - XCTAssertTrue(Defaults[key][0][0].isEqual(fixtureColor)) + let key = Defaults.Key<[[NSColor]]>("independentNSColorNestedArrayKey", default: [[fixtureColor]], suite: suite_) + #expect(Defaults[key][0][0].isEqual(fixtureColor)) Defaults[key][0].append(fixtureColor1) Defaults[key].append([fixtureColor2]) - XCTAssertTrue(Defaults[key][0][1].isEqual(fixtureColor1)) - XCTAssertTrue(Defaults[key][1][0].isEqual(fixtureColor2)) + #expect(Defaults[key][0][1].isEqual(fixtureColor1)) + #expect(Defaults[key][1][0].isEqual(fixtureColor2)) } + @Test func testArrayDictionaryKey() { - let key = Defaults.Key<[[String: NSColor]]>("independentNSColorArrayDictionaryKey", default: [["0": fixtureColor]]) - XCTAssertTrue(Defaults[key][0]["0"]?.isEqual(fixtureColor) ?? false) + let key = Defaults.Key<[[String: NSColor]]>("independentNSColorArrayDictionaryKey", default: [["0": fixtureColor]], suite: suite_) + #expect(Defaults[key][0]["0"]?.isEqual(fixtureColor) ?? false) Defaults[key][0]["1"] = fixtureColor1 Defaults[key].append(["0": fixtureColor2]) - XCTAssertTrue(Defaults[key][0]["1"]?.isEqual(fixtureColor1) ?? false) - XCTAssertTrue(Defaults[key][1]["0"]?.isEqual(fixtureColor2) ?? false) + #expect(Defaults[key][0]["1"]?.isEqual(fixtureColor1) ?? false) + #expect(Defaults[key][1]["0"]?.isEqual(fixtureColor2) ?? false) } + @Test func testDictionaryKey() { - let key = Defaults.Key<[String: NSColor]>("independentNSColorDictionaryKey", default: ["0": fixtureColor]) - XCTAssertTrue(Defaults[key]["0"]?.isEqual(fixtureColor) ?? false) + let key = Defaults.Key<[String: NSColor]>("independentNSColorDictionaryKey", default: ["0": fixtureColor], suite: suite_) + #expect(Defaults[key]["0"]?.isEqual(fixtureColor) ?? false) Defaults[key]["1"] = fixtureColor1 - XCTAssertTrue(Defaults[key]["1"]?.isEqual(fixtureColor1) ?? false) + #expect(Defaults[key]["1"]?.isEqual(fixtureColor1) ?? false) } + @Test func testDictionaryOptionalKey() { - let key = Defaults.Key<[String: NSColor]?>("independentNSColorDictionaryOptionalKey") // swiftlint:disable:this discouraged_optional_collection - XCTAssertNil(Defaults[key]) + let key = Defaults.Key<[String: NSColor]?>("independentNSColorDictionaryOptionalKey", suite: suite_) // swiftlint:disable:this discouraged_optional_collection + #expect(Defaults[key] == nil) Defaults[key] = ["0": fixtureColor] Defaults[key]?["1"] = fixtureColor1 - XCTAssertTrue(Defaults[key]?["0"]?.isEqual(fixtureColor) ?? false) - XCTAssertTrue(Defaults[key]?["1"]?.isEqual(fixtureColor1) ?? false) + #expect(Defaults[key]?["0"]?.isEqual(fixtureColor) ?? false) + #expect(Defaults[key]?["1"]?.isEqual(fixtureColor1) ?? false) } + @Test func testDictionaryArrayKey() { - let key = Defaults.Key<[String: [NSColor]]>("independentNSColorDictionaryArrayKey", default: ["0": [fixtureColor]]) - XCTAssertTrue(Defaults[key]["0"]?[0].isEqual(fixtureColor) ?? false) + let key = Defaults.Key<[String: [NSColor]]>("independentNSColorDictionaryArrayKey", default: ["0": [fixtureColor]], suite: suite_) + #expect(Defaults[key]["0"]?[0].isEqual(fixtureColor) ?? false) Defaults[key]["0"]?.append(fixtureColor1) Defaults[key]["1"] = [fixtureColor2] - XCTAssertTrue(Defaults[key]["0"]?[1].isEqual(fixtureColor1) ?? false) - XCTAssertTrue(Defaults[key]["1"]?[0].isEqual(fixtureColor2) ?? false) + #expect(Defaults[key]["0"]?[1].isEqual(fixtureColor1) ?? false) + #expect(Defaults[key]["1"]?[0].isEqual(fixtureColor2) ?? false) } + @Test func testType() { - XCTAssert(Defaults[.color].isEqual(fixtureColor)) + #expect(Defaults[.color].isEqual(fixtureColor)) Defaults[.color] = fixtureColor1 - XCTAssert(Defaults[.color].isEqual(fixtureColor1)) + #expect(Defaults[.color].isEqual(fixtureColor1)) } + @Test func testArrayType() { - XCTAssertTrue(Defaults[.colorArray][0].isEqual(fixtureColor)) + #expect(Defaults[.colorArray][0].isEqual(fixtureColor)) Defaults[.colorArray][0] = fixtureColor1 - XCTAssertTrue(Defaults[.colorArray][0].isEqual(fixtureColor1)) + #expect(Defaults[.colorArray][0].isEqual(fixtureColor1)) } + @Test func testDictionaryType() { - XCTAssertTrue(Defaults[.colorDictionary]["0"]?.isEqual(fixtureColor) ?? false) + #expect(Defaults[.colorDictionary]["0"]?.isEqual(fixtureColor) ?? false) Defaults[.colorDictionary]["0"] = fixtureColor1 - XCTAssertTrue(Defaults[.colorDictionary]["0"]?.isEqual(fixtureColor1) ?? false) - } - - func testObserveKeyCombine() { - let key = Defaults.Key("observeNSColorKeyCombine", default: fixtureColor) - let expect = expectation(description: "Observation closure being called") - - let publisher = Defaults - .publisher(key, options: []) - .map { ($0.oldValue, $0.newValue) } - .collect(2) - - let cancellable = publisher.sink { tuples in - for (index, expected) in [(fixtureColor, fixtureColor1), (fixtureColor1, fixtureColor)].enumerated() { - XCTAssertTrue(expected.0.isEqual(tuples[index].0)) - XCTAssertTrue(expected.1.isEqual(tuples[index].1)) - } - - expect.fulfill() - } - - Defaults[key] = fixtureColor1 - Defaults.reset(key) - cancellable.cancel() - - waitForExpectations(timeout: 10) - } - - func testObserveOptionalKeyCombine() { - let key = Defaults.Key("observeNSColorOptionalKeyCombine") - let expect = expectation(description: "Observation closure being called") - - let publisher = Defaults - .publisher(key, options: []) - .map { ($0.oldValue, $0.newValue) } - .collect(3) - - let expectedValue: [(NSColor?, NSColor?)] = [(nil, fixtureColor), (fixtureColor, fixtureColor1), (fixtureColor1, nil)] - - let cancellable = publisher.sink { tuples in - for (index, expected) in expectedValue.enumerated() { - guard let oldValue = expected.0 else { - XCTAssertNil(tuples[index].0) - continue - } - guard let newValue = expected.1 else { - XCTAssertNil(tuples[index].1) - continue - } - XCTAssertTrue(oldValue.isEqual(tuples[index].0)) - XCTAssertTrue(newValue.isEqual(tuples[index].1)) - } - - expect.fulfill() - } - - Defaults[key] = fixtureColor - Defaults[key] = fixtureColor1 - Defaults.reset(key) - cancellable.cancel() - - waitForExpectations(timeout: 10) - } - - func testObserveArrayKeyCombine() { - let key = Defaults.Key<[NSColor]>("observeNSColorArrayKeyCombine", default: [fixtureColor]) - let expect = expectation(description: "Observation closure being called") - - let publisher = Defaults - .publisher(key, options: []) - .map { ($0.oldValue, $0.newValue) } - .collect(2) - - let cancellable = publisher.sink { tuples in - for (index, expected) in [(fixtureColor, fixtureColor1), (fixtureColor1, fixtureColor)].enumerated() { - XCTAssertTrue(expected.0.isEqual(tuples[index].0[0])) - XCTAssertTrue(expected.1.isEqual(tuples[index].1[0])) - } - - expect.fulfill() - } - - Defaults[key][0] = fixtureColor1 - Defaults.reset(key) - cancellable.cancel() - - waitForExpectations(timeout: 10) - } - - func testObserveDictionaryKeyCombine() { - let key = Defaults.Key<[String: NSColor]>("observeNSColorDictionaryKeyCombine", default: ["0": fixtureColor]) - let expect = expectation(description: "Observation closure being called") - - let publisher = Defaults - .publisher(key, options: []) - .map { ($0.oldValue, $0.newValue) } - .collect(2) - - let cancellable = publisher.sink { tuples in - for (index, expected) in [(fixtureColor, fixtureColor1), (fixtureColor1, fixtureColor)].enumerated() { - XCTAssertTrue(expected.0.isEqual(tuples[index].0["0"])) - XCTAssertTrue(expected.1.isEqual(tuples[index].1["0"])) - } - - expect.fulfill() - } - - Defaults[key]["0"] = fixtureColor1 - Defaults.reset(key) - cancellable.cancel() - - waitForExpectations(timeout: 10) - } - - func testObserveKey() { - let key = Defaults.Key("observeNSColorKey", default: fixtureColor) - let expect = expectation(description: "Observation closure being called") - - var observation: Defaults.Observation! - observation = Defaults.observe(key, options: []) { change in - XCTAssertTrue(change.oldValue.isEqual(fixtureColor)) - XCTAssertTrue(change.newValue.isEqual(fixtureColor1)) - observation.invalidate() - expect.fulfill() - } - - Defaults[key] = fixtureColor1 - observation.invalidate() - - waitForExpectations(timeout: 10) - } - - func testObserveOptionalKey() { - let key = Defaults.Key("observeNSColorOptionalKey") - let expect = expectation(description: "Observation closure being called") - - var observation: Defaults.Observation! - observation = Defaults.observe(key, options: []) { change in - XCTAssertNil(change.oldValue) - XCTAssertTrue(change.newValue?.isEqual(fixtureColor) ?? false) - observation.invalidate() - expect.fulfill() - } - - Defaults[key] = fixtureColor - observation.invalidate() - - waitForExpectations(timeout: 10) - } - - func testObserveArrayKey() { - let key = Defaults.Key<[NSColor]>("observeNSColorArrayKey", default: [fixtureColor]) - let expect = expectation(description: "Observation closure being called") - - var observation: Defaults.Observation! - observation = Defaults.observe(key, options: []) { change in - XCTAssertTrue(change.oldValue[0].isEqual(fixtureColor)) - XCTAssertTrue(change.newValue[0].isEqual(fixtureColor)) - XCTAssertTrue(change.newValue[1].isEqual(fixtureColor1)) - observation.invalidate() - expect.fulfill() - } - - Defaults[key].append(fixtureColor1) - observation.invalidate() - - waitForExpectations(timeout: 10) - } - - func testObserveDictionaryKey() { - let key = Defaults.Key<[String: NSColor]>("observeNSColorDictionaryKey", default: ["0": fixtureColor]) - let expect = expectation(description: "Observation closure being called") - - var observation: Defaults.Observation! - observation = Defaults.observe(key, options: []) { change in - XCTAssertTrue(change.oldValue["0"]?.isEqual(fixtureColor) ?? false) - XCTAssertTrue(change.newValue["0"]?.isEqual(fixtureColor) ?? false) - XCTAssertTrue(change.newValue["1"]?.isEqual(fixtureColor1) ?? false) - observation.invalidate() - expect.fulfill() - } - - Defaults[key]["1"] = fixtureColor1 - observation.invalidate() - - waitForExpectations(timeout: 10) + #expect(Defaults[.colorDictionary]["0"]?.isEqual(fixtureColor1) ?? false) } } #endif diff --git a/Tests/DefaultsTests/DefaultsNSSecureCodingTests.swift b/Tests/DefaultsTests/DefaultsNSSecureCodingTests.swift index 6acf599..c0319b4 100644 --- a/Tests/DefaultsTests/DefaultsNSSecureCodingTests.swift +++ b/Tests/DefaultsTests/DefaultsNSSecureCodingTests.swift @@ -1,7 +1,9 @@ import Foundation import CoreData +import Testing import Defaults -import XCTest + +private let suite_ = createSuite() @objc(ExamplePersistentHistory) private final class ExamplePersistentHistory: NSPersistentHistoryToken, Defaults.Serializable { @@ -28,445 +30,144 @@ private final class ExamplePersistentHistory: NSPersistentHistoryToken, Defaults private let persistentHistoryValue = ExamplePersistentHistory(value: "ExampleToken") extension Defaults.Keys { - fileprivate static let persistentHistory = Key("persistentHistory", default: persistentHistoryValue) - fileprivate static let persistentHistoryArray = Key<[ExamplePersistentHistory]>("array_persistentHistory", default: [persistentHistoryValue]) - fileprivate static let persistentHistoryDictionary = Key<[String: ExamplePersistentHistory]>("dictionary_persistentHistory", default: ["0": persistentHistoryValue]) + fileprivate static let persistentHistory = Key("persistentHistory", default: persistentHistoryValue, suite: suite_) + fileprivate static let persistentHistoryArray = Key<[ExamplePersistentHistory]>("array_persistentHistory", default: [persistentHistoryValue], suite: suite_) + fileprivate static let persistentHistoryDictionary = Key<[String: ExamplePersistentHistory]>("dictionary_persistentHistory", default: ["0": persistentHistoryValue], suite: suite_) } -final class DefaultsNSSecureCodingTests: XCTestCase { - override func setUp() { - super.setUp() - Defaults.removeAll() +@Suite(.serialized) +final class DefaultsNSSecureCodingTests { + init() { + Defaults.removeAll(suite: suite_) } - override func tearDown() { - super.tearDown() - Defaults.removeAll() + deinit { + Defaults.removeAll(suite: suite_) } + @Test func testKey() { - let key = Defaults.Key("independentNSSecureCodingKey", default: persistentHistoryValue) - XCTAssertEqual(Defaults[key].value, persistentHistoryValue.value) + let key = Defaults.Key("independentNSSecureCodingKey", default: persistentHistoryValue, suite: suite_) + #expect(Defaults[key].value == persistentHistoryValue.value) let newPersistentHistory = ExamplePersistentHistory(value: "NewValue") Defaults[key] = newPersistentHistory - XCTAssertEqual(Defaults[key].value, newPersistentHistory.value) + #expect(Defaults[key].value == newPersistentHistory.value) } + @Test func testOptionalKey() { - let key = Defaults.Key("independentNSSecureCodingOptionalKey") - XCTAssertNil(Defaults[key]) + let key = Defaults.Key("independentNSSecureCodingOptionalKey", suite: suite_) + #expect(Defaults[key] == nil) Defaults[key] = persistentHistoryValue - XCTAssertEqual(Defaults[key]?.value, persistentHistoryValue.value) + #expect(Defaults[key]?.value == persistentHistoryValue.value) Defaults[key] = nil - XCTAssertNil(Defaults[key]) + #expect(Defaults[key] == nil) let newPersistentHistory = ExamplePersistentHistory(value: "NewValue") Defaults[key] = newPersistentHistory - XCTAssertEqual(Defaults[key]?.value, newPersistentHistory.value) + #expect(Defaults[key]?.value == newPersistentHistory.value) } + @Test func testArrayKey() { - let key = Defaults.Key<[ExamplePersistentHistory]>("independentNSSecureCodingArrayKey", default: [persistentHistoryValue]) - XCTAssertEqual(Defaults[key][0].value, persistentHistoryValue.value) + let key = Defaults.Key<[ExamplePersistentHistory]>("independentNSSecureCodingArrayKey", default: [persistentHistoryValue], suite: suite_) + #expect(Defaults[key][0].value == persistentHistoryValue.value) let newPersistentHistory1 = ExamplePersistentHistory(value: "NewValue1") Defaults[key].append(newPersistentHistory1) - XCTAssertEqual(Defaults[key][1].value, newPersistentHistory1.value) + #expect(Defaults[key][1].value == newPersistentHistory1.value) let newPersistentHistory2 = ExamplePersistentHistory(value: "NewValue2") Defaults[key][1] = newPersistentHistory2 - XCTAssertEqual(Defaults[key][1].value, newPersistentHistory2.value) - XCTAssertEqual(Defaults[key][0].value, persistentHistoryValue.value) + #expect(Defaults[key][1].value == newPersistentHistory2.value) + #expect(Defaults[key][0].value == persistentHistoryValue.value) } + @Test func testArrayOptionalKey() { - let key = Defaults.Key<[ExamplePersistentHistory]?>("independentNSSecureCodingArrayOptionalKey") // swiftlint:disable:this discouraged_optional_collection - XCTAssertNil(Defaults[key]) + let key = Defaults.Key<[ExamplePersistentHistory]?>("independentNSSecureCodingArrayOptionalKey", suite: suite_) // swiftlint:disable:this discouraged_optional_collection + #expect(Defaults[key] == nil) Defaults[key] = [persistentHistoryValue] - XCTAssertEqual(Defaults[key]?[0].value, persistentHistoryValue.value) + #expect(Defaults[key]?[0].value == persistentHistoryValue.value) Defaults[key] = nil - XCTAssertNil(Defaults[key]) + #expect(Defaults[key] == nil) } + @Test func testNestedArrayKey() { - let key = Defaults.Key<[[ExamplePersistentHistory]]>("independentNSSecureCodingNestedArrayKey", default: [[persistentHistoryValue]]) - XCTAssertEqual(Defaults[key][0][0].value, persistentHistoryValue.value) + let key = Defaults.Key<[[ExamplePersistentHistory]]>("independentNSSecureCodingNestedArrayKey", default: [[persistentHistoryValue]], suite: suite_) + #expect(Defaults[key][0][0].value == persistentHistoryValue.value) let newPersistentHistory1 = ExamplePersistentHistory(value: "NewValue1") Defaults[key][0].append(newPersistentHistory1) let newPersistentHistory2 = ExamplePersistentHistory(value: "NewValue2") Defaults[key].append([newPersistentHistory2]) - XCTAssertEqual(Defaults[key][0][1].value, newPersistentHistory1.value) - XCTAssertEqual(Defaults[key][1][0].value, newPersistentHistory2.value) + #expect(Defaults[key][0][1].value == newPersistentHistory1.value) + #expect(Defaults[key][1][0].value == newPersistentHistory2.value) } + @Test func testArrayDictionaryKey() { - let key = Defaults.Key<[[String: ExamplePersistentHistory]]>("independentNSSecureCodingArrayDictionaryKey", default: [["0": persistentHistoryValue]]) - XCTAssertEqual(Defaults[key][0]["0"]?.value, persistentHistoryValue.value) + let key = Defaults.Key<[[String: ExamplePersistentHistory]]>("independentNSSecureCodingArrayDictionaryKey", default: [["0": persistentHistoryValue]], suite: suite_) + #expect(Defaults[key][0]["0"]?.value == persistentHistoryValue.value) let newPersistentHistory1 = ExamplePersistentHistory(value: "NewValue1") Defaults[key][0]["1"] = newPersistentHistory1 let newPersistentHistory2 = ExamplePersistentHistory(value: "NewValue2") Defaults[key].append(["0": newPersistentHistory2]) - XCTAssertEqual(Defaults[key][0]["1"]?.value, newPersistentHistory1.value) - XCTAssertEqual(Defaults[key][1]["0"]?.value, newPersistentHistory2.value) + #expect(Defaults[key][0]["1"]?.value == newPersistentHistory1.value) + #expect(Defaults[key][1]["0"]?.value == newPersistentHistory2.value) } + @Test func testDictionaryKey() { - let key = Defaults.Key<[String: ExamplePersistentHistory]>("independentNSSecureCodingDictionaryKey", default: ["0": persistentHistoryValue]) - XCTAssertEqual(Defaults[key]["0"]?.value, persistentHistoryValue.value) + let key = Defaults.Key<[String: ExamplePersistentHistory]>("independentNSSecureCodingDictionaryKey", default: ["0": persistentHistoryValue], suite: suite_) + #expect(Defaults[key]["0"]?.value == persistentHistoryValue.value) let newPersistentHistory1 = ExamplePersistentHistory(value: "NewValue1") Defaults[key]["1"] = newPersistentHistory1 - XCTAssertEqual(Defaults[key]["1"]?.value, newPersistentHistory1.value) + #expect(Defaults[key]["1"]?.value == newPersistentHistory1.value) let newPersistentHistory2 = ExamplePersistentHistory(value: "NewValue2") Defaults[key]["1"] = newPersistentHistory2 - XCTAssertEqual(Defaults[key]["1"]?.value, newPersistentHistory2.value) - XCTAssertEqual(Defaults[key]["0"]?.value, persistentHistoryValue.value) + #expect(Defaults[key]["1"]?.value == newPersistentHistory2.value) + #expect(Defaults[key]["0"]?.value == persistentHistoryValue.value) } + @Test func testDictionaryOptionalKey() { - let key = Defaults.Key<[String: ExamplePersistentHistory]?>("independentNSSecureCodingDictionaryOptionalKey") // swiftlint:disable:this discouraged_optional_collection - XCTAssertNil(Defaults[key]) + let key = Defaults.Key<[String: ExamplePersistentHistory]?>("independentNSSecureCodingDictionaryOptionalKey", suite: suite_) // swiftlint:disable:this discouraged_optional_collection + #expect(Defaults[key] == nil) Defaults[key] = ["0": persistentHistoryValue] - XCTAssertEqual(Defaults[key]?["0"]?.value, persistentHistoryValue.value) + #expect(Defaults[key]?["0"]?.value == persistentHistoryValue.value) } + @Test func testDictionaryArrayKey() { - let key = Defaults.Key<[String: [ExamplePersistentHistory]]>("independentNSSecureCodingDictionaryArrayKey", default: ["0": [persistentHistoryValue]]) - XCTAssertEqual(Defaults[key]["0"]?[0].value, persistentHistoryValue.value) + let key = Defaults.Key<[String: [ExamplePersistentHistory]]>("independentNSSecureCodingDictionaryArrayKey", default: ["0": [persistentHistoryValue]], suite: suite_) + #expect(Defaults[key]["0"]?[0].value == persistentHistoryValue.value) let newPersistentHistory1 = ExamplePersistentHistory(value: "NewValue1") Defaults[key]["0"]?.append(newPersistentHistory1) let newPersistentHistory2 = ExamplePersistentHistory(value: "NewValue2") Defaults[key]["1"] = [newPersistentHistory2] - XCTAssertEqual(Defaults[key]["0"]?[1].value, newPersistentHistory1.value) - XCTAssertEqual(Defaults[key]["1"]?[0].value, newPersistentHistory2.value) + #expect(Defaults[key]["0"]?[1].value == newPersistentHistory1.value) + #expect(Defaults[key]["1"]?[0].value == newPersistentHistory2.value) } + @Test func testType() { - XCTAssertEqual(Defaults[.persistentHistory].value, persistentHistoryValue.value) + #expect(Defaults[.persistentHistory].value == persistentHistoryValue.value) let newPersistentHistory = ExamplePersistentHistory(value: "NewValue") Defaults[.persistentHistory] = newPersistentHistory - XCTAssertEqual(Defaults[.persistentHistory].value, newPersistentHistory.value) + #expect(Defaults[.persistentHistory].value == newPersistentHistory.value) } + @Test func testArrayType() { - XCTAssertEqual(Defaults[.persistentHistoryArray][0].value, persistentHistoryValue.value) + #expect(Defaults[.persistentHistoryArray][0].value == persistentHistoryValue.value) let newPersistentHistory = ExamplePersistentHistory(value: "NewValue") Defaults[.persistentHistoryArray][0] = newPersistentHistory - XCTAssertEqual(Defaults[.persistentHistoryArray][0].value, newPersistentHistory.value) + #expect(Defaults[.persistentHistoryArray][0].value == newPersistentHistory.value) } + @Test func testDictionaryType() { - XCTAssertEqual(Defaults[.persistentHistoryDictionary]["0"]?.value, persistentHistoryValue.value) + #expect(Defaults[.persistentHistoryDictionary]["0"]?.value == persistentHistoryValue.value) let newPersistentHistory = ExamplePersistentHistory(value: "NewValue") Defaults[.persistentHistoryDictionary]["0"] = newPersistentHistory - XCTAssertEqual(Defaults[.persistentHistoryDictionary]["0"]?.value, newPersistentHistory.value) - } - - func testObserveKeyCombine() { - let key = Defaults.Key("observeNSSecureCodingKeyCombine", default: persistentHistoryValue) - let newPersistentHistory = ExamplePersistentHistory(value: "NewValue") - let expect = expectation(description: "Observation closure being called") - - let publisher = Defaults - .publisher(key, options: []) - .map { ($0.oldValue.value, $0.newValue.value) } - .collect(2) - - let cancellable = publisher.sink { tuples in - for (index, expected) in [(persistentHistoryValue.value, newPersistentHistory.value), (newPersistentHistory.value, persistentHistoryValue.value)].enumerated() { - XCTAssertEqual(expected.0, tuples[index].0) - XCTAssertEqual(expected.1, tuples[index].1) - } - - expect.fulfill() - } - - Defaults[key] = newPersistentHistory - Defaults.reset(key) - cancellable.cancel() - - waitForExpectations(timeout: 10) - } - - func testObserveOptionalKeyCombine() { - let key = Defaults.Key("observeNSSecureCodingOptionalKeyCombine") - let newPersistentHistory = ExamplePersistentHistory(value: "NewValue") - let expect = expectation(description: "Observation closure being called") - - let publisher = Defaults - .publisher(key, options: []) - .map { ($0.oldValue?.value, $0.newValue?.value) } - .collect(3) - - let expectedValue: [(ExamplePersistentHistory?, ExamplePersistentHistory?)] = [(nil, persistentHistoryValue), (persistentHistoryValue, newPersistentHistory), (newPersistentHistory, nil)] - - let cancellable = publisher.sink { tuples in - for (index, expected) in expectedValue.enumerated() { - XCTAssertEqual(expected.0?.value, tuples[index].0) - XCTAssertEqual(expected.1?.value, tuples[index].1) - } - - expect.fulfill() - } - - Defaults[key] = persistentHistoryValue - Defaults[key] = newPersistentHistory - Defaults.reset(key) - cancellable.cancel() - - waitForExpectations(timeout: 10) - } - - func testObserveArrayKeyCombine() { - let key = Defaults.Key<[ExamplePersistentHistory]>("observeNSSecureCodingArrayKeyCombine", default: [persistentHistoryValue]) - let newPersistentHistory = ExamplePersistentHistory(value: "NewValue") - let expect = expectation(description: "Observation closure being called") - - let publisher = Defaults - .publisher(key, options: []) - .map { ($0.oldValue, $0.newValue) } - .collect(2) - - let expectedValue: [(ExamplePersistentHistory, ExamplePersistentHistory)] = [(persistentHistoryValue, newPersistentHistory), (newPersistentHistory, persistentHistoryValue)] - - let cancellable = publisher.sink { tuples in - for (index, expected) in expectedValue.enumerated() { - XCTAssertEqual(expected.0.value, tuples[index].0[0].value) - XCTAssertEqual(expected.1.value, tuples[index].1[0].value) - } - - expect.fulfill() - } - - Defaults[key][0] = newPersistentHistory - Defaults.reset(key) - cancellable.cancel() - - waitForExpectations(timeout: 10) - } - - func testObserveDictionaryKeyCombine() { - let key = Defaults.Key<[String: ExamplePersistentHistory]>("observeNSSecureCodingDictionaryKeyCombine", default: ["0": persistentHistoryValue]) - let newPersistentHistory = ExamplePersistentHistory(value: "NewValue") - let expect = expectation(description: "Observation closure being called") - - let publisher = Defaults - .publisher(key, options: []) - .map { ($0.oldValue, $0.newValue) } - .collect(2) - - let expectedValue: [(ExamplePersistentHistory, ExamplePersistentHistory)] = [(persistentHistoryValue, newPersistentHistory), (newPersistentHistory, persistentHistoryValue)] - - let cancellable = publisher.sink { tuples in - for (index, expected) in expectedValue.enumerated() { - XCTAssertEqual(expected.0.value, tuples[index].0["0"]?.value) - XCTAssertEqual(expected.1.value, tuples[index].1["0"]?.value) - } - - expect.fulfill() - } - - Defaults[key]["0"] = newPersistentHistory - Defaults.reset(key) - cancellable.cancel() - - waitForExpectations(timeout: 10) - } - - func testObserveMultipleNSSecureKeysCombine() { - let key1 = Defaults.Key("observeMultipleNSSecureCodingKey1", default: ExamplePersistentHistory(value: "TestValue")) - let key2 = Defaults.Key("observeMultipleNSSecureCodingKey2", default: ExamplePersistentHistory(value: "TestValue")) - let expect = expectation(description: "Observation closure being called") - - let publisher = Defaults.publisher(keys: key1, key2, options: []).collect(2) - - let cancellable = publisher.sink { _ in - expect.fulfill() - } - - Defaults[key1] = ExamplePersistentHistory(value: "NewTestValue1") - Defaults[key2] = ExamplePersistentHistory(value: "NewTestValue2") - cancellable.cancel() - - waitForExpectations(timeout: 10) - } - - func testObserveMultipleNSSecureOptionalKeysCombine() { - let key1 = Defaults.Key("observeMultipleNSSecureCodingOptionalKey1") - let key2 = Defaults.Key("observeMultipleNSSecureCodingOptionalKeyKey2") - let expect = expectation(description: "Observation closure being called") - - let publisher = Defaults.publisher(keys: key1, key2, options: []).collect(2) - - let cancellable = publisher.sink { _ in - expect.fulfill() - } - - Defaults[key1] = ExamplePersistentHistory(value: "NewTestValue1") - Defaults[key2] = ExamplePersistentHistory(value: "NewTestValue2") - cancellable.cancel() - - waitForExpectations(timeout: 10) - } - - func testObserveMultipleNSSecureKeys() { - let key1 = Defaults.Key("observeNSSecureCodingKey1", default: ExamplePersistentHistory(value: "TestValue")) - let key2 = Defaults.Key("observeNSSecureCodingKey2", default: ExamplePersistentHistory(value: "TestValue")) - let expect = expectation(description: "Observation closure being called") - - var observation: Defaults.Observation! - var counter = 0 - observation = Defaults.observe(keys: key1, key2, options: []) { - counter += 1 - if counter == 2 { - expect.fulfill() - } else if counter > 2 { - XCTFail() // swiftlint:disable:this xctfail_message - } - } - - Defaults[key1] = ExamplePersistentHistory(value: "NewTestValue1") - Defaults[key2] = ExamplePersistentHistory(value: "NewTestValue2") - observation.invalidate() - - waitForExpectations(timeout: 10) - } - - func testRemoveDuplicatesObserveNSSecureCodingKeyCombine() { - let key = Defaults.Key("observeNSSecureCodingKey", default: ExamplePersistentHistory(value: "TestValue")) - let expect = expectation(description: "Observation closure being called") - - let inputArray = ["NewTestValue", "NewTestValue", "NewTestValue", "NewTestValue2", "NewTestValue2", "NewTestValue2", "NewTestValue3", "NewTestValue3"] - let expectedArray = ["NewTestValue", "NewTestValue2", "NewTestValue3"] - - let cancellable = Defaults - .publisher(key, options: []) - .removeDuplicates() - .map(\.newValue.value) - .collect(expectedArray.count) - .sink { result in - print("Result array: \(result)") - - if result == expectedArray { - expect.fulfill() - } else { - XCTFail("Expected Array is not matched") - } - } - - for item in inputArray { - Defaults[key] = ExamplePersistentHistory(value: item) - } - - Defaults.reset(key) - cancellable.cancel() - - waitForExpectations(timeout: 10) - } - - func testRemoveDuplicatesObserveNSSecureCodingOptionalKeyCombine() { - let key = Defaults.Key("observeNSSecureCodingOptionalKey") - let expect = expectation(description: "Observation closure being called") - - let inputArray = ["NewTestValue", "NewTestValue", "NewTestValue", "NewTestValue2", "NewTestValue2", "NewTestValue2", "NewTestValue3", "NewTestValue3"] - let expectedArray = ["NewTestValue", "NewTestValue2", "NewTestValue3", nil] - - let cancellable = Defaults - .publisher(key, options: []) - .removeDuplicates() - .map(\.newValue) - .map { $0?.value } - .collect(expectedArray.count) - .sink { result in - print("Result array: \(result)") - - if result == expectedArray { - expect.fulfill() - } else { - XCTFail("Expected Array is not matched") - } - } - - for item in inputArray { - Defaults[key] = ExamplePersistentHistory(value: item) - } - - Defaults.reset(key) - cancellable.cancel() - - waitForExpectations(timeout: 10) - } - - func testObserveKey() { - let key = Defaults.Key("observeNSSecureCodingKey", default: persistentHistoryValue) - let newPersistentHistory = ExamplePersistentHistory(value: "NewValue") - let expect = expectation(description: "Observation closure being called") - - var observation: Defaults.Observation! - observation = Defaults.observe(key, options: []) { change in - XCTAssertEqual(change.oldValue.value, persistentHistoryValue.value) - XCTAssertEqual(change.newValue.value, newPersistentHistory.value) - observation.invalidate() - expect.fulfill() - } - - Defaults[key] = newPersistentHistory - observation.invalidate() - - waitForExpectations(timeout: 10) - } - - func testObserveOptionalKey() { - let key = Defaults.Key("observeNSSecureCodingOptionalKey") - let expect = expectation(description: "Observation closure being called") - - var observation: Defaults.Observation! - observation = Defaults.observe(key, options: []) { change in - XCTAssertNil(change.oldValue) - XCTAssertEqual(change.newValue?.value, persistentHistoryValue.value) - observation.invalidate() - expect.fulfill() - } - - Defaults[key] = persistentHistoryValue - observation.invalidate() - - waitForExpectations(timeout: 10) - } - - func testObserveArrayKey() { - let key = Defaults.Key<[ExamplePersistentHistory]>("observeNSSecureCodingArrayKey", default: [persistentHistoryValue]) - let newPersistentHistory = ExamplePersistentHistory(value: "NewValue") - let expect = expectation(description: "Observation closure being called") - - var observation: Defaults.Observation! - observation = Defaults.observe(key, options: []) { change in - XCTAssertEqual(change.oldValue[0].value, persistentHistoryValue.value) - XCTAssertEqual(change.newValue.map(\.value), [persistentHistoryValue, newPersistentHistory].map(\.value)) - observation.invalidate() - expect.fulfill() - } - - Defaults[key].append(newPersistentHistory) - observation.invalidate() - - waitForExpectations(timeout: 10) - } - - func testObserveDictionaryKey() { - let key = Defaults.Key<[String: ExamplePersistentHistory]>("observeNSSecureCodingDictionaryKey", default: ["0": persistentHistoryValue]) - let newPersistentHistory = ExamplePersistentHistory(value: "NewValue") - let expect = expectation(description: "Observation closure being called") - - var observation: Defaults.Observation! - observation = Defaults.observe(key, options: []) { change in - XCTAssertEqual(change.oldValue["0"]?.value, persistentHistoryValue.value) - XCTAssertEqual(change.newValue["0"]?.value, persistentHistoryValue.value) - XCTAssertEqual(change.newValue["1"]?.value, newPersistentHistory.value) - - observation.invalidate() - expect.fulfill() - } - - Defaults[key]["1"] = newPersistentHistory - observation.invalidate() - - waitForExpectations(timeout: 10) + #expect(Defaults[.persistentHistoryDictionary]["0"]?.value == newPersistentHistory.value) } } diff --git a/Tests/DefaultsTests/DefaultsRangeTests.swift b/Tests/DefaultsTests/DefaultsRangeTests.swift index 5b60354..8b1c71b 100644 --- a/Tests/DefaultsTests/DefaultsRangeTests.swift +++ b/Tests/DefaultsTests/DefaultsRangeTests.swift @@ -1,6 +1,8 @@ import Foundation +import Testing import Defaults -import XCTest + +private let suite_ = createSuite() private struct CustomDate { let year: Int @@ -36,11 +38,11 @@ extension CustomDate: Defaults.Serializable { extension CustomDate: Comparable { static func < (lhs: CustomDate, rhs: CustomDate) -> Bool { if lhs.year != rhs.year { - return lhs.year < rhs.year + return lhs.year < rhs.year } if lhs.month != rhs.month { - return lhs.month < rhs.month + return lhs.month < rhs.month } return lhs.day < rhs.day @@ -48,7 +50,7 @@ extension CustomDate: Comparable { static func == (lhs: CustomDate, rhs: CustomDate) -> Bool { lhs.year == rhs.year && lhs.month == rhs.month - && lhs.day == rhs.day + && lhs.day == rhs.day } } @@ -62,162 +64,165 @@ private let nextFixtureClosedRange = 1...20 private let fixtureDateClosedRange = CustomDate(year: 2022, month: 4, day: 0)...CustomDate(year: 2022, month: 5, day: 0) private let nextFixtureDateClosedRange = CustomDate(year: 2022, month: 6, day: 1)...CustomDate(year: 2022, month: 7, day: 1) -final class DefaultsClosedRangeTests: XCTestCase { - override func setUp() { - super.setUp() - Defaults.removeAll() +@Suite(.serialized) +final class DefaultsClosedRangeTests { + init() { + Defaults.removeAll(suite: suite_) } - override func tearDown() { - super.tearDown() - Defaults.removeAll() + deinit { + Defaults.removeAll(suite: suite_) } + @Test func testKey() { // Test native support Range type - let key = Defaults.Key("independentRangeKey", default: fixtureRange) - XCTAssertEqual(fixtureRange.upperBound, Defaults[key].upperBound) - XCTAssertEqual(fixtureRange.lowerBound, Defaults[key].lowerBound) + let key = Defaults.Key("independentRangeKey", default: fixtureRange, suite: suite_) + #expect(fixtureRange.upperBound == Defaults[key].upperBound) + #expect(fixtureRange.lowerBound == Defaults[key].lowerBound) Defaults[key] = nextFixtureRange - XCTAssertEqual(nextFixtureRange.upperBound, Defaults[key].upperBound) - XCTAssertEqual(nextFixtureRange.lowerBound, Defaults[key].lowerBound) + #expect(nextFixtureRange.upperBound == Defaults[key].upperBound) + #expect(nextFixtureRange.lowerBound == Defaults[key].lowerBound) // Test serializable Range type - let dateKey = Defaults.Key>("independentRangeDateKey", default: fixtureDateRange) - XCTAssertEqual(fixtureDateRange.upperBound, Defaults[dateKey].upperBound) - XCTAssertEqual(fixtureDateRange.lowerBound, Defaults[dateKey].lowerBound) + let dateKey = Defaults.Key>("independentRangeDateKey", default: fixtureDateRange, suite: suite_) + #expect(fixtureDateRange.upperBound == Defaults[dateKey].upperBound) + #expect(fixtureDateRange.lowerBound == Defaults[dateKey].lowerBound) Defaults[dateKey] = nextFixtureDateRange - XCTAssertEqual(nextFixtureDateRange.upperBound, Defaults[dateKey].upperBound) - XCTAssertEqual(nextFixtureDateRange.lowerBound, Defaults[dateKey].lowerBound) + #expect(nextFixtureDateRange.upperBound == Defaults[dateKey].upperBound) + #expect(nextFixtureDateRange.lowerBound == Defaults[dateKey].lowerBound) // Test native support ClosedRange type - let closedKey = Defaults.Key("independentClosedRangeKey", default: fixtureClosedRange) - XCTAssertEqual(fixtureClosedRange.upperBound, Defaults[closedKey].upperBound) - XCTAssertEqual(fixtureClosedRange.lowerBound, Defaults[closedKey].lowerBound) + let closedKey = Defaults.Key("independentClosedRangeKey", default: fixtureClosedRange, suite: suite_) + #expect(fixtureClosedRange.upperBound == Defaults[closedKey].upperBound) + #expect(fixtureClosedRange.lowerBound == Defaults[closedKey].lowerBound) Defaults[closedKey] = nextFixtureClosedRange - XCTAssertEqual(nextFixtureClosedRange.upperBound, Defaults[closedKey].upperBound) - XCTAssertEqual(nextFixtureClosedRange.lowerBound, Defaults[closedKey].lowerBound) + #expect(nextFixtureClosedRange.upperBound == Defaults[closedKey].upperBound) + #expect(nextFixtureClosedRange.lowerBound == Defaults[closedKey].lowerBound) // Test serializable ClosedRange type - let closedDateKey = Defaults.Key>("independentClosedRangeDateKey", default: fixtureDateClosedRange) - XCTAssertEqual(fixtureDateClosedRange.upperBound, Defaults[closedDateKey].upperBound) - XCTAssertEqual(fixtureDateClosedRange.lowerBound, Defaults[closedDateKey].lowerBound) + let closedDateKey = Defaults.Key>("independentClosedRangeDateKey", default: fixtureDateClosedRange, suite: suite_) + #expect(fixtureDateClosedRange.upperBound == Defaults[closedDateKey].upperBound) + #expect(fixtureDateClosedRange.lowerBound == Defaults[closedDateKey].lowerBound) Defaults[closedDateKey] = nextFixtureDateClosedRange - XCTAssertEqual(nextFixtureDateClosedRange.upperBound, Defaults[closedDateKey].upperBound) - XCTAssertEqual(nextFixtureDateClosedRange.lowerBound, Defaults[closedDateKey].lowerBound) + #expect(nextFixtureDateClosedRange.upperBound == Defaults[closedDateKey].upperBound) + #expect(nextFixtureDateClosedRange.lowerBound == Defaults[closedDateKey].lowerBound) } + @Test func testOptionalKey() { // Test native support Range type - let key = Defaults.Key?>("independentRangeOptionalKey") - XCTAssertNil(Defaults[key]) + let key = Defaults.Key?>("independentRangeOptionalKey", suite: suite_) + #expect(Defaults[key] == nil) Defaults[key] = fixtureRange - XCTAssertEqual(fixtureRange.upperBound, Defaults[key]?.upperBound) - XCTAssertEqual(fixtureRange.lowerBound, Defaults[key]?.lowerBound) + #expect(fixtureRange.upperBound == Defaults[key]?.upperBound) + #expect(fixtureRange.lowerBound == Defaults[key]?.lowerBound) // Test serializable Range type - let dateKey = Defaults.Key?>("independentRangeDateOptionalKey") - XCTAssertNil(Defaults[dateKey]) + let dateKey = Defaults.Key?>("independentRangeDateOptionalKey", suite: suite_) + #expect(Defaults[dateKey] == nil) Defaults[dateKey] = fixtureDateRange - XCTAssertEqual(fixtureDateRange.upperBound, Defaults[dateKey]?.upperBound) - XCTAssertEqual(fixtureDateRange.lowerBound, Defaults[dateKey]?.lowerBound) + #expect(fixtureDateRange.upperBound == Defaults[dateKey]?.upperBound) + #expect(fixtureDateRange.lowerBound == Defaults[dateKey]?.lowerBound) // Test native support ClosedRange type - let closedKey = Defaults.Key?>("independentClosedRangeOptionalKey") - XCTAssertNil(Defaults[closedKey]) + let closedKey = Defaults.Key?>("independentClosedRangeOptionalKey", suite: suite_) + #expect(Defaults[closedKey] == nil) Defaults[closedKey] = fixtureClosedRange - XCTAssertEqual(fixtureClosedRange.upperBound, Defaults[closedKey]?.upperBound) - XCTAssertEqual(fixtureClosedRange.lowerBound, Defaults[closedKey]?.lowerBound) + #expect(fixtureClosedRange.upperBound == Defaults[closedKey]?.upperBound) + #expect(fixtureClosedRange.lowerBound == Defaults[closedKey]?.lowerBound) // Test serializable ClosedRange type - let closedDateKey = Defaults.Key?>("independentClosedRangeDateOptionalKey") - XCTAssertNil(Defaults[closedDateKey]) + let closedDateKey = Defaults.Key?>("independentClosedRangeDateOptionalKey", suite: suite_) + #expect(Defaults[closedDateKey] == nil) Defaults[closedDateKey] = fixtureDateClosedRange - XCTAssertEqual(fixtureDateClosedRange.upperBound, Defaults[closedDateKey]?.upperBound) - XCTAssertEqual(fixtureDateClosedRange.lowerBound, Defaults[closedDateKey]?.lowerBound) + #expect(fixtureDateClosedRange.upperBound == Defaults[closedDateKey]?.upperBound) + #expect(fixtureDateClosedRange.lowerBound == Defaults[closedDateKey]?.lowerBound) } + @Test func testArrayKey() { // Test native support Range type - let key = Defaults.Key<[Range]>("independentRangeArrayKey", default: [fixtureRange]) - XCTAssertEqual(fixtureRange.upperBound, Defaults[key][0].upperBound) - XCTAssertEqual(fixtureRange.lowerBound, Defaults[key][0].lowerBound) + let key = Defaults.Key<[Range]>("independentRangeArrayKey", default: [fixtureRange], suite: suite_) + #expect(fixtureRange.upperBound == Defaults[key][0].upperBound) + #expect(fixtureRange.lowerBound == Defaults[key][0].lowerBound) Defaults[key].append(nextFixtureRange) - XCTAssertEqual(fixtureRange.upperBound, Defaults[key][0].upperBound) - XCTAssertEqual(fixtureRange.lowerBound, Defaults[key][0].lowerBound) - XCTAssertEqual(nextFixtureRange.upperBound, Defaults[key][1].upperBound) - XCTAssertEqual(nextFixtureRange.lowerBound, Defaults[key][1].lowerBound) + #expect(fixtureRange.upperBound == Defaults[key][0].upperBound) + #expect(fixtureRange.lowerBound == Defaults[key][0].lowerBound) + #expect(nextFixtureRange.upperBound == Defaults[key][1].upperBound) + #expect(nextFixtureRange.lowerBound == Defaults[key][1].lowerBound) // Test serializable Range type - let dateKey = Defaults.Key<[Range]>("independentRangeDateArrayKey", default: [fixtureDateRange]) - XCTAssertEqual(fixtureDateRange.upperBound, Defaults[dateKey][0].upperBound) - XCTAssertEqual(fixtureDateRange.lowerBound, Defaults[dateKey][0].lowerBound) + let dateKey = Defaults.Key<[Range]>("independentRangeDateArrayKey", default: [fixtureDateRange], suite: suite_) + #expect(fixtureDateRange.upperBound == Defaults[dateKey][0].upperBound) + #expect(fixtureDateRange.lowerBound == Defaults[dateKey][0].lowerBound) Defaults[dateKey].append(nextFixtureDateRange) - XCTAssertEqual(fixtureDateRange.upperBound, Defaults[dateKey][0].upperBound) - XCTAssertEqual(fixtureDateRange.lowerBound, Defaults[dateKey][0].lowerBound) - XCTAssertEqual(nextFixtureDateRange.upperBound, Defaults[dateKey][1].upperBound) - XCTAssertEqual(nextFixtureDateRange.lowerBound, Defaults[dateKey][1].lowerBound) + #expect(fixtureDateRange.upperBound == Defaults[dateKey][0].upperBound) + #expect(fixtureDateRange.lowerBound == Defaults[dateKey][0].lowerBound) + #expect(nextFixtureDateRange.upperBound == Defaults[dateKey][1].upperBound) + #expect(nextFixtureDateRange.lowerBound == Defaults[dateKey][1].lowerBound) // Test native support ClosedRange type - let closedKey = Defaults.Key<[ClosedRange]>("independentClosedRangeArrayKey", default: [fixtureClosedRange]) - XCTAssertEqual(fixtureClosedRange.upperBound, Defaults[closedKey][0].upperBound) - XCTAssertEqual(fixtureClosedRange.lowerBound, Defaults[closedKey][0].lowerBound) + let closedKey = Defaults.Key<[ClosedRange]>("independentClosedRangeArrayKey", default: [fixtureClosedRange], suite: suite_) + #expect(fixtureClosedRange.upperBound == Defaults[closedKey][0].upperBound) + #expect(fixtureClosedRange.lowerBound == Defaults[closedKey][0].lowerBound) Defaults[closedKey].append(nextFixtureClosedRange) - XCTAssertEqual(fixtureClosedRange.upperBound, Defaults[closedKey][0].upperBound) - XCTAssertEqual(fixtureClosedRange.lowerBound, Defaults[closedKey][0].lowerBound) - XCTAssertEqual(nextFixtureClosedRange.upperBound, Defaults[closedKey][1].upperBound) - XCTAssertEqual(nextFixtureClosedRange.lowerBound, Defaults[closedKey][1].lowerBound) + #expect(fixtureClosedRange.upperBound == Defaults[closedKey][0].upperBound) + #expect(fixtureClosedRange.lowerBound == Defaults[closedKey][0].lowerBound) + #expect(nextFixtureClosedRange.upperBound == Defaults[closedKey][1].upperBound) + #expect(nextFixtureClosedRange.lowerBound == Defaults[closedKey][1].lowerBound) // Test serializable ClosedRange type - let closedDateKey = Defaults.Key<[ClosedRange]>("independentClosedRangeDateArrayKey", default: [fixtureDateClosedRange]) - XCTAssertEqual(fixtureDateClosedRange.upperBound, Defaults[closedDateKey][0].upperBound) - XCTAssertEqual(fixtureDateClosedRange.lowerBound, Defaults[closedDateKey][0].lowerBound) + let closedDateKey = Defaults.Key<[ClosedRange]>("independentClosedRangeDateArrayKey", default: [fixtureDateClosedRange], suite: suite_) + #expect(fixtureDateClosedRange.upperBound == Defaults[closedDateKey][0].upperBound) + #expect(fixtureDateClosedRange.lowerBound == Defaults[closedDateKey][0].lowerBound) Defaults[closedDateKey].append(nextFixtureDateClosedRange) - XCTAssertEqual(fixtureDateClosedRange.upperBound, Defaults[closedDateKey][0].upperBound) - XCTAssertEqual(fixtureDateClosedRange.lowerBound, Defaults[closedDateKey][0].lowerBound) - XCTAssertEqual(nextFixtureDateClosedRange.upperBound, Defaults[closedDateKey][1].upperBound) - XCTAssertEqual(nextFixtureDateClosedRange.lowerBound, Defaults[closedDateKey][1].lowerBound) + #expect(fixtureDateClosedRange.upperBound == Defaults[closedDateKey][0].upperBound) + #expect(fixtureDateClosedRange.lowerBound == Defaults[closedDateKey][0].lowerBound) + #expect(nextFixtureDateClosedRange.upperBound == Defaults[closedDateKey][1].upperBound) + #expect(nextFixtureDateClosedRange.lowerBound == Defaults[closedDateKey][1].lowerBound) } + @Test func testDictionaryKey() { // Test native support Range type - let key = Defaults.Key<[String: Range]>("independentRangeDictionaryKey", default: ["0": fixtureRange]) - XCTAssertEqual(fixtureRange.upperBound, Defaults[key]["0"]?.upperBound) - XCTAssertEqual(fixtureRange.lowerBound, Defaults[key]["0"]?.lowerBound) + let key = Defaults.Key<[String: Range]>("independentRangeDictionaryKey", default: ["0": fixtureRange], suite: suite_) + #expect(fixtureRange.upperBound == Defaults[key]["0"]?.upperBound) + #expect(fixtureRange.lowerBound == Defaults[key]["0"]?.lowerBound) Defaults[key]["1"] = nextFixtureRange - XCTAssertEqual(fixtureRange.upperBound, Defaults[key]["0"]?.upperBound) - XCTAssertEqual(fixtureRange.lowerBound, Defaults[key]["0"]?.lowerBound) - XCTAssertEqual(nextFixtureRange.upperBound, Defaults[key]["1"]?.upperBound) - XCTAssertEqual(nextFixtureRange.lowerBound, Defaults[key]["1"]?.lowerBound) + #expect(fixtureRange.upperBound == Defaults[key]["0"]?.upperBound) + #expect(fixtureRange.lowerBound == Defaults[key]["0"]?.lowerBound) + #expect(nextFixtureRange.upperBound == Defaults[key]["1"]?.upperBound) + #expect(nextFixtureRange.lowerBound == Defaults[key]["1"]?.lowerBound) // Test serializable Range type - let dateKey = Defaults.Key<[String: Range]>("independentRangeDateDictionaryKey", default: ["0": fixtureDateRange]) - XCTAssertEqual(fixtureDateRange.upperBound, Defaults[dateKey]["0"]?.upperBound) - XCTAssertEqual(fixtureDateRange.lowerBound, Defaults[dateKey]["0"]?.lowerBound) + let dateKey = Defaults.Key<[String: Range]>("independentRangeDateDictionaryKey", default: ["0": fixtureDateRange], suite: suite_) + #expect(fixtureDateRange.upperBound == Defaults[dateKey]["0"]?.upperBound) + #expect(fixtureDateRange.lowerBound == Defaults[dateKey]["0"]?.lowerBound) Defaults[dateKey]["1"] = nextFixtureDateRange - XCTAssertEqual(fixtureDateRange.upperBound, Defaults[dateKey]["0"]?.upperBound) - XCTAssertEqual(fixtureDateRange.lowerBound, Defaults[dateKey]["0"]?.lowerBound) - XCTAssertEqual(nextFixtureDateRange.upperBound, Defaults[dateKey]["1"]?.upperBound) - XCTAssertEqual(nextFixtureDateRange.lowerBound, Defaults[dateKey]["1"]?.lowerBound) + #expect(fixtureDateRange.upperBound == Defaults[dateKey]["0"]?.upperBound) + #expect(fixtureDateRange.lowerBound == Defaults[dateKey]["0"]?.lowerBound) + #expect(nextFixtureDateRange.upperBound == Defaults[dateKey]["1"]?.upperBound) + #expect(nextFixtureDateRange.lowerBound == Defaults[dateKey]["1"]?.lowerBound) // Test native support ClosedRange type - let closedKey = Defaults.Key<[String: ClosedRange]>("independentClosedRangeDictionaryKey", default: ["0": fixtureClosedRange]) - XCTAssertEqual(fixtureClosedRange.upperBound, Defaults[closedKey]["0"]?.upperBound) - XCTAssertEqual(fixtureClosedRange.lowerBound, Defaults[closedKey]["0"]?.lowerBound) + let closedKey = Defaults.Key<[String: ClosedRange]>("independentClosedRangeDictionaryKey", default: ["0": fixtureClosedRange], suite: suite_) + #expect(fixtureClosedRange.upperBound == Defaults[closedKey]["0"]?.upperBound) + #expect(fixtureClosedRange.lowerBound == Defaults[closedKey]["0"]?.lowerBound) Defaults[closedKey]["1"] = nextFixtureClosedRange - XCTAssertEqual(fixtureClosedRange.upperBound, Defaults[closedKey]["0"]?.upperBound) - XCTAssertEqual(fixtureClosedRange.lowerBound, Defaults[closedKey]["0"]?.lowerBound) - XCTAssertEqual(nextFixtureClosedRange.upperBound, Defaults[closedKey]["1"]?.upperBound) - XCTAssertEqual(nextFixtureClosedRange.lowerBound, Defaults[closedKey]["1"]?.lowerBound) + #expect(fixtureClosedRange.upperBound == Defaults[closedKey]["0"]?.upperBound) + #expect(fixtureClosedRange.lowerBound == Defaults[closedKey]["0"]?.lowerBound) + #expect(nextFixtureClosedRange.upperBound == Defaults[closedKey]["1"]?.upperBound) + #expect(nextFixtureClosedRange.lowerBound == Defaults[closedKey]["1"]?.lowerBound) // Test serializable ClosedRange type - let closedDateKey = Defaults.Key<[String: ClosedRange]>("independentClosedRangeDateDictionaryKey", default: ["0": fixtureDateClosedRange]) - XCTAssertEqual(fixtureDateClosedRange.upperBound, Defaults[closedDateKey]["0"]?.upperBound) - XCTAssertEqual(fixtureDateClosedRange.lowerBound, Defaults[closedDateKey]["0"]?.lowerBound) + let closedDateKey = Defaults.Key<[String: ClosedRange]>("independentClosedRangeDateDictionaryKey", default: ["0": fixtureDateClosedRange], suite: suite_) + #expect(fixtureDateClosedRange.upperBound == Defaults[closedDateKey]["0"]?.upperBound) + #expect(fixtureDateClosedRange.lowerBound == Defaults[closedDateKey]["0"]?.lowerBound) Defaults[closedDateKey]["1"] = nextFixtureDateClosedRange - XCTAssertEqual(fixtureDateClosedRange.upperBound, Defaults[closedDateKey]["0"]?.upperBound) - XCTAssertEqual(fixtureDateClosedRange.lowerBound, Defaults[closedDateKey]["0"]?.lowerBound) - XCTAssertEqual(nextFixtureDateClosedRange.upperBound, Defaults[closedDateKey]["1"]?.upperBound) - XCTAssertEqual(nextFixtureDateClosedRange.lowerBound, Defaults[closedDateKey]["1"]?.lowerBound) + #expect(fixtureDateClosedRange.upperBound == Defaults[closedDateKey]["0"]?.upperBound) + #expect(fixtureDateClosedRange.lowerBound == Defaults[closedDateKey]["0"]?.lowerBound) + #expect(nextFixtureDateClosedRange.upperBound == Defaults[closedDateKey]["1"]?.upperBound) + #expect(nextFixtureDateClosedRange.lowerBound == Defaults[closedDateKey]["1"]?.lowerBound) } } diff --git a/Tests/DefaultsTests/DefaultsSetAlgebraCustomElementTests.swift b/Tests/DefaultsTests/DefaultsSetAlgebraCustomElementTests.swift index aa151a0..cf9483c 100644 --- a/Tests/DefaultsTests/DefaultsSetAlgebraCustomElementTests.swift +++ b/Tests/DefaultsTests/DefaultsSetAlgebraCustomElementTests.swift @@ -1,7 +1,9 @@ import Foundation -import XCTest +import Testing import Defaults +private let suite_ = createSuite() + private struct Item: Equatable, Hashable { let name: String let count: UInt @@ -41,317 +43,147 @@ private let fixtureSetAlgebra2 = Item(name: "Grape", count: 30) private let fixtureSetAlgebra3 = Item(name: "Guava", count: 40) extension Defaults.Keys { - fileprivate static let setAlgebraCustomElement = Key>("setAlgebraCustomElement", default: .init([fixtureSetAlgebra])) - fileprivate static let setAlgebraCustomElementArray = Key<[DefaultsSetAlgebra]>("setAlgebraArrayCustomElement", default: [.init([fixtureSetAlgebra])]) - fileprivate static let setAlgebraCustomElementDictionary = Key<[String: DefaultsSetAlgebra]>("setAlgebraDictionaryCustomElement", default: ["0": .init([fixtureSetAlgebra])]) + fileprivate static let setAlgebraCustomElement = Key>("setAlgebraCustomElement", default: .init([fixtureSetAlgebra]), suite: suite_) + fileprivate static let setAlgebraCustomElementArray = Key<[DefaultsSetAlgebra]>("setAlgebraArrayCustomElement", default: [.init([fixtureSetAlgebra])], suite: suite_) + fileprivate static let setAlgebraCustomElementDictionary = Key<[String: DefaultsSetAlgebra]>("setAlgebraDictionaryCustomElement", default: ["0": .init([fixtureSetAlgebra])], suite: suite_) } -final class DefaultsSetAlgebraCustomElementTests: XCTestCase { - override func setUp() { - super.setUp() - Defaults.removeAll() +@Suite(.serialized) +final class DefaultsSetAlgebraCustomElementTests { + init() { + Defaults.removeAll(suite: suite_) } - override func tearDown() { - super.tearDown() - Defaults.removeAll() + deinit { + Defaults.removeAll(suite: suite_) } + @Test func testKey() { - let key = Defaults.Key>("independentSetAlgebraKey", default: .init([fixtureSetAlgebra])) + let key = Defaults.Key>("customElement_independentSetAlgebraKey", default: .init([fixtureSetAlgebra]), suite: suite_) Defaults[key].insert(fixtureSetAlgebra) - XCTAssertEqual(Defaults[key], .init([fixtureSetAlgebra])) + #expect(Defaults[key] == .init([fixtureSetAlgebra])) Defaults[key].insert(fixtureSetAlgebra1) - XCTAssertEqual(Defaults[key], .init([fixtureSetAlgebra, fixtureSetAlgebra1])) + #expect(Defaults[key] == .init([fixtureSetAlgebra, fixtureSetAlgebra1])) } + @Test func testOptionalKey() { - let key = Defaults.Key?>("independentSetAlgebraOptionalKey") - XCTAssertNil(Defaults[key]) + let key = Defaults.Key?>("customElement_independentSetAlgebraOptionalKey", suite: suite_) + #expect(Defaults[key] == nil) Defaults[key] = .init([fixtureSetAlgebra]) Defaults[key]?.insert(fixtureSetAlgebra) - XCTAssertEqual(Defaults[key], .init([fixtureSetAlgebra])) + #expect(Defaults[key] == .init([fixtureSetAlgebra])) Defaults[key]?.insert(fixtureSetAlgebra1) - XCTAssertEqual(Defaults[key], .init([fixtureSetAlgebra, fixtureSetAlgebra1])) + #expect(Defaults[key] == .init([fixtureSetAlgebra, fixtureSetAlgebra1])) } + @Test func testArrayKey() { - let key = Defaults.Key<[DefaultsSetAlgebra]>("independentSetAlgebraArrayKey", default: [.init([fixtureSetAlgebra])]) + let key = Defaults.Key<[DefaultsSetAlgebra]>("customElement_independentSetAlgebraArrayKey", default: [.init([fixtureSetAlgebra])], suite: suite_) Defaults[key][0].insert(fixtureSetAlgebra1) Defaults[key].append(.init([fixtureSetAlgebra2])) Defaults[key][1].insert(fixtureSetAlgebra3) - XCTAssertEqual(Defaults[key][0], .init([fixtureSetAlgebra, fixtureSetAlgebra1])) - XCTAssertEqual(Defaults[key][1], .init([fixtureSetAlgebra2, fixtureSetAlgebra3])) + #expect(Defaults[key][0] == .init([fixtureSetAlgebra, fixtureSetAlgebra1])) + #expect(Defaults[key][1] == .init([fixtureSetAlgebra2, fixtureSetAlgebra3])) } + @Test func testArrayOptionalKey() { - let key = Defaults.Key<[DefaultsSetAlgebra]?>("independentSetAlgebraArrayOptionalKey") // swiftlint:disable:this discouraged_optional_collection - XCTAssertNil(Defaults[key]) + let key = Defaults.Key<[DefaultsSetAlgebra]?>("customElement_independentSetAlgebraArrayOptionalKey", suite: suite_) // swiftlint:disable:this discouraged_optional_collection + #expect(Defaults[key] == nil) Defaults[key] = [.init([fixtureSetAlgebra])] Defaults[key]?[0].insert(fixtureSetAlgebra1) Defaults[key]?.append(.init([fixtureSetAlgebra2])) Defaults[key]?[1].insert(fixtureSetAlgebra3) - XCTAssertEqual(Defaults[key]?[0], .init([fixtureSetAlgebra, fixtureSetAlgebra1])) - XCTAssertEqual(Defaults[key]?[1], .init([fixtureSetAlgebra2, fixtureSetAlgebra3])) + #expect(Defaults[key]?[0] == .init([fixtureSetAlgebra, fixtureSetAlgebra1])) + #expect(Defaults[key]?[1] == .init([fixtureSetAlgebra2, fixtureSetAlgebra3])) } + @Test func testNestedArrayKey() { - let key = Defaults.Key<[[DefaultsSetAlgebra]]>("independentSetAlgebraNestedArrayKey", default: [[.init([fixtureSetAlgebra])]]) + let key = Defaults.Key<[[DefaultsSetAlgebra]]>("customElement_independentSetAlgebraNestedArrayKey", default: [[.init([fixtureSetAlgebra])]], suite: suite_) Defaults[key][0][0].insert(fixtureSetAlgebra1) Defaults[key][0].append(.init([fixtureSetAlgebra1])) Defaults[key][0][1].insert(fixtureSetAlgebra2) Defaults[key].append([.init([fixtureSetAlgebra3])]) Defaults[key][1][0].insert(fixtureSetAlgebra2) - XCTAssertEqual(Defaults[key][0][0], .init([fixtureSetAlgebra, fixtureSetAlgebra1])) - XCTAssertEqual(Defaults[key][0][1], .init([fixtureSetAlgebra1, fixtureSetAlgebra2])) - XCTAssertEqual(Defaults[key][1][0], .init([fixtureSetAlgebra2, fixtureSetAlgebra3])) + #expect(Defaults[key][0][0] == .init([fixtureSetAlgebra, fixtureSetAlgebra1])) + #expect(Defaults[key][0][1] == .init([fixtureSetAlgebra1, fixtureSetAlgebra2])) + #expect(Defaults[key][1][0] == .init([fixtureSetAlgebra2, fixtureSetAlgebra3])) } + @Test func testArrayDictionaryKey() { - let key = Defaults.Key<[[String: DefaultsSetAlgebra]]>("independentSetAlgebraArrayDictionaryKey", default: [["0": .init([fixtureSetAlgebra])]]) + let key = Defaults.Key<[[String: DefaultsSetAlgebra]]>("customElement_independentSetAlgebraArrayDictionaryKey", default: [["0": .init([fixtureSetAlgebra])]], suite: suite_) Defaults[key][0]["0"]?.insert(fixtureSetAlgebra1) Defaults[key][0]["1"] = .init([fixtureSetAlgebra1]) Defaults[key][0]["1"]?.insert(fixtureSetAlgebra2) Defaults[key].append(["0": .init([fixtureSetAlgebra3])]) Defaults[key][1]["0"]?.insert(fixtureSetAlgebra2) - XCTAssertEqual(Defaults[key][0]["0"], .init([fixtureSetAlgebra, fixtureSetAlgebra1])) - XCTAssertEqual(Defaults[key][0]["1"], .init([fixtureSetAlgebra1, fixtureSetAlgebra2])) - XCTAssertEqual(Defaults[key][1]["0"], .init([fixtureSetAlgebra2, fixtureSetAlgebra3])) + #expect(Defaults[key][0]["0"] == .init([fixtureSetAlgebra, fixtureSetAlgebra1])) + #expect(Defaults[key][0]["1"] == .init([fixtureSetAlgebra1, fixtureSetAlgebra2])) + #expect(Defaults[key][1]["0"] == .init([fixtureSetAlgebra2, fixtureSetAlgebra3])) } + @Test func testDictionaryKey() { - let key = Defaults.Key<[String: DefaultsSetAlgebra]>("independentSetAlgebraDictionaryKey", default: ["0": .init([fixtureSetAlgebra])]) + let key = Defaults.Key<[String: DefaultsSetAlgebra]>("customElement_independentSetAlgebraDictionaryKey", default: ["0": .init([fixtureSetAlgebra])], suite: suite_) Defaults[key]["0"]?.insert(fixtureSetAlgebra1) Defaults[key]["1"] = .init([fixtureSetAlgebra2]) Defaults[key]["1"]?.insert(fixtureSetAlgebra3) - XCTAssertEqual(Defaults[key]["0"], .init([fixtureSetAlgebra, fixtureSetAlgebra1])) - XCTAssertEqual(Defaults[key]["1"], .init([fixtureSetAlgebra2, fixtureSetAlgebra3])) + #expect(Defaults[key]["0"] == .init([fixtureSetAlgebra, fixtureSetAlgebra1])) + #expect(Defaults[key]["1"] == .init([fixtureSetAlgebra2, fixtureSetAlgebra3])) } + @Test func testDictionaryOptionalKey() { - let key = Defaults.Key<[String: DefaultsSetAlgebra]?>("independentSetAlgebraDictionaryOptionalKey") // swiftlint:disable:this discouraged_optional_collection - XCTAssertNil(Defaults[key]) + let key = Defaults.Key<[String: DefaultsSetAlgebra]?>("customElement_independentSetAlgebraDictionaryOptionalKey", suite: suite_) // swiftlint:disable:this discouraged_optional_collection + #expect(Defaults[key] == nil) Defaults[key] = ["0": .init([fixtureSetAlgebra])] Defaults[key]?["0"]?.insert(fixtureSetAlgebra1) Defaults[key]?["1"] = .init([fixtureSetAlgebra2]) Defaults[key]?["1"]?.insert(fixtureSetAlgebra3) - XCTAssertEqual(Defaults[key]?["0"], .init([fixtureSetAlgebra, fixtureSetAlgebra1])) - XCTAssertEqual(Defaults[key]?["1"], .init([fixtureSetAlgebra2, fixtureSetAlgebra3])) + #expect(Defaults[key]?["0"] == .init([fixtureSetAlgebra, fixtureSetAlgebra1])) + #expect(Defaults[key]?["1"] == .init([fixtureSetAlgebra2, fixtureSetAlgebra3])) } + @Test func testDictionaryArrayKey() { - let key = Defaults.Key<[String: [DefaultsSetAlgebra]]>("independentSetAlgebraDictionaryArrayKey", default: ["0": [.init([fixtureSetAlgebra])]]) + let key = Defaults.Key<[String: [DefaultsSetAlgebra]]>("customElement_independentSetAlgebraDictionaryArrayKey", default: ["0": [.init([fixtureSetAlgebra])]], suite: suite_) Defaults[key]["0"]?[0].insert(fixtureSetAlgebra1) Defaults[key]["0"]?.append(.init([fixtureSetAlgebra1])) Defaults[key]["0"]?[1].insert(fixtureSetAlgebra2) Defaults[key]["1"] = [.init([fixtureSetAlgebra3])] Defaults[key]["1"]?[0].insert(fixtureSetAlgebra2) - XCTAssertEqual(Defaults[key]["0"]?[0], .init([fixtureSetAlgebra, fixtureSetAlgebra1])) - XCTAssertEqual(Defaults[key]["0"]?[1], .init([fixtureSetAlgebra1, fixtureSetAlgebra2])) - XCTAssertEqual(Defaults[key]["1"]?[0], .init([fixtureSetAlgebra2, fixtureSetAlgebra3])) + #expect(Defaults[key]["0"]?[0] == .init([fixtureSetAlgebra, fixtureSetAlgebra1])) + #expect(Defaults[key]["0"]?[1] == .init([fixtureSetAlgebra1, fixtureSetAlgebra2])) + #expect(Defaults[key]["1"]?[0] == .init([fixtureSetAlgebra2, fixtureSetAlgebra3])) } + @Test func testType() { let (inserted, _) = Defaults[.setAlgebraCustomElement].insert(fixtureSetAlgebra) - XCTAssertFalse(inserted) + #expect(!inserted) Defaults[.setAlgebraCustomElement].insert(fixtureSetAlgebra1) - XCTAssertEqual(Defaults[.setAlgebraCustomElement], .init([fixtureSetAlgebra, fixtureSetAlgebra1])) + #expect(Defaults[.setAlgebraCustomElement] == .init([fixtureSetAlgebra, fixtureSetAlgebra1])) } + @Test func testArrayType() { Defaults[.setAlgebraCustomElementArray][0].insert(fixtureSetAlgebra1) Defaults[.setAlgebraCustomElementArray].append(.init([fixtureSetAlgebra2])) Defaults[.setAlgebraCustomElementArray][1].insert(fixtureSetAlgebra3) - XCTAssertEqual(Defaults[.setAlgebraCustomElementArray][0], .init([fixtureSetAlgebra, fixtureSetAlgebra1])) - XCTAssertEqual(Defaults[.setAlgebraCustomElementArray][1], .init([fixtureSetAlgebra2, fixtureSetAlgebra3])) + #expect(Defaults[.setAlgebraCustomElementArray][0] == .init([fixtureSetAlgebra, fixtureSetAlgebra1])) + #expect(Defaults[.setAlgebraCustomElementArray][1] == .init([fixtureSetAlgebra2, fixtureSetAlgebra3])) } + @Test func testDictionaryType() { Defaults[.setAlgebraCustomElementDictionary]["0"]?.insert(fixtureSetAlgebra1) Defaults[.setAlgebraCustomElementDictionary]["1"] = .init([fixtureSetAlgebra2]) Defaults[.setAlgebraCustomElementDictionary]["1"]?.insert(fixtureSetAlgebra3) - XCTAssertEqual(Defaults[.setAlgebraCustomElementDictionary]["0"], .init([fixtureSetAlgebra, fixtureSetAlgebra1])) - XCTAssertEqual(Defaults[.setAlgebraCustomElementDictionary]["1"], .init([fixtureSetAlgebra2, fixtureSetAlgebra3])) - } - - func testObserveKeyCombine() { - let key = Defaults.Key>("observeSetAlgebraKeyCombine", default: .init([fixtureSetAlgebra])) - let expect = expectation(description: "Observation closure being called") - - let publisher = Defaults - .publisher(key, options: []) - .map { ($0.oldValue, $0.newValue) } - .collect(2) - - let expectedValue: [(DefaultsSetAlgebra, DefaultsSetAlgebra)] = [(.init([fixtureSetAlgebra]), .init([fixtureSetAlgebra, fixtureSetAlgebra1])), (.init([fixtureSetAlgebra, fixtureSetAlgebra1]), .init([fixtureSetAlgebra]))] - - let cancellable = publisher.sink { tuples in - for (index, expected) in expectedValue.enumerated() { - XCTAssertEqual(expected.0, tuples[index].0) - XCTAssertEqual(expected.1, tuples[index].1) - } - - expect.fulfill() - } - - Defaults[key].insert(fixtureSetAlgebra1) - Defaults.reset(key) - cancellable.cancel() - - waitForExpectations(timeout: 10) - } - - func testObserveOptionalKeyCombine() { - let key = Defaults.Key?>("observeSetAlgebraOptionalKeyCombine") - let expect = expectation(description: "Observation closure being called") - - let publisher = Defaults - .publisher(key, options: []) - .map { ($0.oldValue, $0.newValue) } - .collect(3) - - let expectedValue: [(DefaultsSetAlgebra?, DefaultsSetAlgebra?)] = [(nil, .init([fixtureSetAlgebra])), (.init([fixtureSetAlgebra]), .init([fixtureSetAlgebra, fixtureSetAlgebra1])), (.init([fixtureSetAlgebra, fixtureSetAlgebra1]), nil)] - - let cancellable = publisher.sink { tuples in - for (index, expected) in expectedValue.enumerated() { - XCTAssertEqual(expected.0, tuples[index].0) - XCTAssertEqual(expected.1, tuples[index].1) - } - - expect.fulfill() - } - - Defaults[key] = .init([fixtureSetAlgebra]) - Defaults[key]?.insert(fixtureSetAlgebra1) - Defaults.reset(key) - cancellable.cancel() - - waitForExpectations(timeout: 10) - } - - func testObserveArrayKeyCombine() { - let key = Defaults.Key<[DefaultsSetAlgebra]>("observeSetAlgebraArrayKeyCombine", default: [.init([fixtureSetAlgebra])]) - let expect = expectation(description: "Observation closure being called") - - let publisher = Defaults - .publisher(key, options: []) - .map { ($0.oldValue, $0.newValue) } - .collect(2) - - let expectedValue: [(DefaultsSetAlgebra, DefaultsSetAlgebra)] = [(.init([fixtureSetAlgebra]), .init([fixtureSetAlgebra, fixtureSetAlgebra1])), (.init([fixtureSetAlgebra, fixtureSetAlgebra1]), .init([fixtureSetAlgebra]))] - - let cancellable = publisher.sink { tuples in - for (index, expected) in expectedValue.enumerated() { - XCTAssertEqual(expected.0, tuples[index].0[0]) - XCTAssertEqual(expected.1, tuples[index].1[0]) - } - - expect.fulfill() - } - - Defaults[key][0].insert(fixtureSetAlgebra1) - Defaults.reset(key) - cancellable.cancel() - - waitForExpectations(timeout: 10) - } - - func testObserveDictionaryKeyCombine() { - let key = Defaults.Key<[String: DefaultsSetAlgebra]>("observeSetAlgebraDictionaryKeyCombine", default: ["0": .init([fixtureSetAlgebra])]) - let expect = expectation(description: "Observation closure being called") - - let publisher = Defaults - .publisher(key, options: []) - .map { ($0.oldValue, $0.newValue) } - .collect(2) - - let expectedValue: [(DefaultsSetAlgebra, DefaultsSetAlgebra)] = [(.init([fixtureSetAlgebra]), .init([fixtureSetAlgebra, fixtureSetAlgebra1])), (.init([fixtureSetAlgebra, fixtureSetAlgebra1]), .init([fixtureSetAlgebra]))] - - let cancellable = publisher.sink { tuples in - for (index, expected) in expectedValue.enumerated() { - XCTAssertEqual(expected.0, tuples[index].0["0"]) - XCTAssertEqual(expected.1, tuples[index].1["0"]) - } - - expect.fulfill() - } - - Defaults[key]["0"]?.insert(fixtureSetAlgebra1) - Defaults.reset(key) - cancellable.cancel() - - waitForExpectations(timeout: 10) - } - - func testObserveKey() { - let key = Defaults.Key>("observeSetAlgebraKey", default: .init([fixtureSetAlgebra])) - let expect = expectation(description: "Observation closure being called") - - var observation: Defaults.Observation! - observation = Defaults.observe(key, options: []) { change in - XCTAssertEqual(change.oldValue, .init([fixtureSetAlgebra])) - XCTAssertEqual(change.newValue, .init([fixtureSetAlgebra, fixtureSetAlgebra1])) - observation.invalidate() - expect.fulfill() - } - - Defaults[key].insert(fixtureSetAlgebra1) - observation.invalidate() - - waitForExpectations(timeout: 10) - } - - func testObserveOptionalKey() { - let key = Defaults.Key?>("observeSetAlgebraOptionalKey") - let expect = expectation(description: "Observation closure being called") - - var observation: Defaults.Observation! - observation = Defaults.observe(key, options: []) { change in - XCTAssertNil(change.oldValue) - XCTAssertEqual(change.newValue, .init([fixtureSetAlgebra])) - observation.invalidate() - expect.fulfill() - } - - Defaults[key] = .init([fixtureSetAlgebra]) - observation.invalidate() - - waitForExpectations(timeout: 10) - } - - func testObserveArrayKey() { - let key = Defaults.Key<[DefaultsSetAlgebra]>("observeSetAlgebraArrayKey", default: [.init([fixtureSetAlgebra])]) - let expect = expectation(description: "Observation closure being called") - - var observation: Defaults.Observation! - observation = Defaults.observe(key, options: []) { change in - XCTAssertEqual(change.oldValue[0], .init([fixtureSetAlgebra])) - XCTAssertEqual(change.newValue[1], .init([fixtureSetAlgebra])) - observation.invalidate() - expect.fulfill() - } - - Defaults[key].append(.init([fixtureSetAlgebra])) - observation.invalidate() - - waitForExpectations(timeout: 10) - } - - func testObserveDictioanryKey() { - let key = Defaults.Key<[String: DefaultsSetAlgebra]>("observeSetAlgebraDictionaryKey", default: ["0": .init([fixtureSetAlgebra])]) - let expect = expectation(description: "Observation closure being called") - - var observation: Defaults.Observation! - observation = Defaults.observe(key, options: []) { change in - XCTAssertEqual(change.oldValue["0"], .init([fixtureSetAlgebra])) - XCTAssertEqual(change.newValue["1"], .init([fixtureSetAlgebra])) - observation.invalidate() - expect.fulfill() - } - - Defaults[key]["1"] = .init([fixtureSetAlgebra]) - observation.invalidate() - - waitForExpectations(timeout: 10) + #expect(Defaults[.setAlgebraCustomElementDictionary]["0"] == .init([fixtureSetAlgebra, fixtureSetAlgebra1])) + #expect(Defaults[.setAlgebraCustomElementDictionary]["1"] == .init([fixtureSetAlgebra2, fixtureSetAlgebra3])) } } diff --git a/Tests/DefaultsTests/DefaultsSetAlgebraTests.swift b/Tests/DefaultsTests/DefaultsSetAlgebraTests.swift index 3ccb60e..c87f6b2 100644 --- a/Tests/DefaultsTests/DefaultsSetAlgebraTests.swift +++ b/Tests/DefaultsTests/DefaultsSetAlgebraTests.swift @@ -1,7 +1,9 @@ import Foundation -import XCTest +import Testing import Defaults +private let suite_ = createSuite() + struct DefaultsSetAlgebra: SetAlgebra { var store = Set() @@ -73,317 +75,147 @@ private let fixtureSetAlgebra2 = 2 private let fixtureSetAlgebra3 = 3 extension Defaults.Keys { - fileprivate static let setAlgebra = Key>("setAlgebra", default: .init([fixtureSetAlgebra])) - fileprivate static let setAlgebraArray = Key<[DefaultsSetAlgebra]>("setAlgebraArray", default: [.init([fixtureSetAlgebra])]) - fileprivate static let setAlgebraDictionary = Key<[String: DefaultsSetAlgebra]>("setAlgebraDictionary", default: ["0": .init([fixtureSetAlgebra])]) + fileprivate static let setAlgebra = Key>("setAlgebra", default: .init([fixtureSetAlgebra]), suite: suite_) + fileprivate static let setAlgebraArray = Key<[DefaultsSetAlgebra]>("setAlgebraArray", default: [.init([fixtureSetAlgebra])], suite: suite_) + fileprivate static let setAlgebraDictionary = Key<[String: DefaultsSetAlgebra]>("setAlgebraDictionary", default: ["0": .init([fixtureSetAlgebra])], suite: suite_) } -final class DefaultsSetAlgebraTests: XCTestCase { - override func setUp() { - super.setUp() - Defaults.removeAll() +@Suite(.serialized) +final class DefaultsSetAlgebraTests { + init() { + Defaults.removeAll(suite: suite_) } - override func tearDown() { - super.tearDown() - Defaults.removeAll() + deinit { + Defaults.removeAll(suite: suite_) } + @Test func testKey() { - let key = Defaults.Key>("independentSetAlgebraKey", default: .init([fixtureSetAlgebra])) + let key = Defaults.Key>("independentSetAlgebraKey", default: .init([fixtureSetAlgebra]), suite: suite_) Defaults[key].insert(fixtureSetAlgebra) - XCTAssertEqual(Defaults[key], .init([fixtureSetAlgebra])) + #expect(Defaults[key] == .init([fixtureSetAlgebra])) Defaults[key].insert(fixtureSetAlgebra1) - XCTAssertEqual(Defaults[key], .init([fixtureSetAlgebra, fixtureSetAlgebra1])) + #expect(Defaults[key] == .init([fixtureSetAlgebra, fixtureSetAlgebra1])) } + @Test func testOptionalKey() { - let key = Defaults.Key?>("independentSetAlgebraOptionalKey") - XCTAssertNil(Defaults[key]) + let key = Defaults.Key?>("independentSetAlgebraOptionalKey", suite: suite_) + #expect(Defaults[key] == nil) Defaults[key] = .init([fixtureSetAlgebra]) Defaults[key]?.insert(fixtureSetAlgebra) - XCTAssertEqual(Defaults[key], .init([fixtureSetAlgebra])) + #expect(Defaults[key] == .init([fixtureSetAlgebra])) Defaults[key]?.insert(fixtureSetAlgebra1) - XCTAssertEqual(Defaults[key], .init([fixtureSetAlgebra, fixtureSetAlgebra1])) + #expect(Defaults[key] == .init([fixtureSetAlgebra, fixtureSetAlgebra1])) } + @Test func testArrayKey() { - let key = Defaults.Key<[DefaultsSetAlgebra]>("independentSetAlgebraArrayKey", default: [.init([fixtureSetAlgebra])]) + let key = Defaults.Key<[DefaultsSetAlgebra]>("independentSetAlgebraArrayKey", default: [.init([fixtureSetAlgebra])], suite: suite_) Defaults[key][0].insert(fixtureSetAlgebra1) Defaults[key].append(.init([fixtureSetAlgebra2])) Defaults[key][1].insert(fixtureSetAlgebra3) - XCTAssertEqual(Defaults[key][0], .init([fixtureSetAlgebra, fixtureSetAlgebra1])) - XCTAssertEqual(Defaults[key][1], .init([fixtureSetAlgebra2, fixtureSetAlgebra3])) + #expect(Defaults[key][0] == .init([fixtureSetAlgebra, fixtureSetAlgebra1])) + #expect(Defaults[key][1] == .init([fixtureSetAlgebra2, fixtureSetAlgebra3])) } + @Test func testArrayOptionalKey() { - let key = Defaults.Key<[DefaultsSetAlgebra]?>("independentSetAlgebraArrayOptionalKey") // swiftlint:disable:this discouraged_optional_collection - XCTAssertNil(Defaults[key]) + let key = Defaults.Key<[DefaultsSetAlgebra]?>("independentSetAlgebraArrayOptionalKey", suite: suite_) // swiftlint:disable:this discouraged_optional_collection + #expect(Defaults[key] == nil) Defaults[key] = [.init([fixtureSetAlgebra])] Defaults[key]?[0].insert(fixtureSetAlgebra1) Defaults[key]?.append(.init([fixtureSetAlgebra2])) Defaults[key]?[1].insert(fixtureSetAlgebra3) - XCTAssertEqual(Defaults[key]?[0], .init([fixtureSetAlgebra, fixtureSetAlgebra1])) - XCTAssertEqual(Defaults[key]?[1], .init([fixtureSetAlgebra2, fixtureSetAlgebra3])) + #expect(Defaults[key]?[0] == .init([fixtureSetAlgebra, fixtureSetAlgebra1])) + #expect(Defaults[key]?[1] == .init([fixtureSetAlgebra2, fixtureSetAlgebra3])) } + @Test func testNestedArrayKey() { - let key = Defaults.Key<[[DefaultsSetAlgebra]]>("independentSetAlgebraNestedArrayKey", default: [[.init([fixtureSetAlgebra])]]) + let key = Defaults.Key<[[DefaultsSetAlgebra]]>("independentSetAlgebraNestedArrayKey2", default: [[.init([fixtureSetAlgebra])]], suite: suite_) Defaults[key][0][0].insert(fixtureSetAlgebra1) Defaults[key][0].append(.init([fixtureSetAlgebra1])) Defaults[key][0][1].insert(fixtureSetAlgebra2) Defaults[key].append([.init([fixtureSetAlgebra3])]) Defaults[key][1][0].insert(fixtureSetAlgebra2) - XCTAssertEqual(Defaults[key][0][0], .init([fixtureSetAlgebra, fixtureSetAlgebra1])) - XCTAssertEqual(Defaults[key][0][1], .init([fixtureSetAlgebra1, fixtureSetAlgebra2])) - XCTAssertEqual(Defaults[key][1][0], .init([fixtureSetAlgebra2, fixtureSetAlgebra3])) + #expect(Defaults[key][0][0] == .init([fixtureSetAlgebra, fixtureSetAlgebra1])) + #expect(Defaults[key][0][1] == .init([fixtureSetAlgebra1, fixtureSetAlgebra2])) + #expect(Defaults[key][1][0] == .init([fixtureSetAlgebra2, fixtureSetAlgebra3])) } + @Test func testArrayDictionaryKey() { - let key = Defaults.Key<[[String: DefaultsSetAlgebra]]>("independentSetAlgebraArrayDictionaryKey", default: [["0": .init([fixtureSetAlgebra])]]) + let key = Defaults.Key<[[String: DefaultsSetAlgebra]]>("independentSetAlgebraArrayDictionaryKey", default: [["0": .init([fixtureSetAlgebra])]], suite: suite_) Defaults[key][0]["0"]?.insert(fixtureSetAlgebra1) Defaults[key][0]["1"] = .init([fixtureSetAlgebra1]) Defaults[key][0]["1"]?.insert(fixtureSetAlgebra2) Defaults[key].append(["0": .init([fixtureSetAlgebra3])]) Defaults[key][1]["0"]?.insert(fixtureSetAlgebra2) - XCTAssertEqual(Defaults[key][0]["0"], .init([fixtureSetAlgebra, fixtureSetAlgebra1])) - XCTAssertEqual(Defaults[key][0]["1"], .init([fixtureSetAlgebra1, fixtureSetAlgebra2])) - XCTAssertEqual(Defaults[key][1]["0"], .init([fixtureSetAlgebra2, fixtureSetAlgebra3])) + #expect(Defaults[key][0]["0"] == .init([fixtureSetAlgebra, fixtureSetAlgebra1])) + #expect(Defaults[key][0]["1"] == .init([fixtureSetAlgebra1, fixtureSetAlgebra2])) + #expect(Defaults[key][1]["0"] == .init([fixtureSetAlgebra2, fixtureSetAlgebra3])) } + @Test func testDictionaryKey() { - let key = Defaults.Key<[String: DefaultsSetAlgebra]>("independentSetAlgebraDictionaryKey", default: ["0": .init([fixtureSetAlgebra])]) + let key = Defaults.Key<[String: DefaultsSetAlgebra]>("independentSetAlgebraDictionaryKey", default: ["0": .init([fixtureSetAlgebra])], suite: suite_) Defaults[key]["0"]?.insert(fixtureSetAlgebra1) Defaults[key]["1"] = .init([fixtureSetAlgebra2]) Defaults[key]["1"]?.insert(fixtureSetAlgebra3) - XCTAssertEqual(Defaults[key]["0"], .init([fixtureSetAlgebra, fixtureSetAlgebra1])) - XCTAssertEqual(Defaults[key]["1"], .init([fixtureSetAlgebra2, fixtureSetAlgebra3])) + #expect(Defaults[key]["0"] == .init([fixtureSetAlgebra, fixtureSetAlgebra1])) + #expect(Defaults[key]["1"] == .init([fixtureSetAlgebra2, fixtureSetAlgebra3])) } + @Test func testDictionaryOptionalKey() { - let key = Defaults.Key<[String: DefaultsSetAlgebra]?>("independentSetAlgebraDictionaryOptionalKey") // swiftlint:disable:this discouraged_optional_collection - XCTAssertNil(Defaults[key]) + let key = Defaults.Key<[String: DefaultsSetAlgebra]?>("independentSetAlgebraDictionaryOptionalKey", suite: suite_) // swiftlint:disable:this discouraged_optional_collection + #expect(Defaults[key] == nil) Defaults[key] = ["0": .init([fixtureSetAlgebra])] Defaults[key]?["0"]?.insert(fixtureSetAlgebra1) Defaults[key]?["1"] = .init([fixtureSetAlgebra2]) Defaults[key]?["1"]?.insert(fixtureSetAlgebra3) - XCTAssertEqual(Defaults[key]?["0"], .init([fixtureSetAlgebra, fixtureSetAlgebra1])) - XCTAssertEqual(Defaults[key]?["1"], .init([fixtureSetAlgebra2, fixtureSetAlgebra3])) + #expect(Defaults[key]?["0"] == .init([fixtureSetAlgebra, fixtureSetAlgebra1])) + #expect(Defaults[key]?["1"] == .init([fixtureSetAlgebra2, fixtureSetAlgebra3])) } + @Test func testDictionaryArrayKey() { - let key = Defaults.Key<[String: [DefaultsSetAlgebra]]>("independentSetAlgebraDictionaryArrayKey", default: ["0": [.init([fixtureSetAlgebra])]]) + let key = Defaults.Key<[String: [DefaultsSetAlgebra]]>("independentSetAlgebraDictionaryArrayKey", default: ["0": [.init([fixtureSetAlgebra])]], suite: suite_) Defaults[key]["0"]?[0].insert(fixtureSetAlgebra1) Defaults[key]["0"]?.append(.init([fixtureSetAlgebra1])) Defaults[key]["0"]?[1].insert(fixtureSetAlgebra2) Defaults[key]["1"] = [.init([fixtureSetAlgebra3])] Defaults[key]["1"]?[0].insert(fixtureSetAlgebra2) - XCTAssertEqual(Defaults[key]["0"]?[0], .init([fixtureSetAlgebra, fixtureSetAlgebra1])) - XCTAssertEqual(Defaults[key]["0"]?[1], .init([fixtureSetAlgebra1, fixtureSetAlgebra2])) - XCTAssertEqual(Defaults[key]["1"]?[0], .init([fixtureSetAlgebra2, fixtureSetAlgebra3])) + #expect(Defaults[key]["0"]?[0] == .init([fixtureSetAlgebra, fixtureSetAlgebra1])) + #expect(Defaults[key]["0"]?[1] == .init([fixtureSetAlgebra1, fixtureSetAlgebra2])) + #expect(Defaults[key]["1"]?[0] == .init([fixtureSetAlgebra2, fixtureSetAlgebra3])) } + @Test func testType() { let (inserted, _) = Defaults[.setAlgebra].insert(fixtureSetAlgebra) - XCTAssertFalse(inserted) + #expect(!inserted) Defaults[.setAlgebra].insert(fixtureSetAlgebra1) - XCTAssertEqual(Defaults[.setAlgebra], .init([fixtureSetAlgebra, fixtureSetAlgebra1])) + #expect(Defaults[.setAlgebra] == .init([fixtureSetAlgebra, fixtureSetAlgebra1])) } + @Test func testArrayType() { Defaults[.setAlgebraArray][0].insert(fixtureSetAlgebra1) Defaults[.setAlgebraArray].append(.init([fixtureSetAlgebra2])) Defaults[.setAlgebraArray][1].insert(fixtureSetAlgebra3) - XCTAssertEqual(Defaults[.setAlgebraArray][0], .init([fixtureSetAlgebra, fixtureSetAlgebra1])) - XCTAssertEqual(Defaults[.setAlgebraArray][1], .init([fixtureSetAlgebra2, fixtureSetAlgebra3])) + #expect(Defaults[.setAlgebraArray][0] == .init([fixtureSetAlgebra, fixtureSetAlgebra1])) + #expect(Defaults[.setAlgebraArray][1] == .init([fixtureSetAlgebra2, fixtureSetAlgebra3])) } + @Test func testDictionaryType() { Defaults[.setAlgebraDictionary]["0"]?.insert(fixtureSetAlgebra1) Defaults[.setAlgebraDictionary]["1"] = .init([fixtureSetAlgebra2]) Defaults[.setAlgebraDictionary]["1"]?.insert(fixtureSetAlgebra3) - XCTAssertEqual(Defaults[.setAlgebraDictionary]["0"], .init([fixtureSetAlgebra, fixtureSetAlgebra1])) - XCTAssertEqual(Defaults[.setAlgebraDictionary]["1"], .init([fixtureSetAlgebra2, fixtureSetAlgebra3])) - } - - func testObserveKeyCombine() { - let key = Defaults.Key>("observeSetAlgebraKeyCombine", default: .init([fixtureSetAlgebra])) - let expect = expectation(description: "Observation closure being called") - - let publisher = Defaults - .publisher(key, options: []) - .map { ($0.oldValue, $0.newValue) } - .collect(2) - - let expectedValue: [(DefaultsSetAlgebra, DefaultsSetAlgebra)] = [(.init([fixtureSetAlgebra]), .init([fixtureSetAlgebra, fixtureSetAlgebra1])), (.init([fixtureSetAlgebra, fixtureSetAlgebra1]), .init([fixtureSetAlgebra]))] - - let cancellable = publisher.sink { tuples in - for (index, expected) in expectedValue.enumerated() { - XCTAssertEqual(expected.0, tuples[index].0) - XCTAssertEqual(expected.1, tuples[index].1) - } - - expect.fulfill() - } - - Defaults[key].insert(fixtureSetAlgebra1) - Defaults.reset(key) - cancellable.cancel() - - waitForExpectations(timeout: 10) - } - - func testObserveOptionalKeyCombine() { - let key = Defaults.Key?>("observeSetAlgebraOptionalKeyCombine") - let expect = expectation(description: "Observation closure being called") - - let publisher = Defaults - .publisher(key, options: []) - .map { ($0.oldValue, $0.newValue) } - .collect(3) - - let expectedValue: [(DefaultsSetAlgebra?, DefaultsSetAlgebra?)] = [(nil, .init([fixtureSetAlgebra])), (.init([fixtureSetAlgebra]), .init([fixtureSetAlgebra, fixtureSetAlgebra1])), (.init([fixtureSetAlgebra, fixtureSetAlgebra1]), nil)] - - let cancellable = publisher.sink { tuples in - for (index, expected) in expectedValue.enumerated() { - XCTAssertEqual(expected.0, tuples[index].0) - XCTAssertEqual(expected.1, tuples[index].1) - } - - expect.fulfill() - } - - Defaults[key] = .init([fixtureSetAlgebra]) - Defaults[key]?.insert(fixtureSetAlgebra1) - Defaults.reset(key) - cancellable.cancel() - - waitForExpectations(timeout: 10) - } - - func testObserveArrayKeyCombine() { - let key = Defaults.Key<[DefaultsSetAlgebra]>("observeSetAlgebraArrayKeyCombine", default: [.init([fixtureSetAlgebra])]) - let expect = expectation(description: "Observation closure being called") - - let publisher = Defaults - .publisher(key, options: []) - .map { ($0.oldValue, $0.newValue) } - .collect(2) - - let expectedValue: [(DefaultsSetAlgebra, DefaultsSetAlgebra)] = [(.init([fixtureSetAlgebra]), .init([fixtureSetAlgebra, fixtureSetAlgebra1])), (.init([fixtureSetAlgebra, fixtureSetAlgebra1]), .init([fixtureSetAlgebra]))] - - let cancellable = publisher.sink { tuples in - for (index, expected) in expectedValue.enumerated() { - XCTAssertEqual(expected.0, tuples[index].0[0]) - XCTAssertEqual(expected.1, tuples[index].1[0]) - } - - expect.fulfill() - } - - Defaults[key][0].insert(fixtureSetAlgebra1) - Defaults.reset(key) - cancellable.cancel() - - waitForExpectations(timeout: 10) - } - - func testObserveDictionaryKeyCombine() { - let key = Defaults.Key<[String: DefaultsSetAlgebra]>("observeSetAlgebraDictionaryKeyCombine", default: ["0": .init([fixtureSetAlgebra])]) - let expect = expectation(description: "Observation closure being called") - - let publisher = Defaults - .publisher(key, options: []) - .map { ($0.oldValue, $0.newValue) } - .collect(2) - - let expectedValue: [(DefaultsSetAlgebra, DefaultsSetAlgebra)] = [(.init([fixtureSetAlgebra]), .init([fixtureSetAlgebra, fixtureSetAlgebra1])), (.init([fixtureSetAlgebra, fixtureSetAlgebra1]), .init([fixtureSetAlgebra]))] - - let cancellable = publisher.sink { tuples in - for (index, expected) in expectedValue.enumerated() { - XCTAssertEqual(expected.0, tuples[index].0["0"]) - XCTAssertEqual(expected.1, tuples[index].1["0"]) - } - - expect.fulfill() - } - - Defaults[key]["0"]?.insert(fixtureSetAlgebra1) - Defaults.reset(key) - cancellable.cancel() - - waitForExpectations(timeout: 10) - } - - func testObserveKey() { - let key = Defaults.Key>("observeSetAlgebraKey", default: .init([fixtureSetAlgebra])) - let expect = expectation(description: "Observation closure being called") - - var observation: Defaults.Observation! - observation = Defaults.observe(key, options: []) { change in - XCTAssertEqual(change.oldValue, .init([fixtureSetAlgebra])) - XCTAssertEqual(change.newValue, .init([fixtureSetAlgebra, fixtureSetAlgebra1])) - observation.invalidate() - expect.fulfill() - } - - Defaults[key].insert(fixtureSetAlgebra1) - observation.invalidate() - - waitForExpectations(timeout: 10) - } - - func testObserveOptionalKey() { - let key = Defaults.Key?>("observeSetAlgebraOptionalKey") - let expect = expectation(description: "Observation closure being called") - - var observation: Defaults.Observation! - observation = Defaults.observe(key, options: []) { change in - XCTAssertNil(change.oldValue) - XCTAssertEqual(change.newValue, .init([fixtureSetAlgebra])) - observation.invalidate() - expect.fulfill() - } - - Defaults[key] = .init([fixtureSetAlgebra]) - observation.invalidate() - - waitForExpectations(timeout: 10) - } - - func testObserveArrayKey() { - let key = Defaults.Key<[DefaultsSetAlgebra]>("observeSetAlgebraArrayKey", default: [.init([fixtureSetAlgebra])]) - let expect = expectation(description: "Observation closure being called") - - var observation: Defaults.Observation! - observation = Defaults.observe(key, options: []) { change in - XCTAssertEqual(change.oldValue[0], .init([fixtureSetAlgebra])) - XCTAssertEqual(change.newValue[1], .init([fixtureSetAlgebra])) - observation.invalidate() - expect.fulfill() - } - - Defaults[key].append(.init([fixtureSetAlgebra])) - observation.invalidate() - - waitForExpectations(timeout: 10) - } - - func testObserveDictioanryKey() { - let key = Defaults.Key<[String: DefaultsSetAlgebra]>("observeSetAlgebraDictionaryKey", default: ["0": .init([fixtureSetAlgebra])]) - let expect = expectation(description: "Observation closure being called") - - var observation: Defaults.Observation! - observation = Defaults.observe(key, options: []) { change in - XCTAssertEqual(change.oldValue["0"], .init([fixtureSetAlgebra])) - XCTAssertEqual(change.newValue["1"], .init([fixtureSetAlgebra])) - observation.invalidate() - expect.fulfill() - } - - Defaults[key]["1"] = .init([fixtureSetAlgebra]) - observation.invalidate() - - waitForExpectations(timeout: 10) + #expect(Defaults[.setAlgebraDictionary]["0"] == .init([fixtureSetAlgebra, fixtureSetAlgebra1])) + #expect(Defaults[.setAlgebraDictionary]["1"] == .init([fixtureSetAlgebra2, fixtureSetAlgebra3])) } } diff --git a/Tests/DefaultsTests/DefaultsSetTests.swift b/Tests/DefaultsTests/DefaultsSetTests.swift index d8a5dac..1d0f749 100644 --- a/Tests/DefaultsTests/DefaultsSetTests.swift +++ b/Tests/DefaultsTests/DefaultsSetTests.swift @@ -1,55 +1,60 @@ import Foundation +import Testing import Defaults -import XCTest + +private let suite_ = createSuite() private let fixtureSet = Set(1...5) extension Defaults.Keys { - fileprivate static let set = Key>("setInt", default: fixtureSet) + fileprivate static let set = Key>("setInt", default: fixtureSet, suite: suite_) } -final class DefaultsSetTests: XCTestCase { - override func setUp() { - super.setUp() - Defaults.removeAll() +@Suite(.serialized) +final class DefaultsSetTests { + init() { + Defaults.removeAll(suite: suite_) } - override func tearDown() { - super.tearDown() - Defaults.removeAll() + deinit { + Defaults.removeAll(suite: suite_) } + @Test func testKey() { - let key = Defaults.Key>("independentSetKey", default: fixtureSet) - XCTAssertEqual(Defaults[key].count, fixtureSet.count) + let key = Defaults.Key>("independentSetKey", default: fixtureSet, suite: suite_) + #expect(Defaults[key].count == fixtureSet.count) Defaults[key].insert(6) - XCTAssertEqual(Defaults[key], Set(1...6)) + #expect(Defaults[key] == Set(1...6)) } + @Test func testOptionalKey() { - let key = Defaults.Key?>("independentSetOptionalKey") // swiftlint:disable:this discouraged_optional_collection - XCTAssertNil(Defaults[key]) + let key = Defaults.Key?>("independentSetOptionalKey", suite: suite_) // swiftlint:disable:this discouraged_optional_collection + #expect(Defaults[key] == nil) Defaults[key] = fixtureSet - XCTAssertEqual(Defaults[key]?.count, fixtureSet.count) + #expect(Defaults[key]?.count == fixtureSet.count) Defaults[key]?.insert(6) - XCTAssertEqual(Defaults[key], Set(1...6)) + #expect(Defaults[key] == Set(1...6)) } + @Test func testArrayKey() { - let key = Defaults.Key<[Set]>("independentSetArrayKey", default: [fixtureSet]) - XCTAssertEqual(Defaults[key][0].count, fixtureSet.count) + let key = Defaults.Key<[Set]>("independentSetArrayKey", default: [fixtureSet], suite: suite_) + #expect(Defaults[key][0].count == fixtureSet.count) Defaults[key][0].insert(6) - XCTAssertEqual(Defaults[key][0], Set(1...6)) + #expect(Defaults[key][0] == Set(1...6)) Defaults[key].append(Set(1...4)) - XCTAssertEqual(Defaults[key][1], Set(1...4)) + #expect(Defaults[key][1] == Set(1...4)) } + @Test func testDictionaryKey() { - let key = Defaults.Key<[String: Set]>("independentSetArrayKey", default: ["0": fixtureSet]) - XCTAssertEqual(Defaults[key]["0"]?.count, fixtureSet.count) + let key = Defaults.Key<[String: Set]>("independentSetArrayKey", default: ["0": fixtureSet], suite: suite_) + #expect(Defaults[key]["0"]?.count == fixtureSet.count) Defaults[key]["0"]?.insert(6) - XCTAssertEqual(Defaults[key]["0"], Set(1...6)) + #expect(Defaults[key]["0"] == Set(1...6)) Defaults[key]["1"] = Set(1...4) - XCTAssertEqual(Defaults[key]["1"], Set(1...4)) + #expect(Defaults[key]["1"] == Set(1...4)) } } diff --git a/Tests/DefaultsTests/DefaultsSwiftUITests.swift b/Tests/DefaultsTests/DefaultsSwiftUITests.swift index c189b0a..1aba762 100644 --- a/Tests/DefaultsTests/DefaultsSwiftUITests.swift +++ b/Tests/DefaultsTests/DefaultsSwiftUITests.swift @@ -1,8 +1,10 @@ -import XCTest import Foundation import SwiftUI +import Testing import Defaults +private let suite_ = createSuite() + #if os(macOS) typealias XColor = NSColor #else @@ -10,10 +12,10 @@ typealias XColor = UIColor #endif extension Defaults.Keys { - fileprivate static let hasUnicorn = Key("swiftui_hasUnicorn", default: false) - fileprivate static let user = Key("swiftui_user", default: User(username: "Hank", password: "123456")) - fileprivate static let setInt = Key>("swiftui_setInt", default: Set(1...3)) - fileprivate static let color = Key("swiftui_color", default: .black) + fileprivate static let hasUnicorn = Key("swiftui_hasUnicorn", default: false, suite: suite_) + fileprivate static let user = Key("swiftui_user", default: User(username: "Hank", password: "123456"), suite: suite_) + fileprivate static let setInt = Key>("swiftui_setInt", default: Set(1...3), suite: suite_) + fileprivate static let color = Key("swiftui_color", default: .black, suite: suite_) } struct ContentView: View { @@ -29,34 +31,35 @@ struct ContentView: View { } } - -final class DefaultsSwiftUITests: XCTestCase { - override func setUp() { - super.setUp() - Defaults.removeAll() +@Suite(.serialized) +final class DefaultsSwiftUITests { + init() { + Defaults.removeAll(suite: suite_) } - override func tearDown() { - super.tearDown() - Defaults.removeAll() + deinit { + Defaults.removeAll(suite: suite_) } + @Test func testSwiftUIObserve() { let view = ContentView() - XCTAssertFalse(view.hasUnicorn) - XCTAssertEqual(view.user.username, "Hank") - XCTAssertEqual(view.setInt.count, 3) - XCTAssertEqual(XColor(view.color), XColor(Color.black)) + #expect(!view.hasUnicorn) + #expect(view.user.username == "Hank") + #expect(view.setInt.count == 3) + #expect(XColor(view.color) == XColor(Color.black)) + view.user = User(username: "Chen", password: "123456") view.hasUnicorn.toggle() view.setInt.insert(4) view.color = Color(.sRGB, red: 100, green: 100, blue: 100, opacity: 1) - XCTAssertTrue(view.hasUnicorn) - XCTAssertEqual(view.user.username, "Chen") - XCTAssertEqual(view.setInt, Set(1...4)) - XCTAssertFalse(Default(.hasUnicorn).defaultValue) - XCTAssertFalse(Default(.hasUnicorn).isDefaultValue) - XCTAssertNotEqual(XColor(view.color), XColor(Color.black)) - XCTAssertEqual(XColor(view.color), XColor(Color(.sRGB, red: 100, green: 100, blue: 100, opacity: 1))) + + #expect(view.hasUnicorn) + #expect(view.user.username == "Chen") + #expect(view.setInt == Set(1...4)) + #expect(!Default(.hasUnicorn).defaultValue) + #expect(!Default(.hasUnicorn).isDefaultValue) + #expect(XColor(view.color) != XColor(Color.black)) + #expect(XColor(view.color) == XColor(Color(.sRGB, red: 100, green: 100, blue: 100, opacity: 1))) } } diff --git a/Tests/DefaultsTests/DefaultsTests.swift b/Tests/DefaultsTests/DefaultsTests.swift index 8775016..129db62 100644 --- a/Tests/DefaultsTests/DefaultsTests.swift +++ b/Tests/DefaultsTests/DefaultsTests.swift @@ -1,661 +1,448 @@ // swiftlint:disable discouraged_optional_boolean import Foundation import Combine -import XCTest +import Testing @testable import Defaults +func createSuite() -> UserDefaults { + UserDefaults(suiteName: UUID().uuidString)! +} + +private let suite_ = createSuite() + let fixtureURL = URL(string: "https://sindresorhus.com")! let fixtureFileURL = URL(string: "file://~/icon.png")! let fixtureURL2 = URL(string: "https://example.com")! let fixtureDate = Date() extension Defaults.Keys { - static let key = Key("key", default: false) - static let url = Key("url", default: fixtureURL) - static let file = Key("fileURL", default: fixtureFileURL) - static let data = Key("data", default: Data([])) - static let date = Key("date", default: fixtureDate) - static let uuid = Key("uuid") - static let defaultDynamicDate = Key("defaultDynamicOptionalDate") { Date(timeIntervalSince1970: 0) } - static let defaultDynamicOptionalDate = Key("defaultDynamicOptionalDate") { Date(timeIntervalSince1970: 1) } + static let key = Key("key", default: false, suite: suite_) + static let url = Key("url", default: fixtureURL, suite: suite_) + static let file = Key("fileURL", default: fixtureFileURL, suite: suite_) + static let data = Key("data", default: Data([]), suite: suite_) + static let date = Key("date", default: fixtureDate, suite: suite_) + static let uuid = Key("uuid", suite: suite_) + static let defaultDynamicDate = Key("defaultDynamicOptionalDate", suite: suite_) { Date(timeIntervalSince1970: 0) } + static let defaultDynamicOptionalDate = Key("defaultDynamicOptionalDate", suite: suite_) { Date(timeIntervalSince1970: 1) } } -final class DefaultsTests: XCTestCase { - override func setUp() { - super.setUp() - Defaults.removeAll() +@Suite(.serialized) +final class DefaultsTests { + init() { + Defaults.removeAll(suite: suite_) } - override func tearDown() { - super.tearDown() - Defaults.removeAll() + deinit { + Defaults.removeAll(suite: suite_) } + @Test func testKey() { - let key = Defaults.Key("independentKey", default: false) - XCTAssertFalse(Defaults[key]) + let key = Defaults.Key("independentKey", default: false, suite: suite_) + #expect(!Defaults[key]) Defaults[key] = true - XCTAssertTrue(Defaults[key]) + #expect(Defaults[key]) } + @Test func testValidKeyName() { - let validKey = Defaults.Key("test", default: false) - let containsDotKey = Defaults.Key("test.a", default: false) - let startsWithAtKey = Defaults.Key("@test", default: false) - XCTAssertTrue(Defaults.isValidKeyPath(name: validKey.name)) - XCTAssertFalse(Defaults.isValidKeyPath(name: containsDotKey.name)) - XCTAssertFalse(Defaults.isValidKeyPath(name: startsWithAtKey.name)) + let validKey = Defaults.Key("test", default: false, suite: suite_) + let containsDotKey = Defaults.Key("test.a", default: false, suite: suite_) + let startsWithAtKey = Defaults.Key("@test", default: false, suite: suite_) + #expect(Defaults.isValidKeyPath(name: validKey.name)) + #expect(!Defaults.isValidKeyPath(name: containsDotKey.name)) + #expect(!Defaults.isValidKeyPath(name: startsWithAtKey.name)) } + @Test func testOptionalKey() { - let key = Defaults.Key("independentOptionalKey") - let url = Defaults.Key("independentOptionalURLKey") - XCTAssertNil(Defaults[key]) - XCTAssertNil(Defaults[url]) + let key = Defaults.Key("independentOptionalKey", suite: suite_) + let url = Defaults.Key("independentOptionalURLKey", suite: suite_) + #expect(Defaults[key] == nil) + #expect(Defaults[url] == nil) Defaults[key] = true Defaults[url] = fixtureURL - XCTAssertTrue(Defaults[key]!) - XCTAssertEqual(Defaults[url], fixtureURL) + #expect(Defaults[key] == true) + #expect(Defaults[url] == fixtureURL) Defaults[key] = nil Defaults[url] = nil - XCTAssertNil(Defaults[key]) - XCTAssertNil(Defaults[url]) + #expect(Defaults[key] == nil) + #expect(Defaults[url] == nil) Defaults[key] = false Defaults[url] = fixtureURL2 - XCTAssertFalse(Defaults[key]!) - XCTAssertEqual(Defaults[url], fixtureURL2) + #expect(Defaults[key] == false) + #expect(Defaults[url] == fixtureURL2) } + @Test func testInitializeDynamicDateKey() { - _ = Defaults.Key("independentInitializeDynamicDateKey") { - XCTFail("Init dynamic key should not trigger getter") + _ = Defaults.Key("independentInitializeDynamicDateKey", suite: suite_) { + Issue.record("Init dynamic key should not trigger getter") return Date() } - _ = Defaults.Key("independentInitializeDynamicOptionalDateKey") { - XCTFail("Init dynamic optional key should not trigger getter") + _ = Defaults.Key("independentInitializeDynamicOptionalDateKey", suite: suite_) { + Issue.record("Init dynamic optional key should not trigger getter") return Date() } } + @Test func testKeyRegistersDefault() { let keyName = "registersDefault" - XCTAssertFalse(UserDefaults.standard.bool(forKey: keyName)) - _ = Defaults.Key(keyName, default: true) - XCTAssertTrue(UserDefaults.standard.bool(forKey: keyName)) + #expect(!suite_.bool(forKey: keyName)) + _ = Defaults.Key(keyName, default: true, suite: suite_) + #expect(suite_.bool(forKey: keyName)) - // Test that it works with multiple keys with `Defaults`. let keyName2 = "registersDefault2" - _ = Defaults.Key(keyName2, default: keyName2) - XCTAssertEqual(UserDefaults.standard.string(forKey: keyName2), keyName2) + _ = Defaults.Key(keyName2, default: keyName2, suite: suite_) + #expect(suite_.string(forKey: keyName2) == keyName2) } + @Test func testKeyWithUserDefaultSubscript() { - let key = Defaults.Key("keyWithUserDeaultSubscript", default: false) - XCTAssertFalse(UserDefaults.standard[key]) - UserDefaults.standard[key] = true - XCTAssertTrue(UserDefaults.standard[key]) + let key = Defaults.Key("keyWithUserDeaultSubscript", default: false, suite: suite_) + #expect(!suite_[key]) + suite_[key] = true + #expect(suite_[key]) } + @Test func testKeys() { - XCTAssertFalse(Defaults[.key]) + #expect(!Defaults[.key]) Defaults[.key] = true - XCTAssertTrue(Defaults[.key]) + #expect(Defaults[.key]) } + @Test func testUrlType() { - XCTAssertEqual(Defaults[.url], fixtureURL) + #expect(Defaults[.url] == fixtureURL) let newUrl = URL(string: "https://twitter.com")! Defaults[.url] = newUrl - XCTAssertEqual(Defaults[.url], newUrl) + #expect(Defaults[.url] == newUrl) } + @Test func testDataType() { - XCTAssertEqual(Defaults[.data], Data([])) + #expect(Defaults[.data] == Data([])) let newData = Data([0xFF]) Defaults[.data] = newData - XCTAssertEqual(Defaults[.data], newData) + #expect(Defaults[.data] == newData) } + @Test func testDateType() { - XCTAssertEqual(Defaults[.date], fixtureDate) + #expect(Defaults[.date] == fixtureDate) let newDate = Date() Defaults[.date] = newDate - XCTAssertEqual(Defaults[.date], newDate) + #expect(Defaults[.date] == newDate) } + @Test func testDynamicDateType() { - XCTAssertEqual(Defaults[.defaultDynamicDate], Date(timeIntervalSince1970: 0)) + #expect(Defaults[.defaultDynamicDate] == Date(timeIntervalSince1970: 0)) let next = Date(timeIntervalSince1970: 1) Defaults[.defaultDynamicDate] = next - XCTAssertEqual(Defaults[.defaultDynamicDate], next) - XCTAssertEqual(UserDefaults.standard.object(forKey: Defaults.Key.defaultDynamicDate.name) as! Date, next) + #expect(Defaults[.defaultDynamicDate] == next) + #expect(suite_.object(forKey: Defaults.Key.defaultDynamicDate.name) as! Date == next) Defaults.Key.defaultDynamicDate.reset() - XCTAssertEqual(Defaults[.defaultDynamicDate], Date(timeIntervalSince1970: 0)) + #expect(Defaults[.defaultDynamicDate] == Date(timeIntervalSince1970: 0)) } + @Test func testDynamicOptionalDateType() { - XCTAssertEqual(Defaults[.defaultDynamicOptionalDate], Date(timeIntervalSince1970: 1)) + #expect(Defaults[.defaultDynamicOptionalDate] == Date(timeIntervalSince1970: 1)) let next = Date(timeIntervalSince1970: 2) Defaults[.defaultDynamicOptionalDate] = next - XCTAssertEqual(Defaults[.defaultDynamicOptionalDate], next) - XCTAssertEqual(UserDefaults.standard.object(forKey: Defaults.Key.defaultDynamicOptionalDate.name) as! Date, next) + #expect(Defaults[.defaultDynamicOptionalDate] == next) + #expect(suite_.object(forKey: Defaults.Key.defaultDynamicOptionalDate.name) as! Date == next) Defaults[.defaultDynamicOptionalDate] = nil - XCTAssertEqual(Defaults[.defaultDynamicOptionalDate], Date(timeIntervalSince1970: 1)) - XCTAssertNil(UserDefaults.standard.object(forKey: Defaults.Key.defaultDynamicOptionalDate.name)) + #expect(Defaults[.defaultDynamicOptionalDate] == Date(timeIntervalSince1970: 1)) + #expect(suite_.object(forKey: Defaults.Key.defaultDynamicOptionalDate.name) == nil) } + @Test func testFileURLType() { - XCTAssertEqual(Defaults[.file], fixtureFileURL) + #expect(Defaults[.file] == fixtureFileURL) } + @Test func testUUIDType() { let fixture = UUID() Defaults[.uuid] = fixture - XCTAssertEqual(Defaults[.uuid], fixture) + #expect(Defaults[.uuid] == fixture) } + @Test func testRemoveAll() { - let key = Defaults.Key("removeAll", default: false) - let key2 = Defaults.Key("removeAll2", default: false) + let key = Defaults.Key("removeAll", default: false, suite: suite_) + let key2 = Defaults.Key("removeAll2", default: false, suite: suite_) Defaults[key] = true Defaults[key2] = true - XCTAssertTrue(Defaults[key]) - XCTAssertTrue(Defaults[key2]) - Defaults.removeAll() - XCTAssertFalse(Defaults[key]) - XCTAssertFalse(Defaults[key2]) + #expect(Defaults[key]) + #expect(Defaults[key2]) + Defaults.removeAll(suite: suite_) + #expect(!Defaults[key]) + #expect(!Defaults[key2]) } + @Test func testCustomSuite() { let customSuite = UserDefaults(suiteName: "com.sindresorhus.customSuite")! let key = Defaults.Key("customSuite", default: false, suite: customSuite) - XCTAssertFalse(customSuite[key]) - XCTAssertFalse(Defaults[key]) + #expect(!customSuite[key]) + #expect(!Defaults[key]) Defaults[key] = true - XCTAssertTrue(customSuite[key]) - XCTAssertTrue(Defaults[key]) + #expect(customSuite[key]) + #expect(Defaults[key]) Defaults.removeAll(suite: customSuite) } + @Test func testIsDefaultValue() { - let key = Defaults.Key("isDefaultValue", default: false) - XCTAssert(key.isDefaultValue) + let key = Defaults.Key("isDefaultValue", default: false, suite: suite_) + #expect(key.isDefaultValue) Defaults[key].toggle() - XCTAssert(!key.isDefaultValue) + #expect(!key.isDefaultValue) } - func testObserveKeyCombine() { - let key = Defaults.Key("observeKey", default: false) - let expect = expectation(description: "Observation closure being called") + @available(iOS 16.0, macOS 13.0, tvOS 16.0, watchOS 9.0, visionOS 1.0, *) + @Test + func testObserveKeyCombine() async throws { + let key = Defaults.Key("observeKey", default: false, suite: suite_) + var results: [(Bool, Bool)] = [] - let publisher = Defaults - .publisher(key, options: []) - .map { ($0.oldValue, $0.newValue) } - .collect(2) + try await confirmation(expectedCount: 2) { confirmation in + let publisher = Defaults + .publisher(key, options: []) + .map { ($0.oldValue, $0.newValue) } + .sink { value in + results.append(value) + confirmation() + } - let cancellable = publisher.sink { tuples in - for (index, expected) in [(false, true), (true, false)].enumerated() { - XCTAssertEqual(expected.0, tuples[index].0) - XCTAssertEqual(expected.1, tuples[index].1) - } + await Task.yield() + Defaults[key] = true + Defaults.reset(key) - expect.fulfill() + try await Task.sleep(for: .milliseconds(100)) + publisher.cancel() } - Defaults[key] = true - Defaults.reset(key) - cancellable.cancel() + let expectedValues = [(false, true), (true, false)] +// #expect(results == expectedValues) - waitForExpectations(timeout: 10) + #expect(results.count == expectedValues.count) + for (index, expected) in expectedValues.enumerated() { + #expect(results[index].0 == expected.0) + #expect(results[index].1 == expected.1) + } } - func testObserveOptionalKeyCombine() { - let key = Defaults.Key("observeOptionalKey") - let expect = expectation(description: "Observation closure being called") + @available(iOS 16.0, macOS 13.0, tvOS 16.0, watchOS 9.0, visionOS 1.0, *) + @Test + func testObserveOptionalKeyCombine() async throws { + let key = Defaults.Key("observeOptionalKey", suite: suite_) + var results: [(Bool?, Bool?)] = [] - let publisher = Defaults - .publisher(key, options: []) - .map { ($0.oldValue, $0.newValue) } - .collect(3) + try await confirmation(expectedCount: 3) { confirmation in + let publisher = Defaults + .publisher(key, options: []) + .map { ($0.oldValue, $0.newValue) } + .sink { value in + results.append(value) + confirmation() + } + + await Task.yield() + Defaults[key] = true + Defaults[key] = false + Defaults.reset(key) + + try await Task.sleep(for: .milliseconds(100)) + publisher.cancel() + } let expectedValues: [(Bool?, Bool?)] = [(nil, true), (true, false), (false, nil)] +// #expect(results == expectedValues) - let cancellable = publisher.sink { actualValues in - for (expected, actual) in zip(expectedValues, actualValues) { - XCTAssertEqual(expected.0, actual.0) - XCTAssertEqual(expected.1, actual.1) - } - - expect.fulfill() + #expect(results.count == expectedValues.count) + for (index, expected) in expectedValues.enumerated() { + #expect(results[index].0 == expected.0) + #expect(results[index].1 == expected.1) } - - Defaults[key] = true - Defaults[key] = false - Defaults.reset(key) - cancellable.cancel() - - waitForExpectations(timeout: 10) } - func testDynamicOptionalDateTypeCombine() { + @available(iOS 16.0, macOS 13.0, tvOS 16.0, watchOS 9.0, visionOS 1.0, *) + @Test + func testDynamicOptionalDateTypeCombine() async throws { let first = Date(timeIntervalSince1970: 0) let second = Date(timeIntervalSince1970: 1) let third = Date(timeIntervalSince1970: 2) - let key = Defaults.Key("combineDynamicOptionalDateKey") { first } - let expect = expectation(description: "Observation closure being called") + let key = Defaults.Key("combineDynamicOptionalDateKey", suite: suite_) { first } + var results: [(Date?, Date?)] = [] - let publisher = Defaults - .publisher(key, options: []) - .map { ($0.oldValue, $0.newValue) } - .collect(3) + try await confirmation(expectedCount: 3) { confirmation in + let publisher = Defaults + .publisher(key, options: []) + .map { ($0.oldValue, $0.newValue) } + .sink { value in + results.append(value) + confirmation() + } + + await Task.yield() + Defaults[key] = second + Defaults[key] = third + Defaults.reset(key) + + try await Task.sleep(for: .milliseconds(100)) + publisher.cancel() + } let expectedValues: [(Date?, Date?)] = [(first, second), (second, third), (third, first)] +// #expect(results == expectedValues) - let cancellable = publisher.sink { actualValues in - for (expected, actual) in zip(expectedValues, actualValues) { - XCTAssertEqual(expected.0, actual.0) - XCTAssertEqual(expected.1, actual.1) - } - - expect.fulfill() + #expect(results.count == expectedValues.count) + for (index, expected) in expectedValues.enumerated() { + #expect(results[index].0 == expected.0) + #expect(results[index].1 == expected.1) } - - Defaults[key] = second - Defaults[key] = third - Defaults.reset(key) - cancellable.cancel() - - waitForExpectations(timeout: 10) } - func testObserveMultipleKeysCombine() { - let key1 = Defaults.Key("observeKey1", default: "x") - let key2 = Defaults.Key("observeKey2", default: true) - let expect = expectation(description: "Observation closure being called") + @available(iOS 16.0, macOS 13.0, tvOS 16.0, watchOS 9.0, visionOS 1.0, *) + @Test + func testObserveMultipleKeysCombine() async throws { + let key1 = Defaults.Key("observeKey1", default: "x", suite: suite_) + let key2 = Defaults.Key("observeKey2", default: true, suite: suite_) + var count = 0 - let publisher = Defaults.publisher(keys: key1, key2, options: []).collect(2) + try await confirmation(expectedCount: 2) { confirmation in + let publisher = Defaults.publisher(keys: key1, key2, options: []) + .sink { _ in + count += 1 + confirmation() + } - let cancellable = publisher.sink { _ in - expect.fulfill() + await Task.yield() + Defaults[key1] = "y" + Defaults[key2] = false + + try await Task.sleep(for: .milliseconds(100)) + publisher.cancel() } - Defaults[key1] = "y" - Defaults[key2] = false - cancellable.cancel() - - waitForExpectations(timeout: 10) + #expect(count == 2) } - func testObserveMultipleOptionalKeysCombine() { - let key1 = Defaults.Key("observeOptionalKey1") - let key2 = Defaults.Key("observeOptionalKey2") - let expect = expectation(description: "Observation closure being called") + @available(iOS 16.0, macOS 13.0, tvOS 16.0, watchOS 9.0, visionOS 1.0, *) + @Test + func testObserveMultipleOptionalKeysCombine() async throws { + let key1 = Defaults.Key("observeOptionalKey1", suite: suite_) + let key2 = Defaults.Key("observeOptionalKey2", suite: suite_) + var count = 0 - let publisher = Defaults.publisher(keys: key1, key2, options: []).collect(2) + try await confirmation(expectedCount: 2) { confirmation in + let publisher = Defaults.publisher(keys: key1, key2, options: []) + .sink { _ in + count += 1 + confirmation() + } - let cancellable = publisher.sink { _ in - expect.fulfill() + await Task.yield() + Defaults[key1] = "x" + Defaults[key2] = false + + try await Task.sleep(for: .milliseconds(100)) + publisher.cancel() } - Defaults[key1] = "x" - Defaults[key2] = false - cancellable.cancel() - - waitForExpectations(timeout: 10) + #expect(count == 2) } - func testReceiveValueBeforeSubscriptionCombine() { - let key = Defaults.Key("receiveValueBeforeSubscription", default: "hello") - let expect = expectation(description: "Observation closure being called") + @available(iOS 16.0, macOS 13.0, tvOS 16.0, watchOS 9.0, visionOS 1.0, *) + @Test + func testReceiveValueBeforeSubscriptionCombine() async throws { + let key = Defaults.Key("receiveValueBeforeSubscription", default: "hello", suite: suite_) - let publisher = Defaults - .publisher(key) - .map(\.newValue) - .eraseToAnyPublisher() - .collect(2) + try await confirmation(expectedCount: 2) { confirmation in + let publisher = Defaults + .publisher(key) + .map(\.newValue) + .sink { value in + confirmation() + print("Received value: \(value)") + } - let cancellable = publisher.sink { values in - XCTAssertEqual(["hello", "world"], values) - expect.fulfill() + // Ensure we're subscribed before changing the value + await Task.yield() + + // Change the value + Defaults[key] = "world" + + // Keep the subscription alive + try await Task.sleep(for: .milliseconds(100)) + + publisher.cancel() } - - Defaults[key] = "world" - cancellable.cancel() - waitForExpectations(timeout: 10) } - func testObserveKey() { - let key = Defaults.Key("observeKey", default: false) - let expect = expectation(description: "Observation closure being called") + @Test + func testObservePreventPropagationCombine() async throws { + let key1 = Defaults.Key("preventPropagation6", default: nil, suite: suite_) - var observation: Defaults.Observation! - observation = Defaults.observe(key, options: []) { change in - XCTAssertFalse(change.oldValue) - XCTAssertTrue(change.newValue) - observation.invalidate() - expect.fulfill() - } - - Defaults[key] = true - - waitForExpectations(timeout: 10) - } - - func testObserveOptionalKey() { - let key = Defaults.Key("observeOptionalKey") - let expect = expectation(description: "Observation closure being called") - - var observation: Defaults.Observation! - observation = Defaults.observe(key, options: []) { change in - XCTAssertNil(change.oldValue) - XCTAssertTrue(change.newValue!) - observation.invalidate() - expect.fulfill() - } - - Defaults[key] = true - - waitForExpectations(timeout: 10) - } - - func testObserveMultipleKeys() { - let key1 = Defaults.Key("observeKey1", default: "x") - let key2 = Defaults.Key("observeKey2", default: true) - let expect = expectation(description: "Observation closure being called") - - var observation: Defaults.Observation! - var counter = 0 - observation = Defaults.observe(keys: key1, key2, options: []) { - counter += 1 - if counter == 2 { - expect.fulfill() - } else if counter > 2 { - XCTFail() // swiftlint:disable:this xctfail_message - } - } - - Defaults[key1] = "y" - Defaults[key2] = false - observation.invalidate() - - waitForExpectations(timeout: 10) - } - - func testObserveKeyURL() { - let key = Defaults.Key("observeKeyURL", default: fixtureURL) - let expect = expectation(description: "Observation closure being called") - - var observation: Defaults.Observation! - observation = Defaults.observe(key, options: []) { change in - XCTAssertEqual(change.oldValue, fixtureURL) - XCTAssertEqual(change.newValue, fixtureURL2) - observation.invalidate() - expect.fulfill() - } - - Defaults[key] = fixtureURL2 - - waitForExpectations(timeout: 10) - } - - func testObserveDynamicOptionalDateKey() { - let first = Date(timeIntervalSince1970: 0) - let second = Date(timeIntervalSince1970: 1) - let key = Defaults.Key("observeDynamicOptionalDate") { first } - - let expect = expectation(description: "Observation closure being called") - - var observation: Defaults.Observation! - observation = Defaults.observe(key, options: []) { change in - XCTAssertEqual(change.oldValue, first) - XCTAssertEqual(change.newValue, second) - observation.invalidate() - expect.fulfill() - } - - Defaults[key] = second - - waitForExpectations(timeout: 10) - } - - func testObservePreventPropagation() { - let key1 = Defaults.Key("preventPropagation0", default: nil) - let expect = expectation(description: "No infinite recursion") - - var observation: Defaults.Observation! - var wasInside = false - observation = Defaults.observe(key1, options: []) { _ in - XCTAssertFalse(wasInside) - wasInside = true - Defaults.withoutPropagation { - Defaults[key1] = true - } - expect.fulfill() - } - - Defaults[key1] = false - observation.invalidate() - - waitForExpectations(timeout: 10) - } - - func testObservePreventPropagationMultipleKeys() { - let key1 = Defaults.Key("preventPropagation1", default: nil) - let key2 = Defaults.Key("preventPropagation2", default: nil) - let expect = expectation(description: "No infinite recursion") - - var observation: Defaults.Observation! - var wasInside = false - observation = Defaults.observe(keys: key1, key2, options: []) { - XCTAssertFalse(wasInside) - wasInside = true - Defaults.withoutPropagation { - Defaults[key1] = true - } - expect.fulfill() - } - - Defaults[key1] = false - observation.invalidate() - - waitForExpectations(timeout: 10) - } - - // This checks if the callback is still being called if the value is changed on a second thread while the initial thread is doing some long running task. - func testObservePreventPropagationMultipleThreads() { - let key1 = Defaults.Key("preventPropagation3", default: nil) - let expect = expectation(description: "No infinite recursion") - - var observation: Defaults.Observation! - observation = Defaults.observe(key1, options: []) { _ in - Defaults.withoutPropagation { - Defaults[key1]! += 1 - } - print("--- Main Thread: \(Thread.isMainThread)") - if !Thread.isMainThread { - XCTAssertEqual(Defaults[key1]!, 4) - expect.fulfill() - } else { - usleep(300_000) - print("--- Release: \(Thread.isMainThread)") - } - } - DispatchQueue.global().asyncAfter(deadline: .now() + 0.05) { - Defaults[key1]! += 1 - } - Defaults[key1] = 1 - observation.invalidate() - - waitForExpectations(timeout: 10) - } - - // Check if propagation prevention works across multiple observations. - func testObservePreventPropagationMultipleObservations() { - let key1 = Defaults.Key("preventPropagation4", default: nil) - let key2 = Defaults.Key("preventPropagation5", default: nil) - let expect = expectation(description: "No infinite recursion") - - let observation1 = Defaults.observe(key2, options: []) { _ in - XCTFail() // swiftlint:disable:this xctfail_message - } - - let observation2 = Defaults.observe(keys: key1, key2, options: []) { - Defaults.withoutPropagation { - Defaults[key2] = true - } - expect.fulfill() - } - - Defaults[key1] = false - observation1.invalidate() - observation2.invalidate() - - waitForExpectations(timeout: 10) - } - - func testObservePreventPropagationCombine() { - let key1 = Defaults.Key("preventPropagation6", default: nil) - let expect = expectation(description: "No infinite recursion") - - var wasInside = false - let cancellable = Defaults.publisher(key1, options: []).sink { _ in - XCTAssertFalse(wasInside) - wasInside = true - Defaults.withoutPropagation { - Defaults[key1] = true - } - expect.fulfill() - } - - Defaults[key1] = false - cancellable.cancel() - - waitForExpectations(timeout: 10) - } - - func testObservePreventPropagationMultipleKeysCombine() { - let key1 = Defaults.Key("preventPropagation7", default: nil) - let key2 = Defaults.Key("preventPropagation8", default: nil) - let expect = expectation(description: "No infinite recursion") - - var wasInside = false - let cancellable = Defaults.publisher(keys: key1, key2, options: []).sink { _ in - XCTAssertFalse(wasInside) - wasInside = true - Defaults.withoutPropagation { - Defaults[key1] = true - } - expect.fulfill() - } - - Defaults[key2] = false - cancellable.cancel() - - waitForExpectations(timeout: 10) - } - - func testObservePreventPropagationModifiersCombine() { - let key1 = Defaults.Key("preventPropagation9", default: nil) - let expect = expectation(description: "No infinite recursion") - - var wasInside = false - var cancellable: AnyCancellable! - cancellable = Defaults.publisher(key1, options: []) - .receive(on: DispatchQueue.main) - .delay(for: 0.5, scheduler: DispatchQueue.global()) - .sink { _ in - XCTAssertFalse(wasInside) + await confirmation() { confirmation in + var wasInside = false + let cancellable = Defaults.publisher(key1, options: []).sink { _ in + #expect(!wasInside) wasInside = true Defaults.withoutPropagation { Defaults[key1] = true } - expect.fulfill() - cancellable.cancel() + confirmation() } - Defaults[key1] = false - - waitForExpectations(timeout: 10) - } - - func testRemoveDuplicatesObserveKeyCombine() { - let key = Defaults.Key("observeKey", default: false) - let expect = expectation(description: "Observation closure being called") - - let inputArray = [true, false, false, false, false, false, false, true] - let expectedArray = [true, false, true] - - let cancellable = Defaults - .publisher(key, options: []) - .removeDuplicates() - .map(\.newValue) - .collect(expectedArray.count) - .sink { result in - print("Result array: \(result)") - - if result == expectedArray { - expect.fulfill() - } else { - XCTFail("Expected Array is not matched") - } - } - - for item in inputArray { - Defaults[key] = item + Defaults[key1] = false + cancellable.cancel() } - - Defaults.reset(key) - cancellable.cancel() - - waitForExpectations(timeout: 10) } - func testRemoveDuplicatesOptionalObserveKeyCombine() { - let key = Defaults.Key("observeOptionalKey", default: nil) - let expect = expectation(description: "Observation closure being called") + @Test + func testObservePreventPropagationMultipleKeysCombine() async throws { + let key1 = Defaults.Key("preventPropagation7", default: nil, suite: suite_) + let key2 = Defaults.Key("preventPropagation8", default: nil, suite: suite_) - let inputArray = [true, nil, nil, nil, false, false, false, nil] - let expectedArray = [true, nil, false, nil] - - let cancellable = Defaults - .publisher(key, options: []) - .removeDuplicates() - .map(\.newValue) - .collect(expectedArray.count) - .sink { result in - print("Result array: \(result)") - - if result == expectedArray { - expect.fulfill() - } else { - XCTFail("Expected Array is not matched") + await confirmation() { confirmation in + var wasInside = false + let cancellable = Defaults.publisher(keys: key1, key2, options: []).sink { _ in + #expect(!wasInside) + wasInside = true + Defaults.withoutPropagation { + Defaults[key1] = true } + confirmation() } - for item in inputArray { - Defaults[key] = item + Defaults[key2] = false + cancellable.cancel() } - - Defaults.reset(key) - cancellable.cancel() - - waitForExpectations(timeout: 10) } + @Test func testResetKey() { let defaultFixture1 = "foo1" let defaultFixture2 = 0 let newFixture1 = "bar1" let newFixture2 = 1 - let key1 = Defaults.Key("key1", default: defaultFixture1) - let key2 = Defaults.Key("key2", default: defaultFixture2) + let key1 = Defaults.Key("key1", default: defaultFixture1, suite: suite_) + let key2 = Defaults.Key("key2", default: defaultFixture2, suite: suite_) Defaults[key1] = newFixture1 Defaults[key2] = newFixture2 Defaults.reset(key1) - XCTAssertEqual(Defaults[key1], defaultFixture1) - XCTAssertEqual(Defaults[key2], newFixture2) + #expect(Defaults[key1] == defaultFixture1) + #expect(Defaults[key2] == newFixture2) } + @Test func testResetMultipleKeys() { let defaultFxiture1 = "foo1" let defaultFixture2 = 0 @@ -663,111 +450,94 @@ final class DefaultsTests: XCTestCase { let newFixture1 = "bar1" let newFixture2 = 1 let newFixture3 = "bar3" - let key1 = Defaults.Key("akey1", default: defaultFxiture1) - let key2 = Defaults.Key("akey2", default: defaultFixture2) - let key3 = Defaults.Key("akey3", default: defaultFixture3) + let key1 = Defaults.Key("akey1", default: defaultFxiture1, suite: suite_) + let key2 = Defaults.Key("akey2", default: defaultFixture2, suite: suite_) + let key3 = Defaults.Key("akey3", default: defaultFixture3, suite: suite_) Defaults[key1] = newFixture1 Defaults[key2] = newFixture2 Defaults[key3] = newFixture3 Defaults.reset(key1, key2) - XCTAssertEqual(Defaults[key1], defaultFxiture1) - XCTAssertEqual(Defaults[key2], defaultFixture2) - XCTAssertEqual(Defaults[key3], newFixture3) + #expect(Defaults[key1] == defaultFxiture1) + #expect(Defaults[key2] == defaultFixture2) + #expect(Defaults[key3] == newFixture3) } + @Test func testResetMultipleOptionalKeys() { let newFixture1 = "bar1" let newFixture2 = 1 let newFixture3 = "bar3" - let key1 = Defaults.Key("aoptionalKey1") - let key2 = Defaults.Key("aoptionalKey2") - let key3 = Defaults.Key("aoptionalKey3") + let key1 = Defaults.Key("aoptionalKey1", suite: suite_) + let key2 = Defaults.Key("aoptionalKey2", suite: suite_) + let key3 = Defaults.Key("aoptionalKey3", suite: suite_) Defaults[key1] = newFixture1 Defaults[key2] = newFixture2 Defaults[key3] = newFixture3 Defaults.reset(key1, key2) - XCTAssertNil(Defaults[key1]) - XCTAssertNil(Defaults[key2]) - XCTAssertEqual(Defaults[key3], newFixture3) + #expect(Defaults[key1] == nil) + #expect(Defaults[key2] == nil) + #expect(Defaults[key3] == newFixture3) } - func testObserveWithLifetimeTie() { - let key = Defaults.Key("lifetimeTie", default: false) - let expect = expectation(description: "Observation closure being called") + @available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, visionOS 1.0, *) + @Test + func testImmediatelyFinishingPublisherCombine() async throws { + let key = Defaults.Key("observeKey", default: false, suite: suite_) - weak var observation: Defaults.Observation! - observation = Defaults.observe(key, options: []) { _ in - observation.invalidate() - expect.fulfill() + let result: Void? = try await withThrowingTaskGroup(of: Void.self) { group in + let publisher = Defaults + .publisher(key, options: [.initial]) + .first() + + group.addTask { + for try await _ in publisher.values { + return + } + } + + return try await group.next() } - .tieToLifetime(of: self) - Defaults[key] = true - - waitForExpectations(timeout: 10) + #expect(result != nil) } - func testObserveWithLifetimeTieManualBreak() { - let key = Defaults.Key("lifetimeTieManualBreak", default: false) + @available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, visionOS 1.0, *) + @Test + func testImmediatelyFinishingMultiplePublisherCombine() async throws { + let key1 = Defaults.Key("observeKey1", default: false, suite: suite_) + let key2 = Defaults.Key("observeKey2", default: "🦄", suite: suite_) - weak var observation: Defaults.Observation? = Defaults.observe(key, options: []) { _ in }.tieToLifetime(of: self) - observation!.removeLifetimeTie() + let result: Void? = try await withThrowingTaskGroup(of: Void.self) { group in + let publisher = Defaults + .publisher(keys: [key1, key2], options: [.initial]) + .first() - for index in 1...10 { - if observation == nil { - break + group.addTask { + for try await _ in publisher.values { + return + } } - sleep(1) - - if index == 10 { - XCTFail() // swiftlint:disable:this xctfail_message - } + return try await group.next() } + + #expect(result != nil) } - func testImmediatelyFinishingPublisherCombine() { - let key = Defaults.Key("observeKey", default: false) - let expect = expectation(description: "Observation closure being called without crashing") - - let cancellable = Defaults - .publisher(key, options: [.initial]) - .first() - .sink { _ in - expect.fulfill() - } - - cancellable.cancel() - waitForExpectations(timeout: 10) - } - - func testImmediatelyFinishingMultiplePublisherCombine() { - let key1 = Defaults.Key("observeKey1", default: false) - let key2 = Defaults.Key("observeKey2", default: "🦄") - let expect = expectation(description: "Observation closure being called without crashing") - - let cancellable = Defaults - .publisher(keys: [key1, key2], options: [.initial]) - .first() - .sink { _ in - expect.fulfill() - } - - cancellable.cancel() - - waitForExpectations(timeout: 10) - } - + @Test func testKeyEquatable() { - XCTAssertEqual(Defaults.Key("equatableKeyTest", default: false), Defaults.Key("equatableKeyTest", default: false)) + #expect(Defaults.Key("equatableKeyTest", default: false, suite: suite_) == Defaults.Key("equatableKeyTest", default: false, suite: suite_)) } + @Test func testKeyHashable() { - _ = Set([Defaults.Key("hashableKeyTest", default: false)]) + _ = Set([Defaults.Key("hashableKeyTest", default: false, suite: suite_)]) } + @available(iOS 16.0, macOS 13.0, tvOS 16.0, watchOS 9.0, visionOS 1.0, *) + @Test func testUpdates() async { - let key = Defaults.Key("updatesKey", default: false) + let key = Defaults.Key("updatesKey", default: false, suite: suite_) async let waiter = Defaults.updates(key, initial: false).first { $0 } @@ -776,16 +546,18 @@ final class DefaultsTests: XCTestCase { Defaults[key] = true guard let result = await waiter else { - XCTFail() // swiftlint:disable:this xctfail_message + Issue.record("Failed to get result") return } - XCTAssertTrue(result) + #expect(result) } + @available(iOS 16.0, macOS 13.0, tvOS 16.0, watchOS 9.0, visionOS 1.0, *) + @Test func testUpdatesMultipleKeys() async { - let key1 = Defaults.Key("updatesMultipleKey1", default: false) - let key2 = Defaults.Key("updatesMultipleKey2", default: false) + let key1 = Defaults.Key("updatesMultipleKey1", default: false, suite: suite_) + let key2 = Defaults.Key("updatesMultipleKey2", default: false, suite: suite_) let counter = Counter() async let waiter: Void = { @@ -806,7 +578,7 @@ final class DefaultsTests: XCTestCase { await waiter let count = await counter.count - XCTAssertEqual(count, 2) + #expect(count == 2) } } diff --git a/Tests/DefaultsTests/DefaultsUIColorTests.swift b/Tests/DefaultsTests/DefaultsUIColorTests.swift index c248bf6..ba9073b 100644 --- a/Tests/DefaultsTests/DefaultsUIColorTests.swift +++ b/Tests/DefaultsTests/DefaultsUIColorTests.swift @@ -1,313 +1,142 @@ #if !os(macOS) import Foundation -import Defaults -import XCTest import UIKit +import Testing +import Defaults + +private let suite_ = createSuite() private let fixtureColor = UIColor(red: Double(103) / Double(0xFF), green: Double(132) / Double(0xFF), blue: Double(255) / Double(0xFF), alpha: 1) private let fixtureColor1 = UIColor(red: Double(255) / Double(0xFF), green: Double(241) / Double(0xFF), blue: Double(180) / Double(0xFF), alpha: 1) private let fixtureColor2 = UIColor(red: Double(255) / Double(0xFF), green: Double(180) / Double(0xFF), blue: Double(194) / Double(0xFF), alpha: 1) extension Defaults.Keys { - fileprivate static let color = Defaults.Key("NSColor", default: fixtureColor) - fileprivate static let colorArray = Defaults.Key<[UIColor]>("NSColorArray", default: [fixtureColor]) - fileprivate static let colorDictionary = Defaults.Key<[String: UIColor]>("NSColorArray", default: ["0": fixtureColor]) + fileprivate static let color = Defaults.Key("NSColor", default: fixtureColor, suite: suite_) + fileprivate static let colorArray = Defaults.Key<[UIColor]>("NSColorArray", default: [fixtureColor], suite: suite_) + fileprivate static let colorDictionary = Defaults.Key<[String: UIColor]>("NSColorArray", default: ["0": fixtureColor], suite: suite_) } -final class DefaultsNSColorTests: XCTestCase { - override func setUp() { - super.setUp() - Defaults.removeAll() +@Suite(.serialized) +final class DefaultsNSColorTests { + init() { + Defaults.removeAll(suite: suite_) } - override func tearDown() { - super.tearDown() - Defaults.removeAll() + deinit { + Defaults.removeAll(suite: suite_) } + @Test func testKey() { - let key = Defaults.Key("independentNSColorKey", default: fixtureColor) - XCTAssertTrue(Defaults[key].isEqual(fixtureColor)) + let key = Defaults.Key("independentNSColorKey", default: fixtureColor, suite: suite_) + #expect(Defaults[key].isEqual(fixtureColor)) Defaults[key] = fixtureColor1 - XCTAssertTrue(Defaults[key].isEqual(fixtureColor1)) + #expect(Defaults[key].isEqual(fixtureColor1)) } + @Test func testPreservesColorSpace() { let fixture = UIColor(displayP3Red: 1, green: 0.3, blue: 0.7, alpha: 1) - let key = Defaults.Key("independentNSColorPreservesColorSpaceKey") + let key = Defaults.Key("independentNSColorPreservesColorSpaceKey", suite: suite_) Defaults[key] = fixture - XCTAssertEqual(Defaults[key], fixture) - XCTAssertEqual(Defaults[key]?.cgColor.colorSpace, fixture.cgColor.colorSpace) - XCTAssertEqual(Defaults[key]?.cgColor, fixture.cgColor) + #expect(Defaults[key] == fixture) + #expect(Defaults[key]?.cgColor.colorSpace == fixture.cgColor.colorSpace) + #expect(Defaults[key]?.cgColor == fixture.cgColor) } + @Test func testOptionalKey() { - let key = Defaults.Key("independentNSColorOptionalKey") - XCTAssertNil(Defaults[key]) + let key = Defaults.Key("independentNSColorOptionalKey", suite: suite_) + #expect(Defaults[key] == nil) Defaults[key] = fixtureColor - XCTAssertTrue(Defaults[key]?.isEqual(fixtureColor) ?? false) + #expect(Defaults[key]?.isEqual(fixtureColor) ?? false) } + @Test func testArrayKey() { - let key = Defaults.Key<[UIColor]>("independentNSColorArrayKey", default: [fixtureColor]) - XCTAssertTrue(Defaults[key][0].isEqual(fixtureColor)) + let key = Defaults.Key<[UIColor]>("independentNSColorArrayKey", default: [fixtureColor], suite: suite_) + #expect(Defaults[key][0].isEqual(fixtureColor)) Defaults[key].append(fixtureColor1) - XCTAssertTrue(Defaults[key][1].isEqual(fixtureColor1)) + #expect(Defaults[key][1].isEqual(fixtureColor1)) } + @Test func testArrayOptionalKey() { - let key = Defaults.Key<[UIColor]?>("independentNSColorOptionalKey") // swiftlint:disable:this discouraged_optional_collection - XCTAssertNil(Defaults[key]) + let key = Defaults.Key<[UIColor]?>("independentNSColorOptionalKey", suite: suite_) // swiftlint:disable:this discouraged_optional_collection + #expect(Defaults[key] == nil) Defaults[key] = [fixtureColor] Defaults[key]?.append(fixtureColor1) - XCTAssertTrue(Defaults[key]?[0].isEqual(fixtureColor) ?? false) - XCTAssertTrue(Defaults[key]?[1].isEqual(fixtureColor1) ?? false) + #expect(Defaults[key]?[0].isEqual(fixtureColor) ?? false) + #expect(Defaults[key]?[1].isEqual(fixtureColor1) ?? false) } + @Test func testNestedArrayKey() { - let key = Defaults.Key<[[UIColor]]>("independentNSColorNestedArrayKey", default: [[fixtureColor]]) - XCTAssertTrue(Defaults[key][0][0].isEqual(fixtureColor)) + let key = Defaults.Key<[[UIColor]]>("independentNSColorNestedArrayKey", default: [[fixtureColor]], suite: suite_) + #expect(Defaults[key][0][0].isEqual(fixtureColor)) Defaults[key][0].append(fixtureColor1) Defaults[key].append([fixtureColor2]) - XCTAssertTrue(Defaults[key][0][1].isEqual(fixtureColor1)) - XCTAssertTrue(Defaults[key][1][0].isEqual(fixtureColor2)) + #expect(Defaults[key][0][1].isEqual(fixtureColor1)) + #expect(Defaults[key][1][0].isEqual(fixtureColor2)) } + @Test func testArrayDictionaryKey() { - let key = Defaults.Key<[[String: UIColor]]>("independentNSColorArrayDictionaryKey", default: [["0": fixtureColor]]) - XCTAssertTrue(Defaults[key][0]["0"]?.isEqual(fixtureColor) ?? false) + let key = Defaults.Key<[[String: UIColor]]>("independentNSColorArrayDictionaryKey", default: [["0": fixtureColor]], suite: suite_) + #expect(Defaults[key][0]["0"]?.isEqual(fixtureColor) ?? false) Defaults[key][0]["1"] = fixtureColor1 Defaults[key].append(["0": fixtureColor2]) - XCTAssertTrue(Defaults[key][0]["1"]?.isEqual(fixtureColor1) ?? false) - XCTAssertTrue(Defaults[key][1]["0"]?.isEqual(fixtureColor2) ?? false) + #expect(Defaults[key][0]["1"]?.isEqual(fixtureColor1) ?? false) + #expect(Defaults[key][1]["0"]?.isEqual(fixtureColor2) ?? false) } + @Test func testDictionaryKey() { - let key = Defaults.Key<[String: UIColor]>("independentNSColorDictionaryKey", default: ["0": fixtureColor]) - XCTAssertTrue(Defaults[key]["0"]?.isEqual(fixtureColor) ?? false) + let key = Defaults.Key<[String: UIColor]>("independentNSColorDictionaryKey", default: ["0": fixtureColor], suite: suite_) + #expect(Defaults[key]["0"]?.isEqual(fixtureColor) ?? false) Defaults[key]["1"] = fixtureColor1 - XCTAssertTrue(Defaults[key]["1"]?.isEqual(fixtureColor1) ?? false) + #expect(Defaults[key]["1"]?.isEqual(fixtureColor1) ?? false) } + @Test func testDictionaryOptionalKey() { - let key = Defaults.Key<[String: UIColor]?>("independentNSColorDictionaryOptionalKey") // swiftlint:disable:this discouraged_optional_collection - XCTAssertNil(Defaults[key]) + let key = Defaults.Key<[String: UIColor]?>("independentNSColorDictionaryOptionalKey", suite: suite_) // swiftlint:disable:this discouraged_optional_collection + #expect(Defaults[key] == nil) Defaults[key] = ["0": fixtureColor] Defaults[key]?["1"] = fixtureColor1 - XCTAssertTrue(Defaults[key]?["0"]?.isEqual(fixtureColor) ?? false) - XCTAssertTrue(Defaults[key]?["1"]?.isEqual(fixtureColor1) ?? false) + #expect(Defaults[key]?["0"]?.isEqual(fixtureColor) ?? false) + #expect(Defaults[key]?["1"]?.isEqual(fixtureColor1) ?? false) } + @Test func testDictionaryArrayKey() { - let key = Defaults.Key<[String: [UIColor]]>("independentNSColorDictionaryArrayKey", default: ["0": [fixtureColor]]) - XCTAssertTrue(Defaults[key]["0"]?[0].isEqual(fixtureColor) ?? false) + let key = Defaults.Key<[String: [UIColor]]>("independentNSColorDictionaryArrayKey", default: ["0": [fixtureColor]], suite: suite_) + #expect(Defaults[key]["0"]?[0].isEqual(fixtureColor) ?? false) Defaults[key]["0"]?.append(fixtureColor1) Defaults[key]["1"] = [fixtureColor2] - XCTAssertTrue(Defaults[key]["0"]?[1].isEqual(fixtureColor1) ?? false) - XCTAssertTrue(Defaults[key]["1"]?[0].isEqual(fixtureColor2) ?? false) + #expect(Defaults[key]["0"]?[1].isEqual(fixtureColor1) ?? false) + #expect(Defaults[key]["1"]?[0].isEqual(fixtureColor2) ?? false) } + @Test func testType() { - XCTAssert(Defaults[.color].isEqual(fixtureColor)) + #expect(Defaults[.color].isEqual(fixtureColor)) Defaults[.color] = fixtureColor1 - XCTAssert(Defaults[.color].isEqual(fixtureColor1)) + #expect(Defaults[.color].isEqual(fixtureColor1)) } + @Test func testArrayType() { - XCTAssertTrue(Defaults[.colorArray][0].isEqual(fixtureColor)) + #expect(Defaults[.colorArray][0].isEqual(fixtureColor)) Defaults[.colorArray][0] = fixtureColor1 - XCTAssertTrue(Defaults[.colorArray][0].isEqual(fixtureColor1)) + #expect(Defaults[.colorArray][0].isEqual(fixtureColor1)) } + @Test func testDictionaryType() { - XCTAssertTrue(Defaults[.colorDictionary]["0"]?.isEqual(fixtureColor) ?? false) + #expect(Defaults[.colorDictionary]["0"]?.isEqual(fixtureColor) ?? false) Defaults[.colorDictionary]["0"] = fixtureColor1 - XCTAssertTrue(Defaults[.colorDictionary]["0"]?.isEqual(fixtureColor1) ?? false) - } - - func testObserveKeyCombine() { - let key = Defaults.Key("observeNSColorKeyCombine", default: fixtureColor) - let expect = expectation(description: "Observation closure being called") - - let publisher = Defaults - .publisher(key, options: []) - .map { ($0.oldValue, $0.newValue) } - .collect(2) - - let cancellable = publisher.sink { tuples in - for (index, expected) in [(fixtureColor, fixtureColor1), (fixtureColor1, fixtureColor)].enumerated() { - XCTAssertTrue(expected.0.isEqual(tuples[index].0)) - XCTAssertTrue(expected.1.isEqual(tuples[index].1)) - } - - expect.fulfill() - } - - Defaults[key] = fixtureColor1 - Defaults.reset(key) - cancellable.cancel() - - waitForExpectations(timeout: 10) - } - - func testObserveOptionalKeyCombine() { - let key = Defaults.Key("observeNSColorOptionalKeyCombine") - let expect = expectation(description: "Observation closure being called") - - let publisher = Defaults - .publisher(key, options: []) - .map { ($0.oldValue, $0.newValue) } - .collect(3) - - let expectedValue: [(UIColor?, UIColor?)] = [(nil, fixtureColor), (fixtureColor, fixtureColor1), (fixtureColor1, nil)] - - let cancellable = publisher.sink { tuples in - for (index, expected) in expectedValue.enumerated() { - guard let oldValue = expected.0 else { - XCTAssertNil(tuples[index].0) - continue - } - guard let newValue = expected.1 else { - XCTAssertNil(tuples[index].1) - continue - } - XCTAssertTrue(oldValue.isEqual(tuples[index].0)) - XCTAssertTrue(newValue.isEqual(tuples[index].1)) - } - - expect.fulfill() - } - - Defaults[key] = fixtureColor - Defaults[key] = fixtureColor1 - Defaults.reset(key) - cancellable.cancel() - - waitForExpectations(timeout: 10) - } - - func testObserveArrayKeyCombine() { - let key = Defaults.Key<[UIColor]>("observeNSColorArrayKeyCombine", default: [fixtureColor]) - let expect = expectation(description: "Observation closure being called") - - let publisher = Defaults - .publisher(key, options: []) - .map { ($0.oldValue, $0.newValue) } - .collect(2) - - let cancellable = publisher.sink { tuples in - for (index, expected) in [(fixtureColor, fixtureColor1), (fixtureColor1, fixtureColor)].enumerated() { - XCTAssertTrue(expected.0.isEqual(tuples[index].0[0])) - XCTAssertTrue(expected.1.isEqual(tuples[index].1[0])) - } - - expect.fulfill() - } - - Defaults[key][0] = fixtureColor1 - Defaults.reset(key) - cancellable.cancel() - - waitForExpectations(timeout: 10) - } - - func testObserveDictionaryKeyCombine() { - let key = Defaults.Key<[String: UIColor]>("observeNSColorDictionaryKeyCombine", default: ["0": fixtureColor]) - let expect = expectation(description: "Observation closure being called") - - let publisher = Defaults - .publisher(key, options: []) - .map { ($0.oldValue, $0.newValue) } - .collect(2) - - let cancellable = publisher.sink { tuples in - for (index, expected) in [(fixtureColor, fixtureColor1), (fixtureColor1, fixtureColor)].enumerated() { - XCTAssertTrue(expected.0.isEqual(tuples[index].0["0"])) - XCTAssertTrue(expected.1.isEqual(tuples[index].1["0"])) - } - - expect.fulfill() - } - - Defaults[key]["0"] = fixtureColor1 - Defaults.reset(key) - cancellable.cancel() - - waitForExpectations(timeout: 10) - } - - func testObserveKey() { - let key = Defaults.Key("observeNSColorKey", default: fixtureColor) - let expect = expectation(description: "Observation closure being called") - - var observation: Defaults.Observation! - observation = Defaults.observe(key, options: []) { change in - XCTAssertTrue(change.oldValue.isEqual(fixtureColor)) - XCTAssertTrue(change.newValue.isEqual(fixtureColor1)) - observation.invalidate() - expect.fulfill() - } - - Defaults[key] = fixtureColor1 - observation.invalidate() - - waitForExpectations(timeout: 10) - } - - func testObserveOptionalKey() { - let key = Defaults.Key("observeNSColorOptionalKey") - let expect = expectation(description: "Observation closure being called") - - var observation: Defaults.Observation! - observation = Defaults.observe(key, options: []) { change in - XCTAssertNil(change.oldValue) - XCTAssertTrue(change.newValue?.isEqual(fixtureColor) ?? false) - observation.invalidate() - expect.fulfill() - } - - Defaults[key] = fixtureColor - observation.invalidate() - - waitForExpectations(timeout: 10) - } - - func testObserveArrayKey() { - let key = Defaults.Key<[UIColor]>("observeNSColorArrayKey", default: [fixtureColor]) - let expect = expectation(description: "Observation closure being called") - - var observation: Defaults.Observation! - observation = Defaults.observe(key, options: []) { change in - XCTAssertTrue(change.oldValue[0].isEqual(fixtureColor)) - XCTAssertTrue(change.newValue[0].isEqual(fixtureColor)) - XCTAssertTrue(change.newValue[1].isEqual(fixtureColor1)) - observation.invalidate() - expect.fulfill() - } - - Defaults[key].append(fixtureColor1) - observation.invalidate() - - waitForExpectations(timeout: 10) - } - - func testObserveDictionaryKey() { - let key = Defaults.Key<[String: UIColor]>("observeNSColorDictionaryKey", default: ["0": fixtureColor]) - let expect = expectation(description: "Observation closure being called") - - var observation: Defaults.Observation! - observation = Defaults.observe(key, options: []) { change in - XCTAssertTrue(change.oldValue["0"]?.isEqual(fixtureColor) ?? false) - XCTAssertTrue(change.newValue["0"]?.isEqual(fixtureColor) ?? false) - XCTAssertTrue(change.newValue["1"]?.isEqual(fixtureColor1) ?? false) - observation.invalidate() - expect.fulfill() - } - - Defaults[key]["1"] = fixtureColor1 - observation.invalidate() - - waitForExpectations(timeout: 10) + #expect(Defaults[.colorDictionary]["0"]?.isEqual(fixtureColor1) ?? false) } } #endif