Skip to content

Commit 6d0df37

Browse files
Fix MAP_CLEAR subscription test to use sendMapClearOnChannel
Use sendMapClearOnChannel (server round-trip) instead of processObjectOperationMessageOnChannel (synthetic injection), faithfully porting the JS test. Also add `objects` to the SubscriptionCallbacksScenarios context so that tests can call sendMapClearOnChannel. The test now uses the pre-existing sampleMap and sampleCounter keys (set up by the test runner) rather than manually injecting keys. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 5e0438f commit 6d0df37

2 files changed

Lines changed: 21 additions & 35 deletions

File tree

Tests/AblyLiveObjectsTests/JS Integration Tests/ObjectsHelper.swift

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -226,14 +226,16 @@ final class ObjectsHelper: Sendable {
226226
/// This goes through the real publish path (server round-trip) so the operation gets a
227227
/// real server-assigned timeserial.
228228
func sendMapClearOnChannel(objects: any RealtimeObjects, objectId: String) async throws {
229-
let internallyTypedObjects = objects as! PublicDefaultRealtimeObjects
229+
guard let internallyTypedObjects = objects as? PublicDefaultRealtimeObjects else {
230+
preconditionFailure("Expected PublicDefaultRealtimeObjects")
231+
}
230232
try await internallyTypedObjects.testsOnly_publish(objectMessages: [
231233
OutboundObjectMessage(
232234
operation: ObjectOperation(
233235
action: .known(.mapClear),
234236
objectId: objectId,
235-
mapClear: WireMapClear()
236-
)
237+
mapClear: WireMapClear(),
238+
),
237239
),
238240
])
239241
}

Tests/AblyLiveObjectsTests/JS Integration Tests/ObjectsIntegrationTests.swift

Lines changed: 16 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -4223,6 +4223,7 @@ private struct ObjectsIntegrationTests {
42234223
@available(iOS 17.0.0, tvOS 17.0.0, *)
42244224
enum SubscriptionCallbacksScenarios: Scenarios {
42254225
struct Context {
4226+
var objects: any RealtimeObjects
42264227
var root: any LiveMap
42274228
var objectsHelper: ObjectsHelper
42284229
var channelName: String
@@ -4429,48 +4430,30 @@ private struct ObjectsIntegrationTests {
44294430
.init(
44304431
disabled: false,
44314432
allTransportsAndProtocols: false,
4432-
// Deviation from JS: The JS test checks event.message.operation.action === 'map.clear',
4433-
// but Swift's LiveMapUpdate has no operation action field — it only exposes per-key
4434-
// changes via update: [String: LiveMapUpdateAction]. Additionally, the JS test doesn't
4435-
// verify the per-key 'removed' entries in event.update, which is an untested gap.
4436-
// This Swift port checks the per-key .removed entries instead.
4433+
// Deviation from JS: The JS test checks event.message.operation.action === 'map.clear'
4434+
// (operation metadata), but Swift's LiveMapUpdate has no operation action field — it
4435+
// only exposes per-key changes via update: [String: LiveMapUpdateAction]. So instead
4436+
// of checking the operation action, this test verifies that the subscription update
4437+
// contains .removed entries for each key that existed on the map before the clear.
4438+
// This is something the JS test doesn't verify (it only checks operation metadata,
4439+
// not the per-key update entries).
44374440
description: "can subscribe to the incoming MAP_CLEAR operation on a LiveMap",
44384441
action: { ctx in
44394442
let root = ctx.root
4443+
let objects = ctx.objects
44404444
let objectsHelper = ctx.objectsHelper
4441-
let channel = ctx.channel
4442-
4443-
// set some keys on root so the clear has something to remove
4444-
await objectsHelper.processObjectOperationMessageOnChannel(
4445-
channel: channel,
4446-
serial: lexicoTimeserial(seriesId: "aaa", timestamp: 0, counter: 0),
4447-
siteCode: "aaa",
4448-
state: [objectsHelper.mapSetOp(objectId: "root", key: "foo", data: .object(["string": .string("bar")]))],
4449-
)
4450-
await objectsHelper.processObjectOperationMessageOnChannel(
4451-
channel: channel,
4452-
serial: lexicoTimeserial(seriesId: "aaa", timestamp: 1, counter: 0),
4453-
siteCode: "aaa",
4454-
state: [objectsHelper.mapSetOp(objectId: "root", key: "baz", data: .object(["number": .number(NSNumber(value: 42))]))],
4455-
)
44564445

44574446
let updates = try root.updates()
44584447
async let subscriptionPromise: Void = {
44594448
let update = try #require(await updates.first { _ in true })
4460-
// verify per-key removed entries for all keys that existed before the clear
4461-
#expect(update.update["foo"] == .removed, "Check \"foo\" key has .removed action after MAP_CLEAR")
4462-
#expect(update.update["baz"] == .removed, "Check \"baz\" key has .removed action after MAP_CLEAR")
4449+
// verify per-key removed entries for all keys that existed before the clear.
4450+
// the test setup creates sampleMap and sampleCounter on root, so those are
4451+
// the keys that should be removed.
4452+
#expect(update.update[ctx.sampleMapKey] == .removed, "Check \"\(ctx.sampleMapKey)\" key has .removed action after MAP_CLEAR")
4453+
#expect(update.update[ctx.sampleCounterKey] == .removed, "Check \"\(ctx.sampleCounterKey)\" key has .removed action after MAP_CLEAR")
44634454
}()
44644455

4465-
// send MAP_CLEAR.
4466-
// JS uses sendMapClearOnChannel (channel.sendState) which is a private API.
4467-
// Swift uses processObjectOperationMessageOnChannel instead.
4468-
await objectsHelper.processObjectOperationMessageOnChannel(
4469-
channel: channel,
4470-
serial: lexicoTimeserial(seriesId: "zzz", timestamp: 99_999_999_999_999, counter: 0),
4471-
siteCode: "zzz",
4472-
state: [objectsHelper.mapClearOp(objectId: "root")],
4473-
)
4456+
try await objectsHelper.sendMapClearOnChannel(objects: objects, objectId: "root")
44744457

44754458
try await subscriptionPromise
44764459
},
@@ -4743,6 +4726,7 @@ private struct ObjectsIntegrationTests {
47434726

47444727
try await testCase.scenario.action(
47454728
.init(
4729+
objects: objects,
47464730
root: root,
47474731
objectsHelper: objectsHelper,
47484732
channelName: testCase.channelName,

0 commit comments

Comments
 (0)