[AIT-1081] Update liveobjects uts-to-kotlin skill to generate tests#1221
[AIT-1081] Update liveobjects uts-to-kotlin skill to generate tests#1221sacOO7 wants to merge 9 commits into
uts-to-kotlin skill to generate tests#1221Conversation
WalkthroughReorganizes the UTS test infrastructure into sub-packages ( ChangesUTS infrastructure package reorganization and new tests
UTS-to-Kotlin AI skill and reference documentation
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 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 |
Move the human-readable UTS guide and its self-contained HTML rendering into the uts/ module as README.md and index.html. Both cover the UTS concept, the three test tiers, the spec docs, the uts/ module layout, mock/proxy infrastructure, the two example tests, deviations, and appendices. Spec-doc references link to GitHub; paths are fully qualified; the two artifacts are kept in sync. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ier Gradle tasks Reorganise the uts module under a domain-rooted io.ably.lib.uts package that cleanly separates infrastructure from tests, and unit from integration: infra/ shared awaits (Utils.kt) infra/unit/ mock transports + ConnectionDetails builder infra/integration/ SandboxApp infra/integration/proxy/ ProxyManager, ProxySession unit/realtime/ ConnectionRecoveryTest (mocked) integration/proxy/realtime/ AuthReauthTest (sandbox + proxy) - The ConnectionDetails test builder no longer sits in io.ably.lib.types, so it obtains the package-private constructor reflectively (as liveobjects/TestUtils.kt does). - Add runUtsUnitTests / runUtsIntegrationTests Gradle tasks (filtered by package), mirroring runLiveObjectsUnitTests / runLiveObjectsIntegrationTests. - check.yml now runs :uts:runUtsUnitTests; integration-test.yml gains a check-uts job running :uts:runUtsIntegrationTests. - Bring uts/README.md and uts/index.html in sync with the new structure.
884ee87 to
aa0504e
Compare
Reflect the new test-source structure in the UTS guide, website, and the uts-to-kotlin skill: - Add the direct-sandbox (`integration/standard/<module>/`) tier alongside the existing unit and proxy tiers, and document that every tier is now organised by module (`realtime`, `liveobjects`, …). - Update §2 tier table, §4.2 directory tree + mental model, §7.3 SandboxApp (shared by both integration kinds), and §12 run commands in README.md, and mirror all of it in index.html (tags verified balanced, sections intact). - Generalise the skill's spec→test path mapping to `<module>`, add a direct-sandbox row, and split integration specs into fault-injecting (proxy) vs happy-path (direct sandbox) flows. - Correct stale "both tiers" wording now that there are three tiers.
…ckage mapping Rework the uts-to-kotlin skill to translate a whole UTS module at once instead of a single spec file: - Take a UTS module directory (e.g. .../specification/uts/objects) and validate it sits directly under uts/ with a standard tier structure. - Resolve the target ably-java package via uts-package-mapping.json (a new config file alongside the skill): a shared `testRoot` parent plus a `packages` table mapping each source module to its per-tier output dir (so objects -> liveobjects is explicit). Offer to create a mapping when one is missing. - Let the user pick a tier (unit / integration / proxy) and then translate all specs or a selected subset, looping each through the existing per-spec translation steps. Phase 1 (selection: Steps A-D) is new; Phase 2 (per-spec translation: Steps 1-7) keeps the existing rules, with Step 1/2 adjusted to consume the looped spec and the pre-resolved target.
…aluate mode Make the skill's selection phase deterministic and add an explicit translate-vs-evaluate choice: - Add scripts/resolve_uts.py — a bundled resolver that validates the module directory, reads uts-package-mapping.json, and emits JSON with, per tier, the target dir, Kotlin package, and the candidate specs with derived class names. This replaces the per-run hand-work (regex validation, path joins, snake_case->PascalCase) that the model previously improvised, so Phase 1 is byte-for-byte deterministic. Exclusions are checked relative to the tier base (robust to the checkout location), and --create guards the target name. - Rewrite Phase 1 (Steps A-E) around the resolver: resolve, confirm/create mapping, choose tier, choose specs, choose translate-only vs evaluate. - Gate Step 6 (run/fix) behind evaluate mode per writing-derived-tests.md's Translation (always) vs Evaluation (only when an implementation exists) split; translate-only stops after compile + review. - Make the reference fetch mandatory (WebFetch added to allowed-tools). - Fix the file template to use the resolver's package/className (no hardcoded realtime, no double Test suffix) and the spec's full @uts id; correct stale uts/test/... proxy doc paths.
…rence The objects UTS specs are written in ably-js-style pseudocode, but ably-java is a typed SDK (RTTS1-10 partition). Add references/objects-mapping.md mapping each ably-js symbol to its ably-java equivalent: entry point, async (CompletableFuture/await), the typed PathObject/Instance hierarchies and as* casts, the LiveMapValue write union, creation value types, subscriptions, sync-state events, ValueType, message/operation getters, error codes, path dot-escaping, and the internal-graph caveat for unit specs. Wire it in deterministically: each module declares its translation reference via a `notes` field in uts-package-mapping.json; resolve_uts.py resolves it to `translationNotes` (absolute path, or null), and SKILL.md makes it required reading before Phase 2 when present.
…ap them Translate objects/helpers/standard_test_pool.md into ably-java test helpers in uts/.../unit/liveobjects/helpers.kt: the standard object pool, the protocol- and object-message builders (emitting the integer-coded wire JSON the SDK's Gson expects), setupSyncedChannel/NoAck over the existing MockWebSocket, and buildPublicObjectMessage — which reaches the internal PAOM3/PAOOP3 construction (WireObjectMessage -> DefaultObjectMessage) by reflection, so it runs today even though the rest of :liveobjects is unimplemented. Add testRuntimeOnly(:liveobjects) so that reflection resolves while keeping the compile classpath decoupled. Wire the mapping reference at it: objects-mapping.md gains a "Unit-test helpers" section mapping each spec helper to its Kotlin name, and §11/§13 are corrected to note public_object_message.md is translatable via buildPublicObjectMessage rather than internal-only.
8276473 to
752b45e
Compare
e38b889 to
752b45e
Compare
…efactor - Add ChannelHistoryTest (RTL10d) and TokenRequestTest (RSA9/RSA9a/RSA9g) direct-sandbox integration tests, parameterised over json/msgpack. - Add junit-jupiter-params dependency (@ParameterizedTest / @valuesource). - Consolidate the sandbox host into a single SandboxApp.sandboxHost constant (removed from ProxyManager; ProxySession defaults both hosts to it). - Sync uts/README.md, uts/index.html, and the uts-to-kotlin SKILL.md for the direct-sandbox tier: new ChannelHistoryTest walkthrough, integration-tests umbrella section, section renumber. - Rename unit liveobjects helpers.kt -> Helpers.kt (case-only).
uts-to-kotlin skill to generate tests
There was a problem hiding this comment.
Actionable comments posted: 4
🧹 Nitpick comments (1)
.claude/skills/uts-to-kotlin/SKILL.md (1)
353-374: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winMake this template tier-specific and use explicit imports.
This scaffold is presented as the resolver-selected tier template, but it still hardcodes unit-only setup (
infra.unit.*,MockWebSocket,ConnectionDetails) and star imports. That makes the integration/proxy path easy to start from the wrong skeleton even though later sections requireSandboxApp/ProxySessionwiring. Split this into per-tier templates (or relabel this one as unit-only) and list concrete imports instead of*.🤖 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 @.claude/skills/uts-to-kotlin/SKILL.md around lines 353 - 374, This template is still unit-only even though it is presented as the resolver-selected tier scaffold, and it also relies on star imports. Update the Skill.md template around the test scaffold to either split it into separate tier-specific templates or clearly label this one as unit-only, and replace the wildcard imports with explicit imports for the exact symbols used. Make sure the correct tier-specific setup is shown for the resolver path, especially the symbols that differ between unit and integration/proxy flows such as SandboxApp and ProxySession.
🤖 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 @.claude/skills/uts-to-kotlin/references/objects-mapping.md:
- Around line 530-545: The helper reference in the objects-mapping docs uses the
wrong filename casing, so update the guidance to point consistently to
Helpers.kt instead of helpers.kt. Fix the prose and the table entry that
references uts/src/test/kotlin/io/ably/lib/uts/unit/liveobjects/Helpers.kt so
readers can locate the actual helper file and related symbols like
setupSyncedChannel, setupSyncedChannelNoAck, buildObjectSyncMessage, and
buildPublicObjectMessage without path mismatches.
- Around line 137-147: Add language tags to the fenced code examples in the
objects-mapping reference so markdownlint stops flagging them and syntax
highlighting is restored. Update the affected examples in the translation
guidance sections around the root.entries()/root.keys() snippets and the other
noted example blocks to use an appropriate tag such as kotlin, markdown, or
text, keeping the existing content unchanged.
In `@uts/build.gradle.kts`:
- Around line 44-54: The custom Test tasks runUtsUnitTests and
runUtsIntegrationTests only set filters, so they are not actually wired to the
UTS test source set. Update these tasks in uts/build.gradle.kts to inherit the
same testClassesDirs and classpath as the built-in test task, and keep the
existing includeTestsMatching filters so they execute the intended
io.ably.lib.uts.unit and io.ably.lib.uts.integration tests instead of passing
empty.
In `@uts/README.md`:
- Around line 42-59: The README contains unlabeled fenced code blocks that
trigger markdownlint and lose syntax highlighting. Update the fenced blocks in
the affected diagram/example sections to include an appropriate language
identifier such as text or kotlin, using the same README content around the
spec/test hierarchy and other referenced fenced blocks, so the markdown stays
lint-clean and renders correctly.
---
Nitpick comments:
In @.claude/skills/uts-to-kotlin/SKILL.md:
- Around line 353-374: This template is still unit-only even though it is
presented as the resolver-selected tier scaffold, and it also relies on star
imports. Update the Skill.md template around the test scaffold to either split
it into separate tier-specific templates or clearly label this one as unit-only,
and replace the wildcard imports with explicit imports for the exact symbols
used. Make sure the correct tier-specific setup is shown for the resolver path,
especially the symbols that differ between unit and integration/proxy flows such
as SandboxApp and ProxySession.
🪄 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
Run ID: 27e70f9e-9e77-46d5-a860-34d544c796f2
📒 Files selected for processing (32)
.claude/skills/uts-to-kotlin/SKILL.md.claude/skills/uts-to-kotlin/references/objects-mapping.md.claude/skills/uts-to-kotlin/scripts/resolve_uts.py.claude/skills/uts-to-kotlin/uts-package-mapping.json.github/workflows/check.yml.github/workflows/integration-test.ymluts/README.mduts/build.gradle.ktsuts/index.htmluts/src/test/kotlin/io/ably/lib/types/Utils.ktuts/src/test/kotlin/io/ably/lib/uts/deviations.mduts/src/test/kotlin/io/ably/lib/uts/infra/Utils.ktuts/src/test/kotlin/io/ably/lib/uts/infra/integration/SandboxApp.ktuts/src/test/kotlin/io/ably/lib/uts/infra/integration/proxy/ProxyManager.ktuts/src/test/kotlin/io/ably/lib/uts/infra/integration/proxy/ProxySession.ktuts/src/test/kotlin/io/ably/lib/uts/infra/unit/ClientFactories.ktuts/src/test/kotlin/io/ably/lib/uts/infra/unit/DefaultPendingConnection.ktuts/src/test/kotlin/io/ably/lib/uts/infra/unit/DefaultPendingRequest.ktuts/src/test/kotlin/io/ably/lib/uts/infra/unit/FakeClock.ktuts/src/test/kotlin/io/ably/lib/uts/infra/unit/MockEvent.ktuts/src/test/kotlin/io/ably/lib/uts/infra/unit/MockHttpClient.ktuts/src/test/kotlin/io/ably/lib/uts/infra/unit/MockHttpEngine.ktuts/src/test/kotlin/io/ably/lib/uts/infra/unit/MockWebSocket.ktuts/src/test/kotlin/io/ably/lib/uts/infra/unit/MockWebSocketEngineFactory.ktuts/src/test/kotlin/io/ably/lib/uts/infra/unit/PendingConnection.ktuts/src/test/kotlin/io/ably/lib/uts/infra/unit/PendingRequest.ktuts/src/test/kotlin/io/ably/lib/uts/infra/unit/Utils.ktuts/src/test/kotlin/io/ably/lib/uts/integration/proxy/realtime/AuthReauthTest.ktuts/src/test/kotlin/io/ably/lib/uts/integration/standard/realtime/ChannelHistoryTest.ktuts/src/test/kotlin/io/ably/lib/uts/integration/standard/realtime/TokenRequestTest.ktuts/src/test/kotlin/io/ably/lib/uts/unit/liveobjects/Helpers.ktuts/src/test/kotlin/io/ably/lib/uts/unit/realtime/ConnectionRecoveryTest.kt
💤 Files with no reviewable changes (1)
- uts/src/test/kotlin/io/ably/lib/types/Utils.kt
| ``` | ||
| # spec | ||
| FOR [key, pathObj] IN root.entries(): … | ||
| ASSERT "name" IN root.keys() | ||
| keys = list(root.keys()) | ||
| ``` | ||
| ```kotlin | ||
| for ((key, pathObj) in root.entries()) { … } // Map.Entry destructures into (key, value) | ||
| assertTrue("name" in root.keys()) // Kotlin `in` -> Iterable.contains | ||
| val keys = root.keys().toList() // when the spec materialises a list / checks length | ||
| ``` |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
Add language tags to these fenced examples.
markdownlint is already flagging these code blocks. Adding kotlin, markdown, or text here will clear the lint noise and restore syntax highlighting in the main translation examples.
Also applies to: 191-198, 283-296, 316-323, 418-433, 563-592
🧰 Tools
🪛 markdownlint-cli2 (0.22.1)
[warning] 137-137: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
🤖 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 @.claude/skills/uts-to-kotlin/references/objects-mapping.md around lines 137
- 147, Add language tags to the fenced code examples in the objects-mapping
reference so markdownlint stops flagging them and syntax highlighting is
restored. Update the affected examples in the translation guidance sections
around the root.entries()/root.keys() snippets and the other noted example
blocks to use an appropriate tag such as kotlin, markdown, or text, keeping the
existing content unchanged.
Source: Linters/SAST tools
| ### Unit-test helpers — `standard_test_pool.md` → `helpers.kt` | ||
|
|
||
| Every objects unit spec opens with `setup_synced_channel` and constructs protocol/object messages with the | ||
| `build_*` helpers. These are implemented in | ||
| `uts/src/test/kotlin/io/ably/lib/uts/unit/liveobjects/helpers.kt` — **call them; don't hand-roll the mock | ||
| setup or message JSON.** | ||
|
|
||
| | Spec helper | `helpers.kt` | | ||
| |---|---| | ||
| | `{ client, channel, root, mock_ws } = AWAIT setup_synced_channel("test")` | `val (client, channel, root, mockWs) = setupSyncedChannel("test")` (`suspend`, returns `SyncedChannel`) | | ||
| | `setup_synced_channel_no_ack(...)` | `setupSyncedChannelNoAck(...)` | | ||
| | `build_object_sync_message` / `build_object_message` / `build_ack_message` | `buildObjectSyncMessage` / `buildObjectMessage` / `buildAckMessage` → `ProtocolMessage` | | ||
| | `build_counter_inc` / `build_map_set` / `build_map_remove` / `build_map_clear` / `build_object_delete` / `build_counter_create` / `build_map_create` | same names camelCased → wire `JsonObject` | | ||
| | `build_object_state` / `build_object_message_with_state` | `buildObjectState` / `buildObjectMessageWithState` | | ||
| | `build_public_object_message(msg, channel)` | `buildPublicObjectMessage(wireJson, channel)` (reflective; §11) | | ||
| | `STANDARD_POOL_OBJECTS` | `STANDARD_POOL_OBJECTS` | |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
Fix the helper filename casing.
This section points readers to .../unit/liveobjects/helpers.kt, but the helper added in this stack is uts/src/test/kotlin/io/ably/lib/uts/unit/liveobjects/Helpers.kt. On Linux/macOS source navigation that path mismatch is enough to send people to a non-existent file, so the prose and table should use Helpers.kt consistently.
🤖 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 @.claude/skills/uts-to-kotlin/references/objects-mapping.md around lines 530
- 545, The helper reference in the objects-mapping docs uses the wrong filename
casing, so update the guidance to point consistently to Helpers.kt instead of
helpers.kt. Fix the prose and the table entry that references
uts/src/test/kotlin/io/ably/lib/uts/unit/liveobjects/Helpers.kt so readers can
locate the actual helper file and related symbols like setupSyncedChannel,
setupSyncedChannelNoAck, buildObjectSyncMessage, and buildPublicObjectMessage
without path mismatches.
| tasks.register<Test>("runUtsUnitTests") { | ||
| filter { | ||
| includeTestsMatching("io.ably.lib.uts.unit.*") | ||
| } | ||
| } | ||
|
|
||
| tasks.register<Test>("runUtsIntegrationTests") { | ||
| filter { | ||
| includeTestsMatching("io.ably.lib.uts.integration.*") | ||
| } | ||
| } |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🌐 Web query:
In Gradle Kotlin DSL, does a custom tasks.register("...")automatically inherittestClassesDirsandclasspathfrom the built-intesttask, or do those need to be set explicitly fromsourceSets["test"]?
💡 Result:
In Gradle, a custom task registered with tasks.register<Test>("...") does not automatically inherit testClassesDirs and classpath from the built-in test task [1][2]. By design, Gradle's JVM plugins automatically configure only the built-in test task to use the test source set [1][2]. When you create a custom Test task, you must explicitly configure both testClassesDirs and classpath using the appropriate sourceSets [1][2]. The recommended approach is to manually set these properties as shown below: val myCustomTest = tasks.register("myCustomTest") { testClassesDirs = sourceSets["test"].output.classesDirs classpath = sourceSets["test"].runtimeClasspath } If you are creating a custom test task for a different set of tests (e.g., integration tests), you should define a corresponding sourceSet and point the task properties to that specific source set instead: val integrationTest = tasks.register("integrationTest") { testClassesDirs = sourceSets["intTest"].output.classesDirs classpath = sourceSets["intTest"].runtimeClasspath } Relying on automatic inheritance is not supported, and attempting to do so will result in a task that does not correctly locate or execute your test classes [1][2].
Citations:
- 1: https://docs.gradle.org/current/userguide/java_testing.html
- 2: https://docs.gradle.org/9.5.0/userguide/java_testing.html
Wire the custom Test tasks to the test source set. tasks.register<Test>(...) here only adds the filter; it does not inherit testClassesDirs or classpath from the built-in test task, so these tasks can pass without running any UTS tests.
Suggested fix
+val testSourceSet = sourceSets["test"]
+
tasks.register<Test>("runUtsUnitTests") {
+ testClassesDirs = testSourceSet.output.classesDirs
+ classpath = testSourceSet.runtimeClasspath
filter {
includeTestsMatching("io.ably.lib.uts.unit.*")
}
}
tasks.register<Test>("runUtsIntegrationTests") {
+ testClassesDirs = testSourceSet.output.classesDirs
+ classpath = testSourceSet.runtimeClasspath
filter {
includeTestsMatching("io.ably.lib.uts.integration.*")
}
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| tasks.register<Test>("runUtsUnitTests") { | |
| filter { | |
| includeTestsMatching("io.ably.lib.uts.unit.*") | |
| } | |
| } | |
| tasks.register<Test>("runUtsIntegrationTests") { | |
| filter { | |
| includeTestsMatching("io.ably.lib.uts.integration.*") | |
| } | |
| } | |
| val testSourceSet = sourceSets["test"] | |
| tasks.register<Test>("runUtsUnitTests") { | |
| testClassesDirs = testSourceSet.output.classesDirs | |
| classpath = testSourceSet.runtimeClasspath | |
| filter { | |
| includeTestsMatching("io.ably.lib.uts.unit.*") | |
| } | |
| } | |
| tasks.register<Test>("runUtsIntegrationTests") { | |
| testClassesDirs = testSourceSet.output.classesDirs | |
| classpath = testSourceSet.runtimeClasspath | |
| filter { | |
| includeTestsMatching("io.ably.lib.uts.integration.*") | |
| } | |
| } |
🤖 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 `@uts/build.gradle.kts` around lines 44 - 54, The custom Test tasks
runUtsUnitTests and runUtsIntegrationTests only set filters, so they are not
actually wired to the UTS test source set. Update these tasks in
uts/build.gradle.kts to inherit the same testClassesDirs and classpath as the
built-in test task, and keep the existing includeTestsMatching filters so they
execute the intended io.ably.lib.uts.unit and io.ably.lib.uts.integration tests
instead of passing empty.
| ``` | ||
| ┌──────────────────────────────┐ | ||
| │ Ably features spec │ ← the ultimate authority (RSC*, RTN*, RTL* …) | ||
| │ (features.md) │ | ||
| └──────────────┬───────────────┘ | ||
| │ distilled into portable test specs | ||
| ▼ | ||
| ┌──────────────────────────────┐ | ||
| │ UTS test specs (.md) │ ← language-neutral pseudocode, one file per feature | ||
| │ "writing-test-specs" │ e.g. realtime/unit/connection/connection_recovery_test.md | ||
| └──────────────┬───────────────┘ | ||
| │ translated ("derived") per SDK | ||
| ▼ | ||
| ┌──────────────────────────────┐ | ||
| │ Derived tests │ ← concrete, runnable tests in the SDK's language | ||
| │ (this repo: Kotlin in uts/) │ e.g. ConnectionRecoveryTest.kt | ||
| └──────────────────────────────┘ | ||
| ``` |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
Add language identifiers to the fenced blocks.
These unlabeled fences are already tripping markdownlint. Please mark them as text, kotlin, or another appropriate language so the README stays lint-clean and renders with syntax highlighting.
Also applies to: 224-243, 850-878, 888-909
🧰 Tools
🪛 markdownlint-cli2 (0.22.1)
[warning] 42-42: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
🤖 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 `@uts/README.md` around lines 42 - 59, The README contains unlabeled fenced
code blocks that trigger markdownlint and lose syntax highlighting. Update the
fenced blocks in the affected diagram/example sections to include an appropriate
language identifier such as text or kotlin, using the same README content around
the spec/test hierarchy and other referenced fenced blocks, so the markdown
stays lint-clean and renders correctly.
Source: Linters/SAST tools
uts-to-kotlinskill to better generateably-javatestssandboxtest, need to update the same📚 Human-readable UTS guide + website
To make the UTS setup approachable, this PR adds a comprehensive guide and a self-contained website, kept in sync:
uts/README.md— renders on the module's GitHub page.uts/index.html— a standalone, offline-friendly website (inline SVG flow diagrams, scroll-spy nav, light/dark theme; no external assets).Both walk through: what UTS is → the three test tiers → the spec docs (linked to GitHub) → the
uts/module layout → the SDK hook points → the unit & proxy infrastructure → the two example tests → deviations → how to run → appendices (flow diagrams + per-file API reference + source map).🗂️ Test package restructure
Test sources are reorganised under a domain-rooted
io.ably.lib.utspackage that cleanly separates infrastructure from tests, and unit from integration:The
unit/↔infra/unit/andintegration/↔infra/integration/pairing is what the new Gradle tasks key off.⚙️ Per-tier Gradle tasks + CI wiring
Added two package-filtered test tasks in
uts/build.gradle.kts, mirroringrunLiveObjectsUnitTests/runLiveObjectsIntegrationTests::uts:runUtsUnitTestsio.ably.lib.uts.unit.*(mocked, fast)check.yml(PR gate):uts:runUtsIntegrationTestsio.ably.lib.uts.integration.*(real sandbox + proxy)integration-test.yml→ newcheck-utsjob✅ Validation
./gradlew :uts:runUtsUnitTests→ 6/6 pass ·:uts:runUtsIntegrationTests→ 1/1 pass.checkWithCodenarc checkstyleMain checkstyleTest runUnitTests runLiveObjectsUnitTests :uts:runUtsUnitTests→ BUILD SUCCESSFUL.Summary by CodeRabbit
New Features
Bug Fixes