Convert tests to Swift Testing

This commit is contained in:
Sindre Sorhus 2024-09-26 04:17:26 +07:00
parent 4c009d5c24
commit 72264f116f
24 changed files with 1650 additions and 3964 deletions

View File

@ -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

View File

@ -1,4 +1,4 @@
// swift-tools-version:5.10
// swift-tools-version:5.11
import PackageDescription
let package = Package(

View File

@ -179,11 +179,13 @@ extension UserDefaults: DefaultsKeyValueStore {}
extension DefaultsLockProtocol {
@discardableResult
func with<R>(_ body: @Sendable () throws -> R) rethrows -> R where R: Sendable {
func with<R, E>(_ body: @Sendable () throws(E) -> R) throws(E) -> R where R: Sendable {
lock()
defer {
self.unlock()
unlock()
}
return try body()
}
}

View File

@ -169,5 +169,5 @@ protocol DefaultsLockProtocol {
func unlock()
func with<R>(_ body: @Sendable () throws -> R) rethrows -> R where R: Sendable
func with<R, E>(_ body: @Sendable () throws(E) -> R) throws(E) -> R where R: Sendable
}

View File

@ -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<String>("testICloudInitialize_name", default: "0", iCloud: true)
let quality = Defaults.Key<Double>("testICloudInitialize_quality", default: 0.0, iCloud: true)
let name = Defaults.Key<String>("testICloudInitialize_name", default: "0", suite: suite, iCloud: true)
let quality = Defaults.Key<Double>("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<String?>("testDidChangeExternallyNotification_name", iCloud: true)
let quality = Defaults.Key<Double?>("testDidChangeExternallyNotification_quality", iCloud: true)
let name = Defaults.Key<String?>("testDidChangeExternallyNotification_name", suite: suite, iCloud: true)
let quality = Defaults.Key<Double?>("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<String>("testICloudInitializeSyncLast_name", default: "0", iCloud: true)
let quality = Defaults.Key<Double>("testICloudInitializeSyncLast_quality", default: 0.0, iCloud: true)
let name = Defaults.Key<String>("testICloudInitializeSyncLast_name", default: "0", suite: suite, iCloud: true)
let quality = Defaults.Key<Double>("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..<name_expected.count {
Defaults[name] = name_expected[index]
Defaults[quality] = quality_expected[index]
XCTAssertEqual(Defaults[name], name_expected[index])
XCTAssertEqual(Defaults[quality], quality_expected[index])
#expect(Defaults[name] == name_expected[index])
#expect(Defaults[quality] == quality_expected[index])
}
await Defaults.iCloud.waitForSyncCompletion()
XCTAssertEqual(mockStorage.data(forKey: name.name), "7")
XCTAssertEqual(mockStorage.data(forKey: quality.name), 7.0)
#expect(mockStorage.data(forKey: name.name) == "7")
#expect(mockStorage.data(forKey: quality.name) == 7.0)
}
@Test
func testRemoveKey() async {
let name = Defaults.Key<String>("testRemoveKey_name", default: "0", iCloud: true)
let quality = Defaults.Key<Double>("testRemoveKey_quality", default: 0.0, iCloud: true)
let name = Defaults.Key<String>("testRemoveKey_name", default: "0", suite: suite, iCloud: true)
let quality = Defaults.Key<Double>("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<String>("testSyncKeysFromLocal_name", default: "0")
let quality = Defaults.Key<Double>("testSyncKeysFromLocal_quality", default: 0.0)
let name = Defaults.Key<String>("testSyncKeysFromLocal_name", default: "0", suite: suite)
let quality = Defaults.Key<Double>("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<String?>("testSyncKeysFromRemote_name")
let quality = Defaults.Key<Double?>("testSyncKeysFromRemote_quality")
let name = Defaults.Key<String?>("testSyncKeysFromRemote_name", suite: suite)
let quality = Defaults.Key<Double?>("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<String>("testInitAddFromDetached_name", default: "0")
let quantity = Defaults.Key<Bool>("testInitAddFromDetached_quantity", default: false)
let task = Task.detached {
let name = Defaults.Key<String>("testInitAddFromDetached_name", default: "0", suite: suite)
let quantity = Defaults.Key<Bool>("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<String>("testICloudInitializeFromDetached_name", default: "0", iCloud: true)
await Task.detached {
let name = Defaults.Key<String>("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
}
}

View File

@ -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<Defaults.AnySerializable>("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<Defaults.AnySerializable>("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<Defaults.AnySerializable>("anyKey", default: Defaults.AnySerializable(mime.JSON))
let any = Defaults.Key<Defaults.AnySerializable>("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<Defaults.AnySerializable>("independentAnyKey", default: 121_314)
XCTAssertEqual(Defaults[any], 121_314)
let any = Defaults.Key<Defaults.AnySerializable>("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<Int>.self)?.first, 1)
#expect(Defaults[any].get(Set<Int>.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<Defaults.AnySerializable?>("independentOptionalAnyKey")
XCTAssertNil(Defaults[key])
let key = Defaults.Key<Defaults.AnySerializable?>("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<Set<Defaults.AnySerializable>>("independentArrayAnyKey", default: [123])
XCTAssertEqual(Defaults[key].first, 123)
let key = Defaults.Key<Set<Defaults.AnySerializable>>("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<Int>.self)!.first, 1)
#expect(Defaults[key]["set"]!.get(Set<Int>.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<Defaults.AnySerializable>("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<Defaults.AnySerializable>("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)
cancellable.cancel()
waitForExpectations(timeout: 10)
}
func testObserveOptionalKeyCombine() {
let key = Defaults.Key<Defaults.AnySerializable?>("observeAnyOptionalKeyCombine")
let expect = expectation(description: "Observation closure being called")
for await tuples in publisher.values {
for (index, expected) in expectedValue.enumerated() {
#expect(expected.0 == tuples[index].0)
#expect(expected.1 == tuples[index].1)
}
break
}
}
@available(iOS 16.0, macOS 13.0, tvOS 16.0, watchOS 9.0, visionOS 1.0, *)
@Test
func testObserveOptionalKeyCombine() async {
let key = Defaults.Key<Defaults.AnySerializable?>("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
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)
} else if tuples[index].0?.get(String.self) != nil {
XCTAssertEqual(expected.0, tuples[index].0)
XCTAssertNil(tuples[index].1)
} else {
XCTAssertNil(tuples[index].0)
XCTAssertEqual(expected.1, tuples[index].1)
}
}
expect.fulfill()
}
Task {
try? await Task.sleep(for: .seconds(0.1))
Defaults[key] = 123
Defaults[key] = "🦄"
Defaults.reset(key)
cancellable.cancel()
waitForExpectations(timeout: 10)
}
func testObserveKey() {
let key = Defaults.Key<Defaults.AnySerializable>("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<Defaults.AnySerializable?>("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)
for await tuples in publisher.values {
for (index, expected) in expectedValue.enumerated() {
if tuples[index].0?.get(Int.self) != nil {
#expect(expected.0 == tuples[index].0)
#expect(expected.1 == tuples[index].1)
} else if tuples[index].0?.get(String.self) != nil {
#expect(expected.0 == tuples[index].0)
#expect(tuples[index].1 == nil)
} else {
#expect(tuples[index].0 == nil)
#expect(expected.1 == tuples[index].1)
}
}
break
}
}
@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)
}
}

View File

@ -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])
}
expect.fulfill()
}
let expectedValues = [(fixtureArray[0], newName), (newName, fixtureArray[0])]
Task {
try? await Task.sleep(for: .seconds(0.1))
Defaults[key][0] = newName
Defaults.reset(key)
cancellable.cancel()
waitForExpectations(timeout: 10)
}
func testObserveOptionalKeyCombine() {
let key = Defaults.Key<[String]?>("observeArrayOptionalKeyCombine") // swiftlint:disable:this discouraged_optional_collection
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])
}
break
}
}
@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
for (expected, actual) in zip(expectedValues, actualValues) {
XCTAssertEqual(expected.0, actual.0)
XCTAssertEqual(expected.1, actual.1)
}
expect.fulfill()
}
Task {
try? await Task.sleep(for: .seconds(0.1))
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()
for await actualValues in publisher.values {
for (expected, actual) in zip(expectedValues, actualValues) {
#expect(expected.0 == actual.0)
#expect(expected.1 == actual.1)
}
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)
break
}
}
}

View File

@ -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<FixtureCodableEnum>("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<FixtureCodableEnum>("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<FixtureCodableEnum>("independentCodableEnumKey", default: .tenMinutes)
XCTAssertEqual(Defaults[key], .tenMinutes)
let key = Defaults.Key<FixtureCodableEnum>("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<FixtureCodableEnum?>("independentCodableEnumOptionalKey")
XCTAssertNil(Defaults[key])
let key = Defaults.Key<FixtureCodableEnum?>("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<FixtureCodableEnumPreferRawRepresentable>(keyName, default: fixture)
XCTAssertNotNil(UserDefaults.standard.integer(forKey: keyName))
}
func testObserveKeyCombine() {
let key = Defaults.Key<FixtureCodableEnum>("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<FixtureCodableEnum?>("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<FixtureCodableEnum>("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<FixtureCodableEnum?>("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<FixtureCodableEnumPreferRawRepresentable>(keyName, default: fixture, suite: suite_)
#expect(UserDefaults.standard.integer(forKey: keyName) != 0)
}
}

View File

@ -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<Unicorn>("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<Unicorn>("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<Unicorn>("independentCodableKey", default: fixtureCodable)
XCTAssertTrue(Defaults[key].isUnicorn)
let key = Defaults.Key<Unicorn>("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<Unicorn?>("independentCodableOptionalKey")
XCTAssertNil(Defaults[key])
let key = Defaults.Key<Unicorn?>("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<Unicorn?>("independentKey_codableAndRawRepresentable")
let key = Defaults.Key<Unicorn?>("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<UnicornCodableAndNSSecureCoding>(keyName, default: fixture)
XCTAssertNil(UserDefaults.standard.data(forKey: keyName))
XCTAssertNotNil(UserDefaults.standard.string(forKey: keyName))
_ = Defaults.Key<UnicornCodableAndNSSecureCoding>(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<UnicornCodableAndPreferNSSecureCoding>(keyName, default: fixture)
XCTAssertNil(UserDefaults.standard.string(forKey: keyName))
XCTAssertNotNil(UserDefaults.standard.data(forKey: keyName))
}
func testObserveKeyCombine() {
let key = Defaults.Key<Unicorn>("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<Unicorn?>("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<Unicorn>("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<Unicorn?>("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<UnicornCodableAndPreferNSSecureCoding>(keyName, default: fixture, suite: suite_)
#expect(UserDefaults.standard.string(forKey: keyName) == nil)
#expect(UserDefaults.standard.data(forKey: keyName) != nil)
}
}

View File

@ -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<Bag<Item>>("collectionCustomElement", default: .init(items: [fixtureCustomCollection]))
fileprivate static let collectionCustomElementArray = Key<[Bag<Item>]>("collectionCustomElementArray", default: [.init(items: [fixtureCustomCollection])])
fileprivate static let collectionCustomElementDictionary = Key<[String: Bag<Item>]>("collectionCustomElementDictionary", default: ["0": .init(items: [fixtureCustomCollection])])
fileprivate static let collectionCustomElement = Key<Bag<Item>>("collectionCustomElement", default: .init(items: [fixtureCustomCollection]), suite: suite_)
fileprivate static let collectionCustomElementArray = Key<[Bag<Item>]>("collectionCustomElementArray", default: [.init(items: [fixtureCustomCollection])], suite: suite_)
fileprivate static let collectionCustomElementDictionary = Key<[String: Bag<Item>]>("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<Bag<Item>>("independentCollectionCustomElementKey", default: .init(items: [fixtureCustomCollection]))
let key = Defaults.Key<Bag<Item>>("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<Bag<Item>?>("independentCollectionCustomElementOptionalKey")
let key = Defaults.Key<Bag<Item>?>("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<Item>]>("independentCollectionCustomElementArrayKey", default: [.init(items: [fixtureCustomCollection])])
let key = Defaults.Key<[Bag<Item>]>("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<Item>]?>("independentCollectionCustomElementArrayOptionalKey") // swiftlint:disable:this discouraged_optional_collection
let key = Defaults.Key<[Bag<Item>]?>("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<Item>]]>("independentCollectionCustomElementNestedArrayKey", default: [[.init(items: [fixtureCustomCollection])]])
let key = Defaults.Key<[[Bag<Item>]]>("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<Item>]]>("independentCollectionCustomElementArrayDictionaryKey", default: [["0": .init(items: [fixtureCustomCollection])]])
let key = Defaults.Key<[[String: Bag<Item>]]>("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<Item>]>("independentCollectionCustomElementDictionaryKey", default: ["0": .init(items: [fixtureCustomCollection])])
let key = Defaults.Key<[String: Bag<Item>]>("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<Item>]?>("independentCollectionCustomElementDictionaryOptionalKey") // swiftlint:disable:this discouraged_optional_collection
let key = Defaults.Key<[String: Bag<Item>]?>("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<Item>]]>("independentCollectionCustomElementDictionaryArrayKey", default: ["0": [.init(items: [fixtureCustomCollection])]])
let key = Defaults.Key<[String: [Bag<Item>]]>("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<Bag<Item>>("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<Bag<Item>?>("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<Item>]>("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<Item>]>("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<Bag<Item>>("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<Bag<Item>?>("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<Item>]>("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<Item>]>("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)
}
}

View File

@ -1,7 +1,9 @@
import Foundation
import XCTest
import Testing
import Defaults
private let suite_ = createSuite()
struct Bag<Element: Defaults.Serializable>: 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<Bag<String>>("collection", default: Bag(items: fixtureCollection))
fileprivate static let collectionArray = Key<[Bag<String>]>("collectionArray", default: [Bag(items: fixtureCollection)])
fileprivate static let collectionDictionary = Key<[String: Bag<String>]>("collectionDictionary", default: ["0": Bag(items: fixtureCollection)])
fileprivate static let collection = Key<Bag<String>>("collection", default: Bag(items: fixtureCollection), suite: suite_)
fileprivate static let collectionArray = Key<[Bag<String>]>("collectionArray", default: [Bag(items: fixtureCollection)], suite: suite_)
fileprivate static let collectionDictionary = Key<[String: Bag<String>]>("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<Bag<String>>("independentCollectionKey", default: Bag(items: fixtureCollection))
let key = Defaults.Key<Bag<String>>("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<Bag<String>?>("independentCollectionOptionalKey")
XCTAssertNil(Defaults[key])
let key = Defaults.Key<Bag<String>?>("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<String>]>("independentCollectionArrayKey", default: [Bag(items: [fixtureCollection[0]])])
let key = Defaults.Key<[Bag<String>]>("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<String>]?>("independentCollectionArrayOptionalKey") // swiftlint:disable:this discouraged_optional_collection
XCTAssertNil(Defaults[key])
let key = Defaults.Key<[Bag<String>]?>("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<String>]]>("independentCollectionNestedArrayKey", default: [[Bag(items: [fixtureCollection[0]])]])
let key = Defaults.Key<[[Bag<String>]]>("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<String>]]>("independentCollectionArrayDictionaryKey", default: [["0": Bag(items: [fixtureCollection[0]])]])
let key = Defaults.Key<[[String: Bag<String>]]>("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<String>]>("independentCollectionDictionaryKey", default: ["0": Bag(items: [fixtureCollection[0]])])
let key = Defaults.Key<[String: Bag<String>]>("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<String>]?>("independentCollectionDictionaryOptionalKey") // swiftlint:disable:this discouraged_optional_collection
XCTAssertNil(Defaults[key])
let key = Defaults.Key<[String: Bag<String>]?>("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<String>]]>("independentCollectionDictionaryArrayKey", default: ["0": [Bag(items: [fixtureCollection[0]])]])
let key = Defaults.Key<[String: [Bag<String>]]>("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<Bag<String>>("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<Bag<String>?>("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<String>]>("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<String>]>("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<Bag<String>>("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<Bag<String>?>("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<String>]>("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<String>]>("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])
}
}

View File

@ -1,44 +1,47 @@
import SwiftUI
import Testing
import Defaults
import XCTest
private let suite_ = createSuite()
@Suite(.serialized)
final class DefaultsColorTests {
init() {
Defaults.removeAll(suite: suite_)
}
deinit {
Defaults.removeAll(suite: suite_)
}
@available(macOS 12, iOS 15, tvOS 15, watchOS 8, visionOS 1.0, *)
final class DefaultsColorTests: XCTestCase {
override func setUp() {
super.setUp()
Defaults.removeAll()
}
override func tearDown() {
super.tearDown()
Defaults.removeAll()
}
@Test
func testPreservesColorSpace() {
let fixture = Color(.displayP3, red: 1, green: 0.3, blue: 0.7, opacity: 1)
let key = Defaults.Key<Color?>("independentColorPreservesColorSpaceKey")
let key = Defaults.Key<Color?>("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)
}
}
@Suite(.serialized)
final class DefaultsColorResolvedTests {
init() {
Defaults.removeAll(suite: suite_)
}
deinit {
Defaults.removeAll(suite: suite_)
}
@available(macOS 14, iOS 17, tvOS 17, watchOS 10, visionOS 1, *)
final class DefaultsColorResolvedTests: XCTestCase {
override func setUp() {
super.setUp()
Defaults.removeAll()
}
override func tearDown() {
super.tearDown()
Defaults.removeAll()
}
@Test
func test() {
let fixture = Color(.displayP3, red: 1, green: 0.3, blue: 0.7, opacity: 1).resolve(in: .init())
let key = Defaults.Key<Color.Resolved?>("independentColorResolvedKey")
let key = Defaults.Key<Color.Resolved?>("independentColorResolvedKey", suite: suite_)
Defaults[key] = fixture
XCTAssertEqual(Defaults[key]?.cgColor, fixture.cgColor)
#expect(Defaults[key]?.cgColor == fixture.cgColor)
}
}

View File

@ -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<User>("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<User>("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<User>("independentCustomBridgeKey", default: fixtureCustomBridge)
XCTAssertEqual(Defaults[key], fixtureCustomBridge)
let key = Defaults.Key<User>("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<User?>("independentCustomBridgeOptionalKey")
XCTAssertNil(Defaults[key])
let key = Defaults.Key<User?>("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<Set<User>>("independentCustomBridgeSetKey", default: [fixtureCustomBridge])
XCTAssertEqual(Defaults[key].first, fixtureCustomBridge)
let key = Defaults.Key<Set<User>>("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<PlainHourMinuteTimeRange>("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<PlainHourMinuteTimeRange>("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<User>("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<User?>("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<User>("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<User?>("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)
}
}

View File

@ -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)
}
}

View File

@ -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<FixtureEnum>("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<FixtureEnum>("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<FixtureEnum>("independentEnumKey", default: .tenMinutes)
XCTAssertEqual(Defaults[key], .tenMinutes)
let key = Defaults.Key<FixtureEnum>("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<FixtureEnum?>("independentEnumOptionalKey")
XCTAssertNil(Defaults[key])
let key = Defaults.Key<FixtureEnum?>("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<FixtureEnum>("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<FixtureEnum?>("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<FixtureEnum>("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<FixtureEnum?>("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)
}
}

View File

@ -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>("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>("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<NSColor>("independentNSColorKey", default: fixtureColor)
XCTAssertTrue(Defaults[key].isEqual(fixtureColor))
let key = Defaults.Key<NSColor>("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<NSColor?>("independentNSColorPreservesColorSpaceKey")
let key = Defaults.Key<NSColor?>("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<NSColor?>("independentNSColorOptionalKey")
XCTAssertNil(Defaults[key])
let key = Defaults.Key<NSColor?>("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<NSColor>("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<NSColor?>("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<NSColor>("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<NSColor?>("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

View File

@ -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<ExamplePersistentHistory>("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<ExamplePersistentHistory>("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<ExamplePersistentHistory>("independentNSSecureCodingKey", default: persistentHistoryValue)
XCTAssertEqual(Defaults[key].value, persistentHistoryValue.value)
let key = Defaults.Key<ExamplePersistentHistory>("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<ExamplePersistentHistory?>("independentNSSecureCodingOptionalKey")
XCTAssertNil(Defaults[key])
let key = Defaults.Key<ExamplePersistentHistory?>("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<ExamplePersistentHistory>("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<ExamplePersistentHistory?>("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<ExamplePersistentHistory>("observeMultipleNSSecureCodingKey1", default: ExamplePersistentHistory(value: "TestValue"))
let key2 = Defaults.Key<ExamplePersistentHistory>("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<ExamplePersistentHistory?>("observeMultipleNSSecureCodingOptionalKey1")
let key2 = Defaults.Key<ExamplePersistentHistory?>("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<ExamplePersistentHistory>("observeNSSecureCodingKey1", default: ExamplePersistentHistory(value: "TestValue"))
let key2 = Defaults.Key<ExamplePersistentHistory>("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<ExamplePersistentHistory>("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<ExamplePersistentHistory?>("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<ExamplePersistentHistory>("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<ExamplePersistentHistory?>("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)
}
}

View File

@ -1,6 +1,8 @@
import Foundation
import Testing
import Defaults
import XCTest
private let suite_ = createSuite()
private struct CustomDate {
let year: Int
@ -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<Range>("independentRangeKey", default: fixtureRange)
XCTAssertEqual(fixtureRange.upperBound, Defaults[key].upperBound)
XCTAssertEqual(fixtureRange.lowerBound, Defaults[key].lowerBound)
let key = Defaults.Key<Range>("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<Range<CustomDate>>("independentRangeDateKey", default: fixtureDateRange)
XCTAssertEqual(fixtureDateRange.upperBound, Defaults[dateKey].upperBound)
XCTAssertEqual(fixtureDateRange.lowerBound, Defaults[dateKey].lowerBound)
let dateKey = Defaults.Key<Range<CustomDate>>("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<ClosedRange>("independentClosedRangeKey", default: fixtureClosedRange)
XCTAssertEqual(fixtureClosedRange.upperBound, Defaults[closedKey].upperBound)
XCTAssertEqual(fixtureClosedRange.lowerBound, Defaults[closedKey].lowerBound)
let closedKey = Defaults.Key<ClosedRange>("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<ClosedRange<CustomDate>>("independentClosedRangeDateKey", default: fixtureDateClosedRange)
XCTAssertEqual(fixtureDateClosedRange.upperBound, Defaults[closedDateKey].upperBound)
XCTAssertEqual(fixtureDateClosedRange.lowerBound, Defaults[closedDateKey].lowerBound)
let closedDateKey = Defaults.Key<ClosedRange<CustomDate>>("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<Range<Int>?>("independentRangeOptionalKey")
XCTAssertNil(Defaults[key])
let key = Defaults.Key<Range<Int>?>("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<Range<CustomDate>?>("independentRangeDateOptionalKey")
XCTAssertNil(Defaults[dateKey])
let dateKey = Defaults.Key<Range<CustomDate>?>("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<ClosedRange<Int>?>("independentClosedRangeOptionalKey")
XCTAssertNil(Defaults[closedKey])
let closedKey = Defaults.Key<ClosedRange<Int>?>("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<ClosedRange<CustomDate>?>("independentClosedRangeDateOptionalKey")
XCTAssertNil(Defaults[closedDateKey])
let closedDateKey = Defaults.Key<ClosedRange<CustomDate>?>("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<CustomDate>]>("independentRangeDateArrayKey", default: [fixtureDateRange])
XCTAssertEqual(fixtureDateRange.upperBound, Defaults[dateKey][0].upperBound)
XCTAssertEqual(fixtureDateRange.lowerBound, Defaults[dateKey][0].lowerBound)
let dateKey = Defaults.Key<[Range<CustomDate>]>("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<CustomDate>]>("independentClosedRangeDateArrayKey", default: [fixtureDateClosedRange])
XCTAssertEqual(fixtureDateClosedRange.upperBound, Defaults[closedDateKey][0].upperBound)
XCTAssertEqual(fixtureDateClosedRange.lowerBound, Defaults[closedDateKey][0].lowerBound)
let closedDateKey = Defaults.Key<[ClosedRange<CustomDate>]>("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<CustomDate>]>("independentRangeDateDictionaryKey", default: ["0": fixtureDateRange])
XCTAssertEqual(fixtureDateRange.upperBound, Defaults[dateKey]["0"]?.upperBound)
XCTAssertEqual(fixtureDateRange.lowerBound, Defaults[dateKey]["0"]?.lowerBound)
let dateKey = Defaults.Key<[String: Range<CustomDate>]>("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<CustomDate>]>("independentClosedRangeDateDictionaryKey", default: ["0": fixtureDateClosedRange])
XCTAssertEqual(fixtureDateClosedRange.upperBound, Defaults[closedDateKey]["0"]?.upperBound)
XCTAssertEqual(fixtureDateClosedRange.lowerBound, Defaults[closedDateKey]["0"]?.lowerBound)
let closedDateKey = Defaults.Key<[String: ClosedRange<CustomDate>]>("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)
}
}

View File

@ -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<DefaultsSetAlgebra<Item>>("setAlgebraCustomElement", default: .init([fixtureSetAlgebra]))
fileprivate static let setAlgebraCustomElementArray = Key<[DefaultsSetAlgebra<Item>]>("setAlgebraArrayCustomElement", default: [.init([fixtureSetAlgebra])])
fileprivate static let setAlgebraCustomElementDictionary = Key<[String: DefaultsSetAlgebra<Item>]>("setAlgebraDictionaryCustomElement", default: ["0": .init([fixtureSetAlgebra])])
fileprivate static let setAlgebraCustomElement = Key<DefaultsSetAlgebra<Item>>("setAlgebraCustomElement", default: .init([fixtureSetAlgebra]), suite: suite_)
fileprivate static let setAlgebraCustomElementArray = Key<[DefaultsSetAlgebra<Item>]>("setAlgebraArrayCustomElement", default: [.init([fixtureSetAlgebra])], suite: suite_)
fileprivate static let setAlgebraCustomElementDictionary = Key<[String: DefaultsSetAlgebra<Item>]>("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<DefaultsSetAlgebra<Item>>("independentSetAlgebraKey", default: .init([fixtureSetAlgebra]))
let key = Defaults.Key<DefaultsSetAlgebra<Item>>("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<DefaultsSetAlgebra<Item>?>("independentSetAlgebraOptionalKey")
XCTAssertNil(Defaults[key])
let key = Defaults.Key<DefaultsSetAlgebra<Item>?>("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<Item>]>("independentSetAlgebraArrayKey", default: [.init([fixtureSetAlgebra])])
let key = Defaults.Key<[DefaultsSetAlgebra<Item>]>("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<Item>]?>("independentSetAlgebraArrayOptionalKey") // swiftlint:disable:this discouraged_optional_collection
XCTAssertNil(Defaults[key])
let key = Defaults.Key<[DefaultsSetAlgebra<Item>]?>("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<Item>]]>("independentSetAlgebraNestedArrayKey", default: [[.init([fixtureSetAlgebra])]])
let key = Defaults.Key<[[DefaultsSetAlgebra<Item>]]>("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<Item>]]>("independentSetAlgebraArrayDictionaryKey", default: [["0": .init([fixtureSetAlgebra])]])
let key = Defaults.Key<[[String: DefaultsSetAlgebra<Item>]]>("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<Item>]>("independentSetAlgebraDictionaryKey", default: ["0": .init([fixtureSetAlgebra])])
let key = Defaults.Key<[String: DefaultsSetAlgebra<Item>]>("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<Item>]?>("independentSetAlgebraDictionaryOptionalKey") // swiftlint:disable:this discouraged_optional_collection
XCTAssertNil(Defaults[key])
let key = Defaults.Key<[String: DefaultsSetAlgebra<Item>]?>("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<Item>]]>("independentSetAlgebraDictionaryArrayKey", default: ["0": [.init([fixtureSetAlgebra])]])
let key = Defaults.Key<[String: [DefaultsSetAlgebra<Item>]]>("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<DefaultsSetAlgebra<Item>>("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<Item>, DefaultsSetAlgebra<Item>)] = [(.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<DefaultsSetAlgebra<Item>?>("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<Item>?, DefaultsSetAlgebra<Item>?)] = [(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<Item>]>("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<Item>, DefaultsSetAlgebra<Item>)] = [(.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<Item>]>("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<Item>, DefaultsSetAlgebra<Item>)] = [(.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<DefaultsSetAlgebra<Item>>("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<DefaultsSetAlgebra<Item>?>("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<Item>]>("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<Item>]>("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]))
}
}

View File

@ -1,7 +1,9 @@
import Foundation
import XCTest
import Testing
import Defaults
private let suite_ = createSuite()
struct DefaultsSetAlgebra<Element: Defaults.Serializable & Hashable>: SetAlgebra {
var store = Set<Element>()
@ -73,317 +75,147 @@ private let fixtureSetAlgebra2 = 2
private let fixtureSetAlgebra3 = 3
extension Defaults.Keys {
fileprivate static let setAlgebra = Key<DefaultsSetAlgebra<Int>>("setAlgebra", default: .init([fixtureSetAlgebra]))
fileprivate static let setAlgebraArray = Key<[DefaultsSetAlgebra<Int>]>("setAlgebraArray", default: [.init([fixtureSetAlgebra])])
fileprivate static let setAlgebraDictionary = Key<[String: DefaultsSetAlgebra<Int>]>("setAlgebraDictionary", default: ["0": .init([fixtureSetAlgebra])])
fileprivate static let setAlgebra = Key<DefaultsSetAlgebra<Int>>("setAlgebra", default: .init([fixtureSetAlgebra]), suite: suite_)
fileprivate static let setAlgebraArray = Key<[DefaultsSetAlgebra<Int>]>("setAlgebraArray", default: [.init([fixtureSetAlgebra])], suite: suite_)
fileprivate static let setAlgebraDictionary = Key<[String: DefaultsSetAlgebra<Int>]>("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<DefaultsSetAlgebra<Int>>("independentSetAlgebraKey", default: .init([fixtureSetAlgebra]))
let key = Defaults.Key<DefaultsSetAlgebra<Int>>("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<DefaultsSetAlgebra<Int>?>("independentSetAlgebraOptionalKey")
XCTAssertNil(Defaults[key])
let key = Defaults.Key<DefaultsSetAlgebra<Int>?>("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<Int>]>("independentSetAlgebraArrayKey", default: [.init([fixtureSetAlgebra])])
let key = Defaults.Key<[DefaultsSetAlgebra<Int>]>("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<Int>]?>("independentSetAlgebraArrayOptionalKey") // swiftlint:disable:this discouraged_optional_collection
XCTAssertNil(Defaults[key])
let key = Defaults.Key<[DefaultsSetAlgebra<Int>]?>("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<Int>]]>("independentSetAlgebraNestedArrayKey", default: [[.init([fixtureSetAlgebra])]])
let key = Defaults.Key<[[DefaultsSetAlgebra<Int>]]>("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<Int>]]>("independentSetAlgebraArrayDictionaryKey", default: [["0": .init([fixtureSetAlgebra])]])
let key = Defaults.Key<[[String: DefaultsSetAlgebra<Int>]]>("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<Int>]>("independentSetAlgebraDictionaryKey", default: ["0": .init([fixtureSetAlgebra])])
let key = Defaults.Key<[String: DefaultsSetAlgebra<Int>]>("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<Int>]?>("independentSetAlgebraDictionaryOptionalKey") // swiftlint:disable:this discouraged_optional_collection
XCTAssertNil(Defaults[key])
let key = Defaults.Key<[String: DefaultsSetAlgebra<Int>]?>("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<Int>]]>("independentSetAlgebraDictionaryArrayKey", default: ["0": [.init([fixtureSetAlgebra])]])
let key = Defaults.Key<[String: [DefaultsSetAlgebra<Int>]]>("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<DefaultsSetAlgebra<Int>>("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<Int>, DefaultsSetAlgebra<Int>)] = [(.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<DefaultsSetAlgebra<Int>?>("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<Int>?, DefaultsSetAlgebra<Int>?)] = [(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<Int>]>("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<Int>, DefaultsSetAlgebra<Int>)] = [(.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<Int>]>("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<Int>, DefaultsSetAlgebra<Int>)] = [(.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<DefaultsSetAlgebra<Int>>("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<DefaultsSetAlgebra<Int>?>("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<Int>]>("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<Int>]>("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]))
}
}

View File

@ -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<Set<Int>>("setInt", default: fixtureSet)
fileprivate static let set = Key<Set<Int>>("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<Set<Int>>("independentSetKey", default: fixtureSet)
XCTAssertEqual(Defaults[key].count, fixtureSet.count)
let key = Defaults.Key<Set<Int>>("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<Set<Int>?>("independentSetOptionalKey") // swiftlint:disable:this discouraged_optional_collection
XCTAssertNil(Defaults[key])
let key = Defaults.Key<Set<Int>?>("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<Int>]>("independentSetArrayKey", default: [fixtureSet])
XCTAssertEqual(Defaults[key][0].count, fixtureSet.count)
let key = Defaults.Key<[Set<Int>]>("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<Int>]>("independentSetArrayKey", default: ["0": fixtureSet])
XCTAssertEqual(Defaults[key]["0"]?.count, fixtureSet.count)
let key = Defaults.Key<[String: Set<Int>]>("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))
}
}

View File

@ -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<Bool>("swiftui_hasUnicorn", default: false)
fileprivate static let user = Key<User>("swiftui_user", default: User(username: "Hank", password: "123456"))
fileprivate static let setInt = Key<Set<Int>>("swiftui_setInt", default: Set(1...3))
fileprivate static let color = Key<Color>("swiftui_color", default: .black)
fileprivate static let hasUnicorn = Key<Bool>("swiftui_hasUnicorn", default: false, suite: suite_)
fileprivate static let user = Key<User>("swiftui_user", default: User(username: "Hank", password: "123456"), suite: suite_)
fileprivate static let setInt = Key<Set<Int>>("swiftui_setInt", default: Set(1...3), suite: suite_)
fileprivate static let color = Key<Color>("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)))
}
}

File diff suppressed because it is too large Load Diff

View File

@ -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<UIColor>("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<UIColor>("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<UIColor>("independentNSColorKey", default: fixtureColor)
XCTAssertTrue(Defaults[key].isEqual(fixtureColor))
let key = Defaults.Key<UIColor>("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<UIColor?>("independentNSColorPreservesColorSpaceKey")
let key = Defaults.Key<UIColor?>("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<UIColor?>("independentNSColorOptionalKey")
XCTAssertNil(Defaults[key])
let key = Defaults.Key<UIColor?>("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<UIColor>("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<UIColor?>("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<UIColor>("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<UIColor?>("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