Skip to content

Commit a4cc108

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 e2510e7 commit a4cc108

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
@@ -4148,6 +4148,7 @@ private struct ObjectsIntegrationTests {
41484148
@available(iOS 17.0.0, tvOS 17.0.0, *)
41494149
enum SubscriptionCallbacksScenarios: Scenarios {
41504150
struct Context {
4151+
var objects: any RealtimeObjects
41514152
var root: any LiveMap
41524153
var objectsHelper: ObjectsHelper
41534154
var channelName: String
@@ -4354,48 +4355,30 @@ private struct ObjectsIntegrationTests {
43544355
.init(
43554356
disabled: false,
43564357
allTransportsAndProtocols: false,
4357-
// Deviation from JS: The JS test checks event.message.operation.action === 'map.clear',
4358-
// but Swift's LiveMapUpdate has no operation action field — it only exposes per-key
4359-
// changes via update: [String: LiveMapUpdateAction]. Additionally, the JS test doesn't
4360-
// verify the per-key 'removed' entries in event.update, which is an untested gap.
4361-
// This Swift port checks the per-key .removed entries instead.
4358+
// Deviation from JS: The JS test checks event.message.operation.action === 'map.clear'
4359+
// (operation metadata), but Swift's LiveMapUpdate has no operation action field — it
4360+
// only exposes per-key changes via update: [String: LiveMapUpdateAction]. So instead
4361+
// of checking the operation action, this test verifies that the subscription update
4362+
// contains .removed entries for each key that existed on the map before the clear.
4363+
// This is something the JS test doesn't verify (it only checks operation metadata,
4364+
// not the per-key update entries).
43624365
description: "can subscribe to the incoming MAP_CLEAR operation on a LiveMap",
43634366
action: { ctx in
43644367
let root = ctx.root
4368+
let objects = ctx.objects
43654369
let objectsHelper = ctx.objectsHelper
4366-
let channel = ctx.channel
4367-
4368-
// set some keys on root so the clear has something to remove
4369-
await objectsHelper.processObjectOperationMessageOnChannel(
4370-
channel: channel,
4371-
serial: lexicoTimeserial(seriesId: "aaa", timestamp: 0, counter: 0),
4372-
siteCode: "aaa",
4373-
state: [objectsHelper.mapSetOp(objectId: "root", key: "foo", data: .object(["string": .string("bar")]))],
4374-
)
4375-
await objectsHelper.processObjectOperationMessageOnChannel(
4376-
channel: channel,
4377-
serial: lexicoTimeserial(seriesId: "aaa", timestamp: 1, counter: 0),
4378-
siteCode: "aaa",
4379-
state: [objectsHelper.mapSetOp(objectId: "root", key: "baz", data: .object(["number": .number(NSNumber(value: 42))]))],
4380-
)
43814370

43824371
let updates = try root.updates()
43834372
async let subscriptionPromise: Void = {
43844373
let update = try #require(await updates.first { _ in true })
4385-
// verify per-key removed entries for all keys that existed before the clear
4386-
#expect(update.update["foo"] == .removed, "Check \"foo\" key has .removed action after MAP_CLEAR")
4387-
#expect(update.update["baz"] == .removed, "Check \"baz\" key has .removed action after MAP_CLEAR")
4374+
// verify per-key removed entries for all keys that existed before the clear.
4375+
// the test setup creates sampleMap and sampleCounter on root, so those are
4376+
// the keys that should be removed.
4377+
#expect(update.update[ctx.sampleMapKey] == .removed, "Check \"\(ctx.sampleMapKey)\" key has .removed action after MAP_CLEAR")
4378+
#expect(update.update[ctx.sampleCounterKey] == .removed, "Check \"\(ctx.sampleCounterKey)\" key has .removed action after MAP_CLEAR")
43884379
}()
43894380

4390-
// send MAP_CLEAR.
4391-
// JS uses sendMapClearOnChannel (channel.sendState) which is a private API.
4392-
// Swift uses processObjectOperationMessageOnChannel instead.
4393-
await objectsHelper.processObjectOperationMessageOnChannel(
4394-
channel: channel,
4395-
serial: lexicoTimeserial(seriesId: "zzz", timestamp: 99_999_999_999_999, counter: 0),
4396-
siteCode: "zzz",
4397-
state: [objectsHelper.mapClearOp(objectId: "root")],
4398-
)
4381+
try await objectsHelper.sendMapClearOnChannel(objects: objects, objectId: "root")
43994382

44004383
try await subscriptionPromise
44014384
},
@@ -4668,6 +4651,7 @@ private struct ObjectsIntegrationTests {
46684651

46694652
try await testCase.scenario.action(
46704653
.init(
4654+
objects: objects,
46714655
root: root,
46724656
objectsHelper: objectsHelper,
46734657
channelName: testCase.channelName,

0 commit comments

Comments
 (0)