Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 72 additions & 0 deletions test/uts/deviations.md
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,78 @@ These tests assert spec behavior but are skipped by default because they are kno

---

## Adapted Deviations (tests modified to match ably-js behavior)

These tests have been adapted from the UTS spec to account for ably-js API differences. The test still validates the underlying behavior but uses ably-js's actual API surface.

### objects/live_object_subscribe: RTLO4b4d - objectMessage exposed as `.message`

**Spec (RTLO4b4d)**: `LiveObjectUpdate.objectMessage` carries the source ObjectMessage.

**ably-js behavior**: `InstanceSubscriptionEvent` exposes the public ObjectMessage as `.message` (not `.objectMessage`). The operation action is a string (`'counter.inc'`) instead of the internal numeric constant.

**Test**: Adapted to use `updates[0].message` and string action names.

---

### objects/live_object_subscribe: RTLO4b4e - tombstone flag not on InstanceSubscriptionEvent

**Spec (RTLO4b4e)**: `LiveObjectUpdate.tombstone` indicates whether the update was a tombstone.

**ably-js behavior**: `InstanceSubscriptionEvent` does not expose a `tombstone` field. The tombstone behavior (deregistering listeners) works internally, but is not surfaced to the user-facing event.

**Test**: Adapted to verify the event is delivered and check the operation action (`'object.delete'` for tombstone, `'counter.inc'` for normal) instead of asserting `.tombstone`.

---

### objects/live_object_subscribe: RTLO4b4c3c - tombstone flag not checkable

**Spec (RTLO4b4c3c)**: Tombstone update deregisters all listeners, and `update.tombstone == true`.

**ably-js behavior**: Tombstone deregistration works correctly (subsequent events do not fire), but `InstanceSubscriptionEvent` does not expose `.tombstone`. Test adapted to skip the `.tombstone` assertion.

---

### objects/realtime_object: RTO15 - publish result serials not exposed

**Spec (RTO15)**: `publish()` returns `PublishResult` with `.serials`.

**ably-js behavior**: PathObject mutation methods (`increment`, `set`, etc.) return `void` via `publishAndApply`. The `PublishResult.serials` are consumed internally for apply-on-ACK and not returned to the caller.

**Test**: Removed `result.serials` assertion.

---

### objects/realtime_object: RTO25b/RTO26b - channel.object.get() re-attaches on DETACHED

**Spec (RTO25b/RTO26b)**: Access/write API should throw 90001 on DETACHED channel.

**ably-js behavior**: `channel.object.get()` calls `ensureAttached()` which re-attaches for DETACHED. The precondition check (`throwIfInvalidAccessApiConfiguration`) is on PathObject/Instance methods, not on `channel.object.get()`.

**Test**: Adapted to call `root.value()` / `root.set()` instead of `channel.object.get()` to trigger the precondition.

---

### objects/realtime_object: RTO24c1 - depth semantics

**Spec (RTO24c1)**: `depth: 1` covers "root and immediate children".

**ably-js behavior**: Depth counts the subscription level itself as depth 1. So `depth: 2` means "self + direct children" (matching the spec's `depth: 1` semantics). Also, `PathObject.subscribe(listener, options?)` takes listener first, not options first.

**Test**: Adapted to use `depth: 2` and correct argument order.

---

### objects/instance: RTINS16e2 - MAP_SET serial must exceed entry timeserial

**Spec (RTINS16e2)**: Tests InstanceSubscriptionEvent.message from a MAP_SET operation.

**ably-js behavior**: MAP_SET uses LWW conflict resolution with string-compared serials. The test's original serial `'99'` was less than the standard pool entry timeserial `'t:0'` (since `'9' < 't'` in string ordering), causing the operation to be rejected as stale.

**Test**: Adapted to use serial `'t:1'` which sorts after `'t:0'`.

---

## Mock Infrastructure Limitations

### MsgPack encoding/decoding not supported
Expand Down
2 changes: 2 additions & 0 deletions test/uts/mock_websocket.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ const DEFAULT_CONNECTED = {
maxIdleInterval: 15000,
maxMessageSize: 65536,
serverId: 'test-server',
siteCode: 'test',
objectsGCGracePeriod: 86400000,
},
error: null as any,
};
Expand Down
Loading
Loading