473 lines
18 KiB
Swift
473 lines
18 KiB
Swift
import Foundation
|
|
import CoreData
|
|
import Defaults
|
|
import XCTest
|
|
|
|
@objc(ExamplePersistentHistory)
|
|
private final class ExamplePersistentHistory: NSPersistentHistoryToken, Defaults.Serializable {
|
|
let value: String
|
|
|
|
init(value: String) {
|
|
self.value = value
|
|
super.init()
|
|
}
|
|
|
|
required init?(coder: NSCoder) {
|
|
self.value = coder.decodeObject(forKey: "value") as! String
|
|
super.init()
|
|
}
|
|
|
|
override func encode(with coder: NSCoder) {
|
|
coder.encode(value, forKey: "value")
|
|
}
|
|
|
|
override class var supportsSecureCoding: Bool { true } // swiftlint:disable:this non_overridable_class_declaration
|
|
}
|
|
|
|
// NSSecureCoding
|
|
private let persistentHistoryValue = ExamplePersistentHistory(value: "ExampleToken")
|
|
|
|
extension Defaults.Keys {
|
|
fileprivate static let persistentHistory = Key<ExamplePersistentHistory>("persistentHistory", default: persistentHistoryValue)
|
|
fileprivate static let persistentHistoryArray = Key<[ExamplePersistentHistory]>("array_persistentHistory", default: [persistentHistoryValue])
|
|
fileprivate static let persistentHistoryDictionary = Key<[String: ExamplePersistentHistory]>("dictionary_persistentHistory", default: ["0": persistentHistoryValue])
|
|
}
|
|
|
|
final class DefaultsNSSecureCodingTests: XCTestCase {
|
|
override func setUp() {
|
|
super.setUp()
|
|
Defaults.removeAll()
|
|
}
|
|
|
|
override func tearDown() {
|
|
super.tearDown()
|
|
Defaults.removeAll()
|
|
}
|
|
|
|
func testKey() {
|
|
let key = Defaults.Key<ExamplePersistentHistory>("independentNSSecureCodingKey", default: persistentHistoryValue)
|
|
XCTAssertEqual(Defaults[key].value, persistentHistoryValue.value)
|
|
let newPersistentHistory = ExamplePersistentHistory(value: "NewValue")
|
|
Defaults[key] = newPersistentHistory
|
|
XCTAssertEqual(Defaults[key].value, newPersistentHistory.value)
|
|
}
|
|
|
|
func testOptionalKey() {
|
|
let key = Defaults.Key<ExamplePersistentHistory?>("independentNSSecureCodingOptionalKey")
|
|
XCTAssertNil(Defaults[key])
|
|
Defaults[key] = persistentHistoryValue
|
|
XCTAssertEqual(Defaults[key]?.value, persistentHistoryValue.value)
|
|
Defaults[key] = nil
|
|
XCTAssertNil(Defaults[key])
|
|
let newPersistentHistory = ExamplePersistentHistory(value: "NewValue")
|
|
Defaults[key] = newPersistentHistory
|
|
XCTAssertEqual(Defaults[key]?.value, newPersistentHistory.value)
|
|
}
|
|
|
|
func testArrayKey() {
|
|
let key = Defaults.Key<[ExamplePersistentHistory]>("independentNSSecureCodingArrayKey", default: [persistentHistoryValue])
|
|
XCTAssertEqual(Defaults[key][0].value, persistentHistoryValue.value)
|
|
let newPersistentHistory1 = ExamplePersistentHistory(value: "NewValue1")
|
|
Defaults[key].append(newPersistentHistory1)
|
|
XCTAssertEqual(Defaults[key][1].value, newPersistentHistory1.value)
|
|
let newPersistentHistory2 = ExamplePersistentHistory(value: "NewValue2")
|
|
Defaults[key][1] = newPersistentHistory2
|
|
XCTAssertEqual(Defaults[key][1].value, newPersistentHistory2.value)
|
|
XCTAssertEqual(Defaults[key][0].value, persistentHistoryValue.value)
|
|
}
|
|
|
|
func testArrayOptionalKey() {
|
|
let key = Defaults.Key<[ExamplePersistentHistory]?>("independentNSSecureCodingArrayOptionalKey") // swiftlint:disable:this discouraged_optional_collection
|
|
XCTAssertNil(Defaults[key])
|
|
Defaults[key] = [persistentHistoryValue]
|
|
XCTAssertEqual(Defaults[key]?[0].value, persistentHistoryValue.value)
|
|
Defaults[key] = nil
|
|
XCTAssertNil(Defaults[key])
|
|
}
|
|
|
|
func testNestedArrayKey() {
|
|
let key = Defaults.Key<[[ExamplePersistentHistory]]>("independentNSSecureCodingNestedArrayKey", default: [[persistentHistoryValue]])
|
|
XCTAssertEqual(Defaults[key][0][0].value, persistentHistoryValue.value)
|
|
let newPersistentHistory1 = ExamplePersistentHistory(value: "NewValue1")
|
|
Defaults[key][0].append(newPersistentHistory1)
|
|
let newPersistentHistory2 = ExamplePersistentHistory(value: "NewValue2")
|
|
Defaults[key].append([newPersistentHistory2])
|
|
XCTAssertEqual(Defaults[key][0][1].value, newPersistentHistory1.value)
|
|
XCTAssertEqual(Defaults[key][1][0].value, newPersistentHistory2.value)
|
|
}
|
|
|
|
func testArrayDictionaryKey() {
|
|
let key = Defaults.Key<[[String: ExamplePersistentHistory]]>("independentNSSecureCodingArrayDictionaryKey", default: [["0": persistentHistoryValue]])
|
|
XCTAssertEqual(Defaults[key][0]["0"]?.value, persistentHistoryValue.value)
|
|
let newPersistentHistory1 = ExamplePersistentHistory(value: "NewValue1")
|
|
Defaults[key][0]["1"] = newPersistentHistory1
|
|
let newPersistentHistory2 = ExamplePersistentHistory(value: "NewValue2")
|
|
Defaults[key].append(["0": newPersistentHistory2])
|
|
XCTAssertEqual(Defaults[key][0]["1"]?.value, newPersistentHistory1.value)
|
|
XCTAssertEqual(Defaults[key][1]["0"]?.value, newPersistentHistory2.value)
|
|
}
|
|
|
|
func testDictionaryKey() {
|
|
let key = Defaults.Key<[String: ExamplePersistentHistory]>("independentNSSecureCodingDictionaryKey", default: ["0": persistentHistoryValue])
|
|
XCTAssertEqual(Defaults[key]["0"]?.value, persistentHistoryValue.value)
|
|
let newPersistentHistory1 = ExamplePersistentHistory(value: "NewValue1")
|
|
Defaults[key]["1"] = newPersistentHistory1
|
|
XCTAssertEqual(Defaults[key]["1"]?.value, newPersistentHistory1.value)
|
|
let newPersistentHistory2 = ExamplePersistentHistory(value: "NewValue2")
|
|
Defaults[key]["1"] = newPersistentHistory2
|
|
XCTAssertEqual(Defaults[key]["1"]?.value, newPersistentHistory2.value)
|
|
XCTAssertEqual(Defaults[key]["0"]?.value, persistentHistoryValue.value)
|
|
}
|
|
|
|
func testDictionaryOptionalKey() {
|
|
let key = Defaults.Key<[String: ExamplePersistentHistory]?>("independentNSSecureCodingDictionaryOptionalKey") // swiftlint:disable:this discouraged_optional_collection
|
|
XCTAssertNil(Defaults[key])
|
|
Defaults[key] = ["0": persistentHistoryValue]
|
|
XCTAssertEqual(Defaults[key]?["0"]?.value, persistentHistoryValue.value)
|
|
}
|
|
|
|
func testDictionaryArrayKey() {
|
|
let key = Defaults.Key<[String: [ExamplePersistentHistory]]>("independentNSSecureCodingDictionaryArrayKey", default: ["0": [persistentHistoryValue]])
|
|
XCTAssertEqual(Defaults[key]["0"]?[0].value, persistentHistoryValue.value)
|
|
let newPersistentHistory1 = ExamplePersistentHistory(value: "NewValue1")
|
|
Defaults[key]["0"]?.append(newPersistentHistory1)
|
|
let newPersistentHistory2 = ExamplePersistentHistory(value: "NewValue2")
|
|
Defaults[key]["1"] = [newPersistentHistory2]
|
|
XCTAssertEqual(Defaults[key]["0"]?[1].value, newPersistentHistory1.value)
|
|
XCTAssertEqual(Defaults[key]["1"]?[0].value, newPersistentHistory2.value)
|
|
}
|
|
|
|
func testType() {
|
|
XCTAssertEqual(Defaults[.persistentHistory].value, persistentHistoryValue.value)
|
|
let newPersistentHistory = ExamplePersistentHistory(value: "NewValue")
|
|
Defaults[.persistentHistory] = newPersistentHistory
|
|
XCTAssertEqual(Defaults[.persistentHistory].value, newPersistentHistory.value)
|
|
}
|
|
|
|
func testArrayType() {
|
|
XCTAssertEqual(Defaults[.persistentHistoryArray][0].value, persistentHistoryValue.value)
|
|
let newPersistentHistory = ExamplePersistentHistory(value: "NewValue")
|
|
Defaults[.persistentHistoryArray][0] = newPersistentHistory
|
|
XCTAssertEqual(Defaults[.persistentHistoryArray][0].value, newPersistentHistory.value)
|
|
}
|
|
|
|
func testDictionaryType() {
|
|
XCTAssertEqual(Defaults[.persistentHistoryDictionary]["0"]?.value, persistentHistoryValue.value)
|
|
let newPersistentHistory = ExamplePersistentHistory(value: "NewValue")
|
|
Defaults[.persistentHistoryDictionary]["0"] = newPersistentHistory
|
|
XCTAssertEqual(Defaults[.persistentHistoryDictionary]["0"]?.value, newPersistentHistory.value)
|
|
}
|
|
|
|
func testObserveKeyCombine() {
|
|
let key = Defaults.Key<ExamplePersistentHistory>("observeNSSecureCodingKeyCombine", default: persistentHistoryValue)
|
|
let newPersistentHistory = ExamplePersistentHistory(value: "NewValue")
|
|
let expect = expectation(description: "Observation closure being called")
|
|
|
|
let publisher = Defaults
|
|
.publisher(key, options: [])
|
|
.map { ($0.oldValue.value, $0.newValue.value) }
|
|
.collect(2)
|
|
|
|
let cancellable = publisher.sink { tuples in
|
|
for (index, expected) in [(persistentHistoryValue.value, newPersistentHistory.value), (newPersistentHistory.value, persistentHistoryValue.value)].enumerated() {
|
|
XCTAssertEqual(expected.0, tuples[index].0)
|
|
XCTAssertEqual(expected.1, tuples[index].1)
|
|
}
|
|
|
|
expect.fulfill()
|
|
}
|
|
|
|
Defaults[key] = newPersistentHistory
|
|
Defaults.reset(key)
|
|
cancellable.cancel()
|
|
|
|
waitForExpectations(timeout: 10)
|
|
}
|
|
|
|
func testObserveOptionalKeyCombine() {
|
|
let key = Defaults.Key<ExamplePersistentHistory?>("observeNSSecureCodingOptionalKeyCombine")
|
|
let newPersistentHistory = ExamplePersistentHistory(value: "NewValue")
|
|
let expect = expectation(description: "Observation closure being called")
|
|
|
|
let publisher = Defaults
|
|
.publisher(key, options: [])
|
|
.map { ($0.oldValue?.value, $0.newValue?.value) }
|
|
.collect(3)
|
|
|
|
let expectedValue: [(ExamplePersistentHistory?, ExamplePersistentHistory?)] = [(nil, persistentHistoryValue), (persistentHistoryValue, newPersistentHistory), (newPersistentHistory, nil)]
|
|
|
|
let cancellable = publisher.sink { tuples in
|
|
for (index, expected) in expectedValue.enumerated() {
|
|
XCTAssertEqual(expected.0?.value, tuples[index].0)
|
|
XCTAssertEqual(expected.1?.value, tuples[index].1)
|
|
}
|
|
|
|
expect.fulfill()
|
|
}
|
|
|
|
Defaults[key] = persistentHistoryValue
|
|
Defaults[key] = newPersistentHistory
|
|
Defaults.reset(key)
|
|
cancellable.cancel()
|
|
|
|
waitForExpectations(timeout: 10)
|
|
}
|
|
|
|
func testObserveArrayKeyCombine() {
|
|
let key = Defaults.Key<[ExamplePersistentHistory]>("observeNSSecureCodingArrayKeyCombine", default: [persistentHistoryValue])
|
|
let newPersistentHistory = ExamplePersistentHistory(value: "NewValue")
|
|
let expect = expectation(description: "Observation closure being called")
|
|
|
|
let publisher = Defaults
|
|
.publisher(key, options: [])
|
|
.map { ($0.oldValue, $0.newValue) }
|
|
.collect(2)
|
|
|
|
let expectedValue: [(ExamplePersistentHistory, ExamplePersistentHistory)] = [(persistentHistoryValue, newPersistentHistory), (newPersistentHistory, persistentHistoryValue)]
|
|
|
|
let cancellable = publisher.sink { tuples in
|
|
for (index, expected) in expectedValue.enumerated() {
|
|
XCTAssertEqual(expected.0.value, tuples[index].0[0].value)
|
|
XCTAssertEqual(expected.1.value, tuples[index].1[0].value)
|
|
}
|
|
|
|
expect.fulfill()
|
|
}
|
|
|
|
Defaults[key][0] = newPersistentHistory
|
|
Defaults.reset(key)
|
|
cancellable.cancel()
|
|
|
|
waitForExpectations(timeout: 10)
|
|
}
|
|
|
|
func testObserveDictionaryKeyCombine() {
|
|
let key = Defaults.Key<[String: ExamplePersistentHistory]>("observeNSSecureCodingDictionaryKeyCombine", default: ["0": persistentHistoryValue])
|
|
let newPersistentHistory = ExamplePersistentHistory(value: "NewValue")
|
|
let expect = expectation(description: "Observation closure being called")
|
|
|
|
let publisher = Defaults
|
|
.publisher(key, options: [])
|
|
.map { ($0.oldValue, $0.newValue) }
|
|
.collect(2)
|
|
|
|
let expectedValue: [(ExamplePersistentHistory, ExamplePersistentHistory)] = [(persistentHistoryValue, newPersistentHistory), (newPersistentHistory, persistentHistoryValue)]
|
|
|
|
let cancellable = publisher.sink { tuples in
|
|
for (index, expected) in expectedValue.enumerated() {
|
|
XCTAssertEqual(expected.0.value, tuples[index].0["0"]?.value)
|
|
XCTAssertEqual(expected.1.value, tuples[index].1["0"]?.value)
|
|
}
|
|
|
|
expect.fulfill()
|
|
}
|
|
|
|
Defaults[key]["0"] = newPersistentHistory
|
|
Defaults.reset(key)
|
|
cancellable.cancel()
|
|
|
|
waitForExpectations(timeout: 10)
|
|
}
|
|
|
|
func testObserveMultipleNSSecureKeysCombine() {
|
|
let key1 = Defaults.Key<ExamplePersistentHistory>("observeMultipleNSSecureCodingKey1", default: ExamplePersistentHistory(value: "TestValue"))
|
|
let key2 = Defaults.Key<ExamplePersistentHistory>("observeMultipleNSSecureCodingKey2", default: ExamplePersistentHistory(value: "TestValue"))
|
|
let expect = expectation(description: "Observation closure being called")
|
|
|
|
let publisher = Defaults.publisher(keys: key1, key2, options: []).collect(2)
|
|
|
|
let cancellable = publisher.sink { _ in
|
|
expect.fulfill()
|
|
}
|
|
|
|
Defaults[key1] = ExamplePersistentHistory(value: "NewTestValue1")
|
|
Defaults[key2] = ExamplePersistentHistory(value: "NewTestValue2")
|
|
cancellable.cancel()
|
|
|
|
waitForExpectations(timeout: 10)
|
|
}
|
|
|
|
func testObserveMultipleNSSecureOptionalKeysCombine() {
|
|
let key1 = Defaults.Key<ExamplePersistentHistory?>("observeMultipleNSSecureCodingOptionalKey1")
|
|
let key2 = Defaults.Key<ExamplePersistentHistory?>("observeMultipleNSSecureCodingOptionalKeyKey2")
|
|
let expect = expectation(description: "Observation closure being called")
|
|
|
|
let publisher = Defaults.publisher(keys: key1, key2, options: []).collect(2)
|
|
|
|
let cancellable = publisher.sink { _ in
|
|
expect.fulfill()
|
|
}
|
|
|
|
Defaults[key1] = ExamplePersistentHistory(value: "NewTestValue1")
|
|
Defaults[key2] = ExamplePersistentHistory(value: "NewTestValue2")
|
|
cancellable.cancel()
|
|
|
|
waitForExpectations(timeout: 10)
|
|
}
|
|
|
|
func testObserveMultipleNSSecureKeys() {
|
|
let key1 = Defaults.Key<ExamplePersistentHistory>("observeNSSecureCodingKey1", default: ExamplePersistentHistory(value: "TestValue"))
|
|
let key2 = Defaults.Key<ExamplePersistentHistory>("observeNSSecureCodingKey2", default: ExamplePersistentHistory(value: "TestValue"))
|
|
let expect = expectation(description: "Observation closure being called")
|
|
|
|
var observation: Defaults.Observation!
|
|
var counter = 0
|
|
observation = Defaults.observe(keys: key1, key2, options: []) {
|
|
counter += 1
|
|
if counter == 2 {
|
|
expect.fulfill()
|
|
} else if counter > 2 {
|
|
XCTFail() // swiftlint:disable:this xctfail_message
|
|
}
|
|
}
|
|
|
|
Defaults[key1] = ExamplePersistentHistory(value: "NewTestValue1")
|
|
Defaults[key2] = ExamplePersistentHistory(value: "NewTestValue2")
|
|
observation.invalidate()
|
|
|
|
waitForExpectations(timeout: 10)
|
|
}
|
|
|
|
func testRemoveDuplicatesObserveNSSecureCodingKeyCombine() {
|
|
let key = Defaults.Key<ExamplePersistentHistory>("observeNSSecureCodingKey", default: ExamplePersistentHistory(value: "TestValue"))
|
|
let expect = expectation(description: "Observation closure being called")
|
|
|
|
let inputArray = ["NewTestValue", "NewTestValue", "NewTestValue", "NewTestValue2", "NewTestValue2", "NewTestValue2", "NewTestValue3", "NewTestValue3"]
|
|
let expectedArray = ["NewTestValue", "NewTestValue2", "NewTestValue3"]
|
|
|
|
let cancellable = Defaults
|
|
.publisher(key, options: [])
|
|
.removeDuplicates()
|
|
.map(\.newValue.value)
|
|
.collect(expectedArray.count)
|
|
.sink { result in
|
|
print("Result array: \(result)")
|
|
|
|
if result == expectedArray {
|
|
expect.fulfill()
|
|
} else {
|
|
XCTFail("Expected Array is not matched")
|
|
}
|
|
}
|
|
|
|
inputArray.forEach {
|
|
Defaults[key] = ExamplePersistentHistory(value: $0)
|
|
}
|
|
|
|
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")
|
|
}
|
|
}
|
|
|
|
inputArray.forEach {
|
|
Defaults[key] = ExamplePersistentHistory(value: $0)
|
|
}
|
|
|
|
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)
|
|
}
|
|
}
|