Skip to content

uts: port LiveObjects unit-test harness helpers into infra/unit - #2233

Open
maratal wants to merge 3 commits into
integration/liveobjects-sync-with-mainfrom
integration/liveobjects-uts-unit-helpers
Open

uts: port LiveObjects unit-test harness helpers into infra/unit#2233
maratal wants to merge 3 commits into
integration/liveobjects-sync-with-mainfrom
integration/liveobjects-uts-unit-helpers

Conversation

@maratal

@maratal maratal commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

Stacked on top of #2232 (integration/liveobjects-sync-with-main).

Summary

Brings the LiveObjects UTS unit-test harness into ably-cocoa's Test/UTS/infra/unit, so the objects UTS module's unit tests can be generated by the uts-to-swift skill without also generating harness code — the skill only emits test files.

This is a faithful, file-by-file port of the harness changes from ably-liveobjects-swift-plugin PR #135 (commit 9009067), applied onto ably-cocoa's existing UTS harness. The plugin's changes are applied verbatim; ably-cocoa's pre-existing extras are preserved.

Changes

Package.swift

  • Add AblyLiveObjects to the UTS test target's dependencies (the harness now references the plugin's types).

Test/UTS/infra/unit/ProtocolMessage.swift — apply the plugin's hunks:

  • OBJECT / OBJECT_SYNC / DETACHED / channel-ERROR message builders.
  • HAS_OBJECTS attach flag, connection-details siteCode / objectsGCGracePeriod, and ACK res serials.
  • Object state is delivered to ARTProtocolMessage.state via KVC as the plugin's ObjectMessageBox boxes.
  • (Kept ably-cocoa's existing connectedMessage.)

Test/UTS/infra/unit/MockWebSocket.swift — apply the plugin's hunks:

  • The onMessageFromClient hook, sentFrames, and provider wiring (used by setup_synced_channel to answer ATTACH with ATTACHED+OBJECT_SYNC and to auto-ACK OBJECT publishes).
  • (Kept ably-cocoa's existing parseQueryParams and respondWithSuccess(_:).)

Test/UTS/infra/unit/StandardTestPool.swift (new) — canonical object-tree fixtures + OBJECT/OBJECT_SYNC message builders (uts/objects/helpers/standard_test_pool.md). Verbatim from the plugin.

Test/UTS/infra/unit/UTSTestCase+LiveObjects.swift (new) — the setup_synced_channel pattern (connected client + synced objects channel via the mock) and sent-operation inspection. Verbatim from the plugin.

Notes

  • No objects tests are added here — only the harness. The tests come next, via the uts-to-swift skill.
  • The Instance+Testing.swift helper from the plugin is intentionally not included.

Verification

  • Clean build (swift package clean + swift build --build-tests) — succeeds.
  • Core UTS unit tests (ConnectionRecoveryTests, TimeTests) — 11/11 pass; the shared harness is unaffected.

🤖 Generated with Claude Code

@coderabbitai

coderabbitai Bot commented Jul 30, 2026

Copy link
Copy Markdown

Review Change Stack

Walkthrough

The UTS target now depends on AblyLiveObjects and includes protocol, fixture, mock WebSocket, and test-case helpers for simulating LiveObjects synchronization, operations, acknowledgements, and inbound messages.

Changes

LiveObjects UTS infrastructure

Layer / File(s) Summary
Protocol messages and standard fixtures
Package.swift, Test/UTS/infra/unit/ProtocolMessage.swift, Test/UTS/infra/unit/StandardTestPool.swift
The UTS target adds the LiveObjects dependency; protocol builders support object events and state; StandardTestPool supplies reusable object states and operations.
Mock WebSocket message routing
Test/UTS/infra/unit/MockWebSocket.swift
The mock WebSocket records raw frames and routes decoded client messages to provider callbacks.
LiveObjects channel test helpers
Test/UTS/infra/unit/UTSTestCase+LiveObjects.swift
UTS helpers create mocked objects channels, inject synchronization and object messages, auto-acknowledge publications, and decode outbound operations.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Possibly related PRs

Poem

A rabbit hops through objects bright,
Syncing maps from left to right.
Frames are caught and ACKs take flight,
Mocked channels bloom overnight.
Hop, hop—tests now know the way!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: porting LiveObjects unit-test harness helpers into infra/unit.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch integration/liveobjects-uts-unit-helpers

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions
github-actions Bot temporarily deployed to staging/pull/2233/features July 30, 2026 12:44 Inactive
@github-actions
github-actions Bot temporarily deployed to staging/pull/2233/AblyLiveObjects July 30, 2026 12:45 Inactive
@github-actions
github-actions Bot temporarily deployed to staging/pull/2233/jazzydoc July 30, 2026 12:47 Inactive
@github-actions
github-actions Bot temporarily deployed to staging/pull/2233/markdown-api-reference July 30, 2026 12:47 Inactive
maratal and others added 3 commits July 30, 2026 21:10
The UTS harness references the LiveObjects plugin's types (ProtocolTypes,
DefaultInternalPlugin.ObjectMessageBox) for the `objects` module, so the UTS
target must link against AblyLiveObjects.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Apply the harness changes from ably-liveobjects-swift-plugin PR #135
(commit 9009067) to the UTS unit mock:

- ProtocolMessage: OBJECT / OBJECT_SYNC / DETACHED / channel-ERROR builders,
  the HAS_OBJECTS attach flag, connection-details siteCode/objectsGCGracePeriod,
  and ack `res` serials. Object state is delivered to ARTProtocolMessage.state
  via KVC as the plugin's ObjectMessageBox boxes.
- MockWebSocket: the onMessageFromClient hook, sentFrames, and provider wiring
  (used by setup_synced_channel to answer ATTACH with ATTACHED+OBJECT_SYNC and
  to auto-ACK OBJECT publishes).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…nced_channel)

Port the LiveObjects UTS helpers from ably-liveobjects-swift-plugin PR #135
(commit 9009067) into Test/UTS/infra/unit:

- StandardTestPool: canonical object-tree fixtures and OBJECT/OBJECT_SYNC
  message builders (uts/objects/helpers/standard_test_pool.md).
- UTSTestCase+LiveObjects: the setup_synced_channel pattern (connected client +
  synced objects channel via the mock) and sent-operation inspection.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@Test/UTS/infra/unit/UTSTestCase`+LiveObjects.swift:
- Around line 90-109: Add derived LiveObjects UTS tests that exercise the
channel setup and protocol helpers introduced by this change. In
Test/UTS/infra/unit/UTSTestCase+LiveObjects.swift lines 18-89 and 90-109, cover
objectsChannel, setupSyncedChannel, sentObjectOperations, and StandardTestPool
behavior; in Test/UTS/infra/unit/ProtocolMessage.swift lines 113-130 and
154-169, add assertions covering the ProtocolMessage helpers. Ensure the tests
validate LiveObjects channel flow, sent operation decoding, and relevant
protocol-message behavior rather than only compiling the private APIs.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 71e68f07-4f76-48d2-8a67-46e06d037f21

📥 Commits

Reviewing files that changed from the base of the PR and between c23859e and c2277a7.

📒 Files selected for processing (5)
  • Package.swift
  • Test/UTS/infra/unit/MockWebSocket.swift
  • Test/UTS/infra/unit/ProtocolMessage.swift
  • Test/UTS/infra/unit/StandardTestPool.swift
  • Test/UTS/infra/unit/UTSTestCase+LiveObjects.swift

Comment on lines +90 to +109
func sentObjectOperations(_ ws: MockWebSocketProvider) throws -> [WireObjectOperation] {
guard let connection = ws.activeConnection else { return [] }
var operations: [WireObjectOperation] = []
for frame in connection.sentFrames {
guard let root = try? JSONSerialization.jsonObject(with: frame) as? [String: Any],
(root["action"] as? Int) == WireAction.object,
let state = root["state"] as? [[String: Any]] else { continue }
for objectMessage in state {
guard let operationData = objectMessage["operation"] as? [String: Any] else { continue }
// Decode the operation directly into its wire type. We don't route through
// `InboundWireObjectMessage`: these are messages the client *sent*, so the inbound
// decoder (and its `DecodingContext`, which drives inbound synthetic-ID rules) would
// be the wrong direction. `WireObjectOperation` is `WireObjectCodable`, and its wire
// form is direction-agnostic and retains the outbound-only `*WithObjectId` fields.
let wireOperation = WireValue.objectFromPluginSupportData(operationData)
operations.append(try WireObjectOperation(wireObject: wireOperation))
}
}
return operations
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== repo files of interest =="
git ls-files | rg 'Test/UTS/infra/unit/(UTSTestCase\+LiveObjects|ProtocolMessage)\.(swift|swift\.mm)$|README|Package|Pod|Cartfile|Cartfile\.resolved|package\.json|tsconfig|Makefile|script|\.github/workflows' || true

echo
echo "== changed files/stat =="
git diff --stat HEAD~1..HEAD 2>/dev/null || git diff --stat || true

echo
echo "== target files outline/sections =="
if [ -f Test/UTS/infra/unit/UTSTestCase+LiveObjects.swift ]; then
  wc -l Test/UTS/infra/unit/UTSTestCase+LiveObjects.swift
  sed -n '1,240p' Test/UTS/infra/unit/UTSTestCase+LiveObjects.swift | cat -n
fi
echo
if [ -f Test/UTS/infra/unit/ProtocolMessage.swift ]; then
  wc -l Test/UTS/infra/unit/ProtocolMessage.swift
  sed -n '1,230p' Test/UTS/infra/unit/ProtocolMessage.swift | cat -n
fi

echo
echo "== search for objects/UTS/live objects/test mentions =="
rg -n "objects|LiveObjects|objectSync|sentObjectOperations|setupSyncedChannel|no [Oo]bjects|No [Oo]bjects|AblyLiveObjects|WireObjectOperation|JSONSerialization|default binary|useBinaryProtocol" --glob '*.swift' --glob '*.md' --glob 'Makefile' --glob 'README*' --glob '.github/**' | head -n 240

Repository: ably/ably-cocoa

Length of output: 20414


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== UTS README mentions =="
sed -n '1,260p' Test/UTS/README.md | cat -n

echo
echo "== LiveObjects README mentions =="
sed -n '1,260p' LiveObjects/README.md | cat -n

echo
echo "== Makefile pytest/uts/test commands =="
rg -n "pytest|uts|unit|test|objects|LiveObjects|objects\." Makefile Test/UTS/README.md LiveObjects/README.md README.md | head -n 200

echo
echo "== Search test invocations and object test files =="
git ls-files | rg -n '(\.py$|Makefile|README|README\.md)$' | xargs -r rg -n "objects|LiveObjects|setup_synced_channel|capture|standard_test_pool|objects\." | head -n 300

echo
echo "== ProtocolMessage references =="
rg -n "makeProtocolMessage|ProtocolMessage\(" --glob '*.swift' Test Source | head -n 200

echo
echo "== MockWebSocket definitions/capture =="
rg -n "struct MockWebSocket|class MockWebSocket|sentFrames|activeConnection|sendToClient" --glob '*.swift' Test Source | head -n 200

Repository: ably/ably-cocoa

Length of output: 48039


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== MockWebSocket implementations =="
fd -a 'MockWebSocket.swift|ProtocolMessage.swift|UTSTestCase.swift' Test/UTS/infra/unit -x sh -c 'echo "--- $1"; wc -l "$1"; sed -n "1,260p" "$1"' sh {}

echo
echo "== Search for LiveObjects UTS-derived identifiers across repo =="
rg -n "`@Test`|func .*objects|objectsChannel|setupSyncedChannel|sentObjectOperations|capture|StandardTestPool|LiveObjects|useBinaryProtocol|json.*format|binary" --glob '*.swift' --glob '*.md' --glob 'Makefile' --glob 'Package.swift' Test Source LiveObjects | head -n 400

echo
echo "== Check for `@Test` in LiveObjects helper file exactly =="
python3 - <<'PY'
from pathlib import Path
p = Path('Test/UTS/infra/unit/UTSTestCase+LiveObjects.swift')
if p.exists():
    text = p.read_text(encoding='utf-8')
    print('`@Test` occurrences:', text.count('`@Test`'))
    print('sendObjectOperations calls:', text.count('sentObjectOperations'))
else:
    print("missing")
PY

Repository: ably/ably-cocoa

Length of output: 50371


Add exercising tests for the LiveObjects UTS harness. This PR introduces objectsChannel, setupSyncedChannel, sentObjectOperations, ProtocolMessage helpers, and StandardTestPool, but no derived tests exercise the LiveObjects channel flow. The UTS guide documents infra/* as containing no @Tests, and the current UTS target has no LiveObjects-derived assertions, so these private-API/protocol assumptions can’t be caught until a later LiveObjects test hits them.

📍 Affects 2 files
  • Test/UTS/infra/unit/UTSTestCase+LiveObjects.swift#L90-L109 (this comment)
  • Test/UTS/infra/unit/UTSTestCase+LiveObjects.swift#L18-L89
  • Test/UTS/infra/unit/ProtocolMessage.swift#L113-L130
  • Test/UTS/infra/unit/ProtocolMessage.swift#L154-L169
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@Test/UTS/infra/unit/UTSTestCase`+LiveObjects.swift around lines 90 - 109, Add
derived LiveObjects UTS tests that exercise the channel setup and protocol
helpers introduced by this change. In
Test/UTS/infra/unit/UTSTestCase+LiveObjects.swift lines 18-89 and 90-109, cover
objectsChannel, setupSyncedChannel, sentObjectOperations, and StandardTestPool
behavior; in Test/UTS/infra/unit/ProtocolMessage.swift lines 113-130 and
154-169, add assertions covering the ProtocolMessage helpers. Ensure the tests
validate LiveObjects channel flow, sent operation decoding, and relevant
protocol-message behavior rather than only compiling the private APIs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant