Defaults/Tests/DefaultsTests/DefaultsTests.swift

625 lines
17 KiB
Swift
Raw Normal View History

2024-01-18 17:58:06 +08:00
// swiftlint:disable discouraged_optional_boolean
import Foundation
import Combine
2024-09-26 05:17:26 +08:00
import Testing
@testable import Defaults
2018-04-12 01:19:30 +08:00
2024-09-26 05:17:26 +08:00
func createSuite() -> UserDefaults {
UserDefaults(suiteName: UUID().uuidString)!
}
private let suite_ = createSuite()
let fixtureURL = URL(string: "https://sindresorhus.com")!
let fixtureFileURL = URL(string: "file://~/icon.png")!
let fixtureURL2 = URL(string: "https://example.com")!
let fixtureDate = Date()
2018-04-12 01:19:30 +08:00
extension Defaults.Keys {
2024-09-26 05:17:26 +08:00
static let key = Key<Bool>("key", default: false, suite: suite_)
static let url = Key<URL>("url", default: fixtureURL, suite: suite_)
static let file = Key<URL>("fileURL", default: fixtureFileURL, suite: suite_)
static let data = Key<Data>("data", default: Data([]), suite: suite_)
static let date = Key<Date>("date", default: fixtureDate, suite: suite_)
static let uuid = Key<UUID?>("uuid", suite: suite_)
static let defaultDynamicDate = Key<Date>("defaultDynamicOptionalDate", suite: suite_) { Date(timeIntervalSince1970: 0) }
static let defaultDynamicOptionalDate = Key<Date?>("defaultDynamicOptionalDate", suite: suite_) { Date(timeIntervalSince1970: 1) }
2018-04-12 01:19:30 +08:00
}
2024-09-26 05:17:26 +08:00
@Suite(.serialized)
final class DefaultsTests {
init() {
Defaults.removeAll(suite: suite_)
2018-04-12 01:19:30 +08:00
}
2024-09-26 05:17:26 +08:00
deinit {
Defaults.removeAll(suite: suite_)
}
2024-09-26 05:17:26 +08:00
@Test
func testKey() {
2024-09-26 05:17:26 +08:00
let key = Defaults.Key<Bool>("independentKey", default: false, suite: suite_)
#expect(!Defaults[key])
Defaults[key] = true
2024-09-26 05:17:26 +08:00
#expect(Defaults[key])
2018-04-12 01:19:30 +08:00
}
2024-09-26 05:17:26 +08:00
@Test
func testValidKeyName() {
2024-09-26 05:17:26 +08:00
let validKey = Defaults.Key<Bool>("test", default: false, suite: suite_)
let containsDotKey = Defaults.Key<Bool>("test.a", default: false, suite: suite_)
let startsWithAtKey = Defaults.Key<Bool>("@test", default: false, suite: suite_)
#expect(Defaults.isValidKeyPath(name: validKey.name))
#expect(!Defaults.isValidKeyPath(name: containsDotKey.name))
#expect(!Defaults.isValidKeyPath(name: startsWithAtKey.name))
}
2024-09-26 05:17:26 +08:00
@Test
2018-04-12 01:19:30 +08:00
func testOptionalKey() {
2024-09-26 05:17:26 +08:00
let key = Defaults.Key<Bool?>("independentOptionalKey", suite: suite_)
let url = Defaults.Key<URL?>("independentOptionalURLKey", suite: suite_)
#expect(Defaults[key] == nil)
#expect(Defaults[url] == nil)
Defaults[key] = true
Defaults[url] = fixtureURL
2024-09-26 05:17:26 +08:00
#expect(Defaults[key] == true)
#expect(Defaults[url] == fixtureURL)
Defaults[key] = nil
Defaults[url] = nil
2024-09-26 05:17:26 +08:00
#expect(Defaults[key] == nil)
#expect(Defaults[url] == nil)
Defaults[key] = false
Defaults[url] = fixtureURL2
2024-09-26 05:17:26 +08:00
#expect(Defaults[key] == false)
#expect(Defaults[url] == fixtureURL2)
}
2024-09-26 05:17:26 +08:00
@Test
func testInitializeDynamicDateKey() {
2024-09-26 05:17:26 +08:00
_ = Defaults.Key<Date>("independentInitializeDynamicDateKey", suite: suite_) {
Issue.record("Init dynamic key should not trigger getter")
return Date()
}
2024-09-26 05:17:26 +08:00
_ = Defaults.Key<Date?>("independentInitializeDynamicOptionalDateKey", suite: suite_) {
Issue.record("Init dynamic optional key should not trigger getter")
return Date()
}
}
2024-09-26 05:17:26 +08:00
@Test
func testKeyRegistersDefault() {
let keyName = "registersDefault"
2024-09-26 05:17:26 +08:00
#expect(!suite_.bool(forKey: keyName))
_ = Defaults.Key<Bool>(keyName, default: true, suite: suite_)
#expect(suite_.bool(forKey: keyName))
let keyName2 = "registersDefault2"
2024-09-26 05:17:26 +08:00
_ = Defaults.Key<String>(keyName2, default: keyName2, suite: suite_)
#expect(suite_.string(forKey: keyName2) == keyName2)
}
2024-09-26 05:17:26 +08:00
@Test
func testKeyWithUserDefaultSubscript() {
2024-09-26 05:17:26 +08:00
let key = Defaults.Key<Bool>("keyWithUserDeaultSubscript", default: false, suite: suite_)
#expect(!suite_[key])
suite_[key] = true
#expect(suite_[key])
2018-04-12 01:19:30 +08:00
}
2024-09-26 05:17:26 +08:00
@Test
2018-04-12 01:19:30 +08:00
func testKeys() {
2024-09-26 05:17:26 +08:00
#expect(!Defaults[.key])
Defaults[.key] = true
2024-09-26 05:17:26 +08:00
#expect(Defaults[.key])
2018-04-12 01:19:30 +08:00
}
2024-09-26 05:17:26 +08:00
@Test
2018-04-12 01:19:30 +08:00
func testUrlType() {
2024-09-26 05:17:26 +08:00
#expect(Defaults[.url] == fixtureURL)
2018-04-12 01:19:30 +08:00
let newUrl = URL(string: "https://twitter.com")!
Defaults[.url] = newUrl
2024-09-26 05:17:26 +08:00
#expect(Defaults[.url] == newUrl)
2018-04-12 01:19:30 +08:00
}
2024-09-26 05:17:26 +08:00
@Test
2018-04-16 02:09:53 +08:00
func testDataType() {
2024-09-26 05:17:26 +08:00
#expect(Defaults[.data] == Data([]))
let newData = Data([0xFF])
Defaults[.data] = newData
2024-09-26 05:17:26 +08:00
#expect(Defaults[.data] == newData)
2018-04-16 02:09:53 +08:00
}
2024-09-26 05:17:26 +08:00
@Test
func testDateType() {
2024-09-26 05:17:26 +08:00
#expect(Defaults[.date] == fixtureDate)
let newDate = Date()
Defaults[.date] = newDate
2024-09-26 05:17:26 +08:00
#expect(Defaults[.date] == newDate)
}
2024-09-26 05:17:26 +08:00
@Test
func testDynamicDateType() {
2024-09-26 05:17:26 +08:00
#expect(Defaults[.defaultDynamicDate] == Date(timeIntervalSince1970: 0))
let next = Date(timeIntervalSince1970: 1)
Defaults[.defaultDynamicDate] = next
2024-09-26 05:17:26 +08:00
#expect(Defaults[.defaultDynamicDate] == next)
#expect(suite_.object(forKey: Defaults.Key<Date>.defaultDynamicDate.name) as! Date == next)
Defaults.Key<Date>.defaultDynamicDate.reset()
2024-09-26 05:17:26 +08:00
#expect(Defaults[.defaultDynamicDate] == Date(timeIntervalSince1970: 0))
}
2024-09-26 05:17:26 +08:00
@Test
func testDynamicOptionalDateType() {
2024-09-26 05:17:26 +08:00
#expect(Defaults[.defaultDynamicOptionalDate] == Date(timeIntervalSince1970: 1))
let next = Date(timeIntervalSince1970: 2)
Defaults[.defaultDynamicOptionalDate] = next
2024-09-26 05:17:26 +08:00
#expect(Defaults[.defaultDynamicOptionalDate] == next)
#expect(suite_.object(forKey: Defaults.Key<Date>.defaultDynamicOptionalDate.name) as! Date == next)
Defaults[.defaultDynamicOptionalDate] = nil
2024-09-26 05:17:26 +08:00
#expect(Defaults[.defaultDynamicOptionalDate] == Date(timeIntervalSince1970: 1))
#expect(suite_.object(forKey: Defaults.Key<Date>.defaultDynamicOptionalDate.name) == nil)
}
2024-09-26 05:17:26 +08:00
@Test
func testFileURLType() {
2024-09-26 05:17:26 +08:00
#expect(Defaults[.file] == fixtureFileURL)
}
2024-09-26 05:17:26 +08:00
@Test
2022-01-27 23:14:21 +08:00
func testUUIDType() {
let fixture = UUID()
Defaults[.uuid] = fixture
2024-09-26 05:17:26 +08:00
#expect(Defaults[.uuid] == fixture)
2022-01-27 23:14:21 +08:00
}
2024-09-26 05:17:26 +08:00
@Test
func testRemoveAll() {
2024-09-26 05:17:26 +08:00
let key = Defaults.Key<Bool>("removeAll", default: false, suite: suite_)
let key2 = Defaults.Key<Bool>("removeAll2", default: false, suite: suite_)
Defaults[key] = true
Defaults[key2] = true
2024-09-26 05:17:26 +08:00
#expect(Defaults[key])
#expect(Defaults[key2])
Defaults.removeAll(suite: suite_)
#expect(!Defaults[key])
#expect(!Defaults[key2])
}
2024-09-26 05:17:26 +08:00
@Test
func testCustomSuite() {
let customSuite = UserDefaults(suiteName: "com.sindresorhus.customSuite")!
let key = Defaults.Key<Bool>("customSuite", default: false, suite: customSuite)
2024-09-26 05:17:26 +08:00
#expect(!customSuite[key])
#expect(!Defaults[key])
Defaults[key] = true
2024-09-26 05:17:26 +08:00
#expect(customSuite[key])
#expect(Defaults[key])
Defaults.removeAll(suite: customSuite)
}
2024-09-26 05:17:26 +08:00
@Test
func testIsDefaultValue() {
2024-09-26 05:17:26 +08:00
let key = Defaults.Key<Bool>("isDefaultValue", default: false, suite: suite_)
#expect(key.isDefaultValue)
Defaults[key].toggle()
2024-09-26 05:17:26 +08:00
#expect(!key.isDefaultValue)
}
@available(iOS 16.0, macOS 13.0, tvOS 16.0, watchOS 9.0, visionOS 1.0, *)
@Test
func testObserveKeyCombine() async throws {
let key = Defaults.Key<Bool>("observeKey", default: false, suite: suite_)
var results: [(Bool, Bool)] = []
try await confirmation(expectedCount: 2) { confirmation in
let publisher = Defaults
.publisher(key, options: [])
.map { ($0.oldValue, $0.newValue) }
.sink { value in
results.append(value)
confirmation()
}
2020-06-07 02:14:12 +08:00
2024-09-26 05:17:26 +08:00
await Task.yield()
Defaults[key] = true
Defaults.reset(key)
2020-04-05 22:56:59 +08:00
2024-09-26 05:17:26 +08:00
try await Task.sleep(for: .milliseconds(100))
publisher.cancel()
2020-04-05 22:56:59 +08:00
}
2024-09-26 05:17:26 +08:00
let expectedValues = [(false, true), (true, false)]
// #expect(results == expectedValues)
2020-04-05 22:56:59 +08:00
2024-09-26 05:17:26 +08:00
#expect(results.count == expectedValues.count)
for (index, expected) in expectedValues.enumerated() {
#expect(results[index].0 == expected.0)
#expect(results[index].1 == expected.1)
}
}
2024-09-26 05:17:26 +08:00
@available(iOS 16.0, macOS 13.0, tvOS 16.0, watchOS 9.0, visionOS 1.0, *)
@Test
func testObserveOptionalKeyCombine() async throws {
let key = Defaults.Key<Bool?>("observeOptionalKey", suite: suite_)
var results: [(Bool?, Bool?)] = []
2024-09-26 05:17:26 +08:00
try await confirmation(expectedCount: 3) { confirmation in
let publisher = Defaults
.publisher(key, options: [])
.map { ($0.oldValue, $0.newValue) }
.sink { value in
results.append(value)
confirmation()
}
2024-09-26 05:17:26 +08:00
await Task.yield()
Defaults[key] = true
Defaults[key] = false
Defaults.reset(key)
2020-08-29 04:38:56 +08:00
2024-09-26 05:17:26 +08:00
try await Task.sleep(for: .milliseconds(100))
publisher.cancel()
}
2020-08-29 04:38:56 +08:00
2024-09-26 05:17:26 +08:00
let expectedValues: [(Bool?, Bool?)] = [(nil, true), (true, false), (false, nil)]
// #expect(results == expectedValues)
2024-09-26 05:17:26 +08:00
#expect(results.count == expectedValues.count)
for (index, expected) in expectedValues.enumerated() {
#expect(results[index].0 == expected.0)
#expect(results[index].1 == expected.1)
}
}
2024-09-26 05:17:26 +08:00
@available(iOS 16.0, macOS 13.0, tvOS 16.0, watchOS 9.0, visionOS 1.0, *)
@Test
func testDynamicOptionalDateTypeCombine() async throws {
let first = Date(timeIntervalSince1970: 0)
let second = Date(timeIntervalSince1970: 1)
2024-09-26 05:17:26 +08:00
let third = Date(timeIntervalSince1970: 2)
let key = Defaults.Key<Date?>("combineDynamicOptionalDateKey", suite: suite_) { first }
var results: [(Date?, Date?)] = []
try await confirmation(expectedCount: 3) { confirmation in
let publisher = Defaults
.publisher(key, options: [])
.map { ($0.oldValue, $0.newValue) }
.sink { value in
results.append(value)
confirmation()
}
2024-09-26 05:17:26 +08:00
await Task.yield()
Defaults[key] = second
Defaults[key] = third
Defaults.reset(key)
2024-09-26 05:17:26 +08:00
try await Task.sleep(for: .milliseconds(100))
publisher.cancel()
}
2024-09-26 05:17:26 +08:00
let expectedValues: [(Date?, Date?)] = [(first, second), (second, third), (third, first)]
// #expect(results == expectedValues)
2024-09-26 05:17:26 +08:00
#expect(results.count == expectedValues.count)
for (index, expected) in expectedValues.enumerated() {
#expect(results[index].0 == expected.0)
#expect(results[index].1 == expected.1)
}
}
2020-08-29 04:38:56 +08:00
2024-09-26 05:17:26 +08:00
@available(iOS 16.0, macOS 13.0, tvOS 16.0, watchOS 9.0, visionOS 1.0, *)
@Test
func testObserveMultipleKeysCombine() async throws {
let key1 = Defaults.Key<String>("observeKey1", default: "x", suite: suite_)
let key2 = Defaults.Key<Bool>("observeKey2", default: true, suite: suite_)
var count = 0
2024-09-26 05:17:26 +08:00
try await confirmation(expectedCount: 2) { confirmation in
let publisher = Defaults.publisher(keys: key1, key2, options: [])
.sink { _ in
count += 1
confirmation()
}
2020-08-29 04:38:56 +08:00
2024-09-26 05:17:26 +08:00
await Task.yield()
Defaults[key1] = "y"
Defaults[key2] = false
2020-08-29 04:38:56 +08:00
2024-09-26 05:17:26 +08:00
try await Task.sleep(for: .milliseconds(100))
publisher.cancel()
}
2024-09-26 05:17:26 +08:00
#expect(count == 2)
}
2020-08-29 04:38:56 +08:00
2024-09-26 05:17:26 +08:00
@available(iOS 16.0, macOS 13.0, tvOS 16.0, watchOS 9.0, visionOS 1.0, *)
@Test
func testObserveMultipleOptionalKeysCombine() async throws {
let key1 = Defaults.Key<String?>("observeOptionalKey1", suite: suite_)
let key2 = Defaults.Key<Bool?>("observeOptionalKey2", suite: suite_)
var count = 0
2024-09-26 05:17:26 +08:00
try await confirmation(expectedCount: 2) { confirmation in
let publisher = Defaults.publisher(keys: key1, key2, options: [])
.sink { _ in
count += 1
confirmation()
}
2021-01-24 20:50:11 +08:00
2024-09-26 05:17:26 +08:00
await Task.yield()
Defaults[key1] = "x"
Defaults[key2] = false
2020-08-29 04:38:56 +08:00
2024-09-26 05:17:26 +08:00
try await Task.sleep(for: .milliseconds(100))
publisher.cancel()
}
2020-08-29 04:38:56 +08:00
2024-09-26 05:17:26 +08:00
#expect(count == 2)
}
2020-08-29 04:38:56 +08:00
2024-09-26 05:17:26 +08:00
@available(iOS 16.0, macOS 13.0, tvOS 16.0, watchOS 9.0, visionOS 1.0, *)
@Test
func testReceiveValueBeforeSubscriptionCombine() async throws {
let key = Defaults.Key<String>("receiveValueBeforeSubscription", default: "hello", suite: suite_)
2024-09-26 05:17:26 +08:00
try await confirmation(expectedCount: 2) { confirmation in
let publisher = Defaults
.publisher(key)
.map(\.newValue)
.sink { value in
confirmation()
print("Received value: \(value)")
}
2020-08-29 04:38:56 +08:00
2024-09-26 05:17:26 +08:00
// Ensure we're subscribed before changing the value
await Task.yield()
2020-08-29 04:38:56 +08:00
2024-09-26 05:17:26 +08:00
// Change the value
Defaults[key] = "world"
2020-08-29 04:38:56 +08:00
2024-09-26 05:17:26 +08:00
// Keep the subscription alive
try await Task.sleep(for: .milliseconds(100))
2024-09-26 05:17:26 +08:00
publisher.cancel()
}
}
2020-08-29 04:38:56 +08:00
2024-09-26 05:17:26 +08:00
@Test
func testObservePreventPropagationCombine() async throws {
let key1 = Defaults.Key<Bool?>("preventPropagation6", default: nil, suite: suite_)
2020-08-29 04:38:56 +08:00
2024-09-30 18:19:33 +08:00
await confirmation { confirmation in
2024-09-26 05:17:26 +08:00
var wasInside = false
let cancellable = Defaults.publisher(key1, options: []).sink { _ in
#expect(!wasInside)
wasInside = true
Defaults.withoutPropagation {
Defaults[key1] = true
}
2024-09-26 05:17:26 +08:00
confirmation()
}
2020-08-29 04:38:56 +08:00
2024-09-26 05:17:26 +08:00
Defaults[key1] = false
cancellable.cancel()
}
}
2024-09-26 05:17:26 +08:00
@Test
func testObservePreventPropagationMultipleKeysCombine() async throws {
let key1 = Defaults.Key<Bool?>("preventPropagation7", default: nil, suite: suite_)
let key2 = Defaults.Key<Bool?>("preventPropagation8", default: nil, suite: suite_)
2024-09-30 18:19:33 +08:00
await confirmation { confirmation in
2024-09-26 05:17:26 +08:00
var wasInside = false
let cancellable = Defaults.publisher(keys: key1, key2, options: []).sink { _ in
#expect(!wasInside)
wasInside = true
Defaults.withoutPropagation {
Defaults[key1] = true
2022-10-22 01:04:15 +08:00
}
2024-09-26 05:17:26 +08:00
confirmation()
}
2024-09-26 05:17:26 +08:00
Defaults[key2] = false
cancellable.cancel()
}
}
2024-09-26 05:17:26 +08:00
@Test
func testResetKey() {
2020-04-17 22:32:44 +08:00
let defaultFixture1 = "foo1"
let defaultFixture2 = 0
let newFixture1 = "bar1"
let newFixture2 = 1
2024-09-26 05:17:26 +08:00
let key1 = Defaults.Key<String>("key1", default: defaultFixture1, suite: suite_)
let key2 = Defaults.Key<Int>("key2", default: defaultFixture2, suite: suite_)
2020-04-17 22:32:44 +08:00
Defaults[key1] = newFixture1
Defaults[key2] = newFixture2
Defaults.reset(key1)
2024-09-26 05:17:26 +08:00
#expect(Defaults[key1] == defaultFixture1)
#expect(Defaults[key2] == newFixture2)
}
2020-01-21 01:07:30 +08:00
2024-09-26 05:17:26 +08:00
@Test
2020-04-17 22:32:44 +08:00
func testResetMultipleKeys() {
let defaultFxiture1 = "foo1"
let defaultFixture2 = 0
let defaultFixture3 = "foo3"
let newFixture1 = "bar1"
let newFixture2 = 1
let newFixture3 = "bar3"
2024-09-26 05:17:26 +08:00
let key1 = Defaults.Key<String>("akey1", default: defaultFxiture1, suite: suite_)
let key2 = Defaults.Key<Int>("akey2", default: defaultFixture2, suite: suite_)
let key3 = Defaults.Key<String>("akey3", default: defaultFixture3, suite: suite_)
2020-04-17 22:32:44 +08:00
Defaults[key1] = newFixture1
Defaults[key2] = newFixture2
Defaults[key3] = newFixture3
Defaults.reset(key1, key2)
2024-09-26 05:17:26 +08:00
#expect(Defaults[key1] == defaultFxiture1)
#expect(Defaults[key2] == defaultFixture2)
#expect(Defaults[key3] == newFixture3)
}
2020-01-21 01:07:30 +08:00
2024-09-26 05:17:26 +08:00
@Test
2020-04-17 22:32:44 +08:00
func testResetMultipleOptionalKeys() {
let newFixture1 = "bar1"
let newFixture2 = 1
let newFixture3 = "bar3"
2024-09-26 05:17:26 +08:00
let key1 = Defaults.Key<String?>("aoptionalKey1", suite: suite_)
let key2 = Defaults.Key<Int?>("aoptionalKey2", suite: suite_)
let key3 = Defaults.Key<String?>("aoptionalKey3", suite: suite_)
2020-04-17 22:32:44 +08:00
Defaults[key1] = newFixture1
Defaults[key2] = newFixture2
Defaults[key3] = newFixture3
Defaults.reset(key1, key2)
2024-09-26 05:17:26 +08:00
#expect(Defaults[key1] == nil)
#expect(Defaults[key2] == nil)
#expect(Defaults[key3] == newFixture3)
}
2024-09-26 05:17:26 +08:00
@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, visionOS 1.0, *)
@Test
func testImmediatelyFinishingPublisherCombine() async throws {
let key = Defaults.Key<Bool>("observeKey", default: false, suite: suite_)
2024-09-26 05:17:26 +08:00
let result: Void? = try await withThrowingTaskGroup(of: Void.self) { group in
let publisher = Defaults
.publisher(key, options: [.initial])
.first()
2024-09-26 05:17:26 +08:00
group.addTask {
for try await _ in publisher.values {
return
}
}
2024-09-26 05:17:26 +08:00
return try await group.next()
}
2024-09-26 05:17:26 +08:00
#expect(result != nil)
}
2024-09-26 05:17:26 +08:00
@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, visionOS 1.0, *)
@Test
func testImmediatelyFinishingMultiplePublisherCombine() async throws {
let key1 = Defaults.Key<Bool>("observeKey1", default: false, suite: suite_)
let key2 = Defaults.Key<String>("observeKey2", default: "🦄", suite: suite_)
let result: Void? = try await withThrowingTaskGroup(of: Void.self) { group in
let publisher = Defaults
.publisher(keys: [key1, key2], options: [.initial])
.first()
2024-09-26 05:17:26 +08:00
group.addTask {
for try await _ in publisher.values {
return
}
}
2024-09-26 05:17:26 +08:00
return try await group.next()
}
2024-09-26 05:17:26 +08:00
#expect(result != nil)
}
2024-09-26 05:17:26 +08:00
@Test
func testKeyEquatable() {
2024-09-30 18:19:33 +08:00
// swiftlint:disable:next identical_operands
2024-09-26 05:17:26 +08:00
#expect(Defaults.Key<Bool>("equatableKeyTest", default: false, suite: suite_) == Defaults.Key<Bool>("equatableKeyTest", default: false, suite: suite_))
}
2024-09-26 05:17:26 +08:00
@Test
func testKeyHashable() {
2024-09-26 05:17:26 +08:00
_ = Set([Defaults.Key<Bool>("hashableKeyTest", default: false, suite: suite_)])
}
2022-11-18 20:22:02 +08:00
2024-09-26 05:17:26 +08:00
@available(iOS 16.0, macOS 13.0, tvOS 16.0, watchOS 9.0, visionOS 1.0, *)
@Test
2022-11-18 20:22:02 +08:00
func testUpdates() async {
2024-09-26 05:17:26 +08:00
let key = Defaults.Key<Bool>("updatesKey", default: false, suite: suite_)
2022-11-18 20:22:02 +08:00
async let waiter = Defaults.updates(key, initial: false).first { $0 }
2024-05-15 01:59:24 +08:00
try? await Task.sleep(for: .seconds(0.1))
2022-11-18 20:22:02 +08:00
Defaults[key] = true
guard let result = await waiter else {
2024-09-26 05:17:26 +08:00
Issue.record("Failed to get result")
2022-11-18 20:22:02 +08:00
return
}
2024-09-26 05:17:26 +08:00
#expect(result)
2022-11-18 20:22:02 +08:00
}
2024-09-26 05:17:26 +08:00
@available(iOS 16.0, macOS 13.0, tvOS 16.0, watchOS 9.0, visionOS 1.0, *)
@Test
2022-11-18 20:22:02 +08:00
func testUpdatesMultipleKeys() async {
2024-09-26 05:17:26 +08:00
let key1 = Defaults.Key<Bool>("updatesMultipleKey1", default: false, suite: suite_)
let key2 = Defaults.Key<Bool>("updatesMultipleKey2", default: false, suite: suite_)
2022-11-18 20:22:02 +08:00
let counter = Counter()
async let waiter: Void = {
for await _ in Defaults.updates([key1, key2], initial: false) {
await counter.increment()
if await counter.count == 2 {
break
}
}
}()
2024-05-15 01:59:24 +08:00
try? await Task.sleep(for: .seconds(0.1))
2022-11-18 20:22:02 +08:00
Defaults[key1] = true
Defaults[key2] = true
await waiter
let count = await counter.count
2024-09-26 05:17:26 +08:00
#expect(count == 2)
2022-11-18 20:22:02 +08:00
}
@available(iOS 16.0, macOS 13.0, tvOS 16.0, watchOS 9.0, visionOS 1.0, *)
@Test
func testUpdatesMultipleKeysVariadic() async {
let key1 = Defaults.Key<Bool>("updatesMultipleKeyVariadic1", default: false, suite: suite_)
let key2 = Defaults.Key<Bool>("updatesMultipleKeyVariadic2", default: false, suite: suite_)
let counter = Counter()
async let waiter: Void = {
for await (_, _) in Defaults.updates(key1, key2, initial: false) {
await counter.increment()
if await counter.count == 2 {
break
}
}
}()
try? await Task.sleep(for: .seconds(0.1))
Defaults[key1] = true
Defaults[key2] = true
await waiter
let count = await counter.count
#expect(count == 2)
}
2022-11-18 20:22:02 +08:00
}
actor Counter {
private var _count = 0
var count: Int { _count }
func increment() {
_count += 1
}
}
2024-01-18 17:58:06 +08:00
// swiftlint:enable discouraged_optional_boolean