uts: port LiveObjects unit-test harness helpers into infra/unit - #2233
uts: port LiveObjects unit-test harness helpers into infra/unit#2233maratal wants to merge 3 commits into
Conversation
WalkthroughThe UTS target now depends on ChangesLiveObjects UTS infrastructure
Estimated code review effort: 3 (Moderate) | ~25 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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. Comment |
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>
28aa9bd to
c2277a7
Compare
There was a problem hiding this comment.
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
📒 Files selected for processing (5)
Package.swiftTest/UTS/infra/unit/MockWebSocket.swiftTest/UTS/infra/unit/ProtocolMessage.swiftTest/UTS/infra/unit/StandardTestPool.swiftTest/UTS/infra/unit/UTSTestCase+LiveObjects.swift
| 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 | ||
| } |
There was a problem hiding this comment.
🎯 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 240Repository: 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 200Repository: 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")
PYRepository: 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-L89Test/UTS/infra/unit/ProtocolMessage.swift#L113-L130Test/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.
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 theobjectsUTS module's unit tests can be generated by theuts-to-swiftskill 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-pluginPR #135 (commit9009067), 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.swiftAblyLiveObjectsto theUTStest 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-ERRORmessage builders.HAS_OBJECTSattach flag, connection-detailssiteCode/objectsGCGracePeriod, andACKresserials.ARTProtocolMessage.statevia KVC as the plugin'sObjectMessageBoxboxes.connectedMessage.)Test/UTS/infra/unit/MockWebSocket.swift— apply the plugin's hunks:onMessageFromClienthook,sentFrames, and provider wiring (used bysetup_synced_channelto answerATTACHwithATTACHED+OBJECT_SYNCand to auto-ACKOBJECTpublishes).parseQueryParamsandrespondWithSuccess(_:).)Test/UTS/infra/unit/StandardTestPool.swift(new) — canonical object-tree fixtures +OBJECT/OBJECT_SYNCmessage builders (uts/objects/helpers/standard_test_pool.md). Verbatim from the plugin.Test/UTS/infra/unit/UTSTestCase+LiveObjects.swift(new) — thesetup_synced_channelpattern (connected client + synced objects channel via the mock) and sent-operation inspection. Verbatim from the plugin.Notes
objectstests are added here — only the harness. The tests come next, via theuts-to-swiftskill.Instance+Testing.swifthelper from the plugin is intentionally not included.Verification
swift package clean+swift build --build-tests) — succeeds.ConnectionRecoveryTests,TimeTests) — 11/11 pass; the shared harness is unaffected.🤖 Generated with Claude Code