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 runs-on: macos-14
steps: steps:
- uses: actions/checkout@v4 - 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 - run: swift test
lint: lint:
runs-on: ubuntu-latest runs-on: ubuntu-latest

View File

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

View File

@ -179,11 +179,13 @@ extension UserDefaults: DefaultsKeyValueStore {}
extension DefaultsLockProtocol { extension DefaultsLockProtocol {
@discardableResult @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() lock()
defer { defer {
self.unlock() unlock()
} }
return try body() return try body()
} }
} }

View File

@ -169,5 +169,5 @@ protocol DefaultsLockProtocol {
func unlock() 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 SwiftUI
import XCTest import Testing
@testable import Defaults
final class MockStorage: DefaultsKeyValueStore { private final class MockStorage: DefaultsKeyValueStore {
private var pairs: [String: Any] = [:] private var pairs: [String: Any] = [:]
private let queue = DispatchQueue(label: "a") private let queue = DispatchQueue(label: "a")
@ -51,9 +51,7 @@ final class MockStorage: DefaultsKeyValueStore {
@discardableResult @discardableResult
func synchronize() -> Bool { func synchronize() -> Bool {
let pairs = queue.sync { let pairs = queue.sync { Array(self.pairs.keys) }
Array(self.pairs.keys)
}
NotificationCenter.default.post(Notification(name: NSUbiquitousKeyValueStore.didChangeExternallyNotification, userInfo: [NSUbiquitousKeyValueStoreChangedKeysKey: pairs])) NotificationCenter.default.post(Notification(name: NSUbiquitousKeyValueStore.didChangeExternallyNotification, userInfo: [NSUbiquitousKeyValueStoreChangedKeysKey: pairs]))
return true return true
} }
@ -61,39 +59,34 @@ final class MockStorage: DefaultsKeyValueStore {
private let mockStorage = MockStorage() private let mockStorage = MockStorage()
@available(iOS 15, tvOS 15, watchOS 8, visionOS 1.0, *) @Suite(.serialized)
final class DefaultsICloudTests: XCTestCase { final class DefaultsICloudTests {
override final class func setUp() { private let suite = createSuite()
init() {
Defaults.iCloud.isDebug = true Defaults.iCloud.isDebug = true
Defaults.iCloud.syncOnChange = true Defaults.iCloud.syncOnChange = true
Defaults.iCloud.synchronizer = iCloudSynchronizer(remoteStorage: mockStorage) Defaults.iCloud.synchronizer = iCloudSynchronizer(remoteStorage: mockStorage)
} }
override func setUp() { deinit {
super.setUp()
mockStorage.removeAll() mockStorage.removeAll()
Defaults.iCloud.removeAll() Defaults.iCloud.removeAll()
Defaults.removeAll() Defaults.removeAll(suite: suite)
}
override func tearDown() {
super.tearDown()
mockStorage.removeAll()
Defaults.iCloud.removeAll()
Defaults.removeAll()
} }
private func updateMockStorage(key: String, value: some Any, _ date: Date? = nil) { private func updateMockStorage(key: String, value: some Any, _ date: Date? = nil) {
mockStorage.set([date ?? Date(), value], forKey: key) mockStorage.set([date ?? Date(), value], forKey: key)
} }
@Test
func testICloudInitialize() async { func testICloudInitialize() async {
let name = Defaults.Key<String>("testICloudInitialize_name", default: "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, iCloud: true) let quality = Defaults.Key<Double>("testICloudInitialize_quality", default: 0.0, suite: suite, iCloud: true)
await Defaults.iCloud.waitForSyncCompletion() await Defaults.iCloud.waitForSyncCompletion()
XCTAssertNil(mockStorage.data(forKey: name.name)) #expect(mockStorage.data(forKey: name.name) == nil)
XCTAssertNil(mockStorage.data(forKey: quality.name)) #expect(mockStorage.data(forKey: quality.name) == nil)
let name_expected = ["1", "2", "3", "4", "5", "6", "7"] 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] 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[name] = name_expected[index]
Defaults[quality] = quality_expected[index] Defaults[quality] = quality_expected[index]
await Defaults.iCloud.waitForSyncCompletion() await Defaults.iCloud.waitForSyncCompletion()
XCTAssertEqual(mockStorage.data(forKey: name.name), name_expected[index]) #expect(mockStorage.data(forKey: name.name) == name_expected[index])
XCTAssertEqual(mockStorage.data(forKey: quality.name), quality_expected[index]) #expect(mockStorage.data(forKey: quality.name) == quality_expected[index])
} }
updateMockStorage(key: quality.name, value: 8.0) updateMockStorage(key: quality.name, value: 8.0)
updateMockStorage(key: name.name, value: "8") updateMockStorage(key: name.name, value: "8")
mockStorage.synchronize() mockStorage.synchronize()
await Defaults.iCloud.waitForSyncCompletion() await Defaults.iCloud.waitForSyncCompletion()
XCTAssertEqual(Defaults[quality], 8.0) #expect(Defaults[quality] == 8.0)
XCTAssertEqual(Defaults[name], "8") #expect(Defaults[name] == "8")
Defaults[name] = "9" Defaults[name] = "9"
Defaults[quality] = 9.0 Defaults[quality] = 9.0
await Defaults.iCloud.waitForSyncCompletion() await Defaults.iCloud.waitForSyncCompletion()
XCTAssertEqual(mockStorage.data(forKey: name.name), "9") #expect(mockStorage.data(forKey: name.name) == "9")
XCTAssertEqual(mockStorage.data(forKey: quality.name), 9.0) #expect(mockStorage.data(forKey: quality.name) == 9.0)
updateMockStorage(key: quality.name, value: 10) updateMockStorage(key: quality.name, value: 10)
updateMockStorage(key: name.name, value: "10") updateMockStorage(key: name.name, value: "10")
mockStorage.synchronize() mockStorage.synchronize()
await Defaults.iCloud.waitForSyncCompletion() await Defaults.iCloud.waitForSyncCompletion()
XCTAssertEqual(Defaults[quality], 10.0) #expect(Defaults[quality] == 10.0)
XCTAssertEqual(Defaults[name], "10") #expect(Defaults[name] == "10")
} }
@Test
func testDidChangeExternallyNotification() async { func testDidChangeExternallyNotification() async {
updateMockStorage(key: "testDidChangeExternallyNotification_name", value: "0") updateMockStorage(key: "testDidChangeExternallyNotification_name", value: "0")
updateMockStorage(key: "testDidChangeExternallyNotification_quality", value: 0.0) updateMockStorage(key: "testDidChangeExternallyNotification_quality", value: 0.0)
let name = Defaults.Key<String?>("testDidChangeExternallyNotification_name", iCloud: true) let name = Defaults.Key<String?>("testDidChangeExternallyNotification_name", suite: suite, iCloud: true)
let quality = Defaults.Key<Double?>("testDidChangeExternallyNotification_quality", iCloud: true) let quality = Defaults.Key<Double?>("testDidChangeExternallyNotification_quality", suite: suite, iCloud: true)
await Defaults.iCloud.waitForSyncCompletion() await Defaults.iCloud.waitForSyncCompletion()
XCTAssertEqual(Defaults[name], "0") #expect(Defaults[name] == "0")
XCTAssertEqual(Defaults[quality], 0.0) #expect(Defaults[quality] == 0.0)
let name_expected = ["1", "2", "3", "4", "5", "6", "7"] 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] 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() mockStorage.synchronize()
} }
await Defaults.iCloud.waitForSyncCompletion() await Defaults.iCloud.waitForSyncCompletion()
XCTAssertEqual(Defaults[name], "7") #expect(Defaults[name] == "7")
XCTAssertEqual(Defaults[quality], 7.0) #expect(Defaults[quality] == 7.0)
Defaults[name] = "8" Defaults[name] = "8"
Defaults[quality] = 8.0 Defaults[quality] = 8.0
await Defaults.iCloud.waitForSyncCompletion() await Defaults.iCloud.waitForSyncCompletion()
XCTAssertEqual(mockStorage.data(forKey: name.name), "8") #expect(mockStorage.data(forKey: name.name) == "8")
XCTAssertEqual(mockStorage.data(forKey: quality.name), 8.0) #expect(mockStorage.data(forKey: quality.name) == 8.0)
Defaults[name] = nil Defaults[name] = nil
Defaults[quality] = nil Defaults[quality] = nil
await Defaults.iCloud.waitForSyncCompletion() await Defaults.iCloud.waitForSyncCompletion()
XCTAssertNil(mockStorage.data(forKey: name.name)) #expect(mockStorage.data(forKey: name.name) == nil)
XCTAssertNil(mockStorage.data(forKey: quality.name)) #expect(mockStorage.data(forKey: quality.name) == nil)
} }
@Test
func testICloudInitializeSyncLast() async { func testICloudInitializeSyncLast() async {
let name = Defaults.Key<String>("testICloudInitializeSyncLast_name", default: "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, 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 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] let quality_expected = [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0]
for index in 0..<name_expected.count { for index in 0..<name_expected.count {
Defaults[name] = name_expected[index] Defaults[name] = name_expected[index]
Defaults[quality] = quality_expected[index] Defaults[quality] = quality_expected[index]
XCTAssertEqual(Defaults[name], name_expected[index]) #expect(Defaults[name] == name_expected[index])
XCTAssertEqual(Defaults[quality], quality_expected[index]) #expect(Defaults[quality] == quality_expected[index])
} }
await Defaults.iCloud.waitForSyncCompletion() await Defaults.iCloud.waitForSyncCompletion()
XCTAssertEqual(mockStorage.data(forKey: name.name), "7") #expect(mockStorage.data(forKey: name.name) == "7")
XCTAssertEqual(mockStorage.data(forKey: quality.name), 7.0) #expect(mockStorage.data(forKey: quality.name) == 7.0)
} }
@Test
func testRemoveKey() async { func testRemoveKey() async {
let name = Defaults.Key<String>("testRemoveKey_name", default: "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, iCloud: true) let quality = Defaults.Key<Double>("testRemoveKey_quality", default: 0.0, suite: suite, iCloud: true)
Defaults[name] = "1" Defaults[name] = "1"
Defaults[quality] = 1.0 Defaults[quality] = 1.0
await Defaults.iCloud.waitForSyncCompletion() await Defaults.iCloud.waitForSyncCompletion()
XCTAssertEqual(mockStorage.data(forKey: name.name), "1") #expect(mockStorage.data(forKey: name.name) == "1")
XCTAssertEqual(mockStorage.data(forKey: quality.name), 1.0) #expect(mockStorage.data(forKey: quality.name) == 1.0)
Defaults.iCloud.remove(quality) Defaults.iCloud.remove(quality)
Defaults[name] = "2" Defaults[name] = "2"
Defaults[quality] = 1.0 Defaults[quality] = 1.0
await Defaults.iCloud.waitForSyncCompletion() await Defaults.iCloud.waitForSyncCompletion()
XCTAssertEqual(mockStorage.data(forKey: name.name), "2") #expect(mockStorage.data(forKey: name.name) == "2")
XCTAssertEqual(mockStorage.data(forKey: quality.name), 1.0) #expect(mockStorage.data(forKey: quality.name) == 1.0)
} }
@Test
func testSyncKeysFromLocal() async { func testSyncKeysFromLocal() async {
let name = Defaults.Key<String>("testSyncKeysFromLocal_name", default: "0") let name = Defaults.Key<String>("testSyncKeysFromLocal_name", default: "0", suite: suite)
let quality = Defaults.Key<Double>("testSyncKeysFromLocal_quality", default: 0.0) let quality = Defaults.Key<Double>("testSyncKeysFromLocal_quality", default: 0.0, suite: suite)
let name_expected = ["1", "2", "3", "4", "5", "6", "7"] 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] 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[quality] = quality_expected[index]
Defaults.iCloud.syncWithoutWaiting(name, quality, source: .local) Defaults.iCloud.syncWithoutWaiting(name, quality, source: .local)
await Defaults.iCloud.waitForSyncCompletion() await Defaults.iCloud.waitForSyncCompletion()
XCTAssertEqual(mockStorage.data(forKey: name.name), name_expected[index]) #expect(mockStorage.data(forKey: name.name) == name_expected[index])
XCTAssertEqual(mockStorage.data(forKey: quality.name), quality_expected[index]) #expect(mockStorage.data(forKey: quality.name) == quality_expected[index])
} }
updateMockStorage(key: name.name, value: "8") updateMockStorage(key: name.name, value: "8")
updateMockStorage(key: quality.name, value: 8) updateMockStorage(key: quality.name, value: 8)
Defaults.iCloud.syncWithoutWaiting(name, quality, source: .remote) Defaults.iCloud.syncWithoutWaiting(name, quality, source: .remote)
await Defaults.iCloud.waitForSyncCompletion() await Defaults.iCloud.waitForSyncCompletion()
XCTAssertEqual(Defaults[quality], 8.0) #expect(Defaults[quality] == 8.0)
XCTAssertEqual(Defaults[name], "8") #expect(Defaults[name] == "8")
} }
@Test
func testSyncKeysFromRemote() async { func testSyncKeysFromRemote() async {
let name = Defaults.Key<String?>("testSyncKeysFromRemote_name") let name = Defaults.Key<String?>("testSyncKeysFromRemote_name", suite: suite)
let quality = Defaults.Key<Double?>("testSyncKeysFromRemote_quality") let quality = Defaults.Key<Double?>("testSyncKeysFromRemote_quality", suite: suite)
let name_expected = ["1", "2", "3", "4", "5", "6", "7"] 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] 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]) updateMockStorage(key: quality.name, value: quality_expected[index])
Defaults.iCloud.syncWithoutWaiting(name, quality, source: .remote) Defaults.iCloud.syncWithoutWaiting(name, quality, source: .remote)
await Defaults.iCloud.waitForSyncCompletion() await Defaults.iCloud.waitForSyncCompletion()
XCTAssertEqual(Defaults[name], name_expected[index]) #expect(Defaults[name] == name_expected[index])
XCTAssertEqual(Defaults[quality], quality_expected[index]) #expect(Defaults[quality] == quality_expected[index])
} }
Defaults[name] = "8" Defaults[name] = "8"
Defaults[quality] = 8.0 Defaults[quality] = 8.0
Defaults.iCloud.syncWithoutWaiting(name, quality, source: .local) Defaults.iCloud.syncWithoutWaiting(name, quality, source: .local)
await Defaults.iCloud.waitForSyncCompletion() await Defaults.iCloud.waitForSyncCompletion()
XCTAssertEqual(mockStorage.data(forKey: name.name), "8") #expect(mockStorage.data(forKey: name.name) == "8")
XCTAssertEqual(mockStorage.data(forKey: quality.name), 8.0) #expect(mockStorage.data(forKey: quality.name) == 8.0)
Defaults[name] = nil Defaults[name] = nil
Defaults[quality] = nil Defaults[quality] = nil
Defaults.iCloud.syncWithoutWaiting(name, quality, source: .local) Defaults.iCloud.syncWithoutWaiting(name, quality, source: .local)
await Defaults.iCloud.waitForSyncCompletion() await Defaults.iCloud.waitForSyncCompletion()
XCTAssertNil(mockStorage.object(forKey: name.name)) #expect(mockStorage.object(forKey: name.name) == nil)
XCTAssertNil(mockStorage.object(forKey: quality.name)) #expect(mockStorage.object(forKey: quality.name) == nil)
} }
@Test
func testAddFromDetached() async { func testAddFromDetached() async {
let name = Defaults.Key<String>("testInitAddFromDetached_name", default: "0") let name = Defaults.Key<String>("testInitAddFromDetached_name", default: "0", suite: suite)
let quantity = Defaults.Key<Bool>("testInitAddFromDetached_quantity", default: false) let quantity = Defaults.Key<Bool>("testInitAddFromDetached_quantity", default: false, suite: suite)
let task = Task.detached { await Task.detached {
Defaults.iCloud.add(name, quantity) Defaults.iCloud.add(name, quantity)
Defaults.iCloud.syncWithoutWaiting() Defaults.iCloud.syncWithoutWaiting()
await Defaults.iCloud.waitForSyncCompletion() await Defaults.iCloud.waitForSyncCompletion()
} }.value
await task.value #expect(mockStorage.data(forKey: name.name) == "0")
XCTAssertEqual(mockStorage.data(forKey: name.name), "0")
Defaults[name] = "1" Defaults[name] = "1"
await Defaults.iCloud.waitForSyncCompletion() await Defaults.iCloud.waitForSyncCompletion()
XCTAssertEqual(mockStorage.data(forKey: name.name), "1") #expect(mockStorage.data(forKey: name.name) == "1")
} }
@Test
func testICloudInitializeFromDetached() async { func testICloudInitializeFromDetached() async {
let task = Task.detached { await Task.detached {
let name = Defaults.Key<String>("testICloudInitializeFromDetached_name", default: "0", iCloud: true) let name = Defaults.Key<String>("testICloudInitializeFromDetached_name", default: "0", suite: self.suite, iCloud: true)
await Defaults.iCloud.waitForSyncCompletion() await Defaults.iCloud.waitForSyncCompletion()
XCTAssertNil(mockStorage.data(forKey: name.name)) #expect(mockStorage.data(forKey: name.name) == nil)
} }.value
await task.value
} }
} }

View File

@ -1,6 +1,8 @@
import SwiftUI
import Testing
import Defaults import Defaults
import Foundation
import XCTest private let suite_ = createSuite()
private enum mime: String, Defaults.Serializable { private enum mime: String, Defaults.Serializable {
case JSON = "application/json" case JSON = "application/json"
@ -30,347 +32,360 @@ private struct UnicornBridge: Defaults.Bridge {
} }
extension Defaults.Keys { extension Defaults.Keys {
fileprivate static let magic = Key<[String: Defaults.AnySerializable]>("magic", default: [:]) fileprivate static let magic = Key<[String: Defaults.AnySerializable]>("magic", default: [:], suite: suite_)
fileprivate static let anyKey = Key<Defaults.AnySerializable>("anyKey", default: "🦄") fileprivate static let anyKey = Key<Defaults.AnySerializable>("anyKey", default: "🦄", suite: suite_)
fileprivate static let anyArrayKey = Key<[Defaults.AnySerializable]>("anyArrayKey", default: ["No.1 🦄", "No.2 🦄"]) 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": "🦄"]) fileprivate static let anyDictionaryKey = Key<[String: Defaults.AnySerializable]>("anyDictionaryKey", default: ["unicorn": "🦄"], suite: suite_)
} }
final class DefaultsAnySerializableTests: XCTestCase { @Suite(.serialized)
override func setUp() { final class DefaultsAnySerializableTests {
super.setUp() init() {
Defaults.removeAll() Defaults.removeAll(suite: suite_)
} }
override func tearDown() { deinit {
super.tearDown() Defaults.removeAll(suite: suite_)
Defaults.removeAll()
} }
@Test
func testReadMeExample() { 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() { if let mimeType: mime = Defaults[any].get() {
XCTAssertEqual(mimeType, mime.JSON) #expect(mimeType == mime.JSON)
} }
Defaults[any].set(mime.STREAM) Defaults[any].set(mime.STREAM)
if let mimeType: mime = Defaults[any].get() { if let mimeType: mime = Defaults[any].get() {
XCTAssertEqual(mimeType, mime.STREAM) #expect(mimeType == mime.STREAM)
} }
Defaults[any].set(mime.JSON) Defaults[any].set(mime.JSON)
if let mimeType: mime = Defaults[any].get() { if let mimeType: mime = Defaults[any].get() {
XCTAssertEqual(mimeType, mime.JSON) #expect(mimeType == mime.JSON)
} }
Defaults[.magic]["unicorn"] = "🦄" Defaults[.magic]["unicorn"] = "🦄"
Defaults[.magic]["number"] = 3 Defaults[.magic]["number"] = 3
Defaults[.magic]["boolean"] = true Defaults[.magic]["boolean"] = true
Defaults[.magic]["enum"] = Defaults.AnySerializable(mime.JSON) Defaults[.magic]["enum"] = Defaults.AnySerializable(mime.JSON)
XCTAssertEqual(Defaults[.magic]["unicorn"], "🦄") #expect(Defaults[.magic]["unicorn"] == "🦄")
XCTAssertEqual(Defaults[.magic]["number"], 3) #expect(Defaults[.magic]["number"] == 3)
if let bool: Bool = Defaults[.magic]["unicorn"]?.get() { 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) Defaults[.magic]["enum"]?.set(mime.STREAM)
if let value: String = Defaults[.magic]["unicorn"]?.get() { if let value: String = Defaults[.magic]["unicorn"]?.get() {
XCTAssertEqual(value, "🦄") #expect(value == "🦄")
} }
if let mimeType: mime = Defaults[.magic]["enum"]?.get() { if let mimeType: mime = Defaults[.magic]["enum"]?.get() {
XCTAssertEqual(mimeType, mime.STREAM) #expect(mimeType == mime.STREAM)
} }
Defaults[any].set(mime.JSON) Defaults[any].set(mime.JSON)
if let mimeType: mime = Defaults[any].get() { if let mimeType: mime = Defaults[any].get() {
XCTAssertEqual(mime.JSON, mimeType) #expect(mime.JSON == mimeType)
} }
Defaults[any].set(mime.STREAM) Defaults[any].set(mime.STREAM)
if let mimeType: mime = Defaults[any].get() { if let mimeType: mime = Defaults[any].get() {
XCTAssertEqual(mime.STREAM, mimeType) #expect(mime.STREAM == mimeType)
} }
} }
@Test
func testKey() { func testKey() {
// Test Int // Test Int
let any = Defaults.Key<Defaults.AnySerializable>("independentAnyKey", default: 121_314) let any = Defaults.Key<Defaults.AnySerializable>("independentAnyKey", default: 121_314, suite: suite_)
XCTAssertEqual(Defaults[any], 121_314) #expect(Defaults[any] == 121_314)
// Test Int8 // Test Int8
let int8 = Int8.max let int8 = Int8.max
Defaults[any].set(int8) Defaults[any].set(int8)
XCTAssertEqual(Defaults[any].get(), int8) #expect(Defaults[any].get() == int8)
// Test Int16 // Test Int16
let int16 = Int16.max let int16 = Int16.max
Defaults[any].set(int16) Defaults[any].set(int16)
XCTAssertEqual(Defaults[any].get(), int16) #expect(Defaults[any].get() == int16)
// Test Int32 // Test Int32
let int32 = Int32.max let int32 = Int32.max
Defaults[any].set(int32) Defaults[any].set(int32)
XCTAssertEqual(Defaults[any].get(), int32) #expect(Defaults[any].get() == int32)
// Test Int64 // Test Int64
let int64 = Int64.max let int64 = Int64.max
Defaults[any].set(int64) Defaults[any].set(int64)
XCTAssertEqual(Defaults[any].get(), int64) #expect(Defaults[any].get() == int64)
// Test UInt // Test UInt
let uint = UInt.max let uint = UInt.max
Defaults[any].set(uint) Defaults[any].set(uint)
XCTAssertEqual(Defaults[any].get(), uint) #expect(Defaults[any].get() == uint)
// Test UInt8 // Test UInt8
let uint8 = UInt8.max let uint8 = UInt8.max
Defaults[any].set(uint8) Defaults[any].set(uint8)
XCTAssertEqual(Defaults[any].get(), uint8) #expect(Defaults[any].get() == uint8)
// Test UInt16 // Test UInt16
let uint16 = UInt16.max let uint16 = UInt16.max
Defaults[any].set(uint16) Defaults[any].set(uint16)
XCTAssertEqual(Defaults[any].get(), uint16) #expect(Defaults[any].get() == uint16)
// Test UInt32 // Test UInt32
let uint32 = UInt32.max let uint32 = UInt32.max
Defaults[any].set(uint32) Defaults[any].set(uint32)
XCTAssertEqual(Defaults[any].get(), uint32) #expect(Defaults[any].get() == uint32)
// Test UInt64 // Test UInt64
let uint64 = UInt64.max let uint64 = UInt64.max
Defaults[any].set(uint64) Defaults[any].set(uint64)
XCTAssertEqual(Defaults[any].get(), uint64) #expect(Defaults[any].get() == uint64)
// Test Double // Test Double
Defaults[any] = 12_131.4 Defaults[any] = 12_131.4
XCTAssertEqual(Defaults[any], 12_131.4) #expect(Defaults[any] == 12_131.4)
// Test Bool // Test Bool
Defaults[any] = true Defaults[any] = true
XCTAssertTrue(Defaults[any].get(Bool.self)!) #expect(Defaults[any].get(Bool.self)!)
// Test String // Test String
Defaults[any] = "121314" Defaults[any] = "121314"
XCTAssertEqual(Defaults[any], "121314") #expect(Defaults[any] == "121314")
// Test Float // Test Float
Defaults[any].set(12_131.456, type: Float.self) 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 // Test Date
let date = Date() let date = Date()
Defaults[any].set(date) Defaults[any].set(date)
XCTAssertEqual(Defaults[any].get(Date.self), date) #expect(Defaults[any].get(Date.self) == date)
// Test Data // Test Data
let data = "121314".data(using: .utf8) let data = "121314".data(using: .utf8)
Defaults[any].set(data) Defaults[any].set(data)
XCTAssertEqual(Defaults[any].get(Data.self), data) #expect(Defaults[any].get(Data.self) == data)
// Test Array // Test Array
Defaults[any] = [1, 2, 3] Defaults[any] = [1, 2, 3]
if let array: [Int] = Defaults[any].get() { if let array: [Int] = Defaults[any].get() {
XCTAssertEqual(array[0], 1) #expect(array[0] == 1)
XCTAssertEqual(array[1], 2) #expect(array[1] == 2)
XCTAssertEqual(array[2], 3) #expect(array[2] == 3)
} }
// Test Dictionary // Test Dictionary
Defaults[any] = ["unicorn": "🦄", "boolean": true, "number": 3] Defaults[any] = ["unicorn": "🦄", "boolean": true, "number": 3]
if let dictionary = Defaults[any].get([String: Defaults.AnySerializable].self) { if let dictionary = Defaults[any].get([String: Defaults.AnySerializable].self) {
XCTAssertEqual(dictionary["unicorn"], "🦄") #expect(dictionary["unicorn"] == "🦄")
XCTAssertTrue(dictionary["boolean"]!.get(Bool.self)!) #expect(dictionary["boolean"]?.get(Bool.self) == true)
XCTAssertEqual(dictionary["number"], 3) #expect(dictionary["number"] == 3)
} }
// Test Set // Test Set
Defaults[any].set(Set([1])) 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 // Test URL
Defaults[any].set(URL(string: "https://example.com")!) 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) #if os(macOS)
// Test NSColor // Test NSColor
Defaults[any].set(NSColor(red: Double(103) / Double(0xFF), green: Double(132) / Double(0xFF), blue: Double(255) / Double(0xFF), alpha: 0.987)) 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 #else
// Test UIColor // Test UIColor
Defaults[any].set(UIColor(red: Double(103) / Double(0xFF), green: Double(132) / Double(0xFF), blue: Double(255) / Double(0xFF), alpha: 0.654)) 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 #endif
// Test Codable type // Test Codable type
Defaults[any].set(CodableUnicorn(is_missing: false)) 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 // Test Custom type
Defaults[any].set(Unicorn(is_missing: true)) 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 // Test nil
Defaults[any] = nil Defaults[any] = nil
XCTAssertEqual(Defaults[any], 121_314) #expect(Defaults[any] == 121_314)
} }
@Test
func testOptionalKey() { func testOptionalKey() {
let key = Defaults.Key<Defaults.AnySerializable?>("independentOptionalAnyKey") let key = Defaults.Key<Defaults.AnySerializable?>("independentOptionalAnyKey", suite: suite_)
XCTAssertNil(Defaults[key]) #expect(Defaults[key] == nil)
Defaults[key] = 12_131.4 Defaults[key] = 12_131.4
XCTAssertEqual(Defaults[key], 12_131.4) #expect(Defaults[key] == 12_131.4)
Defaults[key]?.set(mime.JSON) Defaults[key]?.set(mime.JSON)
XCTAssertEqual(Defaults[key]?.get(mime.self), mime.JSON) #expect(Defaults[key]?.get(mime.self) == mime.JSON)
Defaults[key] = nil Defaults[key] = nil
XCTAssertNil(Defaults[key]) #expect(Defaults[key] == nil)
} }
@Test
func testArrayKey() { func testArrayKey() {
let key = Defaults.Key<[Defaults.AnySerializable]>("independentArrayAnyKey", default: [123, 456]) let key = Defaults.Key<[Defaults.AnySerializable]>("independentArrayAnyKey", default: [123, 456], suite: suite_)
XCTAssertEqual(Defaults[key][0], 123) #expect(Defaults[key][0] == 123)
XCTAssertEqual(Defaults[key][1], 456) #expect(Defaults[key][1] == 456)
Defaults[key][0] = 12_131.4 Defaults[key][0] = 12_131.4
XCTAssertEqual(Defaults[key][0], 12_131.4) #expect(Defaults[key][0] == 12_131.4)
} }
@Test
func testSetKey() { func testSetKey() {
let key = Defaults.Key<Set<Defaults.AnySerializable>>("independentArrayAnyKey", default: [123]) let key = Defaults.Key<Set<Defaults.AnySerializable>>("independentArrayAnyKey", default: [123], suite: suite_)
XCTAssertEqual(Defaults[key].first, 123) #expect(Defaults[key].first == 123)
Defaults[key].insert(12_131.4) 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()) let date = Defaults.AnySerializable(Date())
Defaults[key].insert(date) Defaults[key].insert(date)
XCTAssertTrue(Defaults[key].contains(date)) #expect(Defaults[key].contains(date))
let data = Defaults.AnySerializable("Hello World!".data(using: .utf8)) let data = Defaults.AnySerializable("Hello World!".data(using: .utf8))
Defaults[key].insert(data) Defaults[key].insert(data)
XCTAssertTrue(Defaults[key].contains(data)) #expect(Defaults[key].contains(data))
let int = Defaults.AnySerializable(Int.max) let int = Defaults.AnySerializable(Int.max)
Defaults[key].insert(int) Defaults[key].insert(int)
XCTAssertTrue(Defaults[key].contains(int)) #expect(Defaults[key].contains(int))
let int8 = Defaults.AnySerializable(Int8.max) let int8 = Defaults.AnySerializable(Int8.max)
Defaults[key].insert(int8) Defaults[key].insert(int8)
XCTAssertTrue(Defaults[key].contains(int8)) #expect(Defaults[key].contains(int8))
let int16 = Defaults.AnySerializable(Int16.max) let int16 = Defaults.AnySerializable(Int16.max)
Defaults[key].insert(int16) Defaults[key].insert(int16)
XCTAssertTrue(Defaults[key].contains(int16)) #expect(Defaults[key].contains(int16))
let int32 = Defaults.AnySerializable(Int32.max) let int32 = Defaults.AnySerializable(Int32.max)
Defaults[key].insert(int32) Defaults[key].insert(int32)
XCTAssertTrue(Defaults[key].contains(int32)) #expect(Defaults[key].contains(int32))
let int64 = Defaults.AnySerializable(Int64.max) let int64 = Defaults.AnySerializable(Int64.max)
Defaults[key].insert(int64) Defaults[key].insert(int64)
XCTAssertTrue(Defaults[key].contains(int64)) #expect(Defaults[key].contains(int64))
let uint = Defaults.AnySerializable(UInt.max) let uint = Defaults.AnySerializable(UInt.max)
Defaults[key].insert(uint) Defaults[key].insert(uint)
XCTAssertTrue(Defaults[key].contains(uint)) #expect(Defaults[key].contains(uint))
let uint8 = Defaults.AnySerializable(UInt8.max) let uint8 = Defaults.AnySerializable(UInt8.max)
Defaults[key].insert(uint8) Defaults[key].insert(uint8)
XCTAssertTrue(Defaults[key].contains(uint8)) #expect(Defaults[key].contains(uint8))
let uint16 = Defaults.AnySerializable(UInt16.max) let uint16 = Defaults.AnySerializable(UInt16.max)
Defaults[key].insert(uint16) Defaults[key].insert(uint16)
XCTAssertTrue(Defaults[key].contains(uint16)) #expect(Defaults[key].contains(uint16))
let uint32 = Defaults.AnySerializable(UInt32.max) let uint32 = Defaults.AnySerializable(UInt32.max)
Defaults[key].insert(uint32) Defaults[key].insert(uint32)
XCTAssertTrue(Defaults[key].contains(uint32)) #expect(Defaults[key].contains(uint32))
let uint64 = Defaults.AnySerializable(UInt64.max) let uint64 = Defaults.AnySerializable(UInt64.max)
Defaults[key].insert(uint64) Defaults[key].insert(uint64)
XCTAssertTrue(Defaults[key].contains(uint64)) #expect(Defaults[key].contains(uint64))
let bool: Defaults.AnySerializable = false let bool: Defaults.AnySerializable = false
Defaults[key].insert(bool) Defaults[key].insert(bool)
XCTAssertTrue(Defaults[key].contains(bool)) #expect(Defaults[key].contains(bool))
let float = Defaults.AnySerializable(Float(1213.14)) let float = Defaults.AnySerializable(Float(1213.14))
Defaults[key].insert(float) 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 let cgFloat = Defaults.AnySerializable(CGFloat(12_131.415)) // swiftlint:disable:this no_cgfloat2
Defaults[key].insert(cgFloat) Defaults[key].insert(cgFloat)
XCTAssertTrue(Defaults[key].contains(cgFloat)) #expect(Defaults[key].contains(cgFloat))
let string = Defaults.AnySerializable("Hello World!") let string = Defaults.AnySerializable("Hello World!")
Defaults[key].insert(string) Defaults[key].insert(string)
XCTAssertTrue(Defaults[key].contains(string)) #expect(Defaults[key].contains(string))
let array: Defaults.AnySerializable = [1, 2, 3, 4] let array: Defaults.AnySerializable = [1, 2, 3, 4]
Defaults[key].insert(array) Defaults[key].insert(array)
XCTAssertTrue(Defaults[key].contains(array)) #expect(Defaults[key].contains(array))
let dictionary: Defaults.AnySerializable = ["Hello": "World!"] let dictionary: Defaults.AnySerializable = ["Hello": "World!"]
Defaults[key].insert(dictionary) Defaults[key].insert(dictionary)
XCTAssertTrue(Defaults[key].contains(dictionary)) #expect(Defaults[key].contains(dictionary))
let unicorn = Defaults.AnySerializable(Unicorn(is_missing: true)) let unicorn = Defaults.AnySerializable(Unicorn(is_missing: true))
Defaults[key].insert(unicorn) Defaults[key].insert(unicorn)
XCTAssertTrue(Defaults[key].contains(unicorn)) #expect(Defaults[key].contains(unicorn))
} }
@Test
func testArrayOptionalKey() { func testArrayOptionalKey() {
let key = Defaults.Key<[Defaults.AnySerializable]?>("testArrayOptionalAnyKey") // swiftlint:disable:this discouraged_optional_collection let key = Defaults.Key<[Defaults.AnySerializable]?>("testArrayOptionalAnyKey", suite: suite_) // swiftlint:disable:this discouraged_optional_collection
XCTAssertNil(Defaults[key]) #expect(Defaults[key] == nil)
Defaults[key] = [123] Defaults[key] = [123]
Defaults[key]?.append(456) Defaults[key]?.append(456)
XCTAssertEqual(Defaults[key]![0], 123) #expect(Defaults[key]![0] == 123)
XCTAssertEqual(Defaults[key]![1], 456) #expect(Defaults[key]![1] == 456)
Defaults[key]![0] = 12_131.4 Defaults[key]![0] = 12_131.4
XCTAssertEqual(Defaults[key]![0], 12_131.4) #expect(Defaults[key]![0] == 12_131.4)
} }
@Test
func testNestedArrayKey() { 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) Defaults[key][0].append(456)
XCTAssertEqual(Defaults[key][0][0], 123) #expect(Defaults[key][0][0] == 123)
XCTAssertEqual(Defaults[key][0][1], 456) #expect(Defaults[key][0][1] == 456)
Defaults[key].append([12_131.4]) 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() { func testDictionaryKey() {
let key = Defaults.Key<[String: Defaults.AnySerializable]>("independentDictionaryAnyKey", default: ["unicorn": ""]) let key = Defaults.Key<[String: Defaults.AnySerializable]>("independentDictionaryAnyKey", default: ["unicorn": ""], suite: suite_)
XCTAssertEqual(Defaults[key]["unicorn"], "") #expect(Defaults[key]["unicorn"] == "")
Defaults[key]["unicorn"] = "🦄" Defaults[key]["unicorn"] = "🦄"
XCTAssertEqual(Defaults[key]["unicorn"], "🦄") #expect(Defaults[key]["unicorn"] == "🦄")
Defaults[key]["number"] = 3 Defaults[key]["number"] = 3
Defaults[key]["boolean"] = true Defaults[key]["boolean"] = true
XCTAssertEqual(Defaults[key]["number"], 3) #expect(Defaults[key]["number"] == 3)
if let bool: Bool = Defaults[.magic]["unicorn"]?.get() { if let bool: Bool = Defaults[.magic]["unicorn"]?.get() {
XCTAssertTrue(bool) #expect(bool)
} }
Defaults[key]["set"] = Defaults.AnySerializable(Set([1])) 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 Defaults[key]["nil"] = nil
XCTAssertNil(Defaults[key]["nil"]) #expect(Defaults[key]["nil"] == nil)
} }
@Test
func testDictionaryOptionalKey() { func testDictionaryOptionalKey() {
let key = Defaults.Key<[String: Defaults.AnySerializable]?>("independentDictionaryOptionalAnyKey") // swiftlint:disable:this discouraged_optional_collection let key = Defaults.Key<[String: Defaults.AnySerializable]?>("independentDictionaryOptionalAnyKey", suite: suite_) // swiftlint:disable:this discouraged_optional_collection
XCTAssertNil(Defaults[key]) #expect(Defaults[key] == nil)
Defaults[key] = ["unicorn": "🦄"] Defaults[key] = ["unicorn": "🦄"]
XCTAssertEqual(Defaults[key]?["unicorn"], "🦄") #expect(Defaults[key]?["unicorn"] == "🦄")
Defaults[key]?["number"] = 3 Defaults[key]?["number"] = 3
Defaults[key]?["boolean"] = true Defaults[key]?["boolean"] = true
XCTAssertEqual(Defaults[key]?["number"], 3) #expect(Defaults[key]?["number"] == 3)
XCTAssertEqual(Defaults[key]?["boolean"], true) #expect(Defaults[key]?["boolean"] == true)
} }
@Test
func testDictionaryArrayKey() { func testDictionaryArrayKey() {
let key = Defaults.Key<[String: [Defaults.AnySerializable]]>("independentDictionaryArrayAnyKey", default: ["number": [1]]) let key = Defaults.Key<[String: [Defaults.AnySerializable]]>("independentDictionaryArrayAnyKey", default: ["number": [1]], suite: suite_)
XCTAssertEqual(Defaults[key]["number"]?[0], 1) #expect(Defaults[key]["number"]?[0] == 1)
Defaults[key]["number"]?.append(2) Defaults[key]["number"]?.append(2)
Defaults[key]["unicorn"] = ["No.1 🦄"] Defaults[key]["unicorn"] = ["No.1 🦄"]
Defaults[key]["unicorn"]?.append("No.2 🦄") Defaults[key]["unicorn"]?.append("No.2 🦄")
Defaults[key]["unicorn"]?.append("No.3 🦄") Defaults[key]["unicorn"]?.append("No.3 🦄")
Defaults[key]["boolean"] = [true] Defaults[key]["boolean"] = [true]
Defaults[key]["boolean"]?.append(false) Defaults[key]["boolean"]?.append(false)
XCTAssertEqual(Defaults[key]["number"]?[1], 2) #expect(Defaults[key]["number"]?[1] == 2)
XCTAssertEqual(Defaults[key]["unicorn"]?[0], "No.1 🦄") #expect(Defaults[key]["unicorn"]?[0] == "No.1 🦄")
XCTAssertEqual(Defaults[key]["unicorn"]?[1], "No.2 🦄") #expect(Defaults[key]["unicorn"]?[1] == "No.2 🦄")
XCTAssertEqual(Defaults[key]["unicorn"]?[2], "No.3 🦄") #expect(Defaults[key]["unicorn"]?[2] == "No.3 🦄")
XCTAssertTrue(Defaults[key]["boolean"]![0].get(Bool.self)!) // #expect(#require(Defaults[key]["boolean"]?[0].get(Bool.self)) == true)
XCTAssertFalse(Defaults[key]["boolean"]![1].get(Bool.self)!) #expect(Defaults[key]["boolean"]?[1].get(Bool.self) == false)
} }
@Test
func testType() { func testType() {
XCTAssertEqual(Defaults[.anyKey], "🦄") #expect(Defaults[.anyKey] == "🦄")
Defaults[.anyKey] = 123 Defaults[.anyKey] = 123
XCTAssertEqual(Defaults[.anyKey], 123) #expect(Defaults[.anyKey] == 123)
} }
@Test
func testArrayType() { func testArrayType() {
XCTAssertEqual(Defaults[.anyArrayKey][0], "No.1 🦄") #expect(Defaults[.anyArrayKey][0] == "No.1 🦄")
XCTAssertEqual(Defaults[.anyArrayKey][1], "No.2 🦄") #expect(Defaults[.anyArrayKey][1] == "No.2 🦄")
Defaults[.anyArrayKey].append(123) Defaults[.anyArrayKey].append(123)
XCTAssertEqual(Defaults[.anyArrayKey][2], 123) #expect(Defaults[.anyArrayKey][2] == 123)
} }
@Test
func testDictionaryType() { func testDictionaryType() {
XCTAssertEqual(Defaults[.anyDictionaryKey]["unicorn"], "🦄") #expect(Defaults[.anyDictionaryKey]["unicorn"] == "🦄")
Defaults[.anyDictionaryKey]["number"] = 3 Defaults[.anyDictionaryKey]["number"] = 3
XCTAssertEqual(Defaults[.anyDictionaryKey]["number"], 3) #expect(Defaults[.anyDictionaryKey]["number"] == 3)
Defaults[.anyDictionaryKey]["boolean"] = true Defaults[.anyDictionaryKey]["boolean"] = true
XCTAssertTrue(Defaults[.anyDictionaryKey]["boolean"]!.get(Bool.self)!) #expect(Defaults[.anyDictionaryKey]["boolean"]!.get(Bool.self)!)
Defaults[.anyDictionaryKey]["array"] = [1, 2] Defaults[.anyDictionaryKey]["array"] = [1, 2]
if let array = Defaults[.anyDictionaryKey]["array"]?.get([Int].self) { if let array = Defaults[.anyDictionaryKey]["array"]?.get([Int].self) {
XCTAssertEqual(array[0], 1) #expect(array[0] == 1)
XCTAssertEqual(array[1], 2) #expect(array[1] == 2)
} }
} }
func testObserveKeyCombine() { @available(iOS 16.0, macOS 13.0, tvOS 16.0, watchOS 9.0, visionOS 1.0, *)
let key = Defaults.Key<Defaults.AnySerializable>("observeAnyKeyCombine", default: 123) @Test
let expect = expectation(description: "Observation closure being called") func testObserveKeyCombine() async {
let key = Defaults.Key<Defaults.AnySerializable>("observeAnyKeyCombine", default: 123, suite: suite_)
let publisher = Defaults let publisher = Defaults
.publisher(key, options: []) .publisher(key, options: [])
@ -379,25 +394,26 @@ final class DefaultsAnySerializableTests: XCTestCase {
let expectedValue: [(Defaults.AnySerializable, Defaults.AnySerializable)] = [(123, "🦄"), ("🦄", 123)] let expectedValue: [(Defaults.AnySerializable, Defaults.AnySerializable)] = [(123, "🦄"), ("🦄", 123)]
let cancellable = publisher.sink { tuples in Task {
for (index, expected) in expectedValue.enumerated() { try? await Task.sleep(for: .seconds(0.1))
XCTAssertEqual(expected.0, tuples[index].0)
XCTAssertEqual(expected.1, tuples[index].1)
}
expect.fulfill()
}
Defaults[key] = "🦄" Defaults[key] = "🦄"
Defaults.reset(key) Defaults.reset(key)
cancellable.cancel()
waitForExpectations(timeout: 10)
} }
func testObserveOptionalKeyCombine() { for await tuples in publisher.values {
let key = Defaults.Key<Defaults.AnySerializable?>("observeAnyOptionalKeyCombine") for (index, expected) in expectedValue.enumerated() {
let expect = expectation(description: "Observation closure being called") #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 let publisher = Defaults
.publisher(key, options: []) .publisher(key, options: [])
@ -406,70 +422,34 @@ final class DefaultsAnySerializableTests: XCTestCase {
let expectedValue: [(Defaults.AnySerializable?, Defaults.AnySerializable?)] = [(nil, 123), (123, "🦄"), ("🦄", nil)] let expectedValue: [(Defaults.AnySerializable?, Defaults.AnySerializable?)] = [(nil, 123), (123, "🦄"), ("🦄", nil)]
let cancellable = publisher.sink { tuples in Task {
for (index, expected) in expectedValue.enumerated() { try? await Task.sleep(for: .seconds(0.1))
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()
}
Defaults[key] = 123 Defaults[key] = 123
Defaults[key] = "🦄" Defaults[key] = "🦄"
Defaults.reset(key) Defaults.reset(key)
cancellable.cancel()
waitForExpectations(timeout: 10)
} }
func testObserveKey() { for await tuples in publisher.values {
let key = Defaults.Key<Defaults.AnySerializable>("observeAnyKey", default: 123) for (index, expected) in expectedValue.enumerated() {
let expect = expectation(description: "Observation closure being called") if tuples[index].0?.get(Int.self) != nil {
#expect(expected.0 == tuples[index].0)
var observation: Defaults.Observation! #expect(expected.1 == tuples[index].1)
observation = Defaults.observe(key, options: []) { change in } else if tuples[index].0?.get(String.self) != nil {
XCTAssertEqual(change.oldValue, 123) #expect(expected.0 == tuples[index].0)
XCTAssertEqual(change.newValue, "🦄") #expect(tuples[index].1 == nil)
observation.invalidate() } else {
expect.fulfill() #expect(tuples[index].0 == nil)
} #expect(expected.1 == tuples[index].1)
}
Defaults[key] = "🦄" }
observation.invalidate() break
}
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)
} }
@Test
func testWrongCast() { func testWrongCast() {
let value = Defaults.AnySerializable(false) let value = Defaults.AnySerializable(false)
XCTAssertEqual(value.get(Bool.self), false) // swiftlint:disable:this xct_specific_matcher #expect(value.get(Bool.self) == false)
XCTAssertNil(value.get(String.self)) #expect(value.get(String.self) == nil)
} }
} }

View File

@ -1,116 +1,127 @@
import Foundation import Foundation
import Testing
import Defaults import Defaults
import XCTest
private let suite_ = createSuite()
private let fixtureArray = ["Hank", "Chen"] private let fixtureArray = ["Hank", "Chen"]
extension Defaults.Keys { 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 { @Suite(.serialized)
override func setUp() { final class DefaultsArrayTests {
super.setUp() init() {
Defaults.removeAll() Defaults.removeAll(suite: suite_)
} }
override func tearDown() { deinit {
super.tearDown() Defaults.removeAll(suite: suite_)
Defaults.removeAll()
} }
@Test
func testKey() { func testKey() {
let key = Defaults.Key<[String]>("independentArrayStringKey", default: fixtureArray) let key = Defaults.Key<[String]>("independentArrayStringKey", default: fixtureArray, suite: suite_)
XCTAssertEqual(Defaults[key][0], fixtureArray[0]) #expect(Defaults[key][0] == fixtureArray[0])
let newValue = "John" let newValue = "John"
Defaults[key][0] = newValue Defaults[key][0] = newValue
XCTAssertEqual(Defaults[key][0], newValue) #expect(Defaults[key][0] == newValue)
} }
@Test
func testOptionalKey() { func testOptionalKey() {
let key = Defaults.Key<[String]?>("independentArrayOptionalStringKey") // swiftlint:disable:this discouraged_optional_collection let key = Defaults.Key<[String]?>("independentArrayOptionalStringKey", suite: suite_) // swiftlint:disable:this discouraged_optional_collection
XCTAssertNil(Defaults[key]) #expect(Defaults[key] == nil)
Defaults[key] = fixtureArray Defaults[key] = fixtureArray
XCTAssertEqual(Defaults[key]?[0], fixtureArray[0]) #expect(Defaults[key]?[0] == fixtureArray[0])
Defaults[key] = nil Defaults[key] = nil
XCTAssertNil(Defaults[key]) #expect(Defaults[key] == nil)
let newValue = ["John", "Chen"] let newValue = ["John", "Chen"]
Defaults[key] = newValue Defaults[key] = newValue
XCTAssertEqual(Defaults[key]?[0], newValue[0]) #expect(Defaults[key]?[0] == newValue[0])
} }
@Test
func testNestedKey() { func testNestedKey() {
let defaultValue = ["Hank", "Chen"] let defaultValue = ["Hank", "Chen"]
let key = Defaults.Key<[[String]]>("independentArrayNestedKey", default: [defaultValue]) let key = Defaults.Key<[[String]]>("independentArrayNestedKey", default: [defaultValue], suite: suite_)
XCTAssertEqual(Defaults[key][0][0], "Hank") #expect(Defaults[key][0][0] == "Hank")
let newValue = ["Sindre", "Sorhus"] let newValue = ["Sindre", "Sorhus"]
Defaults[key][0] = newValue Defaults[key][0] = newValue
Defaults[key].append(defaultValue) Defaults[key].append(defaultValue)
XCTAssertEqual(Defaults[key][0][0], newValue[0]) #expect(Defaults[key][0][0] == newValue[0])
XCTAssertEqual(Defaults[key][0][1], newValue[1]) #expect(Defaults[key][0][1] == newValue[1])
XCTAssertEqual(Defaults[key][1][0], defaultValue[0]) #expect(Defaults[key][1][0] == defaultValue[0])
XCTAssertEqual(Defaults[key][1][1], defaultValue[1]) #expect(Defaults[key][1][1] == defaultValue[1])
} }
@Test
func testDictionaryKey() { func testDictionaryKey() {
let defaultValue = ["0": "HankChen"] let defaultValue = ["0": "HankChen"]
let key = Defaults.Key<[[String: String]]>("independentArrayDictionaryKey", default: [defaultValue]) let key = Defaults.Key<[[String: String]]>("independentArrayDictionaryKey", default: [defaultValue], suite: suite_)
XCTAssertEqual(Defaults[key][0]["0"], defaultValue["0"]) #expect(Defaults[key][0]["0"] == defaultValue["0"])
let newValue = ["0": "SindreSorhus"] let newValue = ["0": "SindreSorhus"]
Defaults[key][0] = newValue Defaults[key][0] = newValue
Defaults[key].append(defaultValue) Defaults[key].append(defaultValue)
XCTAssertEqual(Defaults[key][0]["0"], newValue["0"]) #expect(Defaults[key][0]["0"] == newValue["0"])
XCTAssertEqual(Defaults[key][1]["0"], defaultValue["0"]) #expect(Defaults[key][1]["0"] == defaultValue["0"])
} }
@Test
func testNestedDictionaryKey() { func testNestedDictionaryKey() {
let defaultValue = ["0": [["0": 0]]] let defaultValue = ["0": [["0": 0]]]
let key = Defaults.Key<[[String: [[String: Int]]]]>("independentArrayNestedDictionaryKey", default: [defaultValue]) let key = Defaults.Key<[[String: [[String: Int]]]]>("independentArrayNestedDictionaryKey", default: [defaultValue], suite: suite_)
XCTAssertEqual(Defaults[key][0]["0"]![0]["0"], 0) #expect(Defaults[key][0]["0"]?[0]["0"] == 0)
let newValue = 1 let newValue = 1
Defaults[key][0]["0"]![0]["0"] = newValue Defaults[key][0]["0"]?[0]["0"] = newValue
Defaults[key].append(defaultValue) Defaults[key].append(defaultValue)
XCTAssertEqual(Defaults[key][1]["0"]![0]["0"], 0) #expect(Defaults[key][1]["0"]?[0]["0"] == 0)
XCTAssertEqual(Defaults[key][0]["0"]![0]["0"], newValue) #expect(Defaults[key][0]["0"]?[0]["0"] == newValue)
} }
@Test
func testType() { func testType() {
XCTAssertEqual(Defaults[.array][0], fixtureArray[0]) #expect(Defaults[.array][0] == fixtureArray[0])
let newName = "Hank121314" let newName = "Hank121314"
Defaults[.array][0] = newName Defaults[.array][0] = newName
XCTAssertEqual(Defaults[.array][0], newName) #expect(Defaults[.array][0] == newName)
} }
func testObserveKeyCombine() { @available(iOS 16.0, macOS 13.0, tvOS 16.0, watchOS 9.0, visionOS 1.0, *)
let key = Defaults.Key<[String]>("observeArrayKeyCombine", default: fixtureArray) @Test
func testObserveKeyCombine() async {
let key = Defaults.Key<[String]>("observeArrayKeyCombine", default: fixtureArray, suite: suite_)
let newName = "Chen" let newName = "Chen"
let expect = expectation(description: "Observation closure being called")
let publisher = Defaults let publisher = Defaults
.publisher(key, options: []) .publisher(key, options: [])
.map { ($0.oldValue, $0.newValue) } .map { ($0.oldValue, $0.newValue) }
.collect(2) .collect(2)
let cancellable = publisher.sink { tuples in let expectedValues = [(fixtureArray[0], newName), (newName, fixtureArray[0])]
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()
}
Task {
try? await Task.sleep(for: .seconds(0.1))
Defaults[key][0] = newName Defaults[key][0] = newName
Defaults.reset(key) Defaults.reset(key)
cancellable.cancel()
waitForExpectations(timeout: 10)
} }
func testObserveOptionalKeyCombine() { for await tuples in publisher.values {
let key = Defaults.Key<[String]?>("observeArrayOptionalKeyCombine") // swiftlint:disable:this discouraged_optional_collection 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 newName = ["Chen"]
let expect = expectation(description: "Observation closure being called")
let publisher = Defaults let publisher = Defaults
.publisher(key, options: []) .publisher(key, options: [])
@ -120,57 +131,20 @@ final class DefaultsArrayTests: XCTestCase {
// swiftlint:disable:next discouraged_optional_collection // swiftlint:disable:next discouraged_optional_collection
let expectedValues: [([String]?, [String]?)] = [(nil, fixtureArray), (fixtureArray, newName), (newName, nil)] let expectedValues: [([String]?, [String]?)] = [(nil, fixtureArray), (fixtureArray, newName), (newName, nil)]
let cancellable = publisher.sink { actualValues in Task {
for (expected, actual) in zip(expectedValues, actualValues) { try? await Task.sleep(for: .seconds(0.1))
XCTAssertEqual(expected.0, actual.0)
XCTAssertEqual(expected.1, actual.1)
}
expect.fulfill()
}
Defaults[key] = fixtureArray Defaults[key] = fixtureArray
Defaults[key] = newName Defaults[key] = newName
Defaults.reset(key) Defaults.reset(key)
cancellable.cancel()
waitForExpectations(timeout: 10)
} }
func testObserveKey() { for await actualValues in publisher.values {
let key = Defaults.Key<[String]>("observeArrayKey", default: fixtureArray) for (expected, actual) in zip(expectedValues, actualValues) {
let newName = "John" #expect(expected.0 == actual.0)
let expect = expectation(description: "Observation closure being called") #expect(expected.1 == actual.1)
var observation: Defaults.Observation!
observation = Defaults.observe(key, options: []) { change in
XCTAssertEqual(change.oldValue, fixtureArray)
XCTAssertEqual(change.newValue, [fixtureArray[0], newName])
observation.invalidate()
expect.fulfill()
} }
Defaults[key][1] = newName break
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)
} }
} }

View File

@ -1,6 +1,8 @@
import Foundation import Foundation
import Testing
import Defaults import Defaults
import XCTest
private let suite_ = createSuite()
private enum FixtureCodableEnum: String, Hashable, Codable, Defaults.Serializable { private enum FixtureCodableEnum: String, Hashable, Codable, Defaults.Serializable {
case tenMinutes = "10 Minutes" case tenMinutes = "10 Minutes"
@ -15,300 +17,131 @@ private enum FixtureCodableEnumPreferRawRepresentable: Int, Hashable, Codable, D
} }
extension Defaults.Keys { extension Defaults.Keys {
fileprivate static let codableEnum = Key<FixtureCodableEnum>("codable_enum", default: .oneHour) fileprivate static let codableEnum = Key<FixtureCodableEnum>("codable_enum", default: .oneHour, suite: suite_)
fileprivate static let codableEnumArray = Key<[FixtureCodableEnum]>("codable_enum", default: [.oneHour]) fileprivate static let codableEnumArray = Key<[FixtureCodableEnum]>("codable_enum", default: [.oneHour], suite: suite_)
fileprivate static let codableEnumDictionary = Key<[String: FixtureCodableEnum]>("codable_enum", default: ["0": .oneHour]) fileprivate static let codableEnumDictionary = Key<[String: FixtureCodableEnum]>("codable_enum", default: ["0": .oneHour], suite: suite_)
} }
final class DefaultsCodableEnumTests: XCTestCase { @Suite(.serialized)
override func setUp() { final class DefaultsCodableEnumTests {
super.setUp() init() {
Defaults.removeAll() Defaults.removeAll(suite: suite_)
} }
override func tearDown() { deinit {
super.tearDown() Defaults.removeAll(suite: suite_)
Defaults.removeAll()
} }
@Test
func testKey() { func testKey() {
let key = Defaults.Key<FixtureCodableEnum>("independentCodableEnumKey", default: .tenMinutes) let key = Defaults.Key<FixtureCodableEnum>("independentCodableEnumKey", default: .tenMinutes, suite: suite_)
XCTAssertEqual(Defaults[key], .tenMinutes) #expect(Defaults[key] == .tenMinutes)
Defaults[key] = .halfHour Defaults[key] = .halfHour
XCTAssertEqual(Defaults[key], .halfHour) #expect(Defaults[key] == .halfHour)
} }
@Test
func testOptionalKey() { func testOptionalKey() {
let key = Defaults.Key<FixtureCodableEnum?>("independentCodableEnumOptionalKey") let key = Defaults.Key<FixtureCodableEnum?>("independentCodableEnumOptionalKey", suite: suite_)
XCTAssertNil(Defaults[key]) #expect(Defaults[key] == nil)
Defaults[key] = .tenMinutes Defaults[key] = .tenMinutes
XCTAssertEqual(Defaults[key], .tenMinutes) #expect(Defaults[key] == .tenMinutes)
} }
@Test
func testArrayKey() { func testArrayKey() {
let key = Defaults.Key<[FixtureCodableEnum]>("independentCodableEnumArrayKey", default: [.tenMinutes]) let key = Defaults.Key<[FixtureCodableEnum]>("independentCodableEnumArrayKey", default: [.tenMinutes], suite: suite_)
XCTAssertEqual(Defaults[key][0], .tenMinutes) #expect(Defaults[key][0] == .tenMinutes)
Defaults[key][0] = .halfHour Defaults[key][0] = .halfHour
XCTAssertEqual(Defaults[key][0], .halfHour) #expect(Defaults[key][0] == .halfHour)
} }
@Test
func testArrayOptionalKey() { func testArrayOptionalKey() {
let key = Defaults.Key<[FixtureCodableEnum]?>("independentCodableEnumArrayOptionalKey") // swiftlint:disable:this discouraged_optional_collection let key = Defaults.Key<[FixtureCodableEnum]?>("independentCodableEnumArrayOptionalKey", suite: suite_) // swiftlint:disable:this discouraged_optional_collection
XCTAssertNil(Defaults[key]) #expect(Defaults[key] == nil)
Defaults[key] = [.halfHour] Defaults[key] = [.halfHour]
} }
@Test
func testNestedArrayKey() { func testNestedArrayKey() {
let key = Defaults.Key<[[FixtureCodableEnum]]>("independentCodableEnumNestedArrayKey", default: [[.tenMinutes]]) let key = Defaults.Key<[[FixtureCodableEnum]]>("independentCodableEnumNestedArrayKey", default: [[.tenMinutes]], suite: suite_)
XCTAssertEqual(Defaults[key][0][0], .tenMinutes) #expect(Defaults[key][0][0] == .tenMinutes)
Defaults[key].append([.halfHour]) Defaults[key].append([.halfHour])
Defaults[key][0].append(.oneHour) Defaults[key][0].append(.oneHour)
XCTAssertEqual(Defaults[key][1][0], .halfHour) #expect(Defaults[key][1][0] == .halfHour)
XCTAssertEqual(Defaults[key][0][1], .oneHour) #expect(Defaults[key][0][1] == .oneHour)
} }
@Test
func testArrayDictionaryKey() { func testArrayDictionaryKey() {
let key = Defaults.Key<[[String: FixtureCodableEnum]]>("independentCodableEnumArrayDictionaryKey", default: [["0": .tenMinutes]]) let key = Defaults.Key<[[String: FixtureCodableEnum]]>("independentCodableEnumArrayDictionaryKey", default: [["0": .tenMinutes]], suite: suite_)
XCTAssertEqual(Defaults[key][0]["0"], .tenMinutes) #expect(Defaults[key][0]["0"] == .tenMinutes)
Defaults[key][0]["1"] = .halfHour Defaults[key][0]["1"] = .halfHour
Defaults[key].append(["0": .oneHour]) Defaults[key].append(["0": .oneHour])
XCTAssertEqual(Defaults[key][0]["1"], .halfHour) #expect(Defaults[key][0]["1"] == .halfHour)
XCTAssertEqual(Defaults[key][1]["0"], .oneHour) #expect(Defaults[key][1]["0"] == .oneHour)
} }
@Test
func testDictionaryKey() { func testDictionaryKey() {
let key = Defaults.Key<[String: FixtureCodableEnum]>("independentCodableEnumDictionaryKey", default: ["0": .tenMinutes]) let key = Defaults.Key<[String: FixtureCodableEnum]>("independentCodableEnumDictionaryKey", default: ["0": .tenMinutes], suite: suite_)
XCTAssertEqual(Defaults[key]["0"], .tenMinutes) #expect(Defaults[key]["0"] == .tenMinutes)
Defaults[key]["1"] = .halfHour Defaults[key]["1"] = .halfHour
Defaults[key]["0"] = .oneHour Defaults[key]["0"] = .oneHour
XCTAssertEqual(Defaults[key]["0"], .oneHour) #expect(Defaults[key]["0"] == .oneHour)
XCTAssertEqual(Defaults[key]["1"], .halfHour) #expect(Defaults[key]["1"] == .halfHour)
} }
@Test
func testDictionaryOptionalKey() { func testDictionaryOptionalKey() {
let key = Defaults.Key<[String: FixtureCodableEnum]?>("independentCodableEnumDictionaryOptionalKey") // swiftlint:disable:this discouraged_optional_collection let key = Defaults.Key<[String: FixtureCodableEnum]?>("independentCodableEnumDictionaryOptionalKey", suite: suite_) // swiftlint:disable:this discouraged_optional_collection
XCTAssertNil(Defaults[key]) #expect(Defaults[key] == nil)
Defaults[key] = ["0": .tenMinutes] Defaults[key] = ["0": .tenMinutes]
Defaults[key]?["1"] = .halfHour Defaults[key]?["1"] = .halfHour
XCTAssertEqual(Defaults[key]?["0"], .tenMinutes) #expect(Defaults[key]?["0"] == .tenMinutes)
XCTAssertEqual(Defaults[key]?["1"], .halfHour) #expect(Defaults[key]?["1"] == .halfHour)
} }
@Test
func testDictionaryArrayKey() { func testDictionaryArrayKey() {
let key = Defaults.Key<[String: [FixtureCodableEnum]]>("independentCodableEnumDictionaryArrayKey", default: ["0": [.tenMinutes]]) let key = Defaults.Key<[String: [FixtureCodableEnum]]>("independentCodableEnumDictionaryArrayKey", default: ["0": [.tenMinutes]], suite: suite_)
XCTAssertEqual(Defaults[key]["0"]?[0], .tenMinutes) #expect(Defaults[key]["0"]?[0] == .tenMinutes)
Defaults[key]["0"]?.append(.halfHour) Defaults[key]["0"]?.append(.halfHour)
Defaults[key]["1"] = [.oneHour] Defaults[key]["1"] = [.oneHour]
XCTAssertEqual(Defaults[key]["0"]?[0], .tenMinutes) #expect(Defaults[key]["0"]?[0] == .tenMinutes)
XCTAssertEqual(Defaults[key]["0"]?[1], .halfHour) #expect(Defaults[key]["0"]?[1] == .halfHour)
XCTAssertEqual(Defaults[key]["1"]?[0], .oneHour) #expect(Defaults[key]["1"]?[0] == .oneHour)
} }
@Test
func testType() { func testType() {
XCTAssertEqual(Defaults[.codableEnum], .oneHour) #expect(Defaults[.codableEnum] == .oneHour)
Defaults[.codableEnum] = .tenMinutes Defaults[.codableEnum] = .tenMinutes
XCTAssertEqual(Defaults[.codableEnum], .tenMinutes) #expect(Defaults[.codableEnum] == .tenMinutes)
} }
@Test
func testArrayType() { func testArrayType() {
XCTAssertEqual(Defaults[.codableEnumArray][0], .oneHour) #expect(Defaults[.codableEnumArray][0] == .oneHour)
Defaults[.codableEnumArray].append(.halfHour) Defaults[.codableEnumArray].append(.halfHour)
XCTAssertEqual(Defaults[.codableEnumArray][0], .oneHour) #expect(Defaults[.codableEnumArray][0] == .oneHour)
XCTAssertEqual(Defaults[.codableEnumArray][1], .halfHour) #expect(Defaults[.codableEnumArray][1] == .halfHour)
} }
@Test
func testDictionaryType() { func testDictionaryType() {
XCTAssertEqual(Defaults[.codableEnumDictionary]["0"], .oneHour) #expect(Defaults[.codableEnumDictionary]["0"] == .oneHour)
Defaults[.codableEnumDictionary]["1"] = .halfHour Defaults[.codableEnumDictionary]["1"] = .halfHour
XCTAssertEqual(Defaults[.codableEnumDictionary]["0"], .oneHour) #expect(Defaults[.codableEnumDictionary]["0"] == .oneHour)
XCTAssertEqual(Defaults[.codableEnumDictionary]["1"], .halfHour) #expect(Defaults[.codableEnumDictionary]["1"] == .halfHour)
} }
@Test
func testFixtureCodableEnumPreferRawRepresentable() { func testFixtureCodableEnumPreferRawRepresentable() {
let fixture: FixtureCodableEnumPreferRawRepresentable = .tenMinutes let fixture: FixtureCodableEnumPreferRawRepresentable = .tenMinutes
let keyName = "testFixtureCodableEnumPreferRawRepresentable" let keyName = "testFixtureCodableEnumPreferRawRepresentable"
_ = Defaults.Key<FixtureCodableEnumPreferRawRepresentable>(keyName, default: fixture) _ = Defaults.Key<FixtureCodableEnumPreferRawRepresentable>(keyName, default: fixture, suite: suite_)
XCTAssertNotNil(UserDefaults.standard.integer(forKey: keyName)) #expect(UserDefaults.standard.integer(forKey: keyName) != 0)
}
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)
} }
} }

View File

@ -1,7 +1,9 @@
import Foundation import Foundation
import XCTest import Testing
import Defaults import Defaults
private let suite_ = createSuite()
private struct Unicorn: Codable, Defaults.Serializable { private struct Unicorn: Codable, Defaults.Serializable {
var isUnicorn: Bool var isUnicorn: Bool
} }
@ -35,99 +37,109 @@ private final class UnicornCodableAndPreferNSSecureCoding: NSObject, NSSecureCod
} }
extension Defaults.Keys { extension Defaults.Keys {
fileprivate static let codable = Key<Unicorn>("codable", default: fixtureCodable) fileprivate static let codable = Key<Unicorn>("codable", default: fixtureCodable, suite: suite_)
fileprivate static let codableArray = Key<[Unicorn]>("codable", default: [fixtureCodable]) fileprivate static let codableArray = Key<[Unicorn]>("codable", default: [fixtureCodable], suite: suite_)
fileprivate static let codableDictionary = Key<[String: Unicorn]>("codable", default: ["0": fixtureCodable]) fileprivate static let codableDictionary = Key<[String: Unicorn]>("codable", default: ["0": fixtureCodable], suite: suite_)
} }
final class DefaultsCodableTests: XCTestCase { @Suite(.serialized)
override func setUp() { final class DefaultsCodableTests {
super.setUp() init() {
Defaults.removeAll() // TODO: Convert all the keys to use a prefix and then remove based on the prefix.
Defaults.removeAll(suite: suite_)
} }
override func tearDown() { deinit {
super.tearDown() Defaults.removeAll(suite: suite_)
Defaults.removeAll()
} }
@Test
func testKey() { func testKey() {
let key = Defaults.Key<Unicorn>("independentCodableKey", default: fixtureCodable) let key = Defaults.Key<Unicorn>("independentCodableKey", default: fixtureCodable, suite: suite_)
XCTAssertTrue(Defaults[key].isUnicorn) #expect(Defaults[key].isUnicorn)
Defaults[key].isUnicorn = false Defaults[key].isUnicorn = false
XCTAssertFalse(Defaults[key].isUnicorn) #expect(!Defaults[key].isUnicorn)
} }
@Test
func testOptionalKey() { func testOptionalKey() {
let key = Defaults.Key<Unicorn?>("independentCodableOptionalKey") let key = Defaults.Key<Unicorn?>("independentCodableOptionalKey", suite: suite_)
XCTAssertNil(Defaults[key]) #expect(Defaults[key] == nil)
Defaults[key] = Unicorn(isUnicorn: true) Defaults[key] = Unicorn(isUnicorn: true)
XCTAssertTrue(Defaults[key]?.isUnicorn ?? false) #expect(Defaults[key]?.isUnicorn ?? false)
} }
@Test
func testArrayKey() { func testArrayKey() {
let key = Defaults.Key<[Unicorn]>("independentCodableArrayKey", default: [fixtureCodable]) let key = Defaults.Key<[Unicorn]>("independentCodableArrayKey", default: [fixtureCodable], suite: suite_)
XCTAssertTrue(Defaults[key][0].isUnicorn) #expect(Defaults[key][0].isUnicorn)
Defaults[key].append(Unicorn(isUnicorn: false)) Defaults[key].append(Unicorn(isUnicorn: false))
XCTAssertTrue(Defaults[key][0].isUnicorn) #expect(Defaults[key][0].isUnicorn)
XCTAssertFalse(Defaults[key][1].isUnicorn) #expect(!Defaults[key][1].isUnicorn)
} }
@Test
func testArrayOptionalKey() { func testArrayOptionalKey() {
let key = Defaults.Key<[Unicorn]?>("independentCodableArrayOptionalKey") // swiftlint:disable:this discouraged_optional_collection let key = Defaults.Key<[Unicorn]?>("independentCodableArrayOptionalKey", suite: suite_) // swiftlint:disable:this discouraged_optional_collection
XCTAssertNil(Defaults[key]) #expect(Defaults[key] == nil)
Defaults[key] = [fixtureCodable] Defaults[key] = [fixtureCodable]
Defaults[key]?.append(Unicorn(isUnicorn: false)) Defaults[key]?.append(Unicorn(isUnicorn: false))
XCTAssertTrue(Defaults[key]?[0].isUnicorn ?? false) #expect(Defaults[key]?[0].isUnicorn ?? false)
XCTAssertFalse(Defaults[key]?[1].isUnicorn ?? false) #expect(!(Defaults[key]?[1].isUnicorn ?? false))
} }
@Test
func testNestedArrayKey() { func testNestedArrayKey() {
let key = Defaults.Key<[[Unicorn]]>("independentCodableNestedArrayKey", default: [[fixtureCodable]]) let key = Defaults.Key<[[Unicorn]]>("independentCodableNestedArrayKey", default: [[fixtureCodable]], suite: suite_)
XCTAssertTrue(Defaults[key][0][0].isUnicorn) #expect(Defaults[key][0][0].isUnicorn)
Defaults[key].append([fixtureCodable]) Defaults[key].append([fixtureCodable])
Defaults[key][0].append(Unicorn(isUnicorn: false)) Defaults[key][0].append(Unicorn(isUnicorn: false))
XCTAssertTrue(Defaults[key][0][0].isUnicorn) #expect(Defaults[key][0][0].isUnicorn)
XCTAssertTrue(Defaults[key][1][0].isUnicorn) #expect(Defaults[key][1][0].isUnicorn)
XCTAssertFalse(Defaults[key][0][1].isUnicorn) #expect(!Defaults[key][0][1].isUnicorn)
} }
@Test
func testArrayDictionaryKey() { func testArrayDictionaryKey() {
let key = Defaults.Key<[[String: Unicorn]]>("independentCodableArrayDictionaryKey", default: [["0": fixtureCodable]]) let key = Defaults.Key<[[String: Unicorn]]>("independentCodableArrayDictionaryKey", default: [["0": fixtureCodable]], suite: suite_)
XCTAssertTrue(Defaults[key][0]["0"]?.isUnicorn ?? false) #expect(Defaults[key][0]["0"]?.isUnicorn ?? false)
Defaults[key].append(["0": fixtureCodable]) Defaults[key].append(["0": fixtureCodable])
Defaults[key][0]["1"] = Unicorn(isUnicorn: false) Defaults[key][0]["1"] = Unicorn(isUnicorn: false)
XCTAssertTrue(Defaults[key][0]["0"]?.isUnicorn ?? false) #expect(Defaults[key][0]["0"]?.isUnicorn ?? false)
XCTAssertTrue(Defaults[key][1]["0"]?.isUnicorn ?? false) #expect(Defaults[key][1]["0"]?.isUnicorn ?? false)
XCTAssertFalse(Defaults[key][0]["1"]?.isUnicorn ?? true) #expect(!(Defaults[key][0]["1"]?.isUnicorn ?? true))
} }
@Test
func testDictionaryKey() { func testDictionaryKey() {
let key = Defaults.Key<[String: Unicorn]>("independentCodableDictionaryKey", default: ["0": fixtureCodable]) let key = Defaults.Key<[String: Unicorn]>("independentCodableDictionaryKey", default: ["0": fixtureCodable], suite: suite_)
XCTAssertTrue(Defaults[key]["0"]?.isUnicorn ?? false) #expect(Defaults[key]["0"]?.isUnicorn ?? false)
Defaults[key]["1"] = Unicorn(isUnicorn: false) Defaults[key]["1"] = Unicorn(isUnicorn: false)
XCTAssertTrue(Defaults[key]["0"]?.isUnicorn ?? false) #expect(Defaults[key]["0"]?.isUnicorn ?? false)
XCTAssertFalse(Defaults[key]["1"]?.isUnicorn ?? true) #expect(!(Defaults[key]["1"]?.isUnicorn ?? true))
} }
@Test
func testDictionaryOptionalKey() { func testDictionaryOptionalKey() {
let key = Defaults.Key<[String: Unicorn]?>("independentCodableDictionaryOptionalKey") // swiftlint:disable:this discouraged_optional_collection let key = Defaults.Key<[String: Unicorn]?>("independentCodableDictionaryOptionalKey", suite: suite_) // swiftlint:disable:this discouraged_optional_collection
XCTAssertNil(Defaults[key]) #expect(Defaults[key] == nil)
Defaults[key] = ["0": fixtureCodable] Defaults[key] = ["0": fixtureCodable]
Defaults[key]?["1"] = Unicorn(isUnicorn: false) Defaults[key]?["1"] = Unicorn(isUnicorn: false)
XCTAssertTrue(Defaults[key]?["0"]?.isUnicorn ?? false) #expect(Defaults[key]?["0"]?.isUnicorn ?? false)
XCTAssertFalse(Defaults[key]?["1"]?.isUnicorn ?? true) #expect(!(Defaults[key]?["1"]?.isUnicorn ?? true))
} }
@Test
func testDictionaryArrayKey() { func testDictionaryArrayKey() {
let key = Defaults.Key<[String: [Unicorn]]>("independentCodableDictionaryArrayKey", default: ["0": [fixtureCodable]]) let key = Defaults.Key<[String: [Unicorn]]>("independentCodableDictionaryArrayKey", default: ["0": [fixtureCodable]], suite: suite_)
XCTAssertTrue(Defaults[key]["0"]?[0].isUnicorn ?? false) #expect(Defaults[key]["0"]?[0].isUnicorn ?? false)
Defaults[key]["1"] = [fixtureCodable] Defaults[key]["1"] = [fixtureCodable]
Defaults[key]["0"]?.append(Unicorn(isUnicorn: false)) Defaults[key]["0"]?.append(Unicorn(isUnicorn: false))
XCTAssertTrue(Defaults[key]["1"]?[0].isUnicorn ?? false) #expect(Defaults[key]["1"]?[0].isUnicorn ?? false)
XCTAssertFalse(Defaults[key]["0"]?[1].isUnicorn ?? true) #expect(!(Defaults[key]["0"]?[1].isUnicorn ?? true))
} }
@Test
func testCodableAndRawRepresentable() { func testCodableAndRawRepresentable() {
struct Unicorn: Codable, RawRepresentable, Defaults.Serializable { struct Unicorn: Codable, RawRepresentable, Defaults.Serializable {
var rawValue: String var rawValue: String
@ -135,217 +147,48 @@ final class DefaultsCodableTests: XCTestCase {
let fixture = Unicorn(rawValue: "x") let fixture = Unicorn(rawValue: "x")
let key = Defaults.Key<Unicorn?>("independentKey_codableAndRawRepresentable") let key = Defaults.Key<Unicorn?>("independentKey_codableAndRawRepresentable", suite: suite_)
Defaults[key] = fixture Defaults[key] = fixture
XCTAssertEqual(Defaults[key]?.rawValue, fixture.rawValue) #expect(Defaults[key]?.rawValue == fixture.rawValue)
XCTAssertEqual(UserDefaults.standard.string(forKey: key.name), #""\#(fixture.rawValue)""#) #expect(suite_.string(forKey: key.name) == #""\#(fixture.rawValue)""#)
} }
@Test
func testType() { func testType() {
XCTAssertTrue(Defaults[.codable].isUnicorn) #expect(Defaults[.codable].isUnicorn)
Defaults[.codable] = Unicorn(isUnicorn: false) Defaults[.codable] = Unicorn(isUnicorn: false)
XCTAssertFalse(Defaults[.codable].isUnicorn) #expect(!Defaults[.codable].isUnicorn)
} }
@Test
func testArrayType() { func testArrayType() {
XCTAssertTrue(Defaults[.codableArray][0].isUnicorn) #expect(Defaults[.codableArray][0].isUnicorn)
Defaults[.codableArray][0] = Unicorn(isUnicorn: false) Defaults[.codableArray][0] = Unicorn(isUnicorn: false)
XCTAssertFalse(Defaults[.codableArray][0].isUnicorn) #expect(!Defaults[.codableArray][0].isUnicorn)
} }
@Test
func testDictionaryType() { func testDictionaryType() {
XCTAssertTrue(Defaults[.codableDictionary]["0"]?.isUnicorn ?? false) #expect(Defaults[.codableDictionary]["0"]?.isUnicorn ?? false)
Defaults[.codableDictionary]["0"] = Unicorn(isUnicorn: false) Defaults[.codableDictionary]["0"] = Unicorn(isUnicorn: false)
XCTAssertFalse(Defaults[.codableDictionary]["0"]?.isUnicorn ?? true) #expect(!(Defaults[.codableDictionary]["0"]?.isUnicorn ?? true))
} }
@Test
func testCodableAndNSSecureCoding() { func testCodableAndNSSecureCoding() {
let fixture = UnicornCodableAndNSSecureCoding() let fixture = UnicornCodableAndNSSecureCoding()
let keyName = "testCodableAndNSSecureCoding" let keyName = "testCodableAndNSSecureCoding"
_ = Defaults.Key<UnicornCodableAndNSSecureCoding>(keyName, default: fixture) _ = Defaults.Key<UnicornCodableAndNSSecureCoding>(keyName, default: fixture, suite: suite_)
XCTAssertNil(UserDefaults.standard.data(forKey: keyName)) #expect(UserDefaults.standard.data(forKey: keyName) == nil)
XCTAssertNotNil(UserDefaults.standard.string(forKey: keyName)) #expect(UserDefaults.standard.string(forKey: keyName) != nil)
} }
@Test
func testCodableAndPreferNSSecureCoding() { func testCodableAndPreferNSSecureCoding() {
let fixture = UnicornCodableAndPreferNSSecureCoding() let fixture = UnicornCodableAndPreferNSSecureCoding()
let keyName = "testCodableAndPreferNSSecureCoding" let keyName = "testCodableAndPreferNSSecureCoding"
_ = Defaults.Key<UnicornCodableAndPreferNSSecureCoding>(keyName, default: fixture) _ = Defaults.Key<UnicornCodableAndPreferNSSecureCoding>(keyName, default: fixture, suite: suite_)
XCTAssertNil(UserDefaults.standard.string(forKey: keyName)) #expect(UserDefaults.standard.string(forKey: keyName) == nil)
XCTAssertNotNil(UserDefaults.standard.data(forKey: keyName)) #expect(UserDefaults.standard.data(forKey: keyName) != nil)
}
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)
} }
} }

View File

@ -1,7 +1,9 @@
import Foundation import Foundation
import XCTest import Testing
import Defaults import Defaults
private let suite_ = createSuite()
private struct Item: Equatable { private struct Item: Equatable {
let name: String let name: String
let count: UInt let count: UInt
@ -40,308 +42,144 @@ private let fixtureCustomCollection1 = Item(name: "Banana", count: 20)
private let fixtureCustomCollection2 = Item(name: "Grape", count: 30) private let fixtureCustomCollection2 = Item(name: "Grape", count: 30)
extension Defaults.Keys { extension Defaults.Keys {
fileprivate static let collectionCustomElement = Key<Bag<Item>>("collectionCustomElement", default: .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])]) 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])]) fileprivate static let collectionCustomElementDictionary = Key<[String: Bag<Item>]>("collectionCustomElementDictionary", default: ["0": .init(items: [fixtureCustomCollection])], suite: suite_)
} }
final class DefaultsCollectionCustomElementTests: XCTestCase { @Suite(.serialized)
override func setUp() { final class DefaultsCollectionCustomElementTests {
super.setUp() init() {
Defaults.removeAll() Defaults.removeAll(suite: suite_)
} }
override func tearDown() { deinit {
super.tearDown() Defaults.removeAll(suite: suite_)
Defaults.removeAll()
} }
@Test
func testKey() { 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: fixtureCustomCollection1, at: 1)
Defaults[key].insert(element: fixtureCustomCollection2, at: 2) Defaults[key].insert(element: fixtureCustomCollection2, at: 2)
XCTAssertEqual(Defaults[key][0], fixtureCustomCollection) #expect(Defaults[key][0] == fixtureCustomCollection)
XCTAssertEqual(Defaults[key][1], fixtureCustomCollection1) #expect(Defaults[key][1] == fixtureCustomCollection1)
XCTAssertEqual(Defaults[key][2], fixtureCustomCollection2) #expect(Defaults[key][2] == fixtureCustomCollection2)
} }
@Test
func testOptionalKey() { 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] = .init(items: [fixtureCustomCollection])
Defaults[key]?.insert(element: fixtureCustomCollection1, at: 1) Defaults[key]?.insert(element: fixtureCustomCollection1, at: 1)
Defaults[key]?.insert(element: fixtureCustomCollection2, at: 2) Defaults[key]?.insert(element: fixtureCustomCollection2, at: 2)
XCTAssertEqual(Defaults[key]?[0], fixtureCustomCollection) #expect(Defaults[key]?[0] == fixtureCustomCollection)
XCTAssertEqual(Defaults[key]?[1], fixtureCustomCollection1) #expect(Defaults[key]?[1] == fixtureCustomCollection1)
XCTAssertEqual(Defaults[key]?[2], fixtureCustomCollection2) #expect(Defaults[key]?[2] == fixtureCustomCollection2)
} }
@Test
func testArrayKey() { 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][0].insert(element: fixtureCustomCollection1, at: 1)
Defaults[key].append(.init(items: [fixtureCustomCollection2])) Defaults[key].append(.init(items: [fixtureCustomCollection2]))
XCTAssertEqual(Defaults[key][0][0], fixtureCustomCollection) #expect(Defaults[key][0][0] == fixtureCustomCollection)
XCTAssertEqual(Defaults[key][0][1], fixtureCustomCollection1) #expect(Defaults[key][0][1] == fixtureCustomCollection1)
XCTAssertEqual(Defaults[key][1][0], fixtureCustomCollection2) #expect(Defaults[key][1][0] == fixtureCustomCollection2)
} }
@Test
func testArrayOptionalKey() { 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] = [.init(items: [fixtureCustomCollection])]
Defaults[key]?[0].insert(element: fixtureCustomCollection1, at: 1) Defaults[key]?[0].insert(element: fixtureCustomCollection1, at: 1)
Defaults[key]?.append(Bag(items: [fixtureCustomCollection2])) Defaults[key]?.append(Bag(items: [fixtureCustomCollection2]))
XCTAssertEqual(Defaults[key]?[0][0], fixtureCustomCollection) #expect(Defaults[key]?[0][0] == fixtureCustomCollection)
XCTAssertEqual(Defaults[key]?[0][1], fixtureCustomCollection1) #expect(Defaults[key]?[0][1] == fixtureCustomCollection1)
XCTAssertEqual(Defaults[key]?[1][0], fixtureCustomCollection2) #expect(Defaults[key]?[1][0] == fixtureCustomCollection2)
} }
@Test
func testNestedArrayKey() { 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][0].insert(element: fixtureCustomCollection, at: 1)
Defaults[key][0].append(.init(items: [fixtureCustomCollection1])) Defaults[key][0].append(.init(items: [fixtureCustomCollection1]))
Defaults[key].append([.init(items: [fixtureCustomCollection2])]) Defaults[key].append([.init(items: [fixtureCustomCollection2])])
XCTAssertEqual(Defaults[key][0][0][0], fixtureCustomCollection) #expect(Defaults[key][0][0][0] == fixtureCustomCollection)
XCTAssertEqual(Defaults[key][0][0][1], fixtureCustomCollection) #expect(Defaults[key][0][0][1] == fixtureCustomCollection)
XCTAssertEqual(Defaults[key][0][1][0], fixtureCustomCollection1) #expect(Defaults[key][0][1][0] == fixtureCustomCollection1)
XCTAssertEqual(Defaults[key][1][0][0], fixtureCustomCollection2) #expect(Defaults[key][1][0][0] == fixtureCustomCollection2)
} }
@Test
func testArrayDictionaryKey() { 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]["0"]?.insert(element: fixtureCustomCollection, at: 1)
Defaults[key][0]["1"] = .init(items: [fixtureCustomCollection1]) Defaults[key][0]["1"] = .init(items: [fixtureCustomCollection1])
Defaults[key].append(["0": .init(items: [fixtureCustomCollection2])]) Defaults[key].append(["0": .init(items: [fixtureCustomCollection2])])
XCTAssertEqual(Defaults[key][0]["0"]?[0], fixtureCustomCollection) #expect(Defaults[key][0]["0"]?[0] == fixtureCustomCollection)
XCTAssertEqual(Defaults[key][0]["0"]?[1], fixtureCustomCollection) #expect(Defaults[key][0]["0"]?[1] == fixtureCustomCollection)
XCTAssertEqual(Defaults[key][0]["1"]?[0], fixtureCustomCollection1) #expect(Defaults[key][0]["1"]?[0] == fixtureCustomCollection1)
XCTAssertEqual(Defaults[key][1]["0"]?[0], fixtureCustomCollection2) #expect(Defaults[key][1]["0"]?[0] == fixtureCustomCollection2)
} }
@Test
func testDictionaryKey() { 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]["0"]?.insert(element: fixtureCustomCollection1, at: 1)
Defaults[key]["1"] = .init(items: [fixtureCustomCollection2]) Defaults[key]["1"] = .init(items: [fixtureCustomCollection2])
XCTAssertEqual(Defaults[key]["0"]?[0], fixtureCustomCollection) #expect(Defaults[key]["0"]?[0] == fixtureCustomCollection)
XCTAssertEqual(Defaults[key]["0"]?[1], fixtureCustomCollection1) #expect(Defaults[key]["0"]?[1] == fixtureCustomCollection1)
XCTAssertEqual(Defaults[key]["1"]?[0], fixtureCustomCollection2) #expect(Defaults[key]["1"]?[0] == fixtureCustomCollection2)
} }
@Test
func testDictionaryOptionalKey() { 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": .init(items: [fixtureCustomCollection])]
Defaults[key]?["0"]?.insert(element: fixtureCustomCollection1, at: 1) Defaults[key]?["0"]?.insert(element: fixtureCustomCollection1, at: 1)
Defaults[key]?["1"] = .init(items: [fixtureCustomCollection2]) Defaults[key]?["1"] = .init(items: [fixtureCustomCollection2])
XCTAssertEqual(Defaults[key]?["0"]?[0], fixtureCustomCollection) #expect(Defaults[key]?["0"]?[0] == fixtureCustomCollection)
XCTAssertEqual(Defaults[key]?["0"]?[1], fixtureCustomCollection1) #expect(Defaults[key]?["0"]?[1] == fixtureCustomCollection1)
XCTAssertEqual(Defaults[key]?["1"]?[0], fixtureCustomCollection2) #expect(Defaults[key]?["1"]?[0] == fixtureCustomCollection2)
} }
@Test
func testDictionaryArrayKey() { 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"]?[0].insert(element: fixtureCustomCollection, at: 1)
Defaults[key]["0"]?.append(.init(items: [fixtureCustomCollection1])) Defaults[key]["0"]?.append(.init(items: [fixtureCustomCollection1]))
Defaults[key]["1"] = [.init(items: [fixtureCustomCollection2])] Defaults[key]["1"] = [.init(items: [fixtureCustomCollection2])]
XCTAssertEqual(Defaults[key]["0"]?[0][0], fixtureCustomCollection) #expect(Defaults[key]["0"]?[0][0] == fixtureCustomCollection)
XCTAssertEqual(Defaults[key]["0"]?[0][1], fixtureCustomCollection) #expect(Defaults[key]["0"]?[0][1] == fixtureCustomCollection)
XCTAssertEqual(Defaults[key]["0"]?[1][0], fixtureCustomCollection1) #expect(Defaults[key]["0"]?[1][0] == fixtureCustomCollection1)
XCTAssertEqual(Defaults[key]["1"]?[0][0], fixtureCustomCollection2) #expect(Defaults[key]["1"]?[0][0] == fixtureCustomCollection2)
} }
@Test
func testType() { func testType() {
Defaults[.collectionCustomElement].insert(element: fixtureCustomCollection1, at: 1) Defaults[.collectionCustomElement].insert(element: fixtureCustomCollection1, at: 1)
Defaults[.collectionCustomElement].insert(element: fixtureCustomCollection2, at: 2) Defaults[.collectionCustomElement].insert(element: fixtureCustomCollection2, at: 2)
XCTAssertEqual(Defaults[.collectionCustomElement][0], fixtureCustomCollection) #expect(Defaults[.collectionCustomElement][0] == fixtureCustomCollection)
XCTAssertEqual(Defaults[.collectionCustomElement][1], fixtureCustomCollection1) #expect(Defaults[.collectionCustomElement][1] == fixtureCustomCollection1)
XCTAssertEqual(Defaults[.collectionCustomElement][2], fixtureCustomCollection2) #expect(Defaults[.collectionCustomElement][2] == fixtureCustomCollection2)
} }
@Test
func testArrayType() { func testArrayType() {
Defaults[.collectionCustomElementArray][0].insert(element: fixtureCustomCollection1, at: 1) Defaults[.collectionCustomElementArray][0].insert(element: fixtureCustomCollection1, at: 1)
Defaults[.collectionCustomElementArray].append(.init(items: [fixtureCustomCollection2])) Defaults[.collectionCustomElementArray].append(.init(items: [fixtureCustomCollection2]))
XCTAssertEqual(Defaults[.collectionCustomElementArray][0][0], fixtureCustomCollection) #expect(Defaults[.collectionCustomElementArray][0][0] == fixtureCustomCollection)
XCTAssertEqual(Defaults[.collectionCustomElementArray][0][1], fixtureCustomCollection1) #expect(Defaults[.collectionCustomElementArray][0][1] == fixtureCustomCollection1)
XCTAssertEqual(Defaults[.collectionCustomElementArray][1][0], fixtureCustomCollection2) #expect(Defaults[.collectionCustomElementArray][1][0] == fixtureCustomCollection2)
} }
@Test
func testDictionaryType() { func testDictionaryType() {
Defaults[.collectionCustomElementDictionary]["0"]?.insert(element: fixtureCustomCollection1, at: 1) Defaults[.collectionCustomElementDictionary]["0"]?.insert(element: fixtureCustomCollection1, at: 1)
Defaults[.collectionCustomElementDictionary]["1"] = .init(items: [fixtureCustomCollection2]) Defaults[.collectionCustomElementDictionary]["1"] = .init(items: [fixtureCustomCollection2])
XCTAssertEqual(Defaults[.collectionCustomElementDictionary]["0"]?[0], fixtureCustomCollection) #expect(Defaults[.collectionCustomElementDictionary]["0"]?[0] == fixtureCustomCollection)
XCTAssertEqual(Defaults[.collectionCustomElementDictionary]["0"]?[1], fixtureCustomCollection1) #expect(Defaults[.collectionCustomElementDictionary]["0"]?[1] == fixtureCustomCollection1)
XCTAssertEqual(Defaults[.collectionCustomElementDictionary]["1"]?[0], fixtureCustomCollection2) #expect(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)
} }
} }

View File

@ -1,7 +1,9 @@
import Foundation import Foundation
import XCTest import Testing
import Defaults import Defaults
private let suite_ = createSuite()
struct Bag<Element: Defaults.Serializable>: Collection { struct Bag<Element: Defaults.Serializable>: Collection {
var items: [Element] var items: [Element]
@ -36,305 +38,133 @@ extension Bag: Defaults.CollectionSerializable {
} }
} }
private let fixtureCollection = ["Juice", "Apple", "Banana"] private let fixtureCollection = ["Juice", "Apple", "Banana"]
extension Defaults.Keys { extension Defaults.Keys {
fileprivate static let collection = Key<Bag<String>>("collection", default: 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)]) 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)]) fileprivate static let collectionDictionary = Key<[String: Bag<String>]>("collectionDictionary", default: ["0": Bag(items: fixtureCollection)], suite: suite_)
} }
final class DefaultsCollectionTests: XCTestCase { @Suite(.serialized)
override func setUp() { final class DefaultsCollectionTests {
super.setUp() init() {
Defaults.removeAll() Defaults.removeAll(suite: suite_)
} }
override func tearDown() { deinit {
super.tearDown() Defaults.removeAll(suite: suite_)
Defaults.removeAll()
} }
@Test
func testKey() { 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) Defaults[key].insert(element: "123", at: 0)
XCTAssertEqual(Defaults[key][0], "123") #expect(Defaults[key][0] == "123")
} }
@Test
func testOptionalKey() { func testOptionalKey() {
let key = Defaults.Key<Bag<String>?>("independentCollectionOptionalKey") let key = Defaults.Key<Bag<String>?>("independentCollectionOptionalKey", suite: suite_)
XCTAssertNil(Defaults[key]) #expect(Defaults[key] == nil)
Defaults[key] = Bag(items: []) Defaults[key] = Bag(items: [])
Defaults[key]?.insert(element: fixtureCollection[0], at: 0) 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) Defaults[key]?.insert(element: fixtureCollection[1], at: 1)
XCTAssertEqual(Defaults[key]?[1], fixtureCollection[1]) #expect(Defaults[key]?[1] == fixtureCollection[1])
} }
@Test
func testArrayKey() { 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]])) 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) 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() { func testArrayOptionalKey() {
let key = Defaults.Key<[Bag<String>]?>("independentCollectionArrayOptionalKey") // swiftlint:disable:this discouraged_optional_collection let key = Defaults.Key<[Bag<String>]?>("independentCollectionArrayOptionalKey", suite: suite_) // swiftlint:disable:this discouraged_optional_collection
XCTAssertNil(Defaults[key]) #expect(Defaults[key] == nil)
Defaults[key] = [Bag(items: [fixtureCollection[0]])] Defaults[key] = [Bag(items: [fixtureCollection[0]])]
Defaults[key]?.append(Bag(items: [fixtureCollection[1]])) 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) 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() { 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][0].append(Bag(items: [fixtureCollection[1]]))
Defaults[key].append([Bag(items: [fixtureCollection[2]])]) Defaults[key].append([Bag(items: [fixtureCollection[2]])])
XCTAssertEqual(Defaults[key][0][0][0], fixtureCollection[0]) #expect(Defaults[key][0][0][0] == fixtureCollection[0])
XCTAssertEqual(Defaults[key][0][1][0], fixtureCollection[1]) #expect(Defaults[key][0][1][0] == fixtureCollection[1])
XCTAssertEqual(Defaults[key][1][0][0], fixtureCollection[2]) #expect(Defaults[key][1][0][0] == fixtureCollection[2])
} }
@Test
func testArrayDictionaryKey() { 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][0]["1"] = Bag(items: [fixtureCollection[1]])
Defaults[key].append(["0": Bag(items: [fixtureCollection[2]])]) Defaults[key].append(["0": Bag(items: [fixtureCollection[2]])])
XCTAssertEqual(Defaults[key][0]["0"]?[0], fixtureCollection[0]) #expect(Defaults[key][0]["0"]?[0] == fixtureCollection[0])
XCTAssertEqual(Defaults[key][0]["1"]?[0], fixtureCollection[1]) #expect(Defaults[key][0]["1"]?[0] == fixtureCollection[1])
XCTAssertEqual(Defaults[key][1]["0"]?[0], fixtureCollection[2]) #expect(Defaults[key][1]["0"]?[0] == fixtureCollection[2])
} }
@Test
func testDictionaryKey() { 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]["0"]?.insert(element: fixtureCollection[1], at: 1)
Defaults[key]["1"] = Bag(items: [fixtureCollection[2]]) Defaults[key]["1"] = Bag(items: [fixtureCollection[2]])
XCTAssertEqual(Defaults[key]["0"]?[0], fixtureCollection[0]) #expect(Defaults[key]["0"]?[0] == fixtureCollection[0])
XCTAssertEqual(Defaults[key]["0"]?[1], fixtureCollection[1]) #expect(Defaults[key]["0"]?[1] == fixtureCollection[1])
XCTAssertEqual(Defaults[key]["1"]?[0], fixtureCollection[2]) #expect(Defaults[key]["1"]?[0] == fixtureCollection[2])
} }
@Test
func testDictionaryOptionalKey() { func testDictionaryOptionalKey() {
let key = Defaults.Key<[String: Bag<String>]?>("independentCollectionDictionaryOptionalKey") // swiftlint:disable:this discouraged_optional_collection let key = Defaults.Key<[String: Bag<String>]?>("independentCollectionDictionaryOptionalKey", suite: suite_) // swiftlint:disable:this discouraged_optional_collection
XCTAssertNil(Defaults[key]) #expect(Defaults[key] == nil)
Defaults[key] = ["0": Bag(items: [fixtureCollection[0]])] Defaults[key] = ["0": Bag(items: [fixtureCollection[0]])]
Defaults[key]?["0"]?.insert(element: fixtureCollection[1], at: 1) Defaults[key]?["0"]?.insert(element: fixtureCollection[1], at: 1)
Defaults[key]?["1"] = Bag(items: [fixtureCollection[2]]) Defaults[key]?["1"] = Bag(items: [fixtureCollection[2]])
XCTAssertEqual(Defaults[key]?["0"]?[0], fixtureCollection[0]) #expect(Defaults[key]?["0"]?[0] == fixtureCollection[0])
XCTAssertEqual(Defaults[key]?["0"]?[1], fixtureCollection[1]) #expect(Defaults[key]?["0"]?[1] == fixtureCollection[1])
XCTAssertEqual(Defaults[key]?["1"]?[0], fixtureCollection[2]) #expect(Defaults[key]?["1"]?[0] == fixtureCollection[2])
} }
@Test
func testDictionaryArrayKey() { 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]["0"]?[0].insert(element: fixtureCollection[1], at: 1)
Defaults[key]["1"] = [Bag(items: [fixtureCollection[2]])] Defaults[key]["1"] = [Bag(items: [fixtureCollection[2]])]
XCTAssertEqual(Defaults[key]["0"]?[0][0], fixtureCollection[0]) #expect(Defaults[key]["0"]?[0][0] == fixtureCollection[0])
XCTAssertEqual(Defaults[key]["0"]?[0][1], fixtureCollection[1]) #expect(Defaults[key]["0"]?[0][1] == fixtureCollection[1])
XCTAssertEqual(Defaults[key]["1"]?[0][0], fixtureCollection[2]) #expect(Defaults[key]["1"]?[0][0] == fixtureCollection[2])
} }
@Test
func testType() { func testType() {
Defaults[.collection].insert(element: "123", at: 0) Defaults[.collection].insert(element: "123", at: 0)
XCTAssertEqual(Defaults[.collection][0], "123") #expect(Defaults[.collection][0] == "123")
} }
@Test
func testArrayType() { func testArrayType() {
Defaults[.collectionArray].append(Bag(items: [fixtureCollection[0]])) Defaults[.collectionArray].append(Bag(items: [fixtureCollection[0]]))
Defaults[.collectionArray][0].insert(element: "123", at: 0) Defaults[.collectionArray][0].insert(element: "123", at: 0)
XCTAssertEqual(Defaults[.collectionArray][0][0], "123") #expect(Defaults[.collectionArray][0][0] == "123")
XCTAssertEqual(Defaults[.collectionArray][1][0], fixtureCollection[0]) #expect(Defaults[.collectionArray][1][0] == fixtureCollection[0])
} }
@Test
func testDictionaryType() { func testDictionaryType() {
Defaults[.collectionDictionary]["1"] = Bag(items: [fixtureCollection[0]]) Defaults[.collectionDictionary]["1"] = Bag(items: [fixtureCollection[0]])
Defaults[.collectionDictionary]["0"]?.insert(element: "123", at: 0) Defaults[.collectionDictionary]["0"]?.insert(element: "123", at: 0)
XCTAssertEqual(Defaults[.collectionDictionary]["0"]?[0], "123") #expect(Defaults[.collectionDictionary]["0"]?[0] == "123")
XCTAssertEqual(Defaults[.collectionDictionary]["1"]?[0], fixtureCollection[0]) #expect(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)
} }
} }

View File

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

View File

@ -1,6 +1,8 @@
import Foundation import Foundation
import Testing
import Defaults import Defaults
import XCTest
private let suite_ = createSuite()
public struct User: Hashable, Equatable { public struct User: Hashable, Equatable {
var username: String var username: String
@ -84,343 +86,176 @@ extension Collection {
} }
extension Defaults.Keys { extension Defaults.Keys {
fileprivate static let customBridge = Key<User>("customBridge", default: fixtureCustomBridge) fileprivate static let customBridge = Key<User>("customBridge", default: fixtureCustomBridge, suite: suite_)
fileprivate static let customBridgeArray = Key<[User]>("array_customBridge", default: [fixtureCustomBridge]) fileprivate static let customBridgeArray = Key<[User]>("array_customBridge", default: [fixtureCustomBridge], suite: suite_)
fileprivate static let customBridgeDictionary = Key<[String: User]>("dictionary_customBridge", default: ["0": fixtureCustomBridge]) fileprivate static let customBridgeDictionary = Key<[String: User]>("dictionary_customBridge", default: ["0": fixtureCustomBridge], suite: suite_)
} }
final class DefaultsCustomBridge: XCTestCase { @Suite(.serialized)
override func setUp() { final class DefaultsCustomBridge {
super.setUp() init() {
Defaults.removeAll() Defaults.removeAll(suite: suite_)
} }
override func tearDown() { deinit {
super.tearDown() Defaults.removeAll(suite: suite_)
Defaults.removeAll()
} }
@Test
func testKey() { func testKey() {
let key = Defaults.Key<User>("independentCustomBridgeKey", default: fixtureCustomBridge) let key = Defaults.Key<User>("independentCustomBridgeKey", default: fixtureCustomBridge, suite: suite_)
XCTAssertEqual(Defaults[key], fixtureCustomBridge) #expect(Defaults[key] == fixtureCustomBridge)
let newUser = User(username: "sindresorhus", password: "123456789") let newUser = User(username: "sindresorhus", password: "123456789")
Defaults[key] = newUser Defaults[key] = newUser
XCTAssertEqual(Defaults[key], newUser) #expect(Defaults[key] == newUser)
} }
@Test
func testOptionalKey() { func testOptionalKey() {
let key = Defaults.Key<User?>("independentCustomBridgeOptionalKey") let key = Defaults.Key<User?>("independentCustomBridgeOptionalKey", suite: suite_)
XCTAssertNil(Defaults[key]) #expect(Defaults[key] == nil)
Defaults[key] = fixtureCustomBridge Defaults[key] = fixtureCustomBridge
XCTAssertEqual(Defaults[key], fixtureCustomBridge) #expect(Defaults[key] == fixtureCustomBridge)
} }
@Test
func testArrayKey() { func testArrayKey() {
let user = User(username: "hank121314", password: "123456") let user = User(username: "hank121314", password: "123456")
let key = Defaults.Key<[User]>("independentCustomBridgeArrayKey", default: [user]) let key = Defaults.Key<[User]>("independentCustomBridgeArrayKey", default: [user], suite: suite_)
XCTAssertEqual(Defaults[key][0], user) #expect(Defaults[key][0] == user)
let newUser = User(username: "sindresorhus", password: "123456789") let newUser = User(username: "sindresorhus", password: "123456789")
Defaults[key][0] = newUser Defaults[key][0] = newUser
XCTAssertEqual(Defaults[key][0], newUser) #expect(Defaults[key][0] == newUser)
} }
@Test
func testArrayOptionalKey() { func testArrayOptionalKey() {
let key = Defaults.Key<[User]?>("independentCustomBridgeArrayOptionalKey") // swiftlint:disable:this discouraged_optional_collection let key = Defaults.Key<[User]?>("independentCustomBridgeArrayOptionalKey", suite: suite_) // swiftlint:disable:this discouraged_optional_collection
XCTAssertNil(Defaults[key]) #expect(Defaults[key] == nil)
let newUser = User(username: "hank121314", password: "123456") let newUser = User(username: "hank121314", password: "123456")
Defaults[key] = [newUser] Defaults[key] = [newUser]
XCTAssertEqual(Defaults[key]?[0], newUser) #expect(Defaults[key]?[0] == newUser)
Defaults[key] = nil Defaults[key] = nil
XCTAssertNil(Defaults[key]) #expect(Defaults[key] == nil)
} }
@Test
func testNestedArrayKey() { func testNestedArrayKey() {
let key = Defaults.Key<[[User]]>("independentCustomBridgeNestedArrayKey", default: [[fixtureCustomBridge], [fixtureCustomBridge]]) let key = Defaults.Key<[[User]]>("independentCustomBridgeNestedArrayKey", default: [[fixtureCustomBridge], [fixtureCustomBridge]], suite: suite_)
XCTAssertEqual(Defaults[key][0][0].username, fixtureCustomBridge.username) #expect(Defaults[key][0][0].username == fixtureCustomBridge.username)
let newUsername = "John" let newUsername = "John"
let newPassword = "7891011" let newPassword = "7891011"
Defaults[key][0][0] = User(username: newUsername, password: newPassword) Defaults[key][0][0] = User(username: newUsername, password: newPassword)
XCTAssertEqual(Defaults[key][0][0].username, newUsername) #expect(Defaults[key][0][0].username == newUsername)
XCTAssertEqual(Defaults[key][0][0].password, newPassword) #expect(Defaults[key][0][0].password == newPassword)
XCTAssertEqual(Defaults[key][1][0].username, fixtureCustomBridge.username) #expect(Defaults[key][1][0].username == fixtureCustomBridge.username)
XCTAssertEqual(Defaults[key][1][0].password, fixtureCustomBridge.password) #expect(Defaults[key][1][0].password == fixtureCustomBridge.password)
} }
@Test
func testArrayDictionaryKey() { func testArrayDictionaryKey() {
let key = Defaults.Key<[[String: User]]>("independentCustomBridgeArrayDictionaryKey", default: [["0": fixtureCustomBridge], ["0": fixtureCustomBridge]]) let key = Defaults.Key<[[String: User]]>("independentCustomBridgeArrayDictionaryKey", default: [["0": fixtureCustomBridge], ["0": fixtureCustomBridge]], suite: suite_)
XCTAssertEqual(Defaults[key][0]["0"]?.username, fixtureCustomBridge.username) #expect(Defaults[key][0]["0"]?.username == fixtureCustomBridge.username)
let newUser = User(username: "sindresorhus", password: "123456789") let newUser = User(username: "sindresorhus", password: "123456789")
Defaults[key][0]["0"] = newUser Defaults[key][0]["0"] = newUser
XCTAssertEqual(Defaults[key][0]["0"], newUser) #expect(Defaults[key][0]["0"] == newUser)
XCTAssertEqual(Defaults[key][1]["0"], fixtureCustomBridge) #expect(Defaults[key][1]["0"] == fixtureCustomBridge)
} }
@Test
func testSetKey() { func testSetKey() {
let key = Defaults.Key<Set<User>>("independentCustomBridgeSetKey", default: [fixtureCustomBridge]) let key = Defaults.Key<Set<User>>("independentCustomBridgeSetKey", default: [fixtureCustomBridge], suite: suite_)
XCTAssertEqual(Defaults[key].first, fixtureCustomBridge) #expect(Defaults[key].first == fixtureCustomBridge)
Defaults[key].insert(fixtureCustomBridge) Defaults[key].insert(fixtureCustomBridge)
XCTAssertEqual(Defaults[key].count, 1) #expect(Defaults[key].count == 1)
let newUser = User(username: "sindresorhus", password: "123456789") let newUser = User(username: "sindresorhus", password: "123456789")
Defaults[key].insert(newUser) Defaults[key].insert(newUser)
XCTAssertTrue(Defaults[key].contains(newUser)) #expect(Defaults[key].contains(newUser))
} }
@Test
func testDictionaryKey() { func testDictionaryKey() {
let key = Defaults.Key<[String: User]>("independentCustomBridgeDictionaryKey", default: ["0": fixtureCustomBridge]) let key = Defaults.Key<[String: User]>("independentCustomBridgeDictionaryKey", default: ["0": fixtureCustomBridge], suite: suite_)
XCTAssertEqual(Defaults[key]["0"], fixtureCustomBridge) #expect(Defaults[key]["0"] == fixtureCustomBridge)
let newUser = User(username: "sindresorhus", password: "123456789") let newUser = User(username: "sindresorhus", password: "123456789")
Defaults[key]["0"] = newUser Defaults[key]["0"] = newUser
XCTAssertEqual(Defaults[key]["0"], newUser) #expect(Defaults[key]["0"] == newUser)
} }
@Test
func testDictionaryOptionalKey() { func testDictionaryOptionalKey() {
let key = Defaults.Key<[String: User]?>("independentCustomBridgeDictionaryOptionalKey") // swiftlint:disable:this discouraged_optional_collection let key = Defaults.Key<[String: User]?>("independentCustomBridgeDictionaryOptionalKey", suite: suite_) // swiftlint:disable:this discouraged_optional_collection
XCTAssertNil(Defaults[key]) #expect(Defaults[key] == nil)
Defaults[key] = ["0": fixtureCustomBridge] Defaults[key] = ["0": fixtureCustomBridge]
XCTAssertEqual(Defaults[key]?["0"], fixtureCustomBridge) #expect(Defaults[key]?["0"] == fixtureCustomBridge)
} }
@Test
func testDictionaryArrayKey() { func testDictionaryArrayKey() {
let key = Defaults.Key<[String: [User]]>("independentCustomBridgeDictionaryArrayKey", default: ["0": [fixtureCustomBridge]]) let key = Defaults.Key<[String: [User]]>("independentCustomBridgeDictionaryArrayKey", default: ["0": [fixtureCustomBridge]], suite: suite_)
XCTAssertEqual(Defaults[key]["0"]?[0], fixtureCustomBridge) #expect(Defaults[key]["0"]?[0] == fixtureCustomBridge)
let newUser = User(username: "sindresorhus", password: "123456789") let newUser = User(username: "sindresorhus", password: "123456789")
Defaults[key]["0"]?[0] = newUser Defaults[key]["0"]?[0] = newUser
Defaults[key]["0"]?.append(fixtureCustomBridge) Defaults[key]["0"]?.append(fixtureCustomBridge)
XCTAssertEqual(Defaults[key]["0"]?[0], newUser) #expect(Defaults[key]["0"]?[0] == newUser)
XCTAssertEqual(Defaults[key]["0"]?[0], newUser) #expect(Defaults[key]["0"]?[0] == newUser)
XCTAssertEqual(Defaults[key]["0"]?[1], fixtureCustomBridge) #expect(Defaults[key]["0"]?[1] == fixtureCustomBridge)
XCTAssertEqual(Defaults[key]["0"]?[1], fixtureCustomBridge) #expect(Defaults[key]["0"]?[1] == fixtureCustomBridge)
} }
@Test
func testRecursiveKey() { func testRecursiveKey() {
let start = PlainHourMinuteTime(hour: 1, minute: 0) let start = PlainHourMinuteTime(hour: 1, minute: 0)
let end = PlainHourMinuteTime(hour: 2, minute: 0) let end = PlainHourMinuteTime(hour: 2, minute: 0)
let range = PlainHourMinuteTimeRange(start: start, end: end) let range = PlainHourMinuteTimeRange(start: start, end: end)
let key = Defaults.Key<PlainHourMinuteTimeRange>("independentCustomBridgeRecursiveKey", default: range) let key = Defaults.Key<PlainHourMinuteTimeRange>("independentCustomBridgeRecursiveKey", default: range, suite: suite_)
XCTAssertEqual(Defaults[key].start.hour, range.start.hour) #expect(Defaults[key].start.hour == range.start.hour)
XCTAssertEqual(Defaults[key].start.minute, range.start.minute) #expect(Defaults[key].start.minute == range.start.minute)
XCTAssertEqual(Defaults[key].end.hour, range.end.hour) #expect(Defaults[key].end.hour == range.end.hour)
XCTAssertEqual(Defaults[key].end.minute, range.end.minute) #expect(Defaults[key].end.minute == range.end.minute)
guard let rawValue = UserDefaults.standard.array(forKey: key.name) as? [String] else { guard let rawValue = suite_.array(forKey: key.name) as? [String] else {
XCTFail("rawValue should not be nil") Issue.record("rawValue should not be nil")
return 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_start = PlainHourMinuteTime(hour: 3, minute: 58)
let next_end = PlainHourMinuteTime(hour: 4, minute: 59) let next_end = PlainHourMinuteTime(hour: 4, minute: 59)
let next_range = PlainHourMinuteTimeRange(start: next_start, end: next_end) let next_range = PlainHourMinuteTimeRange(start: next_start, end: next_end)
Defaults[key] = next_range Defaults[key] = next_range
XCTAssertEqual(Defaults[key].start.hour, next_range.start.hour) #expect(Defaults[key].start.hour == next_range.start.hour)
XCTAssertEqual(Defaults[key].start.minute, next_range.start.minute) #expect(Defaults[key].start.minute == next_range.start.minute)
XCTAssertEqual(Defaults[key].end.hour, next_range.end.hour) #expect(Defaults[key].end.hour == next_range.end.hour)
XCTAssertEqual(Defaults[key].end.minute, next_range.end.minute) #expect(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") guard let nextRawValue = suite_.array(forKey: key.name) as? [String] else {
Issue.record("nextRawValue should not be nil")
return return
} }
XCTAssertEqual(nextRawValue, [#"{"hour":3,"minute":58}"#, #"{"hour":4,"minute":59}"#])
#expect(nextRawValue == [#"{"hour":3,"minute":58}"#, #"{"hour":4,"minute":59}"#])
} }
@Test
func testType() { func testType() {
XCTAssertEqual(Defaults[.customBridge], fixtureCustomBridge) #expect(Defaults[.customBridge] == fixtureCustomBridge)
let newUser = User(username: "sindresorhus", password: "123456789") let newUser = User(username: "sindresorhus", password: "123456789")
Defaults[.customBridge] = newUser Defaults[.customBridge] = newUser
XCTAssertEqual(Defaults[.customBridge], newUser) #expect(Defaults[.customBridge] == newUser)
} }
@Test
func testArrayType() { func testArrayType() {
XCTAssertEqual(Defaults[.customBridgeArray][0], fixtureCustomBridge) #expect(Defaults[.customBridgeArray][0] == fixtureCustomBridge)
let newUser = User(username: "sindresorhus", password: "123456789") let newUser = User(username: "sindresorhus", password: "123456789")
Defaults[.customBridgeArray][0] = newUser Defaults[.customBridgeArray][0] = newUser
XCTAssertEqual(Defaults[.customBridgeArray][0], newUser) #expect(Defaults[.customBridgeArray][0] == newUser)
} }
@Test
func testDictionaryType() { func testDictionaryType() {
XCTAssertEqual(Defaults[.customBridgeDictionary]["0"], fixtureCustomBridge) #expect(Defaults[.customBridgeDictionary]["0"] == fixtureCustomBridge)
let newUser = User(username: "sindresorhus", password: "123456789") let newUser = User(username: "sindresorhus", password: "123456789")
Defaults[.customBridgeDictionary]["0"] = newUser Defaults[.customBridgeDictionary]["0"] = newUser
XCTAssertEqual(Defaults[.customBridgeDictionary]["0"], newUser) #expect(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)
} }
} }

View File

@ -1,167 +1,82 @@
import Foundation import Foundation
import Testing
import Defaults import Defaults
import XCTest
private let suite_ = createSuite()
private let fixtureDictionary = ["0": "Hank"] private let fixtureDictionary = ["0": "Hank"]
private let fixtureArray = ["Hank", "Chen"] private let fixtureArray = ["Hank", "Chen"]
extension Defaults.Keys { 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 { @Suite(.serialized)
override func setUp() { final class DefaultsDictionaryTests {
super.setUp() init() {
Defaults.removeAll() Defaults.removeAll(suite: suite_)
} }
override func tearDown() { deinit {
super.tearDown() Defaults.removeAll(suite: suite_)
Defaults.removeAll()
} }
@Test
func testKey() { func testKey() {
let key = Defaults.Key<[String: String]>("independentDictionaryStringKey", default: fixtureDictionary) let key = Defaults.Key<[String: String]>("independentDictionaryStringKey", default: fixtureDictionary, suite: suite_)
XCTAssertEqual(Defaults[key]["0"], fixtureDictionary["0"]) #expect(Defaults[key]["0"] == fixtureDictionary["0"])
let newValue = "John" let newValue = "John"
Defaults[key]["0"] = newValue Defaults[key]["0"] = newValue
XCTAssertEqual(Defaults[key]["0"], newValue) #expect(Defaults[key]["0"] == newValue)
} }
@Test
func testOptionalKey() { func testOptionalKey() {
let key = Defaults.Key<[String: String]?>("independentDictionaryOptionalKey") // swiftlint:disable:this discouraged_optional_collection let key = Defaults.Key<[String: String]?>("independentDictionaryOptionalKey", suite: suite_) // swiftlint:disable:this discouraged_optional_collection
XCTAssertNil(Defaults[key]) #expect(Defaults[key] == nil)
Defaults[key] = fixtureDictionary Defaults[key] = fixtureDictionary
XCTAssertEqual(Defaults[key]?["0"], fixtureDictionary["0"]) #expect(Defaults[key]?["0"] == fixtureDictionary["0"])
Defaults[key] = nil Defaults[key] = nil
XCTAssertNil(Defaults[key]) #expect(Defaults[key] == nil)
let newValue = ["0": "Chen"] let newValue = ["0": "Chen"]
Defaults[key] = newValue Defaults[key] = newValue
XCTAssertEqual(Defaults[key]?["0"], newValue["0"]) #expect(Defaults[key]?["0"] == newValue["0"])
} }
@Test
func testNestedKey() { func testNestedKey() {
let key = Defaults.Key<[String: [String: String]]>("independentDictionaryNestedKey", default: ["0": fixtureDictionary]) let key = Defaults.Key<[String: [String: String]]>("independentDictionaryNestedKey", default: ["0": fixtureDictionary], suite: suite_)
XCTAssertEqual(Defaults[key]["0"]?["0"], "Hank") #expect(Defaults[key]["0"]?["0"] == "Hank")
let newName = "Chen" let newName = "Chen"
Defaults[key]["0"]?["0"] = newName Defaults[key]["0"]?["0"] = newName
XCTAssertEqual(Defaults[key]["0"]?["0"], newName) #expect(Defaults[key]["0"]?["0"] == newName)
} }
@Test
func testArrayKey() { func testArrayKey() {
let key = Defaults.Key<[String: [String]]>("independentDictionaryArrayKey", default: ["0": fixtureArray]) let key = Defaults.Key<[String: [String]]>("independentDictionaryArrayKey", default: ["0": fixtureArray], suite: suite_)
XCTAssertEqual(Defaults[key]["0"], fixtureArray) #expect(Defaults[key]["0"] == fixtureArray)
let newName = "Chen" let newName = "Chen"
Defaults[key]["0"]?[0] = newName Defaults[key]["0"]?[0] = newName
XCTAssertEqual(Defaults[key]["0"], [newName, fixtureArray[1]]) #expect(Defaults[key]["0"] == [newName, fixtureArray[1]])
} }
@Test
func testIntKey() { func testIntKey() {
let fixture = [1: "x"] let fixture = [1: "x"]
let key = Defaults.Key<[Int: String]>("independentDictionaryIntKey", default: fixture) let key = Defaults.Key<[Int: String]>("independentDictionaryIntKey", default: fixture, suite: suite_)
XCTAssertEqual(Defaults[key][1], fixture[1]) #expect(Defaults[key][1] == fixture[1])
let newValue = "John" let newValue = "John"
Defaults[key][1] = newValue Defaults[key][1] = newValue
XCTAssertEqual(Defaults[key][1], newValue) #expect(Defaults[key][1] == newValue)
} }
@Test
func testType() { func testType() {
XCTAssertEqual(Defaults[.dictionary]["0"], fixtureDictionary["0"]) #expect(Defaults[.dictionary]["0"] == fixtureDictionary["0"])
let newName = "Chen" let newName = "Chen"
Defaults[.dictionary]["0"] = newName Defaults[.dictionary]["0"] = newName
XCTAssertEqual(Defaults[.dictionary]["0"], newName) #expect(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)
} }
} }

View File

@ -1,6 +1,8 @@
import Foundation import Foundation
import Testing
import Defaults import Defaults
import XCTest
private let suite_ = createSuite()
private enum FixtureEnum: String, Defaults.Serializable { private enum FixtureEnum: String, Defaults.Serializable {
case tenMinutes = "10 Minutes" case tenMinutes = "10 Minutes"
@ -9,296 +11,121 @@ private enum FixtureEnum: String, Defaults.Serializable {
} }
extension Defaults.Keys { extension Defaults.Keys {
fileprivate static let `enum` = Key<FixtureEnum>("enum", default: .tenMinutes) fileprivate static let `enum` = Key<FixtureEnum>("enum", default: .tenMinutes, suite: suite_)
fileprivate static let enumArray = Key<[FixtureEnum]>("array_enum", default: [.tenMinutes]) fileprivate static let enumArray = Key<[FixtureEnum]>("array_enum", default: [.tenMinutes], suite: suite_)
fileprivate static let enumDictionary = Key<[String: FixtureEnum]>("dictionary_enum", default: ["0": .tenMinutes]) fileprivate static let enumDictionary = Key<[String: FixtureEnum]>("dictionary_enum", default: ["0": .tenMinutes], suite: suite_)
} }
final class DefaultsEnumTests: XCTestCase { @Suite(.serialized)
override func setUp() { final class DefaultsEnumTests {
super.setUp() init() {
Defaults.removeAll() Defaults.removeAll(suite: suite_)
} }
override func tearDown() { deinit {
super.tearDown() Defaults.removeAll(suite: suite_)
Defaults.removeAll()
} }
@Test
func testKey() { func testKey() {
let key = Defaults.Key<FixtureEnum>("independentEnumKey", default: .tenMinutes) let key = Defaults.Key<FixtureEnum>("independentEnumKey", default: .tenMinutes, suite: suite_)
XCTAssertEqual(Defaults[key], .tenMinutes) #expect(Defaults[key] == .tenMinutes)
Defaults[key] = .halfHour Defaults[key] = .halfHour
XCTAssertEqual(Defaults[key], .halfHour) #expect(Defaults[key] == .halfHour)
} }
@Test
func testOptionalKey() { func testOptionalKey() {
let key = Defaults.Key<FixtureEnum?>("independentEnumOptionalKey") let key = Defaults.Key<FixtureEnum?>("independentEnumOptionalKey", suite: suite_)
XCTAssertNil(Defaults[key]) #expect(Defaults[key] == nil)
Defaults[key] = .tenMinutes Defaults[key] = .tenMinutes
XCTAssertEqual(Defaults[key], .tenMinutes) #expect(Defaults[key] == .tenMinutes)
} }
@Test
func testArrayKey() { func testArrayKey() {
let key = Defaults.Key<[FixtureEnum]>("independentEnumArrayKey", default: [.tenMinutes]) let key = Defaults.Key<[FixtureEnum]>("independentEnumArrayKey", default: [.tenMinutes], suite: suite_)
XCTAssertEqual(Defaults[key][0], .tenMinutes) #expect(Defaults[key][0] == .tenMinutes)
Defaults[key].append(.halfHour) Defaults[key].append(.halfHour)
XCTAssertEqual(Defaults[key][0], .tenMinutes) #expect(Defaults[key][0] == .tenMinutes)
XCTAssertEqual(Defaults[key][1], .halfHour) #expect(Defaults[key][1] == .halfHour)
} }
@Test
func testArrayOptionalKey() { func testArrayOptionalKey() {
let key = Defaults.Key<[FixtureEnum]?>("independentEnumArrayOptionalKey") // swiftlint:disable:this discouraged_optional_collection let key = Defaults.Key<[FixtureEnum]?>("independentEnumArrayOptionalKey", suite: suite_) // swiftlint:disable:this discouraged_optional_collection
XCTAssertNil(Defaults[key]) #expect(Defaults[key] == nil)
Defaults[key] = [.tenMinutes] Defaults[key] = [.tenMinutes]
Defaults[key]?.append(.halfHour) Defaults[key]?.append(.halfHour)
XCTAssertEqual(Defaults[key]?[0], .tenMinutes) #expect(Defaults[key]?[0] == .tenMinutes)
XCTAssertEqual(Defaults[key]?[1], .halfHour) #expect(Defaults[key]?[1] == .halfHour)
} }
@Test
func testNestedArrayKey() { func testNestedArrayKey() {
let key = Defaults.Key<[[FixtureEnum]]>("independentEnumNestedArrayKey", default: [[.tenMinutes]]) let key = Defaults.Key<[[FixtureEnum]]>("independentEnumNestedArrayKey", default: [[.tenMinutes]], suite: suite_)
XCTAssertEqual(Defaults[key][0][0], .tenMinutes) #expect(Defaults[key][0][0] == .tenMinutes)
Defaults[key][0].append(.halfHour) Defaults[key][0].append(.halfHour)
Defaults[key].append([.oneHour]) Defaults[key].append([.oneHour])
XCTAssertEqual(Defaults[key][0][1], .halfHour) #expect(Defaults[key][0][1] == .halfHour)
XCTAssertEqual(Defaults[key][1][0], .oneHour) #expect(Defaults[key][1][0] == .oneHour)
} }
@Test
func testArrayDictionaryKey() { func testArrayDictionaryKey() {
let key = Defaults.Key<[[String: FixtureEnum]]>("independentEnumArrayDictionaryKey", default: [["0": .tenMinutes]]) let key = Defaults.Key<[[String: FixtureEnum]]>("independentEnumArrayDictionaryKey", default: [["0": .tenMinutes]], suite: suite_)
XCTAssertEqual(Defaults[key][0]["0"], .tenMinutes) #expect(Defaults[key][0]["0"] == .tenMinutes)
Defaults[key][0]["1"] = .halfHour Defaults[key][0]["1"] = .halfHour
Defaults[key].append(["0": .oneHour]) Defaults[key].append(["0": .oneHour])
XCTAssertEqual(Defaults[key][0]["1"], .halfHour) #expect(Defaults[key][0]["1"] == .halfHour)
XCTAssertEqual(Defaults[key][1]["0"], .oneHour) #expect(Defaults[key][1]["0"] == .oneHour)
} }
@Test
func testDictionaryKey() { func testDictionaryKey() {
let key = Defaults.Key<[String: FixtureEnum]>("independentEnumDictionaryKey", default: ["0": .tenMinutes]) let key = Defaults.Key<[String: FixtureEnum]>("independentEnumDictionaryKey", default: ["0": .tenMinutes], suite: suite_)
XCTAssertEqual(Defaults[key]["0"], .tenMinutes) #expect(Defaults[key]["0"] == .tenMinutes)
Defaults[key]["1"] = .halfHour Defaults[key]["1"] = .halfHour
XCTAssertEqual(Defaults[key]["0"], .tenMinutes) #expect(Defaults[key]["0"] == .tenMinutes)
XCTAssertEqual(Defaults[key]["1"], .halfHour) #expect(Defaults[key]["1"] == .halfHour)
} }
@Test
func testDictionaryOptionalKey() { func testDictionaryOptionalKey() {
let key = Defaults.Key<[String: FixtureEnum]?>("independentEnumDictionaryOptionalKey") // swiftlint:disable:this discouraged_optional_collection let key = Defaults.Key<[String: FixtureEnum]?>("independentEnumDictionaryOptionalKey", suite: suite_) // swiftlint:disable:this discouraged_optional_collection
XCTAssertNil(Defaults[key]) #expect(Defaults[key] == nil)
Defaults[key] = ["0": .tenMinutes] Defaults[key] = ["0": .tenMinutes]
XCTAssertEqual(Defaults[key]?["0"], .tenMinutes) #expect(Defaults[key]?["0"] == .tenMinutes)
} }
@Test
func testDictionaryArrayKey() { func testDictionaryArrayKey() {
let key = Defaults.Key<[String: [FixtureEnum]]>("independentEnumDictionaryKey", default: ["0": [.tenMinutes]]) let key = Defaults.Key<[String: [FixtureEnum]]>("independentEnumDictionaryKey", default: ["0": [.tenMinutes]], suite: suite_)
XCTAssertEqual(Defaults[key]["0"]?[0], .tenMinutes) #expect(Defaults[key]["0"]?[0] == .tenMinutes)
Defaults[key]["0"]?.append(.halfHour) Defaults[key]["0"]?.append(.halfHour)
Defaults[key]["1"] = [.oneHour] Defaults[key]["1"] = [.oneHour]
XCTAssertEqual(Defaults[key]["0"]?[1], .halfHour) #expect(Defaults[key]["0"]?[1] == .halfHour)
XCTAssertEqual(Defaults[key]["1"]?[0], .oneHour) #expect(Defaults[key]["1"]?[0] == .oneHour)
} }
@Test
func testType() { func testType() {
XCTAssertEqual(Defaults[.enum], .tenMinutes) #expect(Defaults[.enum] == .tenMinutes)
Defaults[.enum] = .halfHour Defaults[.enum] = .halfHour
XCTAssertEqual(Defaults[.enum], .halfHour) #expect(Defaults[.enum] == .halfHour)
} }
@Test
func testArrayType() { func testArrayType() {
XCTAssertEqual(Defaults[.enumArray][0], .tenMinutes) #expect(Defaults[.enumArray][0] == .tenMinutes)
Defaults[.enumArray][0] = .oneHour Defaults[.enumArray][0] = .oneHour
XCTAssertEqual(Defaults[.enumArray][0], .oneHour) #expect(Defaults[.enumArray][0] == .oneHour)
} }
@Test
func testDictionaryType() { func testDictionaryType() {
XCTAssertEqual(Defaults[.enumDictionary]["0"], .tenMinutes) #expect(Defaults[.enumDictionary]["0"] == .tenMinutes)
Defaults[.enumDictionary]["0"] = .halfHour Defaults[.enumDictionary]["0"] = .halfHour
XCTAssertEqual(Defaults[.enumDictionary]["0"], .halfHour) #expect(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)
} }
} }

View File

@ -1,314 +1,143 @@
#if os(macOS) #if os(macOS)
import Foundation import Foundation
import Defaults
import XCTest
import AppKit 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 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 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) private let fixtureColor2 = NSColor(red: Double(255) / Double(0xFF), green: Double(180) / Double(0xFF), blue: Double(194) / Double(0xFF), alpha: 1)
extension Defaults.Keys { extension Defaults.Keys {
fileprivate static let color = Defaults.Key<NSColor>("NSColor", default: fixtureColor) fileprivate static let color = Defaults.Key<NSColor>("NSColor", default: fixtureColor, suite: suite_)
fileprivate static let colorArray = Defaults.Key<[NSColor]>("NSColorArray", default: [fixtureColor]) fileprivate static let colorArray = Defaults.Key<[NSColor]>("NSColorArray", default: [fixtureColor], suite: suite_)
fileprivate static let colorDictionary = Defaults.Key<[String: NSColor]>("NSColorArray", default: ["0": fixtureColor]) fileprivate static let colorDictionary = Defaults.Key<[String: NSColor]>("NSColorArray", default: ["0": fixtureColor], suite: suite_)
} }
final class DefaultsNSColorTests: XCTestCase { @Suite(.serialized)
override func setUp() { final class DefaultsNSColorTests {
super.setUp() init() {
Defaults.removeAll() Defaults.removeAll(suite: suite_)
} }
override func tearDown() { deinit {
super.tearDown() Defaults.removeAll(suite: suite_)
Defaults.removeAll()
} }
@Test
func testKey() { func testKey() {
let key = Defaults.Key<NSColor>("independentNSColorKey", default: fixtureColor) let key = Defaults.Key<NSColor>("independentNSColorKey", default: fixtureColor, suite: suite_)
XCTAssertTrue(Defaults[key].isEqual(fixtureColor)) #expect(Defaults[key].isEqual(fixtureColor))
Defaults[key] = fixtureColor1 Defaults[key] = fixtureColor1
XCTAssertTrue(Defaults[key].isEqual(fixtureColor1)) #expect(Defaults[key].isEqual(fixtureColor1))
} }
@Test
func testPreservesColorSpace() { func testPreservesColorSpace() {
let fixture = NSColor(displayP3Red: 1, green: 0.3, blue: 0.7, alpha: 1) 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 Defaults[key] = fixture
XCTAssertEqual(Defaults[key]?.colorSpace, fixture.colorSpace) #expect(Defaults[key]?.colorSpace == fixture.colorSpace)
XCTAssertEqual(Defaults[key]?.cgColor.colorSpace, fixture.cgColor.colorSpace) #expect(Defaults[key]?.cgColor.colorSpace == fixture.cgColor.colorSpace)
XCTAssertEqual(Defaults[key], fixture) #expect(Defaults[key] == fixture)
XCTAssertEqual(Defaults[key]?.cgColor, fixture.cgColor) #expect(Defaults[key]?.cgColor == fixture.cgColor)
} }
@Test
func testOptionalKey() { func testOptionalKey() {
let key = Defaults.Key<NSColor?>("independentNSColorOptionalKey") let key = Defaults.Key<NSColor?>("independentNSColorOptionalKey", suite: suite_)
XCTAssertNil(Defaults[key]) #expect(Defaults[key] == nil)
Defaults[key] = fixtureColor Defaults[key] = fixtureColor
XCTAssertTrue(Defaults[key]?.isEqual(fixtureColor) ?? false) #expect(Defaults[key]?.isEqual(fixtureColor) ?? false)
} }
@Test
func testArrayKey() { func testArrayKey() {
let key = Defaults.Key<[NSColor]>("independentNSColorArrayKey", default: [fixtureColor]) let key = Defaults.Key<[NSColor]>("independentNSColorArrayKey", default: [fixtureColor], suite: suite_)
XCTAssertTrue(Defaults[key][0].isEqual(fixtureColor)) #expect(Defaults[key][0].isEqual(fixtureColor))
Defaults[key].append(fixtureColor1) Defaults[key].append(fixtureColor1)
XCTAssertTrue(Defaults[key][1].isEqual(fixtureColor1)) #expect(Defaults[key][1].isEqual(fixtureColor1))
} }
@Test
func testArrayOptionalKey() { func testArrayOptionalKey() {
let key = Defaults.Key<[NSColor]?>("independentNSColorOptionalKey") // swiftlint:disable:this discouraged_optional_collection let key = Defaults.Key<[NSColor]?>("independentNSColorOptionalKey", suite: suite_) // swiftlint:disable:this discouraged_optional_collection
XCTAssertNil(Defaults[key]) #expect(Defaults[key] == nil)
Defaults[key] = [fixtureColor] Defaults[key] = [fixtureColor]
Defaults[key]?.append(fixtureColor1) Defaults[key]?.append(fixtureColor1)
XCTAssertTrue(Defaults[key]?[0].isEqual(fixtureColor) ?? false) #expect(Defaults[key]?[0].isEqual(fixtureColor) ?? false)
XCTAssertTrue(Defaults[key]?[1].isEqual(fixtureColor1) ?? false) #expect(Defaults[key]?[1].isEqual(fixtureColor1) ?? false)
} }
@Test
func testNestedArrayKey() { func testNestedArrayKey() {
let key = Defaults.Key<[[NSColor]]>("independentNSColorNestedArrayKey", default: [[fixtureColor]]) let key = Defaults.Key<[[NSColor]]>("independentNSColorNestedArrayKey", default: [[fixtureColor]], suite: suite_)
XCTAssertTrue(Defaults[key][0][0].isEqual(fixtureColor)) #expect(Defaults[key][0][0].isEqual(fixtureColor))
Defaults[key][0].append(fixtureColor1) Defaults[key][0].append(fixtureColor1)
Defaults[key].append([fixtureColor2]) Defaults[key].append([fixtureColor2])
XCTAssertTrue(Defaults[key][0][1].isEqual(fixtureColor1)) #expect(Defaults[key][0][1].isEqual(fixtureColor1))
XCTAssertTrue(Defaults[key][1][0].isEqual(fixtureColor2)) #expect(Defaults[key][1][0].isEqual(fixtureColor2))
} }
@Test
func testArrayDictionaryKey() { func testArrayDictionaryKey() {
let key = Defaults.Key<[[String: NSColor]]>("independentNSColorArrayDictionaryKey", default: [["0": fixtureColor]]) let key = Defaults.Key<[[String: NSColor]]>("independentNSColorArrayDictionaryKey", default: [["0": fixtureColor]], suite: suite_)
XCTAssertTrue(Defaults[key][0]["0"]?.isEqual(fixtureColor) ?? false) #expect(Defaults[key][0]["0"]?.isEqual(fixtureColor) ?? false)
Defaults[key][0]["1"] = fixtureColor1 Defaults[key][0]["1"] = fixtureColor1
Defaults[key].append(["0": fixtureColor2]) Defaults[key].append(["0": fixtureColor2])
XCTAssertTrue(Defaults[key][0]["1"]?.isEqual(fixtureColor1) ?? false) #expect(Defaults[key][0]["1"]?.isEqual(fixtureColor1) ?? false)
XCTAssertTrue(Defaults[key][1]["0"]?.isEqual(fixtureColor2) ?? false) #expect(Defaults[key][1]["0"]?.isEqual(fixtureColor2) ?? false)
} }
@Test
func testDictionaryKey() { func testDictionaryKey() {
let key = Defaults.Key<[String: NSColor]>("independentNSColorDictionaryKey", default: ["0": fixtureColor]) let key = Defaults.Key<[String: NSColor]>("independentNSColorDictionaryKey", default: ["0": fixtureColor], suite: suite_)
XCTAssertTrue(Defaults[key]["0"]?.isEqual(fixtureColor) ?? false) #expect(Defaults[key]["0"]?.isEqual(fixtureColor) ?? false)
Defaults[key]["1"] = fixtureColor1 Defaults[key]["1"] = fixtureColor1
XCTAssertTrue(Defaults[key]["1"]?.isEqual(fixtureColor1) ?? false) #expect(Defaults[key]["1"]?.isEqual(fixtureColor1) ?? false)
} }
@Test
func testDictionaryOptionalKey() { func testDictionaryOptionalKey() {
let key = Defaults.Key<[String: NSColor]?>("independentNSColorDictionaryOptionalKey") // swiftlint:disable:this discouraged_optional_collection let key = Defaults.Key<[String: NSColor]?>("independentNSColorDictionaryOptionalKey", suite: suite_) // swiftlint:disable:this discouraged_optional_collection
XCTAssertNil(Defaults[key]) #expect(Defaults[key] == nil)
Defaults[key] = ["0": fixtureColor] Defaults[key] = ["0": fixtureColor]
Defaults[key]?["1"] = fixtureColor1 Defaults[key]?["1"] = fixtureColor1
XCTAssertTrue(Defaults[key]?["0"]?.isEqual(fixtureColor) ?? false) #expect(Defaults[key]?["0"]?.isEqual(fixtureColor) ?? false)
XCTAssertTrue(Defaults[key]?["1"]?.isEqual(fixtureColor1) ?? false) #expect(Defaults[key]?["1"]?.isEqual(fixtureColor1) ?? false)
} }
@Test
func testDictionaryArrayKey() { func testDictionaryArrayKey() {
let key = Defaults.Key<[String: [NSColor]]>("independentNSColorDictionaryArrayKey", default: ["0": [fixtureColor]]) let key = Defaults.Key<[String: [NSColor]]>("independentNSColorDictionaryArrayKey", default: ["0": [fixtureColor]], suite: suite_)
XCTAssertTrue(Defaults[key]["0"]?[0].isEqual(fixtureColor) ?? false) #expect(Defaults[key]["0"]?[0].isEqual(fixtureColor) ?? false)
Defaults[key]["0"]?.append(fixtureColor1) Defaults[key]["0"]?.append(fixtureColor1)
Defaults[key]["1"] = [fixtureColor2] Defaults[key]["1"] = [fixtureColor2]
XCTAssertTrue(Defaults[key]["0"]?[1].isEqual(fixtureColor1) ?? false) #expect(Defaults[key]["0"]?[1].isEqual(fixtureColor1) ?? false)
XCTAssertTrue(Defaults[key]["1"]?[0].isEqual(fixtureColor2) ?? false) #expect(Defaults[key]["1"]?[0].isEqual(fixtureColor2) ?? false)
} }
@Test
func testType() { func testType() {
XCTAssert(Defaults[.color].isEqual(fixtureColor)) #expect(Defaults[.color].isEqual(fixtureColor))
Defaults[.color] = fixtureColor1 Defaults[.color] = fixtureColor1
XCTAssert(Defaults[.color].isEqual(fixtureColor1)) #expect(Defaults[.color].isEqual(fixtureColor1))
} }
@Test
func testArrayType() { func testArrayType() {
XCTAssertTrue(Defaults[.colorArray][0].isEqual(fixtureColor)) #expect(Defaults[.colorArray][0].isEqual(fixtureColor))
Defaults[.colorArray][0] = fixtureColor1 Defaults[.colorArray][0] = fixtureColor1
XCTAssertTrue(Defaults[.colorArray][0].isEqual(fixtureColor1)) #expect(Defaults[.colorArray][0].isEqual(fixtureColor1))
} }
@Test
func testDictionaryType() { func testDictionaryType() {
XCTAssertTrue(Defaults[.colorDictionary]["0"]?.isEqual(fixtureColor) ?? false) #expect(Defaults[.colorDictionary]["0"]?.isEqual(fixtureColor) ?? false)
Defaults[.colorDictionary]["0"] = fixtureColor1 Defaults[.colorDictionary]["0"] = fixtureColor1
XCTAssertTrue(Defaults[.colorDictionary]["0"]?.isEqual(fixtureColor1) ?? false) #expect(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)
} }
} }
#endif #endif

View File

@ -1,7 +1,9 @@
import Foundation import Foundation
import CoreData import CoreData
import Testing
import Defaults import Defaults
import XCTest
private let suite_ = createSuite()
@objc(ExamplePersistentHistory) @objc(ExamplePersistentHistory)
private final class ExamplePersistentHistory: NSPersistentHistoryToken, Defaults.Serializable { private final class ExamplePersistentHistory: NSPersistentHistoryToken, Defaults.Serializable {
@ -28,445 +30,144 @@ private final class ExamplePersistentHistory: NSPersistentHistoryToken, Defaults
private let persistentHistoryValue = ExamplePersistentHistory(value: "ExampleToken") private let persistentHistoryValue = ExamplePersistentHistory(value: "ExampleToken")
extension Defaults.Keys { extension Defaults.Keys {
fileprivate static let persistentHistory = Key<ExamplePersistentHistory>("persistentHistory", default: persistentHistoryValue) fileprivate static let persistentHistory = Key<ExamplePersistentHistory>("persistentHistory", default: persistentHistoryValue, suite: suite_)
fileprivate static let persistentHistoryArray = Key<[ExamplePersistentHistory]>("array_persistentHistory", default: [persistentHistoryValue]) fileprivate static let persistentHistoryArray = Key<[ExamplePersistentHistory]>("array_persistentHistory", default: [persistentHistoryValue], suite: suite_)
fileprivate static let persistentHistoryDictionary = Key<[String: ExamplePersistentHistory]>("dictionary_persistentHistory", default: ["0": persistentHistoryValue]) fileprivate static let persistentHistoryDictionary = Key<[String: ExamplePersistentHistory]>("dictionary_persistentHistory", default: ["0": persistentHistoryValue], suite: suite_)
} }
final class DefaultsNSSecureCodingTests: XCTestCase { @Suite(.serialized)
override func setUp() { final class DefaultsNSSecureCodingTests {
super.setUp() init() {
Defaults.removeAll() Defaults.removeAll(suite: suite_)
} }
override func tearDown() { deinit {
super.tearDown() Defaults.removeAll(suite: suite_)
Defaults.removeAll()
} }
@Test
func testKey() { func testKey() {
let key = Defaults.Key<ExamplePersistentHistory>("independentNSSecureCodingKey", default: persistentHistoryValue) let key = Defaults.Key<ExamplePersistentHistory>("independentNSSecureCodingKey", default: persistentHistoryValue, suite: suite_)
XCTAssertEqual(Defaults[key].value, persistentHistoryValue.value) #expect(Defaults[key].value == persistentHistoryValue.value)
let newPersistentHistory = ExamplePersistentHistory(value: "NewValue") let newPersistentHistory = ExamplePersistentHistory(value: "NewValue")
Defaults[key] = newPersistentHistory Defaults[key] = newPersistentHistory
XCTAssertEqual(Defaults[key].value, newPersistentHistory.value) #expect(Defaults[key].value == newPersistentHistory.value)
} }
@Test
func testOptionalKey() { func testOptionalKey() {
let key = Defaults.Key<ExamplePersistentHistory?>("independentNSSecureCodingOptionalKey") let key = Defaults.Key<ExamplePersistentHistory?>("independentNSSecureCodingOptionalKey", suite: suite_)
XCTAssertNil(Defaults[key]) #expect(Defaults[key] == nil)
Defaults[key] = persistentHistoryValue Defaults[key] = persistentHistoryValue
XCTAssertEqual(Defaults[key]?.value, persistentHistoryValue.value) #expect(Defaults[key]?.value == persistentHistoryValue.value)
Defaults[key] = nil Defaults[key] = nil
XCTAssertNil(Defaults[key]) #expect(Defaults[key] == nil)
let newPersistentHistory = ExamplePersistentHistory(value: "NewValue") let newPersistentHistory = ExamplePersistentHistory(value: "NewValue")
Defaults[key] = newPersistentHistory Defaults[key] = newPersistentHistory
XCTAssertEqual(Defaults[key]?.value, newPersistentHistory.value) #expect(Defaults[key]?.value == newPersistentHistory.value)
} }
@Test
func testArrayKey() { func testArrayKey() {
let key = Defaults.Key<[ExamplePersistentHistory]>("independentNSSecureCodingArrayKey", default: [persistentHistoryValue]) let key = Defaults.Key<[ExamplePersistentHistory]>("independentNSSecureCodingArrayKey", default: [persistentHistoryValue], suite: suite_)
XCTAssertEqual(Defaults[key][0].value, persistentHistoryValue.value) #expect(Defaults[key][0].value == persistentHistoryValue.value)
let newPersistentHistory1 = ExamplePersistentHistory(value: "NewValue1") let newPersistentHistory1 = ExamplePersistentHistory(value: "NewValue1")
Defaults[key].append(newPersistentHistory1) Defaults[key].append(newPersistentHistory1)
XCTAssertEqual(Defaults[key][1].value, newPersistentHistory1.value) #expect(Defaults[key][1].value == newPersistentHistory1.value)
let newPersistentHistory2 = ExamplePersistentHistory(value: "NewValue2") let newPersistentHistory2 = ExamplePersistentHistory(value: "NewValue2")
Defaults[key][1] = newPersistentHistory2 Defaults[key][1] = newPersistentHistory2
XCTAssertEqual(Defaults[key][1].value, newPersistentHistory2.value) #expect(Defaults[key][1].value == newPersistentHistory2.value)
XCTAssertEqual(Defaults[key][0].value, persistentHistoryValue.value) #expect(Defaults[key][0].value == persistentHistoryValue.value)
} }
@Test
func testArrayOptionalKey() { func testArrayOptionalKey() {
let key = Defaults.Key<[ExamplePersistentHistory]?>("independentNSSecureCodingArrayOptionalKey") // swiftlint:disable:this discouraged_optional_collection let key = Defaults.Key<[ExamplePersistentHistory]?>("independentNSSecureCodingArrayOptionalKey", suite: suite_) // swiftlint:disable:this discouraged_optional_collection
XCTAssertNil(Defaults[key]) #expect(Defaults[key] == nil)
Defaults[key] = [persistentHistoryValue] Defaults[key] = [persistentHistoryValue]
XCTAssertEqual(Defaults[key]?[0].value, persistentHistoryValue.value) #expect(Defaults[key]?[0].value == persistentHistoryValue.value)
Defaults[key] = nil Defaults[key] = nil
XCTAssertNil(Defaults[key]) #expect(Defaults[key] == nil)
} }
@Test
func testNestedArrayKey() { func testNestedArrayKey() {
let key = Defaults.Key<[[ExamplePersistentHistory]]>("independentNSSecureCodingNestedArrayKey", default: [[persistentHistoryValue]]) let key = Defaults.Key<[[ExamplePersistentHistory]]>("independentNSSecureCodingNestedArrayKey", default: [[persistentHistoryValue]], suite: suite_)
XCTAssertEqual(Defaults[key][0][0].value, persistentHistoryValue.value) #expect(Defaults[key][0][0].value == persistentHistoryValue.value)
let newPersistentHistory1 = ExamplePersistentHistory(value: "NewValue1") let newPersistentHistory1 = ExamplePersistentHistory(value: "NewValue1")
Defaults[key][0].append(newPersistentHistory1) Defaults[key][0].append(newPersistentHistory1)
let newPersistentHistory2 = ExamplePersistentHistory(value: "NewValue2") let newPersistentHistory2 = ExamplePersistentHistory(value: "NewValue2")
Defaults[key].append([newPersistentHistory2]) Defaults[key].append([newPersistentHistory2])
XCTAssertEqual(Defaults[key][0][1].value, newPersistentHistory1.value) #expect(Defaults[key][0][1].value == newPersistentHistory1.value)
XCTAssertEqual(Defaults[key][1][0].value, newPersistentHistory2.value) #expect(Defaults[key][1][0].value == newPersistentHistory2.value)
} }
@Test
func testArrayDictionaryKey() { func testArrayDictionaryKey() {
let key = Defaults.Key<[[String: ExamplePersistentHistory]]>("independentNSSecureCodingArrayDictionaryKey", default: [["0": persistentHistoryValue]]) let key = Defaults.Key<[[String: ExamplePersistentHistory]]>("independentNSSecureCodingArrayDictionaryKey", default: [["0": persistentHistoryValue]], suite: suite_)
XCTAssertEqual(Defaults[key][0]["0"]?.value, persistentHistoryValue.value) #expect(Defaults[key][0]["0"]?.value == persistentHistoryValue.value)
let newPersistentHistory1 = ExamplePersistentHistory(value: "NewValue1") let newPersistentHistory1 = ExamplePersistentHistory(value: "NewValue1")
Defaults[key][0]["1"] = newPersistentHistory1 Defaults[key][0]["1"] = newPersistentHistory1
let newPersistentHistory2 = ExamplePersistentHistory(value: "NewValue2") let newPersistentHistory2 = ExamplePersistentHistory(value: "NewValue2")
Defaults[key].append(["0": newPersistentHistory2]) Defaults[key].append(["0": newPersistentHistory2])
XCTAssertEqual(Defaults[key][0]["1"]?.value, newPersistentHistory1.value) #expect(Defaults[key][0]["1"]?.value == newPersistentHistory1.value)
XCTAssertEqual(Defaults[key][1]["0"]?.value, newPersistentHistory2.value) #expect(Defaults[key][1]["0"]?.value == newPersistentHistory2.value)
} }
@Test
func testDictionaryKey() { func testDictionaryKey() {
let key = Defaults.Key<[String: ExamplePersistentHistory]>("independentNSSecureCodingDictionaryKey", default: ["0": persistentHistoryValue]) let key = Defaults.Key<[String: ExamplePersistentHistory]>("independentNSSecureCodingDictionaryKey", default: ["0": persistentHistoryValue], suite: suite_)
XCTAssertEqual(Defaults[key]["0"]?.value, persistentHistoryValue.value) #expect(Defaults[key]["0"]?.value == persistentHistoryValue.value)
let newPersistentHistory1 = ExamplePersistentHistory(value: "NewValue1") let newPersistentHistory1 = ExamplePersistentHistory(value: "NewValue1")
Defaults[key]["1"] = newPersistentHistory1 Defaults[key]["1"] = newPersistentHistory1
XCTAssertEqual(Defaults[key]["1"]?.value, newPersistentHistory1.value) #expect(Defaults[key]["1"]?.value == newPersistentHistory1.value)
let newPersistentHistory2 = ExamplePersistentHistory(value: "NewValue2") let newPersistentHistory2 = ExamplePersistentHistory(value: "NewValue2")
Defaults[key]["1"] = newPersistentHistory2 Defaults[key]["1"] = newPersistentHistory2
XCTAssertEqual(Defaults[key]["1"]?.value, newPersistentHistory2.value) #expect(Defaults[key]["1"]?.value == newPersistentHistory2.value)
XCTAssertEqual(Defaults[key]["0"]?.value, persistentHistoryValue.value) #expect(Defaults[key]["0"]?.value == persistentHistoryValue.value)
} }
@Test
func testDictionaryOptionalKey() { func testDictionaryOptionalKey() {
let key = Defaults.Key<[String: ExamplePersistentHistory]?>("independentNSSecureCodingDictionaryOptionalKey") // swiftlint:disable:this discouraged_optional_collection let key = Defaults.Key<[String: ExamplePersistentHistory]?>("independentNSSecureCodingDictionaryOptionalKey", suite: suite_) // swiftlint:disable:this discouraged_optional_collection
XCTAssertNil(Defaults[key]) #expect(Defaults[key] == nil)
Defaults[key] = ["0": persistentHistoryValue] Defaults[key] = ["0": persistentHistoryValue]
XCTAssertEqual(Defaults[key]?["0"]?.value, persistentHistoryValue.value) #expect(Defaults[key]?["0"]?.value == persistentHistoryValue.value)
} }
@Test
func testDictionaryArrayKey() { func testDictionaryArrayKey() {
let key = Defaults.Key<[String: [ExamplePersistentHistory]]>("independentNSSecureCodingDictionaryArrayKey", default: ["0": [persistentHistoryValue]]) let key = Defaults.Key<[String: [ExamplePersistentHistory]]>("independentNSSecureCodingDictionaryArrayKey", default: ["0": [persistentHistoryValue]], suite: suite_)
XCTAssertEqual(Defaults[key]["0"]?[0].value, persistentHistoryValue.value) #expect(Defaults[key]["0"]?[0].value == persistentHistoryValue.value)
let newPersistentHistory1 = ExamplePersistentHistory(value: "NewValue1") let newPersistentHistory1 = ExamplePersistentHistory(value: "NewValue1")
Defaults[key]["0"]?.append(newPersistentHistory1) Defaults[key]["0"]?.append(newPersistentHistory1)
let newPersistentHistory2 = ExamplePersistentHistory(value: "NewValue2") let newPersistentHistory2 = ExamplePersistentHistory(value: "NewValue2")
Defaults[key]["1"] = [newPersistentHistory2] Defaults[key]["1"] = [newPersistentHistory2]
XCTAssertEqual(Defaults[key]["0"]?[1].value, newPersistentHistory1.value) #expect(Defaults[key]["0"]?[1].value == newPersistentHistory1.value)
XCTAssertEqual(Defaults[key]["1"]?[0].value, newPersistentHistory2.value) #expect(Defaults[key]["1"]?[0].value == newPersistentHistory2.value)
} }
@Test
func testType() { func testType() {
XCTAssertEqual(Defaults[.persistentHistory].value, persistentHistoryValue.value) #expect(Defaults[.persistentHistory].value == persistentHistoryValue.value)
let newPersistentHistory = ExamplePersistentHistory(value: "NewValue") let newPersistentHistory = ExamplePersistentHistory(value: "NewValue")
Defaults[.persistentHistory] = newPersistentHistory Defaults[.persistentHistory] = newPersistentHistory
XCTAssertEqual(Defaults[.persistentHistory].value, newPersistentHistory.value) #expect(Defaults[.persistentHistory].value == newPersistentHistory.value)
} }
@Test
func testArrayType() { func testArrayType() {
XCTAssertEqual(Defaults[.persistentHistoryArray][0].value, persistentHistoryValue.value) #expect(Defaults[.persistentHistoryArray][0].value == persistentHistoryValue.value)
let newPersistentHistory = ExamplePersistentHistory(value: "NewValue") let newPersistentHistory = ExamplePersistentHistory(value: "NewValue")
Defaults[.persistentHistoryArray][0] = newPersistentHistory Defaults[.persistentHistoryArray][0] = newPersistentHistory
XCTAssertEqual(Defaults[.persistentHistoryArray][0].value, newPersistentHistory.value) #expect(Defaults[.persistentHistoryArray][0].value == newPersistentHistory.value)
} }
@Test
func testDictionaryType() { func testDictionaryType() {
XCTAssertEqual(Defaults[.persistentHistoryDictionary]["0"]?.value, persistentHistoryValue.value) #expect(Defaults[.persistentHistoryDictionary]["0"]?.value == persistentHistoryValue.value)
let newPersistentHistory = ExamplePersistentHistory(value: "NewValue") let newPersistentHistory = ExamplePersistentHistory(value: "NewValue")
Defaults[.persistentHistoryDictionary]["0"] = newPersistentHistory Defaults[.persistentHistoryDictionary]["0"] = newPersistentHistory
XCTAssertEqual(Defaults[.persistentHistoryDictionary]["0"]?.value, newPersistentHistory.value) #expect(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)
} }
} }

View File

@ -1,6 +1,8 @@
import Foundation import Foundation
import Testing
import Defaults import Defaults
import XCTest
private let suite_ = createSuite()
private struct CustomDate { private struct CustomDate {
let year: Int 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 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) private let nextFixtureDateClosedRange = CustomDate(year: 2022, month: 6, day: 1)...CustomDate(year: 2022, month: 7, day: 1)
final class DefaultsClosedRangeTests: XCTestCase { @Suite(.serialized)
override func setUp() { final class DefaultsClosedRangeTests {
super.setUp() init() {
Defaults.removeAll() Defaults.removeAll(suite: suite_)
} }
override func tearDown() { deinit {
super.tearDown() Defaults.removeAll(suite: suite_)
Defaults.removeAll()
} }
@Test
func testKey() { func testKey() {
// Test native support Range type // Test native support Range type
let key = Defaults.Key<Range>("independentRangeKey", default: fixtureRange) let key = Defaults.Key<Range>("independentRangeKey", default: fixtureRange, suite: suite_)
XCTAssertEqual(fixtureRange.upperBound, Defaults[key].upperBound) #expect(fixtureRange.upperBound == Defaults[key].upperBound)
XCTAssertEqual(fixtureRange.lowerBound, Defaults[key].lowerBound) #expect(fixtureRange.lowerBound == Defaults[key].lowerBound)
Defaults[key] = nextFixtureRange Defaults[key] = nextFixtureRange
XCTAssertEqual(nextFixtureRange.upperBound, Defaults[key].upperBound) #expect(nextFixtureRange.upperBound == Defaults[key].upperBound)
XCTAssertEqual(nextFixtureRange.lowerBound, Defaults[key].lowerBound) #expect(nextFixtureRange.lowerBound == Defaults[key].lowerBound)
// Test serializable Range type // Test serializable Range type
let dateKey = Defaults.Key<Range<CustomDate>>("independentRangeDateKey", default: fixtureDateRange) let dateKey = Defaults.Key<Range<CustomDate>>("independentRangeDateKey", default: fixtureDateRange, suite: suite_)
XCTAssertEqual(fixtureDateRange.upperBound, Defaults[dateKey].upperBound) #expect(fixtureDateRange.upperBound == Defaults[dateKey].upperBound)
XCTAssertEqual(fixtureDateRange.lowerBound, Defaults[dateKey].lowerBound) #expect(fixtureDateRange.lowerBound == Defaults[dateKey].lowerBound)
Defaults[dateKey] = nextFixtureDateRange Defaults[dateKey] = nextFixtureDateRange
XCTAssertEqual(nextFixtureDateRange.upperBound, Defaults[dateKey].upperBound) #expect(nextFixtureDateRange.upperBound == Defaults[dateKey].upperBound)
XCTAssertEqual(nextFixtureDateRange.lowerBound, Defaults[dateKey].lowerBound) #expect(nextFixtureDateRange.lowerBound == Defaults[dateKey].lowerBound)
// Test native support ClosedRange type // Test native support ClosedRange type
let closedKey = Defaults.Key<ClosedRange>("independentClosedRangeKey", default: fixtureClosedRange) let closedKey = Defaults.Key<ClosedRange>("independentClosedRangeKey", default: fixtureClosedRange, suite: suite_)
XCTAssertEqual(fixtureClosedRange.upperBound, Defaults[closedKey].upperBound) #expect(fixtureClosedRange.upperBound == Defaults[closedKey].upperBound)
XCTAssertEqual(fixtureClosedRange.lowerBound, Defaults[closedKey].lowerBound) #expect(fixtureClosedRange.lowerBound == Defaults[closedKey].lowerBound)
Defaults[closedKey] = nextFixtureClosedRange Defaults[closedKey] = nextFixtureClosedRange
XCTAssertEqual(nextFixtureClosedRange.upperBound, Defaults[closedKey].upperBound) #expect(nextFixtureClosedRange.upperBound == Defaults[closedKey].upperBound)
XCTAssertEqual(nextFixtureClosedRange.lowerBound, Defaults[closedKey].lowerBound) #expect(nextFixtureClosedRange.lowerBound == Defaults[closedKey].lowerBound)
// Test serializable ClosedRange type // Test serializable ClosedRange type
let closedDateKey = Defaults.Key<ClosedRange<CustomDate>>("independentClosedRangeDateKey", default: fixtureDateClosedRange) let closedDateKey = Defaults.Key<ClosedRange<CustomDate>>("independentClosedRangeDateKey", default: fixtureDateClosedRange, suite: suite_)
XCTAssertEqual(fixtureDateClosedRange.upperBound, Defaults[closedDateKey].upperBound) #expect(fixtureDateClosedRange.upperBound == Defaults[closedDateKey].upperBound)
XCTAssertEqual(fixtureDateClosedRange.lowerBound, Defaults[closedDateKey].lowerBound) #expect(fixtureDateClosedRange.lowerBound == Defaults[closedDateKey].lowerBound)
Defaults[closedDateKey] = nextFixtureDateClosedRange Defaults[closedDateKey] = nextFixtureDateClosedRange
XCTAssertEqual(nextFixtureDateClosedRange.upperBound, Defaults[closedDateKey].upperBound) #expect(nextFixtureDateClosedRange.upperBound == Defaults[closedDateKey].upperBound)
XCTAssertEqual(nextFixtureDateClosedRange.lowerBound, Defaults[closedDateKey].lowerBound) #expect(nextFixtureDateClosedRange.lowerBound == Defaults[closedDateKey].lowerBound)
} }
@Test
func testOptionalKey() { func testOptionalKey() {
// Test native support Range type // Test native support Range type
let key = Defaults.Key<Range<Int>?>("independentRangeOptionalKey") let key = Defaults.Key<Range<Int>?>("independentRangeOptionalKey", suite: suite_)
XCTAssertNil(Defaults[key]) #expect(Defaults[key] == nil)
Defaults[key] = fixtureRange Defaults[key] = fixtureRange
XCTAssertEqual(fixtureRange.upperBound, Defaults[key]?.upperBound) #expect(fixtureRange.upperBound == Defaults[key]?.upperBound)
XCTAssertEqual(fixtureRange.lowerBound, Defaults[key]?.lowerBound) #expect(fixtureRange.lowerBound == Defaults[key]?.lowerBound)
// Test serializable Range type // Test serializable Range type
let dateKey = Defaults.Key<Range<CustomDate>?>("independentRangeDateOptionalKey") let dateKey = Defaults.Key<Range<CustomDate>?>("independentRangeDateOptionalKey", suite: suite_)
XCTAssertNil(Defaults[dateKey]) #expect(Defaults[dateKey] == nil)
Defaults[dateKey] = fixtureDateRange Defaults[dateKey] = fixtureDateRange
XCTAssertEqual(fixtureDateRange.upperBound, Defaults[dateKey]?.upperBound) #expect(fixtureDateRange.upperBound == Defaults[dateKey]?.upperBound)
XCTAssertEqual(fixtureDateRange.lowerBound, Defaults[dateKey]?.lowerBound) #expect(fixtureDateRange.lowerBound == Defaults[dateKey]?.lowerBound)
// Test native support ClosedRange type // Test native support ClosedRange type
let closedKey = Defaults.Key<ClosedRange<Int>?>("independentClosedRangeOptionalKey") let closedKey = Defaults.Key<ClosedRange<Int>?>("independentClosedRangeOptionalKey", suite: suite_)
XCTAssertNil(Defaults[closedKey]) #expect(Defaults[closedKey] == nil)
Defaults[closedKey] = fixtureClosedRange Defaults[closedKey] = fixtureClosedRange
XCTAssertEqual(fixtureClosedRange.upperBound, Defaults[closedKey]?.upperBound) #expect(fixtureClosedRange.upperBound == Defaults[closedKey]?.upperBound)
XCTAssertEqual(fixtureClosedRange.lowerBound, Defaults[closedKey]?.lowerBound) #expect(fixtureClosedRange.lowerBound == Defaults[closedKey]?.lowerBound)
// Test serializable ClosedRange type // Test serializable ClosedRange type
let closedDateKey = Defaults.Key<ClosedRange<CustomDate>?>("independentClosedRangeDateOptionalKey") let closedDateKey = Defaults.Key<ClosedRange<CustomDate>?>("independentClosedRangeDateOptionalKey", suite: suite_)
XCTAssertNil(Defaults[closedDateKey]) #expect(Defaults[closedDateKey] == nil)
Defaults[closedDateKey] = fixtureDateClosedRange Defaults[closedDateKey] = fixtureDateClosedRange
XCTAssertEqual(fixtureDateClosedRange.upperBound, Defaults[closedDateKey]?.upperBound) #expect(fixtureDateClosedRange.upperBound == Defaults[closedDateKey]?.upperBound)
XCTAssertEqual(fixtureDateClosedRange.lowerBound, Defaults[closedDateKey]?.lowerBound) #expect(fixtureDateClosedRange.lowerBound == Defaults[closedDateKey]?.lowerBound)
} }
@Test
func testArrayKey() { func testArrayKey() {
// Test native support Range type // Test native support Range type
let key = Defaults.Key<[Range]>("independentRangeArrayKey", default: [fixtureRange]) let key = Defaults.Key<[Range]>("independentRangeArrayKey", default: [fixtureRange], suite: suite_)
XCTAssertEqual(fixtureRange.upperBound, Defaults[key][0].upperBound) #expect(fixtureRange.upperBound == Defaults[key][0].upperBound)
XCTAssertEqual(fixtureRange.lowerBound, Defaults[key][0].lowerBound) #expect(fixtureRange.lowerBound == Defaults[key][0].lowerBound)
Defaults[key].append(nextFixtureRange) Defaults[key].append(nextFixtureRange)
XCTAssertEqual(fixtureRange.upperBound, Defaults[key][0].upperBound) #expect(fixtureRange.upperBound == Defaults[key][0].upperBound)
XCTAssertEqual(fixtureRange.lowerBound, Defaults[key][0].lowerBound) #expect(fixtureRange.lowerBound == Defaults[key][0].lowerBound)
XCTAssertEqual(nextFixtureRange.upperBound, Defaults[key][1].upperBound) #expect(nextFixtureRange.upperBound == Defaults[key][1].upperBound)
XCTAssertEqual(nextFixtureRange.lowerBound, Defaults[key][1].lowerBound) #expect(nextFixtureRange.lowerBound == Defaults[key][1].lowerBound)
// Test serializable Range type // Test serializable Range type
let dateKey = Defaults.Key<[Range<CustomDate>]>("independentRangeDateArrayKey", default: [fixtureDateRange]) let dateKey = Defaults.Key<[Range<CustomDate>]>("independentRangeDateArrayKey", default: [fixtureDateRange], suite: suite_)
XCTAssertEqual(fixtureDateRange.upperBound, Defaults[dateKey][0].upperBound) #expect(fixtureDateRange.upperBound == Defaults[dateKey][0].upperBound)
XCTAssertEqual(fixtureDateRange.lowerBound, Defaults[dateKey][0].lowerBound) #expect(fixtureDateRange.lowerBound == Defaults[dateKey][0].lowerBound)
Defaults[dateKey].append(nextFixtureDateRange) Defaults[dateKey].append(nextFixtureDateRange)
XCTAssertEqual(fixtureDateRange.upperBound, Defaults[dateKey][0].upperBound) #expect(fixtureDateRange.upperBound == Defaults[dateKey][0].upperBound)
XCTAssertEqual(fixtureDateRange.lowerBound, Defaults[dateKey][0].lowerBound) #expect(fixtureDateRange.lowerBound == Defaults[dateKey][0].lowerBound)
XCTAssertEqual(nextFixtureDateRange.upperBound, Defaults[dateKey][1].upperBound) #expect(nextFixtureDateRange.upperBound == Defaults[dateKey][1].upperBound)
XCTAssertEqual(nextFixtureDateRange.lowerBound, Defaults[dateKey][1].lowerBound) #expect(nextFixtureDateRange.lowerBound == Defaults[dateKey][1].lowerBound)
// Test native support ClosedRange type // Test native support ClosedRange type
let closedKey = Defaults.Key<[ClosedRange]>("independentClosedRangeArrayKey", default: [fixtureClosedRange]) let closedKey = Defaults.Key<[ClosedRange]>("independentClosedRangeArrayKey", default: [fixtureClosedRange], suite: suite_)
XCTAssertEqual(fixtureClosedRange.upperBound, Defaults[closedKey][0].upperBound) #expect(fixtureClosedRange.upperBound == Defaults[closedKey][0].upperBound)
XCTAssertEqual(fixtureClosedRange.lowerBound, Defaults[closedKey][0].lowerBound) #expect(fixtureClosedRange.lowerBound == Defaults[closedKey][0].lowerBound)
Defaults[closedKey].append(nextFixtureClosedRange) Defaults[closedKey].append(nextFixtureClosedRange)
XCTAssertEqual(fixtureClosedRange.upperBound, Defaults[closedKey][0].upperBound) #expect(fixtureClosedRange.upperBound == Defaults[closedKey][0].upperBound)
XCTAssertEqual(fixtureClosedRange.lowerBound, Defaults[closedKey][0].lowerBound) #expect(fixtureClosedRange.lowerBound == Defaults[closedKey][0].lowerBound)
XCTAssertEqual(nextFixtureClosedRange.upperBound, Defaults[closedKey][1].upperBound) #expect(nextFixtureClosedRange.upperBound == Defaults[closedKey][1].upperBound)
XCTAssertEqual(nextFixtureClosedRange.lowerBound, Defaults[closedKey][1].lowerBound) #expect(nextFixtureClosedRange.lowerBound == Defaults[closedKey][1].lowerBound)
// Test serializable ClosedRange type // Test serializable ClosedRange type
let closedDateKey = Defaults.Key<[ClosedRange<CustomDate>]>("independentClosedRangeDateArrayKey", default: [fixtureDateClosedRange]) let closedDateKey = Defaults.Key<[ClosedRange<CustomDate>]>("independentClosedRangeDateArrayKey", default: [fixtureDateClosedRange], suite: suite_)
XCTAssertEqual(fixtureDateClosedRange.upperBound, Defaults[closedDateKey][0].upperBound) #expect(fixtureDateClosedRange.upperBound == Defaults[closedDateKey][0].upperBound)
XCTAssertEqual(fixtureDateClosedRange.lowerBound, Defaults[closedDateKey][0].lowerBound) #expect(fixtureDateClosedRange.lowerBound == Defaults[closedDateKey][0].lowerBound)
Defaults[closedDateKey].append(nextFixtureDateClosedRange) Defaults[closedDateKey].append(nextFixtureDateClosedRange)
XCTAssertEqual(fixtureDateClosedRange.upperBound, Defaults[closedDateKey][0].upperBound) #expect(fixtureDateClosedRange.upperBound == Defaults[closedDateKey][0].upperBound)
XCTAssertEqual(fixtureDateClosedRange.lowerBound, Defaults[closedDateKey][0].lowerBound) #expect(fixtureDateClosedRange.lowerBound == Defaults[closedDateKey][0].lowerBound)
XCTAssertEqual(nextFixtureDateClosedRange.upperBound, Defaults[closedDateKey][1].upperBound) #expect(nextFixtureDateClosedRange.upperBound == Defaults[closedDateKey][1].upperBound)
XCTAssertEqual(nextFixtureDateClosedRange.lowerBound, Defaults[closedDateKey][1].lowerBound) #expect(nextFixtureDateClosedRange.lowerBound == Defaults[closedDateKey][1].lowerBound)
} }
@Test
func testDictionaryKey() { func testDictionaryKey() {
// Test native support Range type // Test native support Range type
let key = Defaults.Key<[String: Range]>("independentRangeDictionaryKey", default: ["0": fixtureRange]) let key = Defaults.Key<[String: Range]>("independentRangeDictionaryKey", default: ["0": fixtureRange], suite: suite_)
XCTAssertEqual(fixtureRange.upperBound, Defaults[key]["0"]?.upperBound) #expect(fixtureRange.upperBound == Defaults[key]["0"]?.upperBound)
XCTAssertEqual(fixtureRange.lowerBound, Defaults[key]["0"]?.lowerBound) #expect(fixtureRange.lowerBound == Defaults[key]["0"]?.lowerBound)
Defaults[key]["1"] = nextFixtureRange Defaults[key]["1"] = nextFixtureRange
XCTAssertEqual(fixtureRange.upperBound, Defaults[key]["0"]?.upperBound) #expect(fixtureRange.upperBound == Defaults[key]["0"]?.upperBound)
XCTAssertEqual(fixtureRange.lowerBound, Defaults[key]["0"]?.lowerBound) #expect(fixtureRange.lowerBound == Defaults[key]["0"]?.lowerBound)
XCTAssertEqual(nextFixtureRange.upperBound, Defaults[key]["1"]?.upperBound) #expect(nextFixtureRange.upperBound == Defaults[key]["1"]?.upperBound)
XCTAssertEqual(nextFixtureRange.lowerBound, Defaults[key]["1"]?.lowerBound) #expect(nextFixtureRange.lowerBound == Defaults[key]["1"]?.lowerBound)
// Test serializable Range type // Test serializable Range type
let dateKey = Defaults.Key<[String: Range<CustomDate>]>("independentRangeDateDictionaryKey", default: ["0": fixtureDateRange]) let dateKey = Defaults.Key<[String: Range<CustomDate>]>("independentRangeDateDictionaryKey", default: ["0": fixtureDateRange], suite: suite_)
XCTAssertEqual(fixtureDateRange.upperBound, Defaults[dateKey]["0"]?.upperBound) #expect(fixtureDateRange.upperBound == Defaults[dateKey]["0"]?.upperBound)
XCTAssertEqual(fixtureDateRange.lowerBound, Defaults[dateKey]["0"]?.lowerBound) #expect(fixtureDateRange.lowerBound == Defaults[dateKey]["0"]?.lowerBound)
Defaults[dateKey]["1"] = nextFixtureDateRange Defaults[dateKey]["1"] = nextFixtureDateRange
XCTAssertEqual(fixtureDateRange.upperBound, Defaults[dateKey]["0"]?.upperBound) #expect(fixtureDateRange.upperBound == Defaults[dateKey]["0"]?.upperBound)
XCTAssertEqual(fixtureDateRange.lowerBound, Defaults[dateKey]["0"]?.lowerBound) #expect(fixtureDateRange.lowerBound == Defaults[dateKey]["0"]?.lowerBound)
XCTAssertEqual(nextFixtureDateRange.upperBound, Defaults[dateKey]["1"]?.upperBound) #expect(nextFixtureDateRange.upperBound == Defaults[dateKey]["1"]?.upperBound)
XCTAssertEqual(nextFixtureDateRange.lowerBound, Defaults[dateKey]["1"]?.lowerBound) #expect(nextFixtureDateRange.lowerBound == Defaults[dateKey]["1"]?.lowerBound)
// Test native support ClosedRange type // Test native support ClosedRange type
let closedKey = Defaults.Key<[String: ClosedRange]>("independentClosedRangeDictionaryKey", default: ["0": fixtureClosedRange]) let closedKey = Defaults.Key<[String: ClosedRange]>("independentClosedRangeDictionaryKey", default: ["0": fixtureClosedRange], suite: suite_)
XCTAssertEqual(fixtureClosedRange.upperBound, Defaults[closedKey]["0"]?.upperBound) #expect(fixtureClosedRange.upperBound == Defaults[closedKey]["0"]?.upperBound)
XCTAssertEqual(fixtureClosedRange.lowerBound, Defaults[closedKey]["0"]?.lowerBound) #expect(fixtureClosedRange.lowerBound == Defaults[closedKey]["0"]?.lowerBound)
Defaults[closedKey]["1"] = nextFixtureClosedRange Defaults[closedKey]["1"] = nextFixtureClosedRange
XCTAssertEqual(fixtureClosedRange.upperBound, Defaults[closedKey]["0"]?.upperBound) #expect(fixtureClosedRange.upperBound == Defaults[closedKey]["0"]?.upperBound)
XCTAssertEqual(fixtureClosedRange.lowerBound, Defaults[closedKey]["0"]?.lowerBound) #expect(fixtureClosedRange.lowerBound == Defaults[closedKey]["0"]?.lowerBound)
XCTAssertEqual(nextFixtureClosedRange.upperBound, Defaults[closedKey]["1"]?.upperBound) #expect(nextFixtureClosedRange.upperBound == Defaults[closedKey]["1"]?.upperBound)
XCTAssertEqual(nextFixtureClosedRange.lowerBound, Defaults[closedKey]["1"]?.lowerBound) #expect(nextFixtureClosedRange.lowerBound == Defaults[closedKey]["1"]?.lowerBound)
// Test serializable ClosedRange type // Test serializable ClosedRange type
let closedDateKey = Defaults.Key<[String: ClosedRange<CustomDate>]>("independentClosedRangeDateDictionaryKey", default: ["0": fixtureDateClosedRange]) let closedDateKey = Defaults.Key<[String: ClosedRange<CustomDate>]>("independentClosedRangeDateDictionaryKey", default: ["0": fixtureDateClosedRange], suite: suite_)
XCTAssertEqual(fixtureDateClosedRange.upperBound, Defaults[closedDateKey]["0"]?.upperBound) #expect(fixtureDateClosedRange.upperBound == Defaults[closedDateKey]["0"]?.upperBound)
XCTAssertEqual(fixtureDateClosedRange.lowerBound, Defaults[closedDateKey]["0"]?.lowerBound) #expect(fixtureDateClosedRange.lowerBound == Defaults[closedDateKey]["0"]?.lowerBound)
Defaults[closedDateKey]["1"] = nextFixtureDateClosedRange Defaults[closedDateKey]["1"] = nextFixtureDateClosedRange
XCTAssertEqual(fixtureDateClosedRange.upperBound, Defaults[closedDateKey]["0"]?.upperBound) #expect(fixtureDateClosedRange.upperBound == Defaults[closedDateKey]["0"]?.upperBound)
XCTAssertEqual(fixtureDateClosedRange.lowerBound, Defaults[closedDateKey]["0"]?.lowerBound) #expect(fixtureDateClosedRange.lowerBound == Defaults[closedDateKey]["0"]?.lowerBound)
XCTAssertEqual(nextFixtureDateClosedRange.upperBound, Defaults[closedDateKey]["1"]?.upperBound) #expect(nextFixtureDateClosedRange.upperBound == Defaults[closedDateKey]["1"]?.upperBound)
XCTAssertEqual(nextFixtureDateClosedRange.lowerBound, Defaults[closedDateKey]["1"]?.lowerBound) #expect(nextFixtureDateClosedRange.lowerBound == Defaults[closedDateKey]["1"]?.lowerBound)
} }
} }

View File

@ -1,7 +1,9 @@
import Foundation import Foundation
import XCTest import Testing
import Defaults import Defaults
private let suite_ = createSuite()
private struct Item: Equatable, Hashable { private struct Item: Equatable, Hashable {
let name: String let name: String
let count: UInt let count: UInt
@ -41,317 +43,147 @@ private let fixtureSetAlgebra2 = Item(name: "Grape", count: 30)
private let fixtureSetAlgebra3 = Item(name: "Guava", count: 40) private let fixtureSetAlgebra3 = Item(name: "Guava", count: 40)
extension Defaults.Keys { extension Defaults.Keys {
fileprivate static let setAlgebraCustomElement = Key<DefaultsSetAlgebra<Item>>("setAlgebraCustomElement", default: .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])]) 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])]) fileprivate static let setAlgebraCustomElementDictionary = Key<[String: DefaultsSetAlgebra<Item>]>("setAlgebraDictionaryCustomElement", default: ["0": .init([fixtureSetAlgebra])], suite: suite_)
} }
final class DefaultsSetAlgebraCustomElementTests: XCTestCase { @Suite(.serialized)
override func setUp() { final class DefaultsSetAlgebraCustomElementTests {
super.setUp() init() {
Defaults.removeAll() Defaults.removeAll(suite: suite_)
} }
override func tearDown() { deinit {
super.tearDown() Defaults.removeAll(suite: suite_)
Defaults.removeAll()
} }
@Test
func testKey() { 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) Defaults[key].insert(fixtureSetAlgebra)
XCTAssertEqual(Defaults[key], .init([fixtureSetAlgebra])) #expect(Defaults[key] == .init([fixtureSetAlgebra]))
Defaults[key].insert(fixtureSetAlgebra1) Defaults[key].insert(fixtureSetAlgebra1)
XCTAssertEqual(Defaults[key], .init([fixtureSetAlgebra, fixtureSetAlgebra1])) #expect(Defaults[key] == .init([fixtureSetAlgebra, fixtureSetAlgebra1]))
} }
@Test
func testOptionalKey() { func testOptionalKey() {
let key = Defaults.Key<DefaultsSetAlgebra<Item>?>("independentSetAlgebraOptionalKey") let key = Defaults.Key<DefaultsSetAlgebra<Item>?>("customElement_independentSetAlgebraOptionalKey", suite: suite_)
XCTAssertNil(Defaults[key]) #expect(Defaults[key] == nil)
Defaults[key] = .init([fixtureSetAlgebra]) Defaults[key] = .init([fixtureSetAlgebra])
Defaults[key]?.insert(fixtureSetAlgebra) Defaults[key]?.insert(fixtureSetAlgebra)
XCTAssertEqual(Defaults[key], .init([fixtureSetAlgebra])) #expect(Defaults[key] == .init([fixtureSetAlgebra]))
Defaults[key]?.insert(fixtureSetAlgebra1) Defaults[key]?.insert(fixtureSetAlgebra1)
XCTAssertEqual(Defaults[key], .init([fixtureSetAlgebra, fixtureSetAlgebra1])) #expect(Defaults[key] == .init([fixtureSetAlgebra, fixtureSetAlgebra1]))
} }
@Test
func testArrayKey() { 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][0].insert(fixtureSetAlgebra1)
Defaults[key].append(.init([fixtureSetAlgebra2])) Defaults[key].append(.init([fixtureSetAlgebra2]))
Defaults[key][1].insert(fixtureSetAlgebra3) Defaults[key][1].insert(fixtureSetAlgebra3)
XCTAssertEqual(Defaults[key][0], .init([fixtureSetAlgebra, fixtureSetAlgebra1])) #expect(Defaults[key][0] == .init([fixtureSetAlgebra, fixtureSetAlgebra1]))
XCTAssertEqual(Defaults[key][1], .init([fixtureSetAlgebra2, fixtureSetAlgebra3])) #expect(Defaults[key][1] == .init([fixtureSetAlgebra2, fixtureSetAlgebra3]))
} }
@Test
func testArrayOptionalKey() { func testArrayOptionalKey() {
let key = Defaults.Key<[DefaultsSetAlgebra<Item>]?>("independentSetAlgebraArrayOptionalKey") // swiftlint:disable:this discouraged_optional_collection let key = Defaults.Key<[DefaultsSetAlgebra<Item>]?>("customElement_independentSetAlgebraArrayOptionalKey", suite: suite_) // swiftlint:disable:this discouraged_optional_collection
XCTAssertNil(Defaults[key]) #expect(Defaults[key] == nil)
Defaults[key] = [.init([fixtureSetAlgebra])] Defaults[key] = [.init([fixtureSetAlgebra])]
Defaults[key]?[0].insert(fixtureSetAlgebra1) Defaults[key]?[0].insert(fixtureSetAlgebra1)
Defaults[key]?.append(.init([fixtureSetAlgebra2])) Defaults[key]?.append(.init([fixtureSetAlgebra2]))
Defaults[key]?[1].insert(fixtureSetAlgebra3) Defaults[key]?[1].insert(fixtureSetAlgebra3)
XCTAssertEqual(Defaults[key]?[0], .init([fixtureSetAlgebra, fixtureSetAlgebra1])) #expect(Defaults[key]?[0] == .init([fixtureSetAlgebra, fixtureSetAlgebra1]))
XCTAssertEqual(Defaults[key]?[1], .init([fixtureSetAlgebra2, fixtureSetAlgebra3])) #expect(Defaults[key]?[1] == .init([fixtureSetAlgebra2, fixtureSetAlgebra3]))
} }
@Test
func testNestedArrayKey() { 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][0].insert(fixtureSetAlgebra1)
Defaults[key][0].append(.init([fixtureSetAlgebra1])) Defaults[key][0].append(.init([fixtureSetAlgebra1]))
Defaults[key][0][1].insert(fixtureSetAlgebra2) Defaults[key][0][1].insert(fixtureSetAlgebra2)
Defaults[key].append([.init([fixtureSetAlgebra3])]) Defaults[key].append([.init([fixtureSetAlgebra3])])
Defaults[key][1][0].insert(fixtureSetAlgebra2) Defaults[key][1][0].insert(fixtureSetAlgebra2)
XCTAssertEqual(Defaults[key][0][0], .init([fixtureSetAlgebra, fixtureSetAlgebra1])) #expect(Defaults[key][0][0] == .init([fixtureSetAlgebra, fixtureSetAlgebra1]))
XCTAssertEqual(Defaults[key][0][1], .init([fixtureSetAlgebra1, fixtureSetAlgebra2])) #expect(Defaults[key][0][1] == .init([fixtureSetAlgebra1, fixtureSetAlgebra2]))
XCTAssertEqual(Defaults[key][1][0], .init([fixtureSetAlgebra2, fixtureSetAlgebra3])) #expect(Defaults[key][1][0] == .init([fixtureSetAlgebra2, fixtureSetAlgebra3]))
} }
@Test
func testArrayDictionaryKey() { 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]["0"]?.insert(fixtureSetAlgebra1)
Defaults[key][0]["1"] = .init([fixtureSetAlgebra1]) Defaults[key][0]["1"] = .init([fixtureSetAlgebra1])
Defaults[key][0]["1"]?.insert(fixtureSetAlgebra2) Defaults[key][0]["1"]?.insert(fixtureSetAlgebra2)
Defaults[key].append(["0": .init([fixtureSetAlgebra3])]) Defaults[key].append(["0": .init([fixtureSetAlgebra3])])
Defaults[key][1]["0"]?.insert(fixtureSetAlgebra2) Defaults[key][1]["0"]?.insert(fixtureSetAlgebra2)
XCTAssertEqual(Defaults[key][0]["0"], .init([fixtureSetAlgebra, fixtureSetAlgebra1])) #expect(Defaults[key][0]["0"] == .init([fixtureSetAlgebra, fixtureSetAlgebra1]))
XCTAssertEqual(Defaults[key][0]["1"], .init([fixtureSetAlgebra1, fixtureSetAlgebra2])) #expect(Defaults[key][0]["1"] == .init([fixtureSetAlgebra1, fixtureSetAlgebra2]))
XCTAssertEqual(Defaults[key][1]["0"], .init([fixtureSetAlgebra2, fixtureSetAlgebra3])) #expect(Defaults[key][1]["0"] == .init([fixtureSetAlgebra2, fixtureSetAlgebra3]))
} }
@Test
func testDictionaryKey() { 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]["0"]?.insert(fixtureSetAlgebra1)
Defaults[key]["1"] = .init([fixtureSetAlgebra2]) Defaults[key]["1"] = .init([fixtureSetAlgebra2])
Defaults[key]["1"]?.insert(fixtureSetAlgebra3) Defaults[key]["1"]?.insert(fixtureSetAlgebra3)
XCTAssertEqual(Defaults[key]["0"], .init([fixtureSetAlgebra, fixtureSetAlgebra1])) #expect(Defaults[key]["0"] == .init([fixtureSetAlgebra, fixtureSetAlgebra1]))
XCTAssertEqual(Defaults[key]["1"], .init([fixtureSetAlgebra2, fixtureSetAlgebra3])) #expect(Defaults[key]["1"] == .init([fixtureSetAlgebra2, fixtureSetAlgebra3]))
} }
@Test
func testDictionaryOptionalKey() { func testDictionaryOptionalKey() {
let key = Defaults.Key<[String: DefaultsSetAlgebra<Item>]?>("independentSetAlgebraDictionaryOptionalKey") // swiftlint:disable:this discouraged_optional_collection let key = Defaults.Key<[String: DefaultsSetAlgebra<Item>]?>("customElement_independentSetAlgebraDictionaryOptionalKey", suite: suite_) // swiftlint:disable:this discouraged_optional_collection
XCTAssertNil(Defaults[key]) #expect(Defaults[key] == nil)
Defaults[key] = ["0": .init([fixtureSetAlgebra])] Defaults[key] = ["0": .init([fixtureSetAlgebra])]
Defaults[key]?["0"]?.insert(fixtureSetAlgebra1) Defaults[key]?["0"]?.insert(fixtureSetAlgebra1)
Defaults[key]?["1"] = .init([fixtureSetAlgebra2]) Defaults[key]?["1"] = .init([fixtureSetAlgebra2])
Defaults[key]?["1"]?.insert(fixtureSetAlgebra3) Defaults[key]?["1"]?.insert(fixtureSetAlgebra3)
XCTAssertEqual(Defaults[key]?["0"], .init([fixtureSetAlgebra, fixtureSetAlgebra1])) #expect(Defaults[key]?["0"] == .init([fixtureSetAlgebra, fixtureSetAlgebra1]))
XCTAssertEqual(Defaults[key]?["1"], .init([fixtureSetAlgebra2, fixtureSetAlgebra3])) #expect(Defaults[key]?["1"] == .init([fixtureSetAlgebra2, fixtureSetAlgebra3]))
} }
@Test
func testDictionaryArrayKey() { 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"]?[0].insert(fixtureSetAlgebra1)
Defaults[key]["0"]?.append(.init([fixtureSetAlgebra1])) Defaults[key]["0"]?.append(.init([fixtureSetAlgebra1]))
Defaults[key]["0"]?[1].insert(fixtureSetAlgebra2) Defaults[key]["0"]?[1].insert(fixtureSetAlgebra2)
Defaults[key]["1"] = [.init([fixtureSetAlgebra3])] Defaults[key]["1"] = [.init([fixtureSetAlgebra3])]
Defaults[key]["1"]?[0].insert(fixtureSetAlgebra2) Defaults[key]["1"]?[0].insert(fixtureSetAlgebra2)
XCTAssertEqual(Defaults[key]["0"]?[0], .init([fixtureSetAlgebra, fixtureSetAlgebra1])) #expect(Defaults[key]["0"]?[0] == .init([fixtureSetAlgebra, fixtureSetAlgebra1]))
XCTAssertEqual(Defaults[key]["0"]?[1], .init([fixtureSetAlgebra1, fixtureSetAlgebra2])) #expect(Defaults[key]["0"]?[1] == .init([fixtureSetAlgebra1, fixtureSetAlgebra2]))
XCTAssertEqual(Defaults[key]["1"]?[0], .init([fixtureSetAlgebra2, fixtureSetAlgebra3])) #expect(Defaults[key]["1"]?[0] == .init([fixtureSetAlgebra2, fixtureSetAlgebra3]))
} }
@Test
func testType() { func testType() {
let (inserted, _) = Defaults[.setAlgebraCustomElement].insert(fixtureSetAlgebra) let (inserted, _) = Defaults[.setAlgebraCustomElement].insert(fixtureSetAlgebra)
XCTAssertFalse(inserted) #expect(!inserted)
Defaults[.setAlgebraCustomElement].insert(fixtureSetAlgebra1) Defaults[.setAlgebraCustomElement].insert(fixtureSetAlgebra1)
XCTAssertEqual(Defaults[.setAlgebraCustomElement], .init([fixtureSetAlgebra, fixtureSetAlgebra1])) #expect(Defaults[.setAlgebraCustomElement] == .init([fixtureSetAlgebra, fixtureSetAlgebra1]))
} }
@Test
func testArrayType() { func testArrayType() {
Defaults[.setAlgebraCustomElementArray][0].insert(fixtureSetAlgebra1) Defaults[.setAlgebraCustomElementArray][0].insert(fixtureSetAlgebra1)
Defaults[.setAlgebraCustomElementArray].append(.init([fixtureSetAlgebra2])) Defaults[.setAlgebraCustomElementArray].append(.init([fixtureSetAlgebra2]))
Defaults[.setAlgebraCustomElementArray][1].insert(fixtureSetAlgebra3) Defaults[.setAlgebraCustomElementArray][1].insert(fixtureSetAlgebra3)
XCTAssertEqual(Defaults[.setAlgebraCustomElementArray][0], .init([fixtureSetAlgebra, fixtureSetAlgebra1])) #expect(Defaults[.setAlgebraCustomElementArray][0] == .init([fixtureSetAlgebra, fixtureSetAlgebra1]))
XCTAssertEqual(Defaults[.setAlgebraCustomElementArray][1], .init([fixtureSetAlgebra2, fixtureSetAlgebra3])) #expect(Defaults[.setAlgebraCustomElementArray][1] == .init([fixtureSetAlgebra2, fixtureSetAlgebra3]))
} }
@Test
func testDictionaryType() { func testDictionaryType() {
Defaults[.setAlgebraCustomElementDictionary]["0"]?.insert(fixtureSetAlgebra1) Defaults[.setAlgebraCustomElementDictionary]["0"]?.insert(fixtureSetAlgebra1)
Defaults[.setAlgebraCustomElementDictionary]["1"] = .init([fixtureSetAlgebra2]) Defaults[.setAlgebraCustomElementDictionary]["1"] = .init([fixtureSetAlgebra2])
Defaults[.setAlgebraCustomElementDictionary]["1"]?.insert(fixtureSetAlgebra3) Defaults[.setAlgebraCustomElementDictionary]["1"]?.insert(fixtureSetAlgebra3)
XCTAssertEqual(Defaults[.setAlgebraCustomElementDictionary]["0"], .init([fixtureSetAlgebra, fixtureSetAlgebra1])) #expect(Defaults[.setAlgebraCustomElementDictionary]["0"] == .init([fixtureSetAlgebra, fixtureSetAlgebra1]))
XCTAssertEqual(Defaults[.setAlgebraCustomElementDictionary]["1"], .init([fixtureSetAlgebra2, fixtureSetAlgebra3])) #expect(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)
} }
} }

View File

@ -1,7 +1,9 @@
import Foundation import Foundation
import XCTest import Testing
import Defaults import Defaults
private let suite_ = createSuite()
struct DefaultsSetAlgebra<Element: Defaults.Serializable & Hashable>: SetAlgebra { struct DefaultsSetAlgebra<Element: Defaults.Serializable & Hashable>: SetAlgebra {
var store = Set<Element>() var store = Set<Element>()
@ -73,317 +75,147 @@ private let fixtureSetAlgebra2 = 2
private let fixtureSetAlgebra3 = 3 private let fixtureSetAlgebra3 = 3
extension Defaults.Keys { extension Defaults.Keys {
fileprivate static let setAlgebra = Key<DefaultsSetAlgebra<Int>>("setAlgebra", default: .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])]) 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])]) fileprivate static let setAlgebraDictionary = Key<[String: DefaultsSetAlgebra<Int>]>("setAlgebraDictionary", default: ["0": .init([fixtureSetAlgebra])], suite: suite_)
} }
final class DefaultsSetAlgebraTests: XCTestCase { @Suite(.serialized)
override func setUp() { final class DefaultsSetAlgebraTests {
super.setUp() init() {
Defaults.removeAll() Defaults.removeAll(suite: suite_)
} }
override func tearDown() { deinit {
super.tearDown() Defaults.removeAll(suite: suite_)
Defaults.removeAll()
} }
@Test
func testKey() { 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) Defaults[key].insert(fixtureSetAlgebra)
XCTAssertEqual(Defaults[key], .init([fixtureSetAlgebra])) #expect(Defaults[key] == .init([fixtureSetAlgebra]))
Defaults[key].insert(fixtureSetAlgebra1) Defaults[key].insert(fixtureSetAlgebra1)
XCTAssertEqual(Defaults[key], .init([fixtureSetAlgebra, fixtureSetAlgebra1])) #expect(Defaults[key] == .init([fixtureSetAlgebra, fixtureSetAlgebra1]))
} }
@Test
func testOptionalKey() { func testOptionalKey() {
let key = Defaults.Key<DefaultsSetAlgebra<Int>?>("independentSetAlgebraOptionalKey") let key = Defaults.Key<DefaultsSetAlgebra<Int>?>("independentSetAlgebraOptionalKey", suite: suite_)
XCTAssertNil(Defaults[key]) #expect(Defaults[key] == nil)
Defaults[key] = .init([fixtureSetAlgebra]) Defaults[key] = .init([fixtureSetAlgebra])
Defaults[key]?.insert(fixtureSetAlgebra) Defaults[key]?.insert(fixtureSetAlgebra)
XCTAssertEqual(Defaults[key], .init([fixtureSetAlgebra])) #expect(Defaults[key] == .init([fixtureSetAlgebra]))
Defaults[key]?.insert(fixtureSetAlgebra1) Defaults[key]?.insert(fixtureSetAlgebra1)
XCTAssertEqual(Defaults[key], .init([fixtureSetAlgebra, fixtureSetAlgebra1])) #expect(Defaults[key] == .init([fixtureSetAlgebra, fixtureSetAlgebra1]))
} }
@Test
func testArrayKey() { 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][0].insert(fixtureSetAlgebra1)
Defaults[key].append(.init([fixtureSetAlgebra2])) Defaults[key].append(.init([fixtureSetAlgebra2]))
Defaults[key][1].insert(fixtureSetAlgebra3) Defaults[key][1].insert(fixtureSetAlgebra3)
XCTAssertEqual(Defaults[key][0], .init([fixtureSetAlgebra, fixtureSetAlgebra1])) #expect(Defaults[key][0] == .init([fixtureSetAlgebra, fixtureSetAlgebra1]))
XCTAssertEqual(Defaults[key][1], .init([fixtureSetAlgebra2, fixtureSetAlgebra3])) #expect(Defaults[key][1] == .init([fixtureSetAlgebra2, fixtureSetAlgebra3]))
} }
@Test
func testArrayOptionalKey() { func testArrayOptionalKey() {
let key = Defaults.Key<[DefaultsSetAlgebra<Int>]?>("independentSetAlgebraArrayOptionalKey") // swiftlint:disable:this discouraged_optional_collection let key = Defaults.Key<[DefaultsSetAlgebra<Int>]?>("independentSetAlgebraArrayOptionalKey", suite: suite_) // swiftlint:disable:this discouraged_optional_collection
XCTAssertNil(Defaults[key]) #expect(Defaults[key] == nil)
Defaults[key] = [.init([fixtureSetAlgebra])] Defaults[key] = [.init([fixtureSetAlgebra])]
Defaults[key]?[0].insert(fixtureSetAlgebra1) Defaults[key]?[0].insert(fixtureSetAlgebra1)
Defaults[key]?.append(.init([fixtureSetAlgebra2])) Defaults[key]?.append(.init([fixtureSetAlgebra2]))
Defaults[key]?[1].insert(fixtureSetAlgebra3) Defaults[key]?[1].insert(fixtureSetAlgebra3)
XCTAssertEqual(Defaults[key]?[0], .init([fixtureSetAlgebra, fixtureSetAlgebra1])) #expect(Defaults[key]?[0] == .init([fixtureSetAlgebra, fixtureSetAlgebra1]))
XCTAssertEqual(Defaults[key]?[1], .init([fixtureSetAlgebra2, fixtureSetAlgebra3])) #expect(Defaults[key]?[1] == .init([fixtureSetAlgebra2, fixtureSetAlgebra3]))
} }
@Test
func testNestedArrayKey() { 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][0].insert(fixtureSetAlgebra1)
Defaults[key][0].append(.init([fixtureSetAlgebra1])) Defaults[key][0].append(.init([fixtureSetAlgebra1]))
Defaults[key][0][1].insert(fixtureSetAlgebra2) Defaults[key][0][1].insert(fixtureSetAlgebra2)
Defaults[key].append([.init([fixtureSetAlgebra3])]) Defaults[key].append([.init([fixtureSetAlgebra3])])
Defaults[key][1][0].insert(fixtureSetAlgebra2) Defaults[key][1][0].insert(fixtureSetAlgebra2)
XCTAssertEqual(Defaults[key][0][0], .init([fixtureSetAlgebra, fixtureSetAlgebra1])) #expect(Defaults[key][0][0] == .init([fixtureSetAlgebra, fixtureSetAlgebra1]))
XCTAssertEqual(Defaults[key][0][1], .init([fixtureSetAlgebra1, fixtureSetAlgebra2])) #expect(Defaults[key][0][1] == .init([fixtureSetAlgebra1, fixtureSetAlgebra2]))
XCTAssertEqual(Defaults[key][1][0], .init([fixtureSetAlgebra2, fixtureSetAlgebra3])) #expect(Defaults[key][1][0] == .init([fixtureSetAlgebra2, fixtureSetAlgebra3]))
} }
@Test
func testArrayDictionaryKey() { 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]["0"]?.insert(fixtureSetAlgebra1)
Defaults[key][0]["1"] = .init([fixtureSetAlgebra1]) Defaults[key][0]["1"] = .init([fixtureSetAlgebra1])
Defaults[key][0]["1"]?.insert(fixtureSetAlgebra2) Defaults[key][0]["1"]?.insert(fixtureSetAlgebra2)
Defaults[key].append(["0": .init([fixtureSetAlgebra3])]) Defaults[key].append(["0": .init([fixtureSetAlgebra3])])
Defaults[key][1]["0"]?.insert(fixtureSetAlgebra2) Defaults[key][1]["0"]?.insert(fixtureSetAlgebra2)
XCTAssertEqual(Defaults[key][0]["0"], .init([fixtureSetAlgebra, fixtureSetAlgebra1])) #expect(Defaults[key][0]["0"] == .init([fixtureSetAlgebra, fixtureSetAlgebra1]))
XCTAssertEqual(Defaults[key][0]["1"], .init([fixtureSetAlgebra1, fixtureSetAlgebra2])) #expect(Defaults[key][0]["1"] == .init([fixtureSetAlgebra1, fixtureSetAlgebra2]))
XCTAssertEqual(Defaults[key][1]["0"], .init([fixtureSetAlgebra2, fixtureSetAlgebra3])) #expect(Defaults[key][1]["0"] == .init([fixtureSetAlgebra2, fixtureSetAlgebra3]))
} }
@Test
func testDictionaryKey() { 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]["0"]?.insert(fixtureSetAlgebra1)
Defaults[key]["1"] = .init([fixtureSetAlgebra2]) Defaults[key]["1"] = .init([fixtureSetAlgebra2])
Defaults[key]["1"]?.insert(fixtureSetAlgebra3) Defaults[key]["1"]?.insert(fixtureSetAlgebra3)
XCTAssertEqual(Defaults[key]["0"], .init([fixtureSetAlgebra, fixtureSetAlgebra1])) #expect(Defaults[key]["0"] == .init([fixtureSetAlgebra, fixtureSetAlgebra1]))
XCTAssertEqual(Defaults[key]["1"], .init([fixtureSetAlgebra2, fixtureSetAlgebra3])) #expect(Defaults[key]["1"] == .init([fixtureSetAlgebra2, fixtureSetAlgebra3]))
} }
@Test
func testDictionaryOptionalKey() { func testDictionaryOptionalKey() {
let key = Defaults.Key<[String: DefaultsSetAlgebra<Int>]?>("independentSetAlgebraDictionaryOptionalKey") // swiftlint:disable:this discouraged_optional_collection let key = Defaults.Key<[String: DefaultsSetAlgebra<Int>]?>("independentSetAlgebraDictionaryOptionalKey", suite: suite_) // swiftlint:disable:this discouraged_optional_collection
XCTAssertNil(Defaults[key]) #expect(Defaults[key] == nil)
Defaults[key] = ["0": .init([fixtureSetAlgebra])] Defaults[key] = ["0": .init([fixtureSetAlgebra])]
Defaults[key]?["0"]?.insert(fixtureSetAlgebra1) Defaults[key]?["0"]?.insert(fixtureSetAlgebra1)
Defaults[key]?["1"] = .init([fixtureSetAlgebra2]) Defaults[key]?["1"] = .init([fixtureSetAlgebra2])
Defaults[key]?["1"]?.insert(fixtureSetAlgebra3) Defaults[key]?["1"]?.insert(fixtureSetAlgebra3)
XCTAssertEqual(Defaults[key]?["0"], .init([fixtureSetAlgebra, fixtureSetAlgebra1])) #expect(Defaults[key]?["0"] == .init([fixtureSetAlgebra, fixtureSetAlgebra1]))
XCTAssertEqual(Defaults[key]?["1"], .init([fixtureSetAlgebra2, fixtureSetAlgebra3])) #expect(Defaults[key]?["1"] == .init([fixtureSetAlgebra2, fixtureSetAlgebra3]))
} }
@Test
func testDictionaryArrayKey() { 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"]?[0].insert(fixtureSetAlgebra1)
Defaults[key]["0"]?.append(.init([fixtureSetAlgebra1])) Defaults[key]["0"]?.append(.init([fixtureSetAlgebra1]))
Defaults[key]["0"]?[1].insert(fixtureSetAlgebra2) Defaults[key]["0"]?[1].insert(fixtureSetAlgebra2)
Defaults[key]["1"] = [.init([fixtureSetAlgebra3])] Defaults[key]["1"] = [.init([fixtureSetAlgebra3])]
Defaults[key]["1"]?[0].insert(fixtureSetAlgebra2) Defaults[key]["1"]?[0].insert(fixtureSetAlgebra2)
XCTAssertEqual(Defaults[key]["0"]?[0], .init([fixtureSetAlgebra, fixtureSetAlgebra1])) #expect(Defaults[key]["0"]?[0] == .init([fixtureSetAlgebra, fixtureSetAlgebra1]))
XCTAssertEqual(Defaults[key]["0"]?[1], .init([fixtureSetAlgebra1, fixtureSetAlgebra2])) #expect(Defaults[key]["0"]?[1] == .init([fixtureSetAlgebra1, fixtureSetAlgebra2]))
XCTAssertEqual(Defaults[key]["1"]?[0], .init([fixtureSetAlgebra2, fixtureSetAlgebra3])) #expect(Defaults[key]["1"]?[0] == .init([fixtureSetAlgebra2, fixtureSetAlgebra3]))
} }
@Test
func testType() { func testType() {
let (inserted, _) = Defaults[.setAlgebra].insert(fixtureSetAlgebra) let (inserted, _) = Defaults[.setAlgebra].insert(fixtureSetAlgebra)
XCTAssertFalse(inserted) #expect(!inserted)
Defaults[.setAlgebra].insert(fixtureSetAlgebra1) Defaults[.setAlgebra].insert(fixtureSetAlgebra1)
XCTAssertEqual(Defaults[.setAlgebra], .init([fixtureSetAlgebra, fixtureSetAlgebra1])) #expect(Defaults[.setAlgebra] == .init([fixtureSetAlgebra, fixtureSetAlgebra1]))
} }
@Test
func testArrayType() { func testArrayType() {
Defaults[.setAlgebraArray][0].insert(fixtureSetAlgebra1) Defaults[.setAlgebraArray][0].insert(fixtureSetAlgebra1)
Defaults[.setAlgebraArray].append(.init([fixtureSetAlgebra2])) Defaults[.setAlgebraArray].append(.init([fixtureSetAlgebra2]))
Defaults[.setAlgebraArray][1].insert(fixtureSetAlgebra3) Defaults[.setAlgebraArray][1].insert(fixtureSetAlgebra3)
XCTAssertEqual(Defaults[.setAlgebraArray][0], .init([fixtureSetAlgebra, fixtureSetAlgebra1])) #expect(Defaults[.setAlgebraArray][0] == .init([fixtureSetAlgebra, fixtureSetAlgebra1]))
XCTAssertEqual(Defaults[.setAlgebraArray][1], .init([fixtureSetAlgebra2, fixtureSetAlgebra3])) #expect(Defaults[.setAlgebraArray][1] == .init([fixtureSetAlgebra2, fixtureSetAlgebra3]))
} }
@Test
func testDictionaryType() { func testDictionaryType() {
Defaults[.setAlgebraDictionary]["0"]?.insert(fixtureSetAlgebra1) Defaults[.setAlgebraDictionary]["0"]?.insert(fixtureSetAlgebra1)
Defaults[.setAlgebraDictionary]["1"] = .init([fixtureSetAlgebra2]) Defaults[.setAlgebraDictionary]["1"] = .init([fixtureSetAlgebra2])
Defaults[.setAlgebraDictionary]["1"]?.insert(fixtureSetAlgebra3) Defaults[.setAlgebraDictionary]["1"]?.insert(fixtureSetAlgebra3)
XCTAssertEqual(Defaults[.setAlgebraDictionary]["0"], .init([fixtureSetAlgebra, fixtureSetAlgebra1])) #expect(Defaults[.setAlgebraDictionary]["0"] == .init([fixtureSetAlgebra, fixtureSetAlgebra1]))
XCTAssertEqual(Defaults[.setAlgebraDictionary]["1"], .init([fixtureSetAlgebra2, fixtureSetAlgebra3])) #expect(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)
} }
} }

View File

@ -1,55 +1,60 @@
import Foundation import Foundation
import Testing
import Defaults import Defaults
import XCTest
private let suite_ = createSuite()
private let fixtureSet = Set(1...5) private let fixtureSet = Set(1...5)
extension Defaults.Keys { 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 { @Suite(.serialized)
override func setUp() { final class DefaultsSetTests {
super.setUp() init() {
Defaults.removeAll() Defaults.removeAll(suite: suite_)
} }
override func tearDown() { deinit {
super.tearDown() Defaults.removeAll(suite: suite_)
Defaults.removeAll()
} }
@Test
func testKey() { func testKey() {
let key = Defaults.Key<Set<Int>>("independentSetKey", default: fixtureSet) let key = Defaults.Key<Set<Int>>("independentSetKey", default: fixtureSet, suite: suite_)
XCTAssertEqual(Defaults[key].count, fixtureSet.count) #expect(Defaults[key].count == fixtureSet.count)
Defaults[key].insert(6) Defaults[key].insert(6)
XCTAssertEqual(Defaults[key], Set(1...6)) #expect(Defaults[key] == Set(1...6))
} }
@Test
func testOptionalKey() { func testOptionalKey() {
let key = Defaults.Key<Set<Int>?>("independentSetOptionalKey") // swiftlint:disable:this discouraged_optional_collection let key = Defaults.Key<Set<Int>?>("independentSetOptionalKey", suite: suite_) // swiftlint:disable:this discouraged_optional_collection
XCTAssertNil(Defaults[key]) #expect(Defaults[key] == nil)
Defaults[key] = fixtureSet Defaults[key] = fixtureSet
XCTAssertEqual(Defaults[key]?.count, fixtureSet.count) #expect(Defaults[key]?.count == fixtureSet.count)
Defaults[key]?.insert(6) Defaults[key]?.insert(6)
XCTAssertEqual(Defaults[key], Set(1...6)) #expect(Defaults[key] == Set(1...6))
} }
@Test
func testArrayKey() { func testArrayKey() {
let key = Defaults.Key<[Set<Int>]>("independentSetArrayKey", default: [fixtureSet]) let key = Defaults.Key<[Set<Int>]>("independentSetArrayKey", default: [fixtureSet], suite: suite_)
XCTAssertEqual(Defaults[key][0].count, fixtureSet.count) #expect(Defaults[key][0].count == fixtureSet.count)
Defaults[key][0].insert(6) 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)) Defaults[key].append(Set(1...4))
XCTAssertEqual(Defaults[key][1], Set(1...4)) #expect(Defaults[key][1] == Set(1...4))
} }
@Test
func testDictionaryKey() { func testDictionaryKey() {
let key = Defaults.Key<[String: Set<Int>]>("independentSetArrayKey", default: ["0": fixtureSet]) let key = Defaults.Key<[String: Set<Int>]>("independentSetArrayKey", default: ["0": fixtureSet], suite: suite_)
XCTAssertEqual(Defaults[key]["0"]?.count, fixtureSet.count) #expect(Defaults[key]["0"]?.count == fixtureSet.count)
Defaults[key]["0"]?.insert(6) 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) 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 Foundation
import SwiftUI import SwiftUI
import Testing
import Defaults import Defaults
private let suite_ = createSuite()
#if os(macOS) #if os(macOS)
typealias XColor = NSColor typealias XColor = NSColor
#else #else
@ -10,10 +12,10 @@ typealias XColor = UIColor
#endif #endif
extension Defaults.Keys { extension Defaults.Keys {
fileprivate static let hasUnicorn = Key<Bool>("swiftui_hasUnicorn", default: false) 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")) 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)) 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) fileprivate static let color = Key<Color>("swiftui_color", default: .black, suite: suite_)
} }
struct ContentView: View { struct ContentView: View {
@ -29,34 +31,35 @@ struct ContentView: View {
} }
} }
@Suite(.serialized)
final class DefaultsSwiftUITests: XCTestCase { final class DefaultsSwiftUITests {
override func setUp() { init() {
super.setUp() Defaults.removeAll(suite: suite_)
Defaults.removeAll()
} }
override func tearDown() { deinit {
super.tearDown() Defaults.removeAll(suite: suite_)
Defaults.removeAll()
} }
@Test
func testSwiftUIObserve() { func testSwiftUIObserve() {
let view = ContentView() let view = ContentView()
XCTAssertFalse(view.hasUnicorn) #expect(!view.hasUnicorn)
XCTAssertEqual(view.user.username, "Hank") #expect(view.user.username == "Hank")
XCTAssertEqual(view.setInt.count, 3) #expect(view.setInt.count == 3)
XCTAssertEqual(XColor(view.color), XColor(Color.black)) #expect(XColor(view.color) == XColor(Color.black))
view.user = User(username: "Chen", password: "123456") view.user = User(username: "Chen", password: "123456")
view.hasUnicorn.toggle() view.hasUnicorn.toggle()
view.setInt.insert(4) view.setInt.insert(4)
view.color = Color(.sRGB, red: 100, green: 100, blue: 100, opacity: 1) view.color = Color(.sRGB, red: 100, green: 100, blue: 100, opacity: 1)
XCTAssertTrue(view.hasUnicorn)
XCTAssertEqual(view.user.username, "Chen") #expect(view.hasUnicorn)
XCTAssertEqual(view.setInt, Set(1...4)) #expect(view.user.username == "Chen")
XCTAssertFalse(Default(.hasUnicorn).defaultValue) #expect(view.setInt == Set(1...4))
XCTAssertFalse(Default(.hasUnicorn).isDefaultValue) #expect(!Default(.hasUnicorn).defaultValue)
XCTAssertNotEqual(XColor(view.color), XColor(Color.black)) #expect(!Default(.hasUnicorn).isDefaultValue)
XCTAssertEqual(XColor(view.color), XColor(Color(.sRGB, red: 100, green: 100, blue: 100, opacity: 1))) #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) #if !os(macOS)
import Foundation import Foundation
import Defaults
import XCTest
import UIKit 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 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 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) private let fixtureColor2 = UIColor(red: Double(255) / Double(0xFF), green: Double(180) / Double(0xFF), blue: Double(194) / Double(0xFF), alpha: 1)
extension Defaults.Keys { extension Defaults.Keys {
fileprivate static let color = Defaults.Key<UIColor>("NSColor", default: fixtureColor) fileprivate static let color = Defaults.Key<UIColor>("NSColor", default: fixtureColor, suite: suite_)
fileprivate static let colorArray = Defaults.Key<[UIColor]>("NSColorArray", default: [fixtureColor]) fileprivate static let colorArray = Defaults.Key<[UIColor]>("NSColorArray", default: [fixtureColor], suite: suite_)
fileprivate static let colorDictionary = Defaults.Key<[String: UIColor]>("NSColorArray", default: ["0": fixtureColor]) fileprivate static let colorDictionary = Defaults.Key<[String: UIColor]>("NSColorArray", default: ["0": fixtureColor], suite: suite_)
} }
final class DefaultsNSColorTests: XCTestCase { @Suite(.serialized)
override func setUp() { final class DefaultsNSColorTests {
super.setUp() init() {
Defaults.removeAll() Defaults.removeAll(suite: suite_)
} }
override func tearDown() { deinit {
super.tearDown() Defaults.removeAll(suite: suite_)
Defaults.removeAll()
} }
@Test
func testKey() { func testKey() {
let key = Defaults.Key<UIColor>("independentNSColorKey", default: fixtureColor) let key = Defaults.Key<UIColor>("independentNSColorKey", default: fixtureColor, suite: suite_)
XCTAssertTrue(Defaults[key].isEqual(fixtureColor)) #expect(Defaults[key].isEqual(fixtureColor))
Defaults[key] = fixtureColor1 Defaults[key] = fixtureColor1
XCTAssertTrue(Defaults[key].isEqual(fixtureColor1)) #expect(Defaults[key].isEqual(fixtureColor1))
} }
@Test
func testPreservesColorSpace() { func testPreservesColorSpace() {
let fixture = UIColor(displayP3Red: 1, green: 0.3, blue: 0.7, alpha: 1) 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 Defaults[key] = fixture
XCTAssertEqual(Defaults[key], fixture) #expect(Defaults[key] == fixture)
XCTAssertEqual(Defaults[key]?.cgColor.colorSpace, fixture.cgColor.colorSpace) #expect(Defaults[key]?.cgColor.colorSpace == fixture.cgColor.colorSpace)
XCTAssertEqual(Defaults[key]?.cgColor, fixture.cgColor) #expect(Defaults[key]?.cgColor == fixture.cgColor)
} }
@Test
func testOptionalKey() { func testOptionalKey() {
let key = Defaults.Key<UIColor?>("independentNSColorOptionalKey") let key = Defaults.Key<UIColor?>("independentNSColorOptionalKey", suite: suite_)
XCTAssertNil(Defaults[key]) #expect(Defaults[key] == nil)
Defaults[key] = fixtureColor Defaults[key] = fixtureColor
XCTAssertTrue(Defaults[key]?.isEqual(fixtureColor) ?? false) #expect(Defaults[key]?.isEqual(fixtureColor) ?? false)
} }
@Test
func testArrayKey() { func testArrayKey() {
let key = Defaults.Key<[UIColor]>("independentNSColorArrayKey", default: [fixtureColor]) let key = Defaults.Key<[UIColor]>("independentNSColorArrayKey", default: [fixtureColor], suite: suite_)
XCTAssertTrue(Defaults[key][0].isEqual(fixtureColor)) #expect(Defaults[key][0].isEqual(fixtureColor))
Defaults[key].append(fixtureColor1) Defaults[key].append(fixtureColor1)
XCTAssertTrue(Defaults[key][1].isEqual(fixtureColor1)) #expect(Defaults[key][1].isEqual(fixtureColor1))
} }
@Test
func testArrayOptionalKey() { func testArrayOptionalKey() {
let key = Defaults.Key<[UIColor]?>("independentNSColorOptionalKey") // swiftlint:disable:this discouraged_optional_collection let key = Defaults.Key<[UIColor]?>("independentNSColorOptionalKey", suite: suite_) // swiftlint:disable:this discouraged_optional_collection
XCTAssertNil(Defaults[key]) #expect(Defaults[key] == nil)
Defaults[key] = [fixtureColor] Defaults[key] = [fixtureColor]
Defaults[key]?.append(fixtureColor1) Defaults[key]?.append(fixtureColor1)
XCTAssertTrue(Defaults[key]?[0].isEqual(fixtureColor) ?? false) #expect(Defaults[key]?[0].isEqual(fixtureColor) ?? false)
XCTAssertTrue(Defaults[key]?[1].isEqual(fixtureColor1) ?? false) #expect(Defaults[key]?[1].isEqual(fixtureColor1) ?? false)
} }
@Test
func testNestedArrayKey() { func testNestedArrayKey() {
let key = Defaults.Key<[[UIColor]]>("independentNSColorNestedArrayKey", default: [[fixtureColor]]) let key = Defaults.Key<[[UIColor]]>("independentNSColorNestedArrayKey", default: [[fixtureColor]], suite: suite_)
XCTAssertTrue(Defaults[key][0][0].isEqual(fixtureColor)) #expect(Defaults[key][0][0].isEqual(fixtureColor))
Defaults[key][0].append(fixtureColor1) Defaults[key][0].append(fixtureColor1)
Defaults[key].append([fixtureColor2]) Defaults[key].append([fixtureColor2])
XCTAssertTrue(Defaults[key][0][1].isEqual(fixtureColor1)) #expect(Defaults[key][0][1].isEqual(fixtureColor1))
XCTAssertTrue(Defaults[key][1][0].isEqual(fixtureColor2)) #expect(Defaults[key][1][0].isEqual(fixtureColor2))
} }
@Test
func testArrayDictionaryKey() { func testArrayDictionaryKey() {
let key = Defaults.Key<[[String: UIColor]]>("independentNSColorArrayDictionaryKey", default: [["0": fixtureColor]]) let key = Defaults.Key<[[String: UIColor]]>("independentNSColorArrayDictionaryKey", default: [["0": fixtureColor]], suite: suite_)
XCTAssertTrue(Defaults[key][0]["0"]?.isEqual(fixtureColor) ?? false) #expect(Defaults[key][0]["0"]?.isEqual(fixtureColor) ?? false)
Defaults[key][0]["1"] = fixtureColor1 Defaults[key][0]["1"] = fixtureColor1
Defaults[key].append(["0": fixtureColor2]) Defaults[key].append(["0": fixtureColor2])
XCTAssertTrue(Defaults[key][0]["1"]?.isEqual(fixtureColor1) ?? false) #expect(Defaults[key][0]["1"]?.isEqual(fixtureColor1) ?? false)
XCTAssertTrue(Defaults[key][1]["0"]?.isEqual(fixtureColor2) ?? false) #expect(Defaults[key][1]["0"]?.isEqual(fixtureColor2) ?? false)
} }
@Test
func testDictionaryKey() { func testDictionaryKey() {
let key = Defaults.Key<[String: UIColor]>("independentNSColorDictionaryKey", default: ["0": fixtureColor]) let key = Defaults.Key<[String: UIColor]>("independentNSColorDictionaryKey", default: ["0": fixtureColor], suite: suite_)
XCTAssertTrue(Defaults[key]["0"]?.isEqual(fixtureColor) ?? false) #expect(Defaults[key]["0"]?.isEqual(fixtureColor) ?? false)
Defaults[key]["1"] = fixtureColor1 Defaults[key]["1"] = fixtureColor1
XCTAssertTrue(Defaults[key]["1"]?.isEqual(fixtureColor1) ?? false) #expect(Defaults[key]["1"]?.isEqual(fixtureColor1) ?? false)
} }
@Test
func testDictionaryOptionalKey() { func testDictionaryOptionalKey() {
let key = Defaults.Key<[String: UIColor]?>("independentNSColorDictionaryOptionalKey") // swiftlint:disable:this discouraged_optional_collection let key = Defaults.Key<[String: UIColor]?>("independentNSColorDictionaryOptionalKey", suite: suite_) // swiftlint:disable:this discouraged_optional_collection
XCTAssertNil(Defaults[key]) #expect(Defaults[key] == nil)
Defaults[key] = ["0": fixtureColor] Defaults[key] = ["0": fixtureColor]
Defaults[key]?["1"] = fixtureColor1 Defaults[key]?["1"] = fixtureColor1
XCTAssertTrue(Defaults[key]?["0"]?.isEqual(fixtureColor) ?? false) #expect(Defaults[key]?["0"]?.isEqual(fixtureColor) ?? false)
XCTAssertTrue(Defaults[key]?["1"]?.isEqual(fixtureColor1) ?? false) #expect(Defaults[key]?["1"]?.isEqual(fixtureColor1) ?? false)
} }
@Test
func testDictionaryArrayKey() { func testDictionaryArrayKey() {
let key = Defaults.Key<[String: [UIColor]]>("independentNSColorDictionaryArrayKey", default: ["0": [fixtureColor]]) let key = Defaults.Key<[String: [UIColor]]>("independentNSColorDictionaryArrayKey", default: ["0": [fixtureColor]], suite: suite_)
XCTAssertTrue(Defaults[key]["0"]?[0].isEqual(fixtureColor) ?? false) #expect(Defaults[key]["0"]?[0].isEqual(fixtureColor) ?? false)
Defaults[key]["0"]?.append(fixtureColor1) Defaults[key]["0"]?.append(fixtureColor1)
Defaults[key]["1"] = [fixtureColor2] Defaults[key]["1"] = [fixtureColor2]
XCTAssertTrue(Defaults[key]["0"]?[1].isEqual(fixtureColor1) ?? false) #expect(Defaults[key]["0"]?[1].isEqual(fixtureColor1) ?? false)
XCTAssertTrue(Defaults[key]["1"]?[0].isEqual(fixtureColor2) ?? false) #expect(Defaults[key]["1"]?[0].isEqual(fixtureColor2) ?? false)
} }
@Test
func testType() { func testType() {
XCTAssert(Defaults[.color].isEqual(fixtureColor)) #expect(Defaults[.color].isEqual(fixtureColor))
Defaults[.color] = fixtureColor1 Defaults[.color] = fixtureColor1
XCTAssert(Defaults[.color].isEqual(fixtureColor1)) #expect(Defaults[.color].isEqual(fixtureColor1))
} }
@Test
func testArrayType() { func testArrayType() {
XCTAssertTrue(Defaults[.colorArray][0].isEqual(fixtureColor)) #expect(Defaults[.colorArray][0].isEqual(fixtureColor))
Defaults[.colorArray][0] = fixtureColor1 Defaults[.colorArray][0] = fixtureColor1
XCTAssertTrue(Defaults[.colorArray][0].isEqual(fixtureColor1)) #expect(Defaults[.colorArray][0].isEqual(fixtureColor1))
} }
@Test
func testDictionaryType() { func testDictionaryType() {
XCTAssertTrue(Defaults[.colorDictionary]["0"]?.isEqual(fixtureColor) ?? false) #expect(Defaults[.colorDictionary]["0"]?.isEqual(fixtureColor) ?? false)
Defaults[.colorDictionary]["0"] = fixtureColor1 Defaults[.colorDictionary]["0"] = fixtureColor1
XCTAssertTrue(Defaults[.colorDictionary]["0"]?.isEqual(fixtureColor1) ?? false) #expect(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)
} }
} }
#endif #endif