Skip to content

[AIT-1231][LiveObjects] Enable UTS integration test suites (17/17 objects tier passing) - #2235

Merged
sacOO7 merged 11 commits into
feature/liveobjects-implementationfrom
feature/liveobjects-uts-integration-tests
Aug 6, 2026
Merged

[AIT-1231][LiveObjects] Enable UTS integration test suites (17/17 objects tier passing) #2235
sacOO7 merged 11 commits into
feature/liveobjects-implementationfrom
feature/liveobjects-uts-integration-tests

Conversation

@sacOO7

@sacOO7 sacOO7 commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

Summary

This PR enables the UTS integration test suites for LiveObjects, originally translated from the UTS integration specs in #2226. When that PR was authored, the path-based API was a compile-only skeleton, so its suites carried a .disabled("Compile-only until the implementation lands") trait. The implementation has now landed on the base branch (feature/liveobjects-implementation), and these tests run — and pass — exactly as originally written, with zero test adaptations.

Results

All suites verified against the real (nonprod) Ably sandbox:

Tier Suite Result Wall time
Standard ObjectsSyncTests 4/4 ✅ ~83s
Standard ObjectsLifecycleTests 6/6 ✅ ~132s
Standard ObjectsGcTests 2/2 ✅ ~54s
Proxy ObjectsFaultsTests 5/5 ✅ ~53s
Rest HistoryTests / PresenceTests / PublishTests 27/27 ✅ (1 documented skip) ~280s

Each @Test runs both JSON and msgpack protocol variants. The proxy tier self-provisions the uts-proxy binary (checksum-verified GitHub release download).

What's included

  • Test/UTS/integration/standard/objects/ — the sync, lifecycle, and GC suites plus their helpers (ObjectsIntegrationHelpers, ObjectsRestProvisioning).
  • Test/UTS/integration/proxy/objects/ — the fault-injection suite (ObjectsFaultsTests: sync interruption, buffering across faults, detach/reattach, publish-ack loss).
  • Test/UTS/integration/standard/rest/ — the History/Presence/Publish suites from the same source PR.
  • Package.swift — adds the AblyLiveObjects dependency to the UTS test target (required by the objects suites).
  • Test/UTS/deviations.md — appended records: the RSL1l1 skip gate and the application record for this test-enablement pass.
  • .claude/skills/uts-to-swift/ — skill routing updated so future objects UTS ports land in the correct targets (unit → LiveObjects/Tests/AblyLiveObjectsTests/UTS/; integration/proxy → Test/UTS/integration/…), plus the refreshed objects mapping reference.

Relationship to the base branch

These tests are the acceptance evidence for the implementation work on feature/liveobjects-implementation. Three defects they exposed were fixed there (not here — this PR contains no library source changes):

  1. Engine deinit on the internal queue tripped a dispatch precondition (SIGTRAP during ARC-driven teardown).
  2. get() did not implicitly attach the channel (RTL33b) — every integration spec's setup relies on it.
  3. siteCode was never delivered to channels created after CONNECTED, silently disabling RTO20 local echo.

The suites in this PR now pass with those fixes in place, unmodified from their spec translations.

Notes for reviewers

  • The integration specs live at uts/objects/integration/ in the specification repo; the test bodies are line-by-line translations (deviations, where unavoidable, are recorded in Test/UTS/deviations.md).
  • Suggested CI budget if these are wired into a workflow: ~300s for the three standard suites, ~60s for the proxy suite. They need sandbox network access and (proxy tier) permission to download the uts-proxy release binary.
  • Run locally with swift test --filter ObjectsSyncTests (etc.) from the repo root, after git submodule update --init --recursive.

Summary by CodeRabbit

Summary by CodeRabbit

  • New Features

    • Added comprehensive documentation for the LiveObjects path-based API.
    • Expanded coverage for synchronization, lifecycle, garbage collection, fault handling, REST history, presence, and publishing.
  • Bug Fixes

    • Improved validation for invalid counter increments and publish failures.
    • Strengthened reconnect and synchronization checks across supported data formats.
  • Documentation

    • Updated changelogs, testing guidance, UTS references, and deviation tracking.
  • Chores

    • Added automated quality checks and expanded continuous integration validation.

…t tiers)

Applies the UTS integration test suites translated in #2226, now runnable
against the completed LiveObjects implementation. The compile-only
.disabled traits are removed; all suites pass against the Ably sandbox
exactly as originally written (17/17 objects-tier + 27/27 rest-tier):

- standard/objects: sync, lifecycle, and GC suites + helpers
- proxy/objects: fault-injection suite (self-provisioning uts-proxy)
- standard/rest: History/Presence/Publish suites
- Package.swift: AblyLiveObjects dependency for the UTS target
- deviations.md records and uts-to-swift skill routing updates
@coderabbitai

coderabbitai Bot commented Jul 31, 2026

Copy link
Copy Markdown

Review Change Stack

Walkthrough

The PR adds Objects-specific UTS translation guidance, resolver path overrides, a dedicated AblyLiveObjectsTesting module, LiveObjects unit and integration coverage, test-seam validation, and CI documentation.

Changes

LiveObjects UTS workflow

Layer / File(s) Summary
Resolver and Objects mapping
.claude/skills/uts-to-swift/*, uts-package-mapping.json
The resolver now controls target paths and class names. Objects mapping guidance covers Swift concurrency, CRDT tests, plugin wiring, REST provisioning, and deviations.
Testing seams and package wiring
Package.swift, Test/AblyLiveObjectsTesting/*, LiveObjects/Sources/AblyLiveObjects/*
Test-only extensions move most testing access into AblyLiveObjectsTesting. Required production symbols use internal visibility. Package targets and platform availability support the module.
UTS and integration coverage
Test/UTS/unit/objects/*, Test/UTS/integration/*
Objects unit suites use standardized names and specification references. Integration suites cover synchronization, lifecycle, garbage collection, proxy faults, history, presence, and publishing.
Validation and project documentation
Scripts/check-liveobjects-test-seams.sh, .github/workflows/*, Makefile, LiveObjects/*, CONTRIBUTING.md
Lint checks sanctioned seams. CI documents scoped builds and test jobs. Documentation records commands, deviations, untranslated cases, release rules, and implementation status.

Estimated code review effort: 5 (Critical) | ~120 minutes

Possibly related PRs

Suggested reviewers: lawrence-forooghian, maratal

Poem

A rabbit checks each object path,
And keeps the test seams clear.
Maps and counters sync in hops,
While sandbox suites draw near.
The UTS trail is marked and bright.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the primary change: enabling the LiveObjects UTS integration test suites and reporting their passing status.
Docstring Coverage ✅ Passed Docstring coverage is 98.18% which is sufficient. The required threshold is 80.00%.
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.
✨ 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 feature/liveobjects-uts-integration-tests

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/2235/features July 31, 2026 12:42 Inactive
@github-actions
github-actions Bot temporarily deployed to staging/pull/2235/AblyLiveObjects July 31, 2026 12:42 Inactive
@github-actions
github-actions Bot temporarily deployed to staging/pull/2235/jazzydoc July 31, 2026 12:46 Inactive
@github-actions
github-actions Bot temporarily deployed to staging/pull/2235/markdown-api-reference July 31, 2026 12:46 Inactive
Covers the questions that the LiveObjects monorepo merge left
unanswered in the contributor docs.

CONTRIBUTING.md:

- Running tests: a table of the package's four test targets and the CI
  workflows that run each. Records that every target selects its files
  by directory, so new tests need no manifest, test-plan or workflow
  change, and that the LiveObjects UTS ports live in
  AblyLiveObjectsTests rather than the UTS target. Notes the
  AllTests/UnitTests asymmetry between the Xcode and coverage jobs.

- New LiveObjects section:
  - Supported OS versions: the macOS 11 / iOS 14 / tvOS 14 floor and
    its provenance in ADR-114; the @available mechanism that lets one
    package host two floors, with the command that applies it and the
    two CI checks that enforce it; and why test code instead raises its
    build's deployment target (the @suite macro rejects @available),
    listing both places that do so.
  - Distribution: the channel/product matrix and the four independent
    reasons AblyLiveObjects is SPM-only, plus the note that OS version
    requirements are not among them.

- Release Process: a Versioning preamble recording that the repository
  has one version number for all products, that the standalone
  plugin's 0.x line does not continue, that a tag does not mean the
  same thing on every channel, and that AblyLiveObjects is exempt from
  semver while experimental. Adds an SPM resolution check to the
  release steps, and fixes a stale bullet that described
  _AblyPluginSupportPrivate as an external dependency needing its own
  release.

LiveObjects/CONTRIBUTING.md: its release-process pointer now links the
two new sections and summarises them inline, and the description of
where the standalone plugin was released is reworded — "released
independently from the ably-liveobjects-swift-plugin repository" reads
as "released separately from that repository", i.e. not in it, which
is the opposite of what happened.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
maratal and others added 2 commits August 3, 2026 00:14
The UTS test target links AblyLiveObjects (iOS 14 / tvOS 14 / macOS 11), but the
package's platform floor is lower and SwiftPM has no per-target floor. The core
SDK's fastlane integration build compiles the `ably-cocoa` scheme's test target
at that low floor, so the UTS harness's direct references to AblyLiveObjects
types failed on the iOS/tvOS simulators with "'ProtocolTypes' is only available
in iOS 14.0 or newer".

Rather than annotate/erase the harness, raise the deployment target of the test
build itself via fastlane xcargs (IPHONEOS/TVOS_DEPLOYMENT_TARGET = 14.0),
mirroring LiveObjects/BuildTool's `testDeploymentTargetOverrides`. This affects
the test build only — shipped artifacts and the package's declared floor are
unchanged (respecting the ADR-128 / #2222 decision to keep ably-cocoa's
platforms low and gate LiveObjects via @available). It also lets the UTS
harness embed the plugin's OBJECT/OBJECT_SYNC types verbatim (no erasure) and
lets future objects @suite tests compile without @available/#available guards
(the Swift Testing macros reject @available).

macOS needs no override (its default test-build floor already satisfies
AblyLiveObjects).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
(cherry picked from commit 9b844bb)
Extract all test-only plumbing from the shipped LiveObjects sources and
consolidate the objects UTS unit tier into the standard UTS layout:

- Add the Test/AblyLiveObjectsTesting test-support target: the 57
  testsOnly_ internal-access extensions (moved out of
  LiveObjects/Sources, which now carries only 5 physically-immovable
  instrumentation seams behind marker comments) plus the shared test
  helpers/mocks (TestFactories, UTSTestPoolFactories, TestLogger,
  Subscriber, Assertions, 4 mocks), consumed via @testable import by
  both test targets and unreachable from any product.
- Raise the seams' backing members from private to internal (module-
  scoped; each carries an intent comment) and delete 3 dead seams.
- Move the 16 objects UTS unit-spec suites to Test/UTS/unit/objects/
  (UTS target, resolver-default <Stem>Tests names, canonical
  "// UTS: <id>" tags so audit_translation.py works again); unlike
  ably-java, cocoa's cross-target @testable access means these ports
  need not live inside the plugin module.
- Remove 20 native tests proven duplicated by the UTS ports (each
  verified against a UTS counterpart asserting a superset; one
  statusCode assertion ported into the UTS RTLC12e1 tests first);
  renumber the affected @specOneOf groups.
- Add Scripts/check-liveobjects-test-seams.sh, wired into make lint
  and CI, failing if LiveObjects/Sources grows testsOnly_ declarations
  outside the sanctioned allowlist.
- Align the uts-to-swift skill (routing, reading lists, naming rules,
  spec-helper coverage tables, publish-capture recipe) with the new
  layout; scope the SPM release CI job to --target AblyLiveObjects and
  run the UTS job with -warnings-as-errors.

Test counts: native suite 399 -> 379 (zero coverage loss); UTS tier
330 green; public API and shipped sources behaviour unchanged.
@github-actions
github-actions Bot temporarily deployed to staging/pull/2235/features August 5, 2026 08:22 Inactive
@github-actions
github-actions Bot temporarily deployed to staging/pull/2235/AblyLiveObjects August 5, 2026 08:22 Inactive
@github-actions
github-actions Bot temporarily deployed to staging/pull/2235/jazzydoc August 5, 2026 08:26 Inactive
@github-actions
github-actions Bot temporarily deployed to staging/pull/2235/markdown-api-reference August 5, 2026 08:26 Inactive

@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: 5

🧹 Nitpick comments (6)
Test/UTS/unit/objects/InternalLiveCounterApiTests.swift (1)

72-102: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Fold the ported assertion into the table test and drop the duplicate.

RTLC12e1_increment_non_finite_throws now asserts exactly what RTLC12e1_increment_invalid_amounts_table asserts for its .nan row: code == 40003 and statusCode == 400. The single-case test adds no coverage. Move the porting note onto the table test and remove the duplicate.

♻️ Proposed change
-    // UTS: objects/unit/RTLC12e1/increment-non-number-0 — the representable non-finite doubles throw 40003.
-    `@Test`
-    func RTLC12e1_increment_non_finite_throws() async throws {
-        let (counter, _) = try makeCounter(objectID: "counter:score@1000", data: 100)
-        let error = await `#expect`(throws: ARTErrorInfo.self) {
-            try await counter.increment(amount: .nan)
-        }
-        `#expect`(error?.code == 40003)
-        // Ported from the native IncrementTests.throwsErrorForInvalidAmount before its removal
-        // (Wave-1 dedup): the invalid-amount error also carries HTTP status 400.
-        `#expect`(error?.statusCode == 400)
-    }
-
     // UTS: objects/unit/RTLC12e1/increment-invalid-amounts-table-0 — every representable non-finite amount
-    // throws 40003. The non-numeric rows are compile-time-unrepresentable (Double parameter).
+    // throws 40003. The non-numeric rows are compile-time-unrepresentable (Double parameter).
+    // Ported from the native IncrementTests.throwsErrorForInvalidAmount before its removal
+    // (Wave-1 dedup): the invalid-amount error also carries HTTP status 400.
     `@Test`
🤖 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/unit/objects/InternalLiveCounterApiTests.swift` around lines 72 -
102, Remove the redundant RTLC12e1_increment_non_finite_throws test, move its
native-test porting note to RTLC12e1_increment_invalid_amounts_table, and retain
the existing code and status assertions in the table test, including the .nan
case.
Test/UTS/integration/standard/rest/PresenceTests.swift (1)

25-28: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Extract the repeated REST client setup into one helper.

The same four-line block appears in all 15 tests: build ARTClientOptions, set restHost, set useBinaryProtocol, and construct ARTRest. The realtime variant repeats six lines in six tests. Two small helpers remove that duplication and keep the per-test body focused on the spec steps.

♻️ Proposed helpers

Add to the extension PresenceTests block:

private func restClient(_ app: SandboxApp, useBinaryProtocol: Bool, clientId: String? = nil) -> ARTRest {
    let options = ARTClientOptions(key: app.defaultKey)
    options.restHost = SandboxApp.sandboxHost // the spec's endpoint: "nonprod:sandbox"
    options.useBinaryProtocol = useBinaryProtocol
    options.clientId = clientId
    return ARTRest(options: options)
}

private func realtimeOptions(_ app: SandboxApp, useBinaryProtocol: Bool, clientId: String) -> ARTClientOptions {
    let options = ARTClientOptions(key: app.defaultKey)
    options.realtimeHost = SandboxApp.sandboxHost
    options.restHost = SandboxApp.sandboxHost
    options.useBinaryProtocol = useBinaryProtocol
    options.clientId = clientId
    options.autoConnect = false
    return options
}

Then each test body reduces to:

-            let options = ARTClientOptions(key: app.defaultKey)
-            options.restHost = SandboxApp.sandboxHost // the spec's endpoint: "nonprod:sandbox"
-            options.useBinaryProtocol = useBinaryProtocol
-            let client = ARTRest(options: options)
+            let client = self.restClient(app, useBinaryProtocol: useBinaryProtocol)
🤖 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/integration/standard/rest/PresenceTests.swift` around lines 25 - 28,
Add private restClient and realtimeOptions helpers to the PresenceTests
extension, encapsulating the repeated REST and realtime ARTClientOptions setup
shown in the tests. Replace each duplicated setup block with the appropriate
helper call, preserving useBinaryProtocol, optional clientId, host values, and
autoConnect behavior.
Test/UTS/integration/standard/objects/helpers/ObjectsIntegrationHelpers.swift (1)

60-71: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Throw a purpose-built error instead of HTTPError.

counterInstanceId throws HTTPError when the resolved instance is not a counter. HTTPError describes a sandbox provisioning or HTTP transport failure, not a type mismatch in an objects instance. A reader who sees HTTPError in a CI log will look for a network problem. The Issue.record call on line 66 carries the real cause, so the thrown type only needs to unwind the test.

Define a small dedicated error, or return the failure through #require alone.

♻️ Proposed refactor
+/// Signals that a UTS objects helper could not satisfy its expected-type contract. The paired
+/// `Issue.record` call carries the diagnostic; this type only unwinds the test.
+struct ObjectsHelperError: Error, CustomStringConvertible {
+    let description: String
+}
+
 /// The spec's `pathObj.instance().id` against an expected **counter** — unwraps the `Instance` enum
 /// (`objects-mapping.md` §5), stopping the test if nothing resolves or the instance isn't a counter.
 func counterInstanceId(at node: any PathObject,
                        sourceLocation: SourceLocation = `#_sourceLocation`) throws -> String {
     let instance = try `#require`(try node.instance(),
                                 "expected an instance at path '\(node.path)'",
                                 sourceLocation: sourceLocation)
     guard case let .liveCounter(counter) = instance else {
         Issue.record("expected a liveCounter instance at path '\(node.path)', got \(instance.type)",
                      sourceLocation: sourceLocation)
-        throw HTTPError("expected a liveCounter instance at path '\(node.path)'")
+        throw ObjectsHelperError(description: "expected a liveCounter instance at path '\(node.path)'")
     }
     return counter.id
 }
🤖 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/integration/standard/objects/helpers/ObjectsIntegrationHelpers.swift`
around lines 60 - 71, Update counterInstanceId so the non-liveCounter branch no
longer throws HTTPError; define and throw a small purpose-built local error for
this type-mismatch failure, or rely solely on `#require` to unwind after
Issue.record. Preserve the existing diagnostic message and successful counter.id
return path.
Test/AblyLiveObjectsTesting/InternalDefaultRealtimeObjects+TestsOnly.swift (1)

94-94: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Update the stale comment.

This comment describes the member as exposed "in the early days of the SDK" and predicts it will become private later. The member now lives in a dedicated testing target, so the stated plan no longer applies. Rewrite the comment to state what the seam does for tests.

🤖 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/AblyLiveObjectsTesting/InternalDefaultRealtimeObjects`+TestsOnly.swift
at line 94, Update the comment above the exposed member to describe its current
purpose as a testing seam for sending an OBJECT ProtocolMessage, and remove the
outdated references to the SDK’s early days and making it private later.
Test/UTS/integration/standard/rest/PublishTests.swift (1)

128-145: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Drop the protocol parameterization on the deviation placeholder.

The body only calls Issue.record. It never uses useBinaryProtocol, so the two arguments record the same issue twice with no added coverage. The signature is also async throws with no await and no try in the body.

♻️ Proposed simplification
-    `@Test`(.enabled(if: ProcessInfo.processInfo.environment["RUN_DEVIATIONS"] != nil),
-          arguments: [false, true]) // useBinaryProtocol: false = JSON, true = msgpack
-    func test_RSL1l1_publish_params_with_forceNack(useBinaryProtocol: Bool) async throws {
+    `@Test`(.enabled(if: ProcessInfo.processInfo.environment["RUN_DEVIATIONS"] != nil))
+    func test_RSL1l1_publish_params_with_forceNack() {
🤖 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/integration/standard/rest/PublishTests.swift` around lines 128 -
145, Simplify test_RSL1l1_publish_params_with_forceNack by removing the unused
useBinaryProtocol argument and its protocol parameterization, leaving a single
non-async, non-throwing test that records the deviation once. Preserve the
existing Issue.record message and test enablement condition.
Test/AblyLiveObjectsTesting/LiveObjectMutableState+TestsOnly.swift (1)

14-18: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Consider a non-optional parameter with an empty-dictionary default.

siteTimeserials is declared optional and then collapsed to [:] with ?? [:]. Callers cannot distinguish "not supplied" from "supplied as empty", so the optional adds no information. A non-optional parameter with a default removes the coalescing operator.

♻️ Proposed simplification
     init(
         objectID: String,
-        testsOnly_siteTimeserials siteTimeserials: [String: String]? = nil,
+        testsOnly_siteTimeserials siteTimeserials: [String: String] = [:],
         testsOnly_tombstonedAt tombstonedAt: Date? = nil,
     ) {
         self.init(objectID: objectID)
-        self.siteTimeserials = siteTimeserials ?? [:]
+        self.siteTimeserials = siteTimeserials
         self.tombstonedAt = tombstonedAt
     }
🤖 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/AblyLiveObjectsTesting/LiveObjectMutableState`+TestsOnly.swift around
lines 14 - 18, Update the tests-only initializer’s siteTimeserials parameter to
be non-optional with an empty-dictionary default, then assign it directly to
self.siteTimeserials and remove the nil-coalescing fallback. Preserve the
existing initializer behavior for callers that omit the parameter or provide an
explicit dictionary.
🤖 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
`@LiveObjects/Sources/AblyLiveObjects/Internal/InternalDefaultRealtimeObjects.swift`:
- Line 572: The testsOnly_publish seam must remain a pass-through instead of
duplicating publish behavior. Extract the mutex hop, validation, error handling,
and coreSDK.nosync_publish logic from ensureMessageSizeWithinLimit into a tested
internal production method, then have the test helper delegate directly to it;
otherwise obtain approval for and record a residual exception.

In `@Test/AblyLiveObjectsTesting/Subscriber.swift`:
- Line 6: Update the availability annotations for every test path that
constructs Subscriber, including DefaultInstanceTests, to require macOS 14.0
alongside the existing iOS and tvOS requirements. Alternatively, revise
Subscriber so it remains compatible with the package’s macOS 10.11 baseline,
while preserving the existing test behavior.

In `@Test/AblyLiveObjectsTesting/TestFactories.swift`:
- Line 185: Align TestFactories availability with the package’s declared
deployment floors: either remove the newer availability restriction and keep it
usable on macOS 10.11, iOS 9, and tvOS 10, or ensure TestFactories is not
exposed to callers on those older platforms while preserving the existing
Package.swift support declarations.

In `@Test/UTS/integration/standard/rest/HistoryTests.swift`:
- Around line 175-193: The timestamp split in the history test can exclude all
late messages when maxEarlyTs equals minLateTs. Update the timeBoundary and
lateQuery setup in this test to detect the collapsed-timestamp case and skip the
split or widen the boundary so lateHistory still includes the late messages,
while preserving the existing behavior for distinct timestamps.
- Around line 250-266: Split historyItems into reporting and non-reporting
variants: retain Issue.record behavior for final reads, while the variant used
by pollUntil predicates returns history results and errors without recording
issues. Update every poll predicate calling historyItems (including the usages
near lines 39, 81, 116, and 159) to use the non-reporting variant, preserving
the existing reporting behavior elsewhere.

---

Nitpick comments:
In `@Test/AblyLiveObjectsTesting/InternalDefaultRealtimeObjects`+TestsOnly.swift:
- Line 94: Update the comment above the exposed member to describe its current
purpose as a testing seam for sending an OBJECT ProtocolMessage, and remove the
outdated references to the SDK’s early days and making it private later.

In `@Test/AblyLiveObjectsTesting/LiveObjectMutableState`+TestsOnly.swift:
- Around line 14-18: Update the tests-only initializer’s siteTimeserials
parameter to be non-optional with an empty-dictionary default, then assign it
directly to self.siteTimeserials and remove the nil-coalescing fallback.
Preserve the existing initializer behavior for callers that omit the parameter
or provide an explicit dictionary.

In
`@Test/UTS/integration/standard/objects/helpers/ObjectsIntegrationHelpers.swift`:
- Around line 60-71: Update counterInstanceId so the non-liveCounter branch no
longer throws HTTPError; define and throw a small purpose-built local error for
this type-mismatch failure, or rely solely on `#require` to unwind after
Issue.record. Preserve the existing diagnostic message and successful counter.id
return path.

In `@Test/UTS/integration/standard/rest/PresenceTests.swift`:
- Around line 25-28: Add private restClient and realtimeOptions helpers to the
PresenceTests extension, encapsulating the repeated REST and realtime
ARTClientOptions setup shown in the tests. Replace each duplicated setup block
with the appropriate helper call, preserving useBinaryProtocol, optional
clientId, host values, and autoConnect behavior.

In `@Test/UTS/integration/standard/rest/PublishTests.swift`:
- Around line 128-145: Simplify test_RSL1l1_publish_params_with_forceNack by
removing the unused useBinaryProtocol argument and its protocol
parameterization, leaving a single non-async, non-throwing test that records the
deviation once. Preserve the existing Issue.record message and test enablement
condition.

In `@Test/UTS/unit/objects/InternalLiveCounterApiTests.swift`:
- Around line 72-102: Remove the redundant RTLC12e1_increment_non_finite_throws
test, move its native-test porting note to
RTLC12e1_increment_invalid_amounts_table, and retain the existing code and
status assertions in the table test, including the .nan case.
🪄 Autofix

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: f13a09da-2db6-4567-b136-1da5058d1c6c

📥 Commits

Reviewing files that changed from the base of the PR and between 0d2cd22 and 36b57c6.

📒 Files selected for processing (88)
  • .claude/skills/uts-to-swift/SKILL.md
  • .claude/skills/uts-to-swift/references/objects-mapping.md
  • .claude/skills/uts-to-swift/scripts/resolve_uts.py
  • .claude/skills/uts-to-swift/uts-package-mapping.json
  • .github/workflows/liveobjects.yaml
  • LiveObjects/CHANGELOG.md
  • LiveObjects/CLAUDE.md
  • LiveObjects/Sources/AblyLiveObjects/Internal/CoreSDK.swift
  • LiveObjects/Sources/AblyLiveObjects/Internal/InternalDefaultLiveCounter.swift
  • LiveObjects/Sources/AblyLiveObjects/Internal/InternalDefaultLiveMap.swift
  • LiveObjects/Sources/AblyLiveObjects/Internal/InternalDefaultRealtimeObjects.swift
  • LiveObjects/Sources/AblyLiveObjects/Internal/LiveObjectMutableState.swift
  • LiveObjects/Sources/AblyLiveObjects/Internal/ObjectCreationHelpers.swift
  • LiveObjects/Sources/AblyLiveObjects/Internal/ObjectsPool.swift
  • LiveObjects/Sources/AblyLiveObjects/Path Based API/Public/Channel+Object.swift
  • LiveObjects/Sources/AblyLiveObjects/Public/Public Proxy Objects/PublicDefaultRealtimeObject.swift
  • LiveObjects/Sources/AblyLiveObjects/Utility/Errors.swift
  • LiveObjects/Tests/AblyLiveObjectsTests/AblyLiveObjectsTests.swift
  • LiveObjects/Tests/AblyLiveObjectsTests/DefaultInstanceTests.swift
  • LiveObjects/Tests/AblyLiveObjectsTests/DefaultInternalPluginTests.swift
  • LiveObjects/Tests/AblyLiveObjectsTests/DefaultPathObjectTests.swift
  • LiveObjects/Tests/AblyLiveObjectsTests/Helpers/ClientHelper.swift
  • LiveObjects/Tests/AblyLiveObjectsTests/InternalDefaultLiveCounterTests.swift
  • LiveObjects/Tests/AblyLiveObjectsTests/InternalDefaultLiveMapTests.swift
  • LiveObjects/Tests/AblyLiveObjectsTests/InternalDefaultRealtimeObjectsTests.swift
  • LiveObjects/Tests/AblyLiveObjectsTests/LiveObjectMutableStateTests.swift
  • LiveObjects/Tests/AblyLiveObjectsTests/ObjectCreationHelpersTests.swift
  • LiveObjects/Tests/AblyLiveObjectsTests/ObjectDiffHelpersTests.swift
  • LiveObjects/Tests/AblyLiveObjectsTests/ObjectLifetimesTests.swift
  • LiveObjects/Tests/AblyLiveObjectsTests/ObjectsPoolTests.swift
  • LiveObjects/Tests/AblyLiveObjectsTests/ParentReferencesTests.swift
  • LiveObjects/Tests/AblyLiveObjectsTests/PathObjectSubscriptionTests.swift
  • LiveObjects/Tests/AblyLiveObjectsTests/PublicRealtimeObjectTests.swift
  • LiveObjects/Tests/AblyLiveObjectsTests/SyncObjectsPoolTests.swift
  • LiveObjects/Tests/AblyLiveObjectsTests/TestsOnlySeamsTests.swift
  • LiveObjects/Tests/AblyLiveObjectsTests/UTS/README.md
  • LiveObjects/Tests/AblyLiveObjectsTests/WireObjectMessageSizeTests.swift
  • Makefile
  • Package.swift
  • Scripts/check-liveobjects-test-seams.sh
  • Test/AblyLiveObjectsTesting/ARTRealtimeChannel+TestsOnly.swift
  • Test/AblyLiveObjectsTesting/AblyLiveObjectsTesting.swift
  • Test/AblyLiveObjectsTesting/Assertions.swift
  • Test/AblyLiveObjectsTesting/InternalDefaultLiveCounter+TestsOnly.swift
  • Test/AblyLiveObjectsTesting/InternalDefaultLiveMap+TestsOnly.swift
  • Test/AblyLiveObjectsTesting/InternalDefaultRealtimeObjects+TestsOnly.swift
  • Test/AblyLiveObjectsTesting/LiveObjectMutableState+TestsOnly.swift
  • Test/AblyLiveObjectsTesting/MockCoreSDK.swift
  • Test/AblyLiveObjectsTesting/MockLiveMapObjectsPoolDelegate.swift
  • Test/AblyLiveObjectsTesting/MockRealtimeObjects.swift
  • Test/AblyLiveObjectsTesting/MockSimpleClock.swift
  • Test/AblyLiveObjectsTesting/ObjectCreationHelpers+TestsOnly.swift
  • Test/AblyLiveObjectsTesting/ObjectsPool+TestsOnly.swift
  • Test/AblyLiveObjectsTesting/PublicDefaultRealtimeObject+TestsOnly.swift
  • Test/AblyLiveObjectsTesting/README.md
  • Test/AblyLiveObjectsTesting/Subscriber.swift
  • Test/AblyLiveObjectsTesting/TestFactories.swift
  • Test/AblyLiveObjectsTesting/TestLogger.swift
  • Test/AblyLiveObjectsTesting/UTSTestPoolFactories.swift
  • Test/UTS/deviations.md
  • Test/UTS/integration/proxy/objects/ObjectsFaultsTests.swift
  • Test/UTS/integration/standard/objects/ObjectsGcTests.swift
  • Test/UTS/integration/standard/objects/ObjectsLifecycleTests.swift
  • Test/UTS/integration/standard/objects/ObjectsSyncTests.swift
  • Test/UTS/integration/standard/objects/helpers/ObjectsIntegrationHelpers.swift
  • Test/UTS/integration/standard/objects/helpers/ObjectsRestProvisioning.swift
  • Test/UTS/integration/standard/rest/HistoryTests.swift
  • Test/UTS/integration/standard/rest/PresenceTests.swift
  • Test/UTS/integration/standard/rest/PublishTests.swift
  • Test/UTS/unit/objects/InstanceTests.swift
  • Test/UTS/unit/objects/InternalLiveCounterApiTests.swift
  • Test/UTS/unit/objects/InternalLiveCounterTests.swift
  • Test/UTS/unit/objects/InternalLiveMapApiTests.swift
  • Test/UTS/unit/objects/InternalLiveMapParentReferencesTests.swift
  • Test/UTS/unit/objects/InternalLiveMapTests.swift
  • Test/UTS/unit/objects/LiveObjectSubscribeTests.swift
  • Test/UTS/unit/objects/ObjectIdTests.swift
  • Test/UTS/unit/objects/ObjectsPoolTests.swift
  • Test/UTS/unit/objects/ObjectsUTSHelpers.swift
  • Test/UTS/unit/objects/ParentReferencesTests.swift
  • Test/UTS/unit/objects/PathObjectMutationsTests.swift
  • Test/UTS/unit/objects/PathObjectSubscribeTests.swift
  • Test/UTS/unit/objects/PathObjectTests.swift
  • Test/UTS/unit/objects/PublicObjectMessageTests.swift
  • Test/UTS/unit/objects/README.md
  • Test/UTS/unit/objects/RealtimeObjectTests.swift
  • Test/UTS/unit/objects/ValueTypesTests.swift
  • Test/UTS/unit/objects/deviations.md
💤 Files with no reviewable changes (1)
  • LiveObjects/Tests/AblyLiveObjectsTests/UTS/README.md

Comment thread Test/AblyLiveObjectsTesting/Subscriber.swift
Comment thread Test/AblyLiveObjectsTesting/TestFactories.swift
Comment thread Test/UTS/integration/standard/rest/HistoryTests.swift
Comment thread Test/UTS/integration/standard/rest/HistoryTests.swift
sacOO7 added 3 commits August 5, 2026 17:08
Addresses CodeRabbit review feedback on #2237: the note refers to the
plugin's historical releases page, so link directly to /releases rather
than the repository root.
The target branch's commit 36b57c6 moved the LiveObjects 'objects' UTS
unit ports out of AblyLiveObjectsTests and into the UTS target
(Test/UTS/unit/objects/), and added the shared AblyLiveObjectsTesting
support target. Correct the test-target table and CI notes, which still
described the pre-restructure layout.
docs: document LiveObjects versioning, distribution and test targets; fix UTS integration build on iOS/tvOS
@github-actions
github-actions Bot temporarily deployed to staging/pull/2235/features August 5, 2026 11:52 Inactive
@github-actions
github-actions Bot temporarily deployed to staging/pull/2235/AblyLiveObjects August 5, 2026 11:52 Inactive
clearOnDetachedEmitsNoUpdateEvents constructs Subscriber<...>, whose
parameter-pack generics require iOS 17 / tvOS 17, but it was the one
Subscriber-using test missing the @available(iOS 17.0.0, tvOS 17.0.0, *)
annotation its siblings carry. BuildTool compiles the iOS/tvOS test
bundles at the plugin floor of 14.0, so the gap failed the
"Xcode, iOS/tvOS (Xcode 16.4)" jobs at build-for-testing; macOS passed
only because xcodebuild raises the macOS bundle floor to 14 on its own.

A mechanical sweep confirmed this was the only unguarded Subscriber use.

Also documents the Test/UTS and Test/AblyLiveObjectsTesting targets in
the root CLAUDE.md test-structure section.
@github-actions
github-actions Bot temporarily deployed to staging/pull/2235/features August 5, 2026 11:56 Inactive
@github-actions
github-actions Bot temporarily deployed to staging/pull/2235/AblyLiveObjects August 5, 2026 11:57 Inactive
@github-actions
github-actions Bot temporarily deployed to staging/pull/2235/jazzydoc August 5, 2026 12:00 Inactive
@github-actions
github-actions Bot temporarily deployed to staging/pull/2235/markdown-api-reference August 5, 2026 12:00 Inactive
…kflows

Remove liveobjects.yaml's build-and-test-uts job (and its aggregation-gate
entry): both of its purposes were already covered elsewhere —

- execution: integration-test.yaml's Fastlane lanes run the whole UTS
  target on iOS, tvOS and macOS via Test/Ably.xctestplan (including the
  LiveObjects objects unit tier, the sandbox integration tier and the
  macOS-only proxy tier);
- warnings-as-errors compilation: the build-and-test-spm job compiles
  every test target in the package under the flag, UTS included.

It was also a flake source, running the network-bound sandbox/proxy
suites on every PR in duplicate.

So that this topology is discoverable from any workflow a developer
opens, add orientation comments across the family: where UTS tests
execute and why (integration-test.yaml), why liveobjects.yaml has no UTS
job, what check-spm.yaml does and doesn't cover, why the plugin is absent
from check-pod.yaml (SPM-only), where LiveObjects DocC is built vs the
core Jazzy docs (docs.yml), and a job-level comment for every previously
uncommented liveobjects.yaml job (matrices, Xcode test/release builds,
coverage's UnitTests-vs-AllTests plan asymmetry, example app, DocC).
Also drop integration-test.yaml's stale note about replicating changes
to integration-test-*.yaml siblings (none exist) and update
CONTRIBUTING.md's CI section to match.
@github-actions
github-actions Bot temporarily deployed to staging/pull/2235/features August 5, 2026 13:01 Inactive
@github-actions
github-actions Bot temporarily deployed to staging/pull/2235/AblyLiveObjects August 5, 2026 13:02 Inactive
@github-actions
github-actions Bot temporarily deployed to staging/pull/2235/jazzydoc August 5, 2026 13:06 Inactive
@github-actions
github-actions Bot temporarily deployed to staging/pull/2235/markdown-api-reference August 5, 2026 13:06 Inactive
@sacOO7
sacOO7 requested a lite review from Copilot August 5, 2026 13:19

Copilot AI 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.

Pull request overview

This PR enables LiveObjects UTS coverage by (1) moving the objects unit-tier UTS suites into the shared UTS target, (2) adding new objects integration suites that run against the Ably nonprod sandbox, and (3) introducing a dedicated AblyLiveObjectsTesting support target to keep test seams out of shipped LiveObjects sources (enforced via a new guard script run in CI and make lint).

Changes:

  • Added LiveObjects objects integration suites (ObjectsSyncTests, ObjectsLifecycleTests, ObjectsGcTests) plus REST provisioning + helper wiring.
  • Introduced AblyLiveObjectsTesting SPM target and migrated testsOnly_ seams out of LiveObjects/Sources into test-support extensions, with a guard script to prevent regressions.
  • Relocated/renamed objects unit-tier UTS ports into Test/UTS/unit/objects/ and updated CI/docs/tooling to reflect the new layout.

Reviewed changes

Copilot reviewed 96 out of 96 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
Test/UTS/unit/objects/ValueTypesTests.swift Renames suite + updates UTS provenance/comments.
Test/UTS/unit/objects/RealtimeObjectTests.swift Renames suite + imports AblyLiveObjectsTesting for internal seams.
Test/UTS/unit/objects/README.md Documents objects unit-tier UTS layout/conventions in UTS target.
Test/UTS/unit/objects/PublicObjectMessageTests.swift Renames suite + updates UTS provenance/comments.
Test/UTS/unit/objects/PathObjectSubscribeTests.swift Renames suite + imports AblyLiveObjectsTesting.
Test/UTS/unit/objects/PathObjectMutationsTests.swift Renames suite + updates UTS test-ID tags.
Test/UTS/unit/objects/ParentReferencesTests.swift Renames suite + imports AblyLiveObjectsTesting; updates UTS tags.
Test/UTS/unit/objects/ObjectsUTSHelpers.swift Updates helper commentary for renamed suites; imports testing target.
Test/UTS/unit/objects/ObjectsPoolTests.swift Renames suite + imports AblyLiveObjectsTesting; updates internal references.
Test/UTS/unit/objects/ObjectIdTests.swift Renames suite + imports AblyLiveObjectsTesting; updates tags.
Test/UTS/unit/objects/LiveObjectSubscribeTests.swift Renames suite + imports AblyLiveObjectsTesting.
Test/UTS/unit/objects/InternalLiveMapParentReferencesTests.swift Renames suite + imports AblyLiveObjectsTesting; updates internal references.
Test/UTS/unit/objects/InternalLiveMapApiTests.swift Renames suite + updates UTS provenance/comments.
Test/UTS/unit/objects/InternalLiveCounterApiTests.swift Renames suite + adds statusCode assertions for invalid increment amounts.
Test/UTS/unit/objects/InstanceTests.swift Renames suite + imports AblyLiveObjectsTesting.
Test/UTS/integration/standard/objects/ObjectsSyncTests.swift Adds direct-sandbox objects sync integration coverage.
Test/UTS/integration/standard/objects/ObjectsLifecycleTests.swift Adds end-to-end lifecycle/mutation propagation integration coverage.
Test/UTS/integration/standard/objects/ObjectsGcTests.swift Adds tombstone/recreate integration coverage (GC sweep remains unit-tier).
Test/UTS/integration/standard/objects/helpers/ObjectsRestProvisioning.swift Adds REST provisioning helper for objects fixtures (V2 REST shape).
Test/UTS/integration/standard/objects/helpers/ObjectsIntegrationHelpers.swift Adds shared client/channel wiring + typed value readers for integration suites.
Test/UTS/deviations.md Appends deviations + application record for enabling these suites.
Test/AblyLiveObjectsTesting/UTSTestPoolFactories.swift Adds availability annotations to align with LiveObjects platform floor.
Test/AblyLiveObjectsTesting/TestLogger.swift Adds availability annotations for LiveObjects-compatible builds.
Test/AblyLiveObjectsTesting/TestFactories.swift Adds availability annotations for LiveObjects-compatible builds.
Test/AblyLiveObjectsTesting/Subscriber.swift Expands availability to macOS 14 to match parameter-pack requirement.
Test/AblyLiveObjectsTesting/README.md Documents purpose + seam-migration rule + residual allowlist.
Test/AblyLiveObjectsTesting/PublicDefaultRealtimeObject+TestsOnly.swift Adds test-only accessors for PublicDefaultRealtimeObject.
Test/AblyLiveObjectsTesting/ObjectsPool+TestsOnly.swift Adds test-only init/setters (and Entry helpers) for ObjectsPool.
Test/AblyLiveObjectsTesting/ObjectCreationHelpers+TestsOnly.swift Exposes object-ID creation helper for tests without shipping seams.
Test/AblyLiveObjectsTesting/MockSimpleClock.swift Adds availability annotations.
Test/AblyLiveObjectsTesting/MockRealtimeObjects.swift Adds availability annotations.
Test/AblyLiveObjectsTesting/MockLiveMapObjectsPoolDelegate.swift Adds availability annotations.
Test/AblyLiveObjectsTesting/MockCoreSDK.swift Adds availability annotations.
Test/AblyLiveObjectsTesting/LiveObjectMutableState+TestsOnly.swift Adds test-only initializer to avoid shipping testsOnly_ init.
Test/AblyLiveObjectsTesting/InternalDefaultRealtimeObjects+TestsOnly.swift Adds test-only accessors and helpers for engine state/control.
Test/AblyLiveObjectsTesting/InternalDefaultLiveMap+TestsOnly.swift Migrates testsOnly_ seams for map internals out of shipped sources.
Test/AblyLiveObjectsTesting/InternalDefaultLiveCounter+TestsOnly.swift Migrates testsOnly_ seams for counter internals out of shipped sources.
Test/AblyLiveObjectsTesting/Assertions.swift Adds availability annotation to helper fatalError.
Test/AblyLiveObjectsTesting/ARTRealtimeChannel+TestsOnly.swift Exposes non-type-erased object seam for tests without shipping accessors.
Test/AblyLiveObjectsTesting/AblyLiveObjectsTesting.swift Adds module anchor file for the new test-support target.
Scripts/check-liveobjects-test-seams.sh Adds guardrail script to prevent new shipped testsOnly_ seams.
Package.swift Adds AblyLiveObjectsTesting target + wires it into test targets; adds LiveObjects deps to UTS.
Makefile Runs the seams guard script as part of make lint.
LiveObjects/Tests/AblyLiveObjectsTests/WireObjectMessageSizeTests.swift Switches to using AblyLiveObjectsTesting seams.
LiveObjects/Tests/AblyLiveObjectsTests/TestsOnlySeamsTests.swift Switches to using AblyLiveObjectsTesting seams.
LiveObjects/Tests/AblyLiveObjectsTests/SyncObjectsPoolTests.swift Updates imports; removes duplicated spec coverage.
LiveObjects/Tests/AblyLiveObjectsTests/PublicRealtimeObjectTests.swift Updates imports; removes duplicated spec coverage; adjusts one error assertion.
LiveObjects/Tests/AblyLiveObjectsTests/PathObjectSubscriptionTests.swift Updates imports; removes duplicated spec coverage.
LiveObjects/Tests/AblyLiveObjectsTests/ParentReferencesTests.swift Updates imports to use AblyLiveObjectsTesting.
LiveObjects/Tests/AblyLiveObjectsTests/ObjectsPoolTests.swift Updates imports; removes duplicated spec coverage.
LiveObjects/Tests/AblyLiveObjectsTests/ObjectLifetimesTests.swift Updates imports to use AblyLiveObjectsTesting.
LiveObjects/Tests/AblyLiveObjectsTests/ObjectDiffHelpersTests.swift Updates imports to use AblyLiveObjectsTesting.
LiveObjects/Tests/AblyLiveObjectsTests/ObjectCreationHelpersTests.swift Updates imports to use AblyLiveObjectsTesting.
LiveObjects/Tests/AblyLiveObjectsTests/LiveObjectMutableStateTests.swift Updates imports; removes duplicated spec coverage.
LiveObjects/Tests/AblyLiveObjectsTests/InternalDefaultRealtimeObjectsTests.swift Updates imports; removes duplicated spec coverage; adds availability on one test.
LiveObjects/Tests/AblyLiveObjectsTests/InternalDefaultLiveMapTests.swift Updates imports; removes duplicated spec coverage; minor cleanup.
LiveObjects/Tests/AblyLiveObjectsTests/InternalDefaultLiveCounterTests.swift Updates imports; removes duplicated spec coverage.
LiveObjects/Tests/AblyLiveObjectsTests/Helpers/ClientHelper.swift Updates imports to use AblyLiveObjectsTesting.
LiveObjects/Tests/AblyLiveObjectsTests/DefaultPathObjectTests.swift Updates imports; removes duplicated spec coverage.
LiveObjects/Tests/AblyLiveObjectsTests/DefaultInternalPluginTests.swift Updates imports to use AblyLiveObjectsTesting.
LiveObjects/Tests/AblyLiveObjectsTests/DefaultInstanceTests.swift Updates imports; removes duplicated spec coverage.
LiveObjects/Tests/AblyLiveObjectsTests/AblyLiveObjectsTests.swift Updates imports to use AblyLiveObjectsTesting.
LiveObjects/Tests/AblyLiveObjectsTests/UTS/README.md Removes outdated/misleading UTS-unit documentation from plugin test target.
LiveObjects/Sources/AblyLiveObjects/Utility/Errors.swift Removes shipped testsOnly_ error accessor and clarifies comment.
LiveObjects/Sources/AblyLiveObjects/Public/Public Proxy Objects/PublicDefaultRealtimeObject.swift Makes members internal for AblyLiveObjectsTesting; removes shipped testsOnly_ accessors.
LiveObjects/Sources/AblyLiveObjects/Path Based API/Public/Channel+Object.swift Makes seam internal for AblyLiveObjectsTesting; removes shipped testsOnly_ accessor.
LiveObjects/Sources/AblyLiveObjects/Internal/ObjectsPool.swift Removes shipped testsOnly_ seams; relaxes access for test-support target.
LiveObjects/Sources/AblyLiveObjects/Internal/ObjectCreationHelpers.swift Makes object-ID creator internal for test-support target; removes shipped testsOnly_.
LiveObjects/Sources/AblyLiveObjects/Internal/LiveObjectMutableState.swift Removes shipped testsOnly_ initializer from production sources.
LiveObjects/Sources/AblyLiveObjects/Internal/InternalDefaultLiveMap.swift Removes shipped testsOnly_ seams; relaxes access for test-support target.
LiveObjects/Sources/AblyLiveObjects/Internal/InternalDefaultLiveCounter.swift Removes shipped testsOnly_ seams; relaxes access for test-support target.
LiveObjects/Sources/AblyLiveObjects/Internal/CoreSDK.swift Documents remaining sanctioned testsOnly_ residuals in production.
LiveObjects/CONTRIBUTING.md Clarifies plugin versioning/distribution relationship to ably-cocoa releases.
LiveObjects/CLAUDE.md Notes that objects UTS suites live under Test/UTS/unit/objects/ now.
LiveObjects/CHANGELOG.md Adds Unreleased notes summarizing implementation/testing progress.
fastlane/Fastfile Raises test build deployment targets for UTS (needed due to LiveObjects floor).
CLAUDE.md Updates repo-level structure notes for UTS objects + new testing target.
.github/workflows/liveobjects.yaml Adds test-seams check; scopes release build to shipped target; updates commentary.
.github/workflows/integration-test.yaml Adds documentation clarifying UTS execution responsibilities in CI.
.github/workflows/docs.yml Clarifies core SDK docs vs LiveObjects DocC docs responsibility.
.github/workflows/check-spm.yaml Clarifies compile-only nature and CI split for tests.
.github/workflows/check-pod.yaml Clarifies LiveObjects is SPM-only and intentionally absent from pod/carthage packaging.
.claude/skills/uts-to-swift/uts-package-mapping.json Documents resolver behavior + adds dormant // override semantics.
.claude/skills/uts-to-swift/scripts/resolve_uts.py Implements // override + documents class-name derivation.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread Test/AblyLiveObjectsTesting/README.md
Comment thread Test/AblyLiveObjectsTesting/ObjectsPool+TestsOnly.swift Outdated
- Add non-reporting history/presence-history helpers and use them inside
  every pollUntil predicate (HistoryTests, PublishTests, PresenceTests,
  ChannelHistoryTests — 11 sites): a transient error during polling now
  retries instead of permanently failing the test; final reads keep the
  reporting variants. (CodeRabbit, extended to two suites it didn't flag.)
- Remove the unused ObjectsPool.Entry tombstone accessors (Copilot);
  verified unused by compile proof and receiver type audit.
- README (AblyLiveObjectsTesting): clarify the D3 dumb-accessor rule —
  mechanical shape-preserving constructs (enum-case dispatch, element-wise
  forwarding, continuation bridging) are not "logic" — and record
  testsOnly_publish as a lead-approved D3 exception with rationale
  (composes the production RTO15d validator + CoreSDK.nosync_publish,
  deliberately without the RTO20 apply stage). Rewrite its stale
  "early days of the SDK" comment accordingly. (Copilot + CodeRabbit.)
- Throw a purpose-built ObjectsHelperError instead of HTTPError for the
  type-mismatch failure in counterInstanceId (CodeRabbit nitpick).
- Make the tests-only siteTimeserials init parameter non-optional with an
  empty-dictionary default and drop the dead nil-coalescing (CodeRabbit
  nitpick).

Verified: swift build --build-tests green; TestsOnlySeamsTests +
LiveObjectMutableStateTests pass (21 tests); make lint (EditorConfig +
seams guardrail) green.
@github-actions
github-actions Bot temporarily deployed to staging/pull/2235/features August 6, 2026 06:18 Inactive
@sacOO7

sacOO7 commented Aug 6, 2026

Copy link
Copy Markdown
Contributor Author

Re the six CodeRabbit nitpicks (posted in the review body, so answering here) — three applied in fadb670, three declined:

Applied:

  • ObjectsIntegrationHelpers — purpose-built error: counterInstanceId now throws a dedicated ObjectsHelperError instead of HTTPError (which stays for the genuine HTTP failure in ObjectsRestProvisioning).
  • Stale testsOnly_publish comment: rewritten to describe the seam's current purpose (validate with the production RTO15d check, publish via CoreSDK.nosync_publish, deliberately without the RTO20 apply stage), cross-referencing the new README exception entry.
  • testsOnly_siteTimeserials optionality: parameter is now [String: String] = [:] and the dead ?? [:] is gone (the sole call site passes a non-optional dictionary).

Declined:

  • Fold RTLC12e1_increment_non_finite_throws into the table test: the two tests map to two distinct spec Test IDs (objects/unit/RTLC12e1/increment-non-number-0 and …/increment-invalid-amounts-table-0 in internal_live_counter_api.md), and the UTS translation audit keys off exactly those // UTS: tags — folding one orphans a spec ID.
  • PresenceTests client-setup helpers: the UTS suites are deliberately line-by-line translations of the spec's per-test Setup blocks; factoring the setup into helpers trades that traceability for brevity we don't need.
  • Drop parameterization on the RSL1l1 deviation placeholder: the spec runs every test in the file per protocol variant; the placeholder keeps arguments: [false, true] for structural parity and is disabled by default behind RUN_DEVIATIONS, so the double record costs nothing.

@github-actions
github-actions Bot temporarily deployed to staging/pull/2235/AblyLiveObjects August 6, 2026 06:19 Inactive
@github-actions
github-actions Bot temporarily deployed to staging/pull/2235/jazzydoc August 6, 2026 06:20 Inactive
@github-actions
github-actions Bot temporarily deployed to staging/pull/2235/markdown-api-reference August 6, 2026 06:21 Inactive
@sacOO7 sacOO7 changed the title [LiveObjects] Enable UTS integration test suites (17/17 objects tier passing) [AIT-1231][LiveObjects] Enable UTS integration test suites (17/17 objects tier passing) Aug 6, 2026
…jects-uts-integration-tests

Brings in the PR #2234 review fixes (comment-policy sweep, citation
corrections, the nosync_onChannelRelease/nosync_resetDataToZeroValued
renames, the subscription-register let refactor, the SyncCursor revert
to throws, the CCR3b size fix, Errors numericCode single-sourcing) and
the CI fixes.

Conflict resolutions:
- Seam extraction wins: the testsOnly_ members stay in
  Test/AblyLiveObjectsTesting (not Sources); the register-refactor
  signature change is ported into the extracted
  testsOnly_applyObjectMessages seam.
- Wave-1 dedup deletions win: the dispose-twin tests and the noop emit
  test stay deleted; the base's comment/citation fixes are applied to
  the surviving tests (nosync_onChannelRelease doc, RTLO4b4c3a retag).
- Leaked-tag cleanups reconciled (UTS/README.md stays deleted;
  deviations.md files keep the moved content, tags gone).
- testsOnly_underlyingLiveObjectsError re-homed in AblyLiveObjectsTesting
  (the reverted SyncCursorTests need it; the userInfo key is raised to
  internal with the usual intent comment).

Verified: swift build --build-tests green; native unit suite, UTS unit
sample, SyncCursor/seams/mutable-state/PluginAPI suites all pass;
EditorConfig + seams guardrail green.
@sacOO7
sacOO7 merged commit c745f40 into feature/liveobjects-implementation Aug 6, 2026
24 of 27 checks passed
@sacOO7
sacOO7 deleted the feature/liveobjects-uts-integration-tests branch August 6, 2026 09:40

@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.

🧹 Nitpick comments (2)
LiveObjects/Tests/AblyLiveObjectsTests/InternalDefaultLiveMapTests.swift (2)

1349-1349: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick win

Restore duplicate MAP_CREATE coverage.

Line 1349 removes the test that verifies a second create is discarded after the initial value is merged. This guard protects idempotent operation application. Without the test, a regression can merge the initial value twice and change map state incorrectly. Keep an equivalent assertion through the new test seam.

The removed test is identified in the supplied line-range change details.

🤖 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 `@LiveObjects/Tests/AblyLiveObjectsTests/InternalDefaultLiveMapTests.swift` at
line 1349, Restore duplicate MAP_CREATE coverage in MapCreateOperationTests by
adding an equivalent test through the new test seam. Verify that after the
initial value is merged, applying a second create is discarded and does not
alter the map state, preserving idempotent operation application.

315-315: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick win

Keep the RTLM6i omission regression test.

Line 315 removes coverage for a replacement state that omits clearTimeserial. InternalDefaultLiveMap.replaceData assigns clearTimeserial = state.map?.clearTimeserial, so this transition clears stale state. Restore the case or add an equivalent test in the new test-support layout.

The production assignment is in LiveObjects/Sources/AblyLiveObjects/Internal/InternalDefaultLiveMap.swift.

🤖 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 `@LiveObjects/Tests/AblyLiveObjectsTests/InternalDefaultLiveMapTests.swift` at
line 315, Restore or add the RTLM6i regression test in the
InternalDefaultLiveMap tests for replacing state that omits clearTimeserial.
Verify that replaceData clears the previously stored clearTimeserial value when
state.map?.clearTimeserial is absent, while preserving the existing RTLM6h
coverage.
🤖 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.

Nitpick comments:
In `@LiveObjects/Tests/AblyLiveObjectsTests/InternalDefaultLiveMapTests.swift`:
- Line 1349: Restore duplicate MAP_CREATE coverage in MapCreateOperationTests by
adding an equivalent test through the new test seam. Verify that after the
initial value is merged, applying a second create is discarded and does not
alter the map state, preserving idempotent operation application.
- Line 315: Restore or add the RTLM6i regression test in the
InternalDefaultLiveMap tests for replacing state that omits clearTimeserial.
Verify that replaceData clears the previously stored clearTimeserial value when
state.map?.clearTimeserial is absent, while preserving the existing RTLM6h
coverage.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 73723c01-f466-4b53-a21d-1c906e89963a

📥 Commits

Reviewing files that changed from the base of the PR and between fadb670 and 9c176af.

📒 Files selected for processing (21)
  • LiveObjects/Sources/AblyLiveObjects/Internal/CoreSDK.swift
  • LiveObjects/Sources/AblyLiveObjects/Internal/InternalDefaultLiveCounter.swift
  • LiveObjects/Sources/AblyLiveObjects/Internal/InternalDefaultLiveMap.swift
  • LiveObjects/Sources/AblyLiveObjects/Internal/InternalDefaultRealtimeObjects.swift
  • LiveObjects/Sources/AblyLiveObjects/Internal/LiveObjectMutableState.swift
  • LiveObjects/Sources/AblyLiveObjects/Internal/ObjectsPool.swift
  • LiveObjects/Sources/AblyLiveObjects/Public/Public Proxy Objects/PublicDefaultRealtimeObject.swift
  • LiveObjects/Sources/AblyLiveObjects/Utility/Errors.swift
  • LiveObjects/Tests/AblyLiveObjectsTests/DefaultPathObjectTests.swift
  • LiveObjects/Tests/AblyLiveObjectsTests/InternalDefaultLiveMapTests.swift
  • LiveObjects/Tests/AblyLiveObjectsTests/InternalDefaultRealtimeObjectsTests.swift
  • LiveObjects/Tests/AblyLiveObjectsTests/LiveObjectMutableStateTests.swift
  • LiveObjects/Tests/AblyLiveObjectsTests/ParentReferencesTests.swift
  • LiveObjects/Tests/AblyLiveObjectsTests/PublicRealtimeObjectTests.swift
  • LiveObjects/Tests/AblyLiveObjectsTests/SyncCursorTests.swift
  • LiveObjects/Tests/AblyLiveObjectsTests/TestsOnlySeamsTests.swift
  • Test/AblyLiveObjectsTesting/ARTErrorInfo+TestsOnly.swift
  • Test/AblyLiveObjectsTesting/InternalDefaultRealtimeObjects+TestsOnly.swift
  • Test/AblyLiveObjectsTesting/MockRealtimeObjects.swift
  • Test/UTS/deviations.md
  • Test/UTS/unit/objects/ObjectsUTSHelpers.swift
💤 Files with no reviewable changes (1)
  • Test/UTS/deviations.md
🚧 Files skipped from review as they are similar to previous changes (16)
  • LiveObjects/Tests/AblyLiveObjectsTests/ParentReferencesTests.swift
  • LiveObjects/Tests/AblyLiveObjectsTests/LiveObjectMutableStateTests.swift
  • Test/UTS/unit/objects/ObjectsUTSHelpers.swift
  • Test/AblyLiveObjectsTesting/MockRealtimeObjects.swift
  • LiveObjects/Sources/AblyLiveObjects/Internal/LiveObjectMutableState.swift
  • LiveObjects/Tests/AblyLiveObjectsTests/TestsOnlySeamsTests.swift
  • LiveObjects/Tests/AblyLiveObjectsTests/InternalDefaultRealtimeObjectsTests.swift
  • LiveObjects/Sources/AblyLiveObjects/Internal/CoreSDK.swift
  • LiveObjects/Sources/AblyLiveObjects/Public/Public Proxy Objects/PublicDefaultRealtimeObject.swift
  • LiveObjects/Tests/AblyLiveObjectsTests/DefaultPathObjectTests.swift
  • LiveObjects/Sources/AblyLiveObjects/Utility/Errors.swift
  • LiveObjects/Sources/AblyLiveObjects/Internal/InternalDefaultLiveMap.swift
  • LiveObjects/Tests/AblyLiveObjectsTests/PublicRealtimeObjectTests.swift
  • LiveObjects/Sources/AblyLiveObjects/Internal/ObjectsPool.swift
  • Test/AblyLiveObjectsTesting/InternalDefaultRealtimeObjects+TestsOnly.swift
  • LiveObjects/Sources/AblyLiveObjects/Internal/InternalDefaultRealtimeObjects.swift

sacOO7 added a commit that referenced this pull request Aug 6, 2026
…atch)

- ObjectsUTSSeededRealtimeObjects now echoes each captured publishAndApply
  operation back onto its existing pool entry (a reduced RTO20 ACK echo),
  so PathObjectMutationsTests asserts the spec's post-apply value reads
  verbatim for primitive writes; the deviation record is narrowed to the
  *_CREATE blueprint cases. The echo is asynchronous like the real ACK:
  the write APIs call publishAndApply while holding the written object's
  state mutex, so a synchronous echo violates exclusivity.
- Remove the channelName defaults from InternalDefaultRealtimeObjects
  (init + MutableState); production always supplies the name, and every
  test construction site now passes it explicitly.
- Reword the testsOnly_getFullPaths seam docs (counter + map) to describe
  the accessor rather than the pool DFS rationale that doesn't apply.
- Correct stale test_-prefixed method references in the objects UTS
  deviations record (the Swift Testing methods carry no prefix).

Verified: swift build --build-tests green; full UTS target 330 tests
passed (incl. sandbox integration; one documented RSL1l1 skip); native
unit tier TEST SUCCEEDED; EditorConfig + seams guardrail green.
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.

3 participants