Skip to content

Commit fd0db23

Browse files
Fix nullability and default values of common LiveObject properties
This is based on the values stated in RTOL3 of [1] at 29276a5. (We'll formalise the fact that these are common LiveObject properties in an upcoming commit.) [1] ably/specification#343
1 parent 8d881e2 commit fd0db23

File tree

6 files changed

+111
-68
lines changed

6 files changed

+111
-68
lines changed

Sources/AblyLiveObjects/Internal/DefaultLiveCounter.swift

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,19 @@ internal final class DefaultLiveCounter: LiveCounter {
88

99
private nonisolated(unsafe) var mutableState: MutableState
1010

11-
internal var testsOnly_siteTimeserials: [String: String]? {
11+
internal var testsOnly_siteTimeserials: [String: String] {
1212
mutex.withLock {
1313
mutableState.siteTimeserials
1414
}
1515
}
1616

17-
internal var testsOnly_createOperationIsMerged: Bool? {
17+
internal var testsOnly_createOperationIsMerged: Bool {
1818
mutex.withLock {
1919
mutableState.createOperationIsMerged
2020
}
2121
}
2222

23-
internal var testsOnly_objectID: String? {
23+
internal var testsOnly_objectID: String {
2424
mutex.withLock {
2525
mutableState.objectID
2626
}
@@ -32,15 +32,15 @@ internal final class DefaultLiveCounter: LiveCounter {
3232

3333
internal convenience init(
3434
testsOnly_data data: Double,
35-
objectID: String?,
35+
objectID: String,
3636
coreSDK: CoreSDK
3737
) {
3838
self.init(data: data, objectID: objectID, coreSDK: coreSDK)
3939
}
4040

4141
private init(
4242
data: Double,
43-
objectID: String?,
43+
objectID: String,
4444
coreSDK: CoreSDK
4545
) {
4646
mutableState = .init(data: data, objectID: objectID)
@@ -52,7 +52,7 @@ internal final class DefaultLiveCounter: LiveCounter {
5252
/// - Parameters:
5353
/// - objectID: The value for the "private objectId field" of RTO5c1b1a.
5454
internal static func createZeroValued(
55-
objectID: String? = nil,
55+
objectID: String,
5656
coreSDK: CoreSDK,
5757
) -> Self {
5858
.init(
@@ -123,13 +123,13 @@ internal final class DefaultLiveCounter: LiveCounter {
123123
internal var data: Double
124124

125125
/// The site timeserials for this counter, per RTLC6a.
126-
internal var siteTimeserials: [String: String]?
126+
internal var siteTimeserials: [String: String] = [:]
127127

128128
/// Whether the create operation has been merged, per RTLC6b and RTLC6d2.
129-
internal var createOperationIsMerged: Bool?
129+
internal var createOperationIsMerged = false
130130

131131
/// The "private `objectId` field" of RTO5c1b1a.
132-
internal var objectID: String?
132+
internal var objectID: String
133133

134134
/// Replaces the internal data of this counter with the provided ObjectState, per RTLC6.
135135
internal mutating func replaceData(using state: ObjectState) {

Sources/AblyLiveObjects/Internal/DefaultLiveMap.swift

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ internal final class DefaultLiveMap: LiveMap {
1919
}
2020
}
2121

22-
internal var testsOnly_objectID: String? {
22+
internal var testsOnly_objectID: String {
2323
mutex.withLock {
2424
mutableState.objectID
2525
}
@@ -31,13 +31,13 @@ internal final class DefaultLiveMap: LiveMap {
3131
}
3232
}
3333

34-
internal var testsOnly_siteTimeserials: [String: String]? {
34+
internal var testsOnly_siteTimeserials: [String: String] {
3535
mutex.withLock {
3636
mutableState.siteTimeserials
3737
}
3838
}
3939

40-
internal var testsOnly_createOperationIsMerged: Bool? {
40+
internal var testsOnly_createOperationIsMerged: Bool {
4141
mutex.withLock {
4242
mutableState.createOperationIsMerged
4343
}
@@ -55,7 +55,7 @@ internal final class DefaultLiveMap: LiveMap {
5555

5656
internal convenience init(
5757
testsOnly_data data: [String: ObjectsMapEntry],
58-
objectID: String? = nil,
58+
objectID: String,
5959
testsOnly_semantics semantics: WireEnum<ObjectsMapSemantics>? = nil,
6060
delegate: LiveMapObjectPoolDelegate?,
6161
coreSDK: CoreSDK
@@ -71,7 +71,7 @@ internal final class DefaultLiveMap: LiveMap {
7171

7272
private init(
7373
data: [String: ObjectsMapEntry],
74-
objectID: String?,
74+
objectID: String,
7575
semantics: WireEnum<ObjectsMapSemantics>?,
7676
delegate: LiveMapObjectPoolDelegate?,
7777
coreSDK: CoreSDK
@@ -87,7 +87,7 @@ internal final class DefaultLiveMap: LiveMap {
8787
/// - objectID: The value to use for the "private `objectId` field" of RTO5c1b1b.
8888
/// - semantics: The value to use for the "private `semantics` field" of RTO5c1b1b.
8989
internal static func createZeroValued(
90-
objectID: String? = nil,
90+
objectID: String,
9191
semantics: WireEnum<ObjectsMapSemantics>? = nil,
9292
delegate: LiveMapObjectPoolDelegate?,
9393
coreSDK: CoreSDK,
@@ -275,16 +275,16 @@ internal final class DefaultLiveMap: LiveMap {
275275
internal var data: [String: ObjectsMapEntry]
276276

277277
/// The "private `objectId` field" of RTO5c1b1b.
278-
internal var objectID: String?
278+
internal var objectID: String
279279

280280
/// The "private `semantics` field" of RTO5c1b1b.
281281
internal var semantics: WireEnum<ObjectsMapSemantics>?
282282

283283
/// The site timeserials for this map, per RTLM6a.
284-
internal var siteTimeserials: [String: String]?
284+
internal var siteTimeserials: [String: String] = [:]
285285

286286
/// Whether the create operation has been merged, per RTLM6b and RTLM6d2.
287-
internal var createOperationIsMerged: Bool?
287+
internal var createOperationIsMerged = false
288288

289289
/// Replaces the internal data of this map with the provided ObjectState, per RTLM6.
290290
///

Sources/AblyLiveObjects/Internal/ObjectsPool.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ internal struct ObjectsPool {
6060
) {
6161
entries = otherEntries ?? [:]
6262
// TODO: What initial root entry to use? https://github.com/ably/specification/pull/333/files#r2152312933
63-
entries[Self.rootKey] = .map(.createZeroValued(delegate: rootDelegate, coreSDK: rootCoreSDK))
63+
entries[Self.rootKey] = .map(.createZeroValued(objectID: Self.rootKey, delegate: rootDelegate, coreSDK: rootCoreSDK))
6464
}
6565

6666
// MARK: - Typed root

Tests/AblyLiveObjectsTests/DefaultLiveCounterTests.swift

Lines changed: 28 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ struct DefaultLiveCounterTests {
99
// @spec RTLC5b
1010
@Test(arguments: [.detached, .failed] as [ARTRealtimeChannelState])
1111
func valueThrowsIfChannelIsDetachedOrFailed(channelState: ARTRealtimeChannelState) async throws {
12-
let counter = DefaultLiveCounter.createZeroValued(coreSDK: MockCoreSDK(channelState: channelState))
12+
let counter = DefaultLiveCounter.createZeroValued(objectID: "arbitrary", coreSDK: MockCoreSDK(channelState: channelState))
1313

1414
#expect {
1515
_ = try counter.value
@@ -25,7 +25,7 @@ struct DefaultLiveCounterTests {
2525
// @spec RTLC5c
2626
@Test
2727
func valueReturnsCurrentDataWhenChannelIsValid() throws {
28-
let counter = DefaultLiveCounter.createZeroValued(coreSDK: MockCoreSDK(channelState: .attached))
28+
let counter = DefaultLiveCounter.createZeroValued(objectID: "arbitrary", coreSDK: MockCoreSDK(channelState: .attached))
2929

3030
// Set some test data
3131
counter.replaceData(using: TestFactories.counterObjectState(count: 42))
@@ -39,7 +39,7 @@ struct DefaultLiveCounterTests {
3939
// @spec RTLC6a
4040
@Test
4141
func replacesSiteTimeserials() {
42-
let counter = DefaultLiveCounter.createZeroValued(coreSDK: MockCoreSDK(channelState: .attaching))
42+
let counter = DefaultLiveCounter.createZeroValued(objectID: "arbitrary", coreSDK: MockCoreSDK(channelState: .attaching))
4343
let state = TestFactories.counterObjectState(
4444
siteTimeserials: ["site1": "ts1"], // Test value
4545
)
@@ -52,18 +52,35 @@ struct DefaultLiveCounterTests {
5252
// @spec RTLC6b - Tests the case without createOp, as RTLC6d2 takes precedence when createOp exists
5353
@Test
5454
func setsCreateOperationIsMergedToFalse() {
55-
let counter = DefaultLiveCounter.createZeroValued(coreSDK: MockCoreSDK(channelState: .attaching))
55+
// Given: A counter whose createOperationIsMerged is true
56+
let counter = {
57+
let counter = DefaultLiveCounter.createZeroValued(objectID: "arbitrary", coreSDK: MockCoreSDK(channelState: .attaching))
58+
// Test setup: Manipulate counter so that its createOperationIsMerged gets set to true (we need to do this since we want to later assert that it gets set to false, but the default is false).
59+
let state = TestFactories.counterObjectState(
60+
createOp: TestFactories.objectOperation(
61+
action: .known(.counterCreate),
62+
),
63+
)
64+
counter.replaceData(using: state)
65+
#expect(counter.testsOnly_createOperationIsMerged)
66+
67+
return counter
68+
}()
69+
70+
// When:
5671
let state = TestFactories.counterObjectState(
5772
createOp: nil, // Test value - must be nil to test RTLC6b
5873
)
5974
counter.replaceData(using: state)
60-
#expect(counter.testsOnly_createOperationIsMerged == false)
75+
76+
// Then:
77+
#expect(!counter.testsOnly_createOperationIsMerged)
6178
}
6279

6380
// @specOneOf(1/4) RTLC6c - count but no createOp
6481
@Test
6582
func setsDataToCounterCount() throws {
66-
let counter = DefaultLiveCounter.createZeroValued(coreSDK: MockCoreSDK(channelState: .attaching))
83+
let counter = DefaultLiveCounter.createZeroValued(objectID: "arbitrary", coreSDK: MockCoreSDK(channelState: .attaching))
6784
let state = TestFactories.counterObjectState(
6885
count: 42, // Test value
6986
)
@@ -74,7 +91,7 @@ struct DefaultLiveCounterTests {
7491
// @specOneOf(2/4) RTLC6c - no count, no createOp
7592
@Test
7693
func setsDataToZeroWhenCounterCountDoesNotExist() throws {
77-
let counter = DefaultLiveCounter.createZeroValued(coreSDK: MockCoreSDK(channelState: .attaching))
94+
let counter = DefaultLiveCounter.createZeroValued(objectID: "arbitrary", coreSDK: MockCoreSDK(channelState: .attaching))
7895
counter.replaceData(using: TestFactories.counterObjectState(
7996
count: nil, // Test value - must be nil
8097
))
@@ -88,7 +105,7 @@ struct DefaultLiveCounterTests {
88105
// @specOneOf(3/4) RTLC6c - count and createOp
89106
@Test
90107
func setsDataToCounterCountThenAddsCreateOpCounterCount() throws {
91-
let counter = DefaultLiveCounter.createZeroValued(coreSDK: MockCoreSDK(channelState: .attaching))
108+
let counter = DefaultLiveCounter.createZeroValued(objectID: "arbitrary", coreSDK: MockCoreSDK(channelState: .attaching))
92109
let state = TestFactories.counterObjectState(
93110
createOp: TestFactories.counterCreateOperation(count: 10), // Test value - must exist
94111
count: 5, // Test value - must exist
@@ -101,7 +118,7 @@ struct DefaultLiveCounterTests {
101118
// @specOneOf(4/4) RTLC6c - no count but createOp
102119
@Test
103120
func doesNotModifyDataWhenCreateOpCounterCountDoesNotExist() throws {
104-
let counter = DefaultLiveCounter.createZeroValued(coreSDK: MockCoreSDK(channelState: .attaching))
121+
let counter = DefaultLiveCounter.createZeroValued(objectID: "arbitrary", coreSDK: MockCoreSDK(channelState: .attaching))
105122
let state = TestFactories.counterObjectState(
106123
createOp: TestFactories.objectOperation(
107124
action: .known(.counterCreate),
@@ -116,14 +133,14 @@ struct DefaultLiveCounterTests {
116133
// @spec RTLC6d2
117134
@Test
118135
func setsCreateOperationIsMergedToTrue() {
119-
let counter = DefaultLiveCounter.createZeroValued(coreSDK: MockCoreSDK(channelState: .attaching))
136+
let counter = DefaultLiveCounter.createZeroValued(objectID: "arbitrary", coreSDK: MockCoreSDK(channelState: .attaching))
120137
let state = TestFactories.counterObjectState(
121138
createOp: TestFactories.objectOperation( // Test value - must be non-nil
122139
action: .known(.counterCreate),
123140
),
124141
)
125142
counter.replaceData(using: state)
126-
#expect(counter.testsOnly_createOperationIsMerged == true)
143+
#expect(counter.testsOnly_createOperationIsMerged)
127144
}
128145
}
129146
}

0 commit comments

Comments
 (0)