Skip to content

[DX-947] Expand unit test coverage and add TTY test infrastructure#162

Merged
umair-ably merged 5 commits intomainfrom
DX-947-tests
Mar 12, 2026
Merged

[DX-947] Expand unit test coverage and add TTY test infrastructure#162
umair-ably merged 5 commits intomainfrom
DX-947-tests

Conversation

@umair-ably
Copy link
Contributor

@umair-ably umair-ably commented Mar 11, 2026

Summary

  • Standardises all ~130 unit test files with shared helpers (standardHelpTests(), standardFlagTests(), standardArgValidationTests(), standardControlApiErrorTests()) to enforce the 5 required describe blocks and eliminate boilerplate
  • Adds new shared test infrastructure: test/helpers/standard-tests.ts, test/helpers/control-api-test-helpers.ts, test/fixtures/control-api.ts (mock factories for apps, keys, rules)
  • Adds 16 new test files for previously untested commands: apps switch, auth keys switch, bench publisher/subscriber, integrations list, login, rooms messages (send/subscribe/history), rooms list, spaces list, channels occupancy get, logs connection-lifecycle subscribe, support ask, test wait, version
  • Introduces test/tty/ test tier with node-pty for testing interactive mode SIGINT handling in real pseudo-terminals (migrated from flaky piped-stdio unit tests)
  • Fixes flaky web CLI E2E tests by matching stable content text instead of styled COMMANDS headers that get garbled by xterm escape codes
  • Adds docs/Testing.md and test/README.md; updates CLAUDE.md, docs/Project-Structure.md

Stats

127 files changed, ~6,500 insertions, ~4,050 deletions (net ~2,450 lines — most reduction is boilerplate removal)

Review strategy

This is a large PR but most changes are mechanical and repetitive. Suggested review approach:

  1. Start with new helpers (high-impact): test/helpers/standard-tests.ts, test/helpers/control-api-test-helpers.ts, test/fixtures/control-api.ts
  2. TTY infrastructure: test/tty/tty-test-helper.ts, test/tty/commands/interactive-sigint.test.ts, vitest.config.ts, package.json
  3. Review new test files (16 files): test/unit/commands/apps/switch.test.ts, test/unit/commands/rooms/messages/send.test.ts, etc.
  4. Spot-check standardised test files — the pattern is the same across all ~130 modified files (replaced duplicate boilerplate with shared helper calls). Review 3-4 representative examples, then scan the rest for outliers:
    • Simple command: test/unit/commands/status.test.ts
    • Control API command: test/unit/commands/apps/create.test.ts
    • Realtime command: test/unit/commands/channels/subscribe.test.ts
    • Rooms command: test/unit/commands/rooms/presence/subscribe.test.ts
  5. Flaky test fixes: test/e2e/web-cli/web-cli.test.ts and siblings — changed assertions from styled headers to stable content
  6. Docs: docs/Testing.md, test/README.md

Test plan

  • pnpm test:unit passes
  • pnpm test:tty passes (local only, requires real terminal)
  • pnpm exec eslint . shows 0 errors
  • pnpm prepare succeeds

🤖 Generated with Claude Code

@vercel
Copy link

vercel bot commented Mar 11, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
cli-web-cli Ready Ready Preview, Comment Mar 11, 2026 9:07pm

Request Review

@coderabbitai
Copy link

coderabbitai bot commented Mar 11, 2026

Important

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 6fcf9db4-44af-47f7-be23-977e4965e397

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Walkthrough

This PR introduces TTY-dependent test infrastructure for interactive terminal testing, updates build and test documentation to reflect a new README regeneration step, expands the README with --json and --client-id flag examples across many commands, relocates flaky TTY-specific tests from unit tests to a dedicated TTY test suite, and adds extensive test coverage for help output and flag validation across numerous CLI command tests.

Changes

Cohort / File(s) Summary
Build & Test Infrastructure
.claude/skills/ably-new-command/SKILL.md, AGENTS.md, CONTRIBUTING.md, docs/Project-Structure.md, docs/Testing.md, test/README.md, package.json, vitest.config.ts
Updated build instructions to include README regeneration via pnpm exec oclif readme as a distinct step, added TTY test documentation and execution guidance, introduced test:tty npm script and new vitest tty project configuration for sequential TTY test execution with 15s timeout.
README Documentation
README.md
Expanded command documentation across channels, apps, auth, integrations, bench, config, status, rooms, spaces, and logs commands to include --json/--pretty-json usage examples and new --client-id, --mutable-messages flags with corresponding help text updates.
TTY Test Infrastructure
test/tty/tty-test-helper.ts, test/tty/commands/interactive-sigint.test.ts
Added new TTY testing framework using node-pty for interactive terminal testing, including PTY spawning, output capture, input simulation, and Ctrl+C signal handling; comprehensive test suite for SIGINT behavior in interactive mode with multiple prompt scenarios.
Interactive Test Cleanup
test/unit/commands/interactive-sigint.test.ts, test/unit/commands/interactive.test.ts
Removed flaky TTY-dependent Ctrl+C tests and replaced with note referencing new dedicated TTY test suite; consolidated imports and reduced boilerplate in interactive test file.
Account & Auth Command Tests
test/unit/commands/accounts/*, test/unit/commands/auth/*
Added consistent test suites across all account and auth commands for help output validation, flag presence verification (--json), and argument validation; includes comprehensive test suite for auth:keys:switch with API mocking.
App Command Tests
test/unit/commands/apps/*.test.ts
Added help, flag (--json), and argument validation tests across all app commands; comprehensive test suite for apps:switch including JSON output validation, API mocking for GET /v1/me and app listing, and authentication error handling.
Channel & Room Command Tests
test/unit/commands/channels/*, test/unit/commands/rooms/*
Added help, flag (--json), and argument validation tests across channel and room commands; comprehensive test suites for rooms:messages:* and rooms:occupancy:* with mock Ably chat interactions, duration parameter handling, metadata support, and error scenarios; updated many test invocations to include --duration 1.
Space Command Tests
test/unit/commands/spaces/*
Added help, flag (--json), and argument validation tests across all space commands; includes tests for space members, locks, locations, and cursors with explicit duration parameters and error handling for failed space entry/attachment.
Bench, Config, Logs & Status Tests
test/unit/commands/bench/*.test.ts, test/unit/commands/config/*.test.ts, test/unit/commands/logs/*, test/unit/commands/status.test.ts
Added help output and flag validation tests for all commands; comprehensive test suites for bench:publisher and bench:subscriber with Ably realtime mocking; extended logs tests with duration parameters and network error handling.
Integration, Support & Other Command Tests
test/unit/commands/integrations/*, test/unit/commands/support/*, test/unit/commands/queues/*, test/unit/commands/channel-rule/*, test/unit/commands/connections/test.test.ts, test/unit/commands/login.test.ts, test/unit/commands/test/wait.test.ts, test/unit/commands/version.test.ts`
Added help and flag validation tests across integration and support commands; comprehensive test suites for integrations:list, support:ask with API mocking via nock; added stdin mocking for interactive queue deletion tests; extended command coverage with help output, argument validation, and error handling tests.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~35 minutes

Possibly related PRs

Suggested reviewers

  • jamiehenson
  • sacOO7
  • denissellu

Poem

🐰 Testing hops through TTY terminals true,
With Ctrl+C signals and prompts fresh and new,
README regenerates, flags shine bright,
Help validation spreads left and right,
Interactive testing now takes proper flight!

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The PR title clearly summarizes the main change: expanding unit test coverage and adding TTY test infrastructure, which aligns with the substantial additions across 90+ test files and new test tier.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch DX-947-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 and usage tips.

@umair-ably
Copy link
Contributor Author

#163

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 6

Note

Due to the large number of review comments, Critical, Major severity comments were prioritized as inline comments.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
test/unit/commands/logs/connection-lifecycle/subscribe.test.ts (1)

64-75: ⚠️ Potential issue | 🟡 Minor

Avoid stdout assertions for streamed subscribe output.

These cases are still verifying real-time subscribe output via the resolved stdout string, which is brittle for long-running commands and can miss this.log() emissions that happen before process teardown. Please switch these human-readable cases to the same vi.spyOn(console, "log") capture pattern used in other streaming tests, and keep captureJsonLogs() for the JSON path. Based on learnings: In tests for streaming commands under the ably-cli repo, replace stdout-based assertions with spying on console.log to capture real-time this.log() outputs, and parse the captured lines using parseLogLines() from test/helpers/ndjson.ts.

Also applies to: 129-170, 201-208, 239-245, 276-282

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@test/unit/commands/logs/connection-lifecycle/subscribe.test.ts` around lines
64 - 75, The test currently asserts streamed subscribe output by inspecting the
resolved stdout from runCommand (see uses of runCommand, stdout,
expect(channel.subscribe) and expect(stdout). Replace the human-readable stdout
assertions with a console.log spy: use vi.spyOn(console, "log") to capture
real-time this.log() emissions for the non-JSON path, then parse the captured
lines with parseLogLines from test/helpers/ndjson.ts and assert the expected
human-readable messages (e.g., "Subscribed to connection lifecycle logs"); keep
captureJsonLogs() and existing JSON-path assertions for the JSON route. Apply
the same replacement pattern to the other blocks noted (lines ~129-170, 201-208,
239-245, 276-282).
🟡 Minor comments (20)
test/unit/commands/support.test.ts-100-119 (1)

100-119: ⚠️ Potential issue | 🟡 Minor

Duplicate test — remove or consolidate.

This test is functionally identical to the existing test at lines 41-63 in the "unknown subcommand" describe block. Both tests:

  1. Set ABLY_CLI_NON_INTERACTIVE to "true"
  2. Run ["support", "unknowncommand"]
  3. Assert the output matches /not found|not.*command|available/i
  4. Restore the environment variable

Remove this duplicate test block to avoid redundancy.

Proposed fix
-  describe("error handling", () => {
-    it("should handle unknown subcommand gracefully", async () => {
-      const originalEnv = process.env.ABLY_CLI_NON_INTERACTIVE;
-      process.env.ABLY_CLI_NON_INTERACTIVE = "true";
-
-      try {
-        const { stdout, stderr } = await runCommand(
-          ["support", "unknowncommand"],
-          import.meta.url,
-        );
-        const output = stdout + (stderr || "");
-        expect(output).toMatch(/not found|not.*command|available/i);
-      } finally {
-        if (originalEnv === undefined) {
-          delete process.env.ABLY_CLI_NON_INTERACTIVE;
-        } else {
-          process.env.ABLY_CLI_NON_INTERACTIVE = originalEnv;
-        }
-      }
-    });
-  });
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@test/unit/commands/support.test.ts` around lines 100 - 119, Remove the
duplicate test case "should handle unknown subcommand gracefully" inside the
"error handling" describe block: either delete this it(...) block or consolidate
its assertions into the existing "unknown subcommand" test (the test with the
same runCommand(["support", "unknowncommand"]) call). Ensure any environment
setup/teardown for process.env.ABLY_CLI_NON_INTERACTIVE is preserved (move the
try/finally cleanup into the remaining test if needed) so no test relies on
leftover env changes.
test/unit/commands/channels/presence/enter.test.ts-215-229 (1)

215-229: ⚠️ Potential issue | 🟡 Minor

Assert the surfaced error message here.

expect(error).toBeDefined() passes for any command failure, so this does not prove the rejected presence.enter() error is what users actually see. Please assert on error?.message as well.

Suggested tightening
       const { error } = await runCommand(
         ["channels:presence:enter", "test-channel"],
         import.meta.url,
       );

       expect(error).toBeDefined();
+      expect(error?.message).toContain("Presence enter failed");
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@test/unit/commands/channels/presence/enter.test.ts` around lines 215 - 229,
The test currently only checks that an error exists; update the assertion to
verify the surfaced message matches the mocked rejection from
channel.presence.enter so we confirm the real error is propagated. After calling
runCommand([...], import.meta.url) and obtaining error, assert on error?.message
(e.g., contains or equals "Presence enter failed") instead of only
expect(error).toBeDefined(); this ensures the mocked Error("Presence enter
failed") is what users see.
test/unit/commands/support/contact.test.ts-132-139 (1)

132-139: ⚠️ Potential issue | 🟡 Minor

Assert the specific unknown-flag failure.

expect(error).toBeDefined() will pass for any thrown error, including unrelated command failures. Tighten this to verify the parser rejected --unknown-flag-xyz so the test actually protects the intended behavior.

Proposed tightening
   describe("error handling", () => {
     it("should handle errors gracefully", async () => {
       const { error } = await runCommand(
         ["support:contact", "--unknown-flag-xyz"],
         import.meta.url,
       );
-      expect(error).toBeDefined();
+      expect(error).toBeDefined();
+      expect(error?.message).toContain("--unknown-flag-xyz");
     });
   });
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@test/unit/commands/support/contact.test.ts` around lines 132 - 139, The test
currently only checks that an error exists which is too broad; update the
assertion in the "should handle errors gracefully" test that calls
runCommand(["support:contact", "--unknown-flag-xyz"], import.meta.url) to assert
the error specifically indicates the unknown-flag rejection (e.g. inspect
error.message or parser error code returned by runCommand) and assert it
contains the string "--unknown-flag-xyz" or the parser’s standard unknown-option
text (e.g. /unknown (flag|option)|unrecognized option/), so the test verifies
the parser rejected that specific flag rather than any generic failure.
test/unit/commands/logs/push/subscribe.test.ts-68-69 (1)

68-69: ⚠️ Potential issue | 🟡 Minor

Tighten the error-message assertion.

/No mock|client/i passes on any unrelated failure that happens to mention client, so this test can go green without actually exercising the missing-mock path.

🎯 Suggested fix
       expect(error).toBeDefined();
-      expect(error?.message).toMatch(/No mock|client/i);
+      expect(error?.message).toMatch(/no mock/i);
+      expect(error?.message).toMatch(/client/i);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@test/unit/commands/logs/push/subscribe.test.ts` around lines 68 - 69, The
current assertion expect(error?.message).toMatch(/No mock|client/i) is too
permissive; tighten it to assert the specific missing-mock error produced by the
code under test (the failure path exercised in this test). Update the assertion
in subscribe.test.ts to match the exact error text emitted when a mock client is
absent (e.g., use expect(error?.message).toMatch(/No mock client configured/i)
or expect(error?.message).toContain('No mock client configured')) so the test
only passes for the intended missing-mock path rather than any message
containing "client".
.claude/skills/ably-new-command/SKILL.md-364-370 (1)

364-370: ⚠️ Potential issue | 🟡 Minor

Keep this validation workflow aligned with the repo’s required sequence.

This now teaches a different flow from the repository guidance by splitting README generation out of pnpm prepare. Please reconcile this block with the actual required workflow, and update the checklist below to match the same source of truth.

As per coding guidelines, Run mandatory workflow IN ORDER for every change: pnpm prepare (build + update manifest/README), pnpm exec eslint . (lint, MUST be 0 errors), pnpm test:unit (test at minimum), and update docs if needed.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.claude/skills/ably-new-command/SKILL.md around lines 364 - 370, The
checklist shows a different command sequence (splitting README generation into a
separate pnpm exec oclif readme step) which diverges from the repo’s required
workflow; update the block to match the canonical sequence used by the repo:
ensure the instructions list the exact ordered steps for every change — pnpm
prepare (which performs build + updates manifest and README), then pnpm exec
eslint . (lint must be 0 errors), then pnpm test:unit — and remove or fold the
separate pnpm exec oclif readme line so the README generation is covered by pnpm
prepare and the checklist wording matches that single-source-of-truth sequence.
test/unit/commands/spaces/cursors/subscribe.test.ts-200-211 (1)

200-211: ⚠️ Potential issue | 🟡 Minor

Make the failure assertion specific.

This only proves that the command failed somehow. If the command starts failing earlier for an unrelated reason, this test still passes. Please assert the propagated message and that the subscription path was not reached.

Suggested tightening
       const { error } = await runCommand(
         ["spaces:cursors:subscribe", "test-space"],
         import.meta.url,
       );
       expect(error).toBeDefined();
+      expect(error!.message).toContain("Connection failed");
+      expect(space.cursors.subscribe).not.toHaveBeenCalled();
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@test/unit/commands/spaces/cursors/subscribe.test.ts` around lines 200 - 211,
The test "should handle space entry failure" currently only checks that an error
occurred; update it to assert the exact propagated error message and that the
subscription code path was not executed: after mocking
space.enter.mockRejectedValue(new Error("Connection failed")), call runCommand
as before and assert error.message === "Connection failed" (or that error
contains that string) and also assert that the space subscription mock (the mock
on the space object used for subscribing, e.g., space.subscribe or
spacesMock._getSpace(...).subscribe) was not called to guarantee the
subscription path was skipped.
test/unit/commands/spaces/locations/get-all.test.ts-123-136 (1)

123-136: ⚠️ Potential issue | 🟡 Minor

Assert the expected failure, not just any failure.

Right now this passes for any exception path. Since the test is named around getAll rejection, it should verify that the surfaced error matches that rejection.

Suggested tightening
       const { error } = await runCommand(
         ["spaces:locations:get-all", "test-space"],
         import.meta.url,
       );
       expect(error).toBeDefined();
+      expect(error!.message).toContain("Failed to get locations");
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@test/unit/commands/spaces/locations/get-all.test.ts` around lines 123 - 136,
The test currently only checks that some error is returned; change the assertion
to verify the specific rejection from space.locations.getAll by asserting the
surfaced error message matches "Failed to get locations" (e.g., replace
expect(error).toBeDefined() with an assertion on error.message or error string).
Update the test that uses getMockAblySpaces(),
space.locations.getAll.mockRejectedValue(new Error("Failed to get locations")),
and runCommand(...) to assert the exact error text so the test ensures the
getAll rejection is what was propagated.
test/unit/commands/integrations/delete.test.ts-289-296 (1)

289-296: ⚠️ Potential issue | 🟡 Minor

Duplicate test: this scenario is already covered at lines 96-104.

The "error handling" describe block already contains the exact same test case: it("should require ruleId argument", ...) with identical command invocation and assertion pattern. Remove this duplicate to avoid test redundancy.

🗑️ Suggested removal
-  describe("argument validation", () => {
-    it("should require ruleId argument", async () => {
-      const { error } = await runCommand(
-        ["integrations:delete", "--force"],
-        import.meta.url,
-      );
-      expect(error?.message).toMatch(/required|Missing/i);
-    });
-  });
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@test/unit/commands/integrations/delete.test.ts` around lines 289 - 296,
Remove the duplicate test case that asserts the required ruleId argument: inside
the "argument validation" describe in delete.test.ts remove the it("should
require ruleId argument", ...) block (the one invoking
runCommand(["integrations:delete", "--force"], import.meta.url) and expecting
error?.message toMatch /required|Missing/i) because the same scenario is already
covered in the "error handling" describe; keep one canonical test (the existing
one at lines ~96-104) and delete this redundant one to avoid duplicate
assertions.
CONTRIBUTING.md-13-13 (1)

13-13: ⚠️ Potential issue | 🟡 Minor

Keep pnpm test:unit explicit as the minimum required suite.

The current wording reads like contributors can pick any relevant test command. Please make pnpm test:unit mandatory first, then list the extra suites as conditional follow-ups.

Suggested wording
-3.  **Test:** Run relevant tests (`pnpm test:unit`, `pnpm test:integration`, `pnpm test:e2e`, `pnpm test:playwright`, or specific files) and ensure they pass. For interactive mode changes, also run `pnpm run test:tty` (requires a real terminal, not run in CI). Add new tests or update existing ones as needed.
+3.  **Test:** Run `pnpm test:unit` at minimum, then run any additional relevant suites (`pnpm test:integration`, `pnpm test:e2e`, `pnpm test:playwright`, or specific files) as needed. For interactive mode changes, also run `pnpm run test:tty` (requires a real terminal, not run in CI). Add new tests or update existing ones as needed.

As per coding guidelines **/*.{ts,tsx,js,mjs}: "Run mandatory workflow IN ORDER for every change: pnpm prepare ... pnpm exec eslint . ... pnpm test:unit (test at minimum), and update docs if needed."

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@CONTRIBUTING.md` at line 13, Update the "3.  **Test:**" bullet in
CONTRIBUTING.md so that "pnpm test:unit" is required first and explicitly
mandatory, then list the other test commands (`pnpm test:integration`, `pnpm
test:e2e`, `pnpm test:playwright`, `pnpm run test:tty`) as optional/conditional
follow-ups; specifically edit the sentence starting with "3.  **Test:** Run
relevant tests..." to require "pnpm test:unit" as the minimum mandatory suite
before mentioning the additional suites and the tty note.
test/unit/commands/spaces/locks/get-all.test.ts-123-134 (1)

123-134: ⚠️ Potential issue | 🟡 Minor

Assert the expected failure message.

Right now this will pass for any thrown error. Since the mock is explicitly rejecting with "Failed to get locks", assert on that message so the test validates the intended error path.

🔎 Tighten the assertion
       const { error } = await runCommand(
         ["spaces:locks:get-all", "test-space"],
         import.meta.url,
       );
-      expect(error).toBeDefined();
+      expect(error).toBeDefined();
+      expect(error?.message).toContain("Failed to get locks");
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@test/unit/commands/spaces/locks/get-all.test.ts` around lines 123 - 134, The
test currently only checks that an error was thrown; tighten it to assert the
specific failure message from the mock. Update the "error handling" spec (the
test invoking runCommand) to assert that the returned error's message equals or
matches "Failed to get locks" (the value the mock
space.locks.getAll.mockRejectedValue was given) instead of just using
expect(error).toBeDefined(); reference the runCommand invocation and the
space.locks.getAll mock to locate the assertion to change.
test/unit/commands/spaces/list.test.ts-135-142 (1)

135-142: ⚠️ Potential issue | 🟡 Minor

Make the error-path assertion specific.

expect(error).toBeDefined() is too permissive here. The mock sets a concrete "API error" message, so assert on it to avoid this test passing on an unrelated failure.

🔎 Tighten the assertion
       const { error } = await runCommand(["spaces:list"], import.meta.url);
-      expect(error).toBeDefined();
+      expect(error).toBeDefined();
+      expect(error?.message).toContain("API error");
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@test/unit/commands/spaces/list.test.ts` around lines 135 - 142, The test's
error-path assertion is too broad; replace the permissive
expect(error).toBeDefined() with a specific assertion that checks the mocked
message from mock.request.mockRejectedValue(new Error("API error")). Update the
assertion after runCommand(["spaces:list"], import.meta.url) to assert the
error's message (for example expect(error?.message).toEqual("API error") or
expect(error?.message).toContain("API error")), so the test verifies the exact
failure produced by the mocked getMockAblyRest request.
test/unit/commands/spaces/locks/get.test.ts-126-137 (1)

126-137: ⚠️ Potential issue | 🟡 Minor

Assert the propagated error text here.

This currently passes on any failure path, including unrelated setup regressions. Since the mock already injects "Failed to get lock", assert that message so the test proves the command surfaces the intended error.

🔎 Tighten the assertion
     const { error } = await runCommand(
       ["spaces:locks:get", "test-space", "my-lock"],
       import.meta.url,
     );
-      expect(error).toBeDefined();
+      expect(error).toBeDefined();
+      expect(error?.message).toContain("Failed to get lock");
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@test/unit/commands/spaces/locks/get.test.ts` around lines 126 - 137, The
test's final assertion is too loose; update the assertion that currently reads
expect(error).toBeDefined() to assert the propagated error text from the mocked
rejection (space.locks.get.mockRejectedValue(new Error("Failed to get lock"))).
Locate the test in get.test.ts that calls runCommand(["spaces:locks:get",
"test-space", "my-lock"], import.meta.url) and replace the broad check with an
assertion that the returned error object's message contains or equals "Failed to
get lock" (e.g., expect(error).toHaveProperty("message", "Failed to get lock")
or expect(error?.message).toContain("Failed to get lock")) so the test verifies
the intended error is surfaced.
AGENTS.md-8-13 (1)

8-13: ⚠️ Potential issue | 🟡 Minor

Don’t require pnpm test:tty for every change.

This makes a local-only, CI-skipped suite part of the mandatory workflow for all contributors, which conflicts with the note on the same line and raises the bar for unrelated changes. Keep pnpm test:unit as the required baseline and document pnpm test:tty as an extra step when touching TTY-specific behavior. As per coding guidelines, "Run mandatory workflow IN ORDER for every change: pnpm prepare (build + update manifest/README), pnpm exec eslint . (lint, MUST be 0 errors), pnpm test:unit (test at minimum), and update docs if needed."

📝 Suggested wording
 pnpm prepare        # 1. Build + update manifest
 pnpm exec oclif readme  # 2. Regenerate README.md from command metadata
 pnpm exec eslint .  # 3. Lint (MUST be 0 errors)
 pnpm test:unit      # 4. Test (at minimum)
-pnpm test:tty       # 5. TTY tests (local only, skip in CI)
-                    # 6. Update docs if needed
+                    # 5. Update docs if needed
+
+# Run when touching TTY-specific behavior or debugging interactive flows:
+# pnpm test:tty
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@AGENTS.md` around lines 8 - 13, Update AGENTS.md to remove "pnpm test:tty"
from the mandatory workflow list and instead document it as an optional/extra
step for TTY-specific changes; keep the required sequence as "pnpm prepare",
"pnpm exec eslint .", "pnpm test:unit" and then "update docs if needed", and add
a short note stating "Run pnpm test:tty locally when touching TTY-specific
behavior (CI skips this)". Use the exact tokens from the diff—pnpm prepare, pnpm
exec eslint ., pnpm test:unit, pnpm test:tty—to locate and edit the list and the
explanatory comment.
README.md-3575-3588 (1)

3575-3588: ⚠️ Potential issue | 🟡 Minor

Add a language to this fenced block.

The changed fence is still bare ``` and trips MD040 on this section. Use a neutral language like text if this is generated command output.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@README.md` around lines 3575 - 3588, The fenced code block in the README
showing the "USAGE/DESCRIPTION/EXAMPLES" output uses a bare ``` fence which
triggers MD040; change the opening fence to specify a neutral language like
backtick fence with "text" (i.e., replace ``` with ```text) so the block is
annotated as plain text; update the block around the Ably Spaces location
commands (the USAGE/EXAMPLES section) accordingly.
test/unit/commands/apps/switch.test.ts-4-4 (1)

4-4: ⚠️ Potential issue | 🟡 Minor

Remove the unused getMockConfigManager import.

It is never read in this file, so this will fail the repo’s zero-error lint pass. As per coding guidelines **/*.{ts,tsx,js,mjs}: "pnpm exec eslint . (lint, MUST be 0 errors)."

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@test/unit/commands/apps/switch.test.ts` at line 4, Remove the unused import
getMockConfigManager from the test file to satisfy lint rules; locate the import
statement importing getMockConfigManager in the top of the test module (the line
with "import { getMockConfigManager }") and delete that named import (or remove
the entire import statement if it only referenced getMockConfigManager) so the
symbol is no longer imported but unused.
README.md-3856-3861 (1)

3856-3861: ⚠️ Potential issue | 🟡 Minor

Remove the get-all example from src/commands/spaces/members/index.ts or implement the missing command.

The spaces members get-all example is listed in the source code (line 12 of src/commands/spaces/members/index.ts) and generates into README, but there is no corresponding get-all.ts implementation file. Other spaces subcommands (cursors, locations, locks) all have get-all.ts files; only members is missing one. Either remove the example from the index or create the implementation.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@README.md` around lines 3856 - 3861, The README lists a "spaces members
get-all" example but there is no corresponding implementation; either remove
that example entry from the members index or add the missing get-all command
file. To fix by implementing, create a new get-all.ts alongside the other member
subcommands exporting the same command shape (export const command, description,
and an async handler) and implement the handler to call the members listing API
(mirror how the other subcommands like cursors/locations/locks implement
get-all), then ensure the members index (index.ts) imports/exports the new
get-all command so it appears in the CLI help and README generation;
alternatively, simply delete the "get-all" example line from the members index
so the README no longer references a non-existent command.
vitest.config.ts-91-105 (1)

91-105: ⚠️ Potential issue | 🟡 Minor

Default test command will attempt TTY tests — consider excluding from shared projects or documenting the requirement.

The CI workflows are properly guarded with explicit --project flags (test:unit, test:integration, test:e2e, test:hooks), so CI safety is addressed. However, the default pnpm test script (vitest run without a project filter) and pnpm test:coverage (vitest run --coverage) will still attempt to run all projects including tty, which requires a real TTY and will fail in non-TTY environments.

Either remove tty from the shared projects array and only include it when explicitly requested (keeping it opt-in via CLI), or document that pnpm test requires TTY support and developers should use specific scripts like pnpm test:unit for headless CI/environments.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@vitest.config.ts` around lines 91 - 105, The "tty" shared project in the
Vitest projects array will be picked up by default runs and fails in non-TTY
environments; remove the project object whose test.name is "tty" from the common
projects array (or guard its inclusion behind an opt-in condition such as an
environment variable like RUN_TTY_TESTS) so that default "vitest run" and
coverage runs do not attempt TTY tests; update README or scripts to document how
to run the tty suite explicitly (e.g., via a dedicated npm script that passes
--project=tty or sets RUN_TTY_TESTS).
test/tty/commands/interactive-sigint.test.ts-89-113 (1)

89-113: ⚠️ Potential issue | 🟡 Minor

Test intent and assertion conflict on expected exit code.

The title says code 130, but the assertion accepts [0, 42, 130]. Please either tighten the assertion to 130 or rename the test to reflect multiple acceptable outcomes.

Possible rename-only fix
-    "should exit cleanly with code 130 when Ctrl+C is pressed during command execution",
+    "should interrupt command and allow clean exit after Ctrl+C during command execution",
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@test/tty/commands/interactive-sigint.test.ts` around lines 89 - 113, The test
title asserts that Ctrl+C should produce exit code 130 but the assertion allows
[0, 42, 130]; update the test to make intent consistent by changing the
expectation to only 130: replace the expect([0, 42, 130]).toContain(code) with
expect(code).toBe(130) (in the test whose description string is "should exit
cleanly with code 130 when Ctrl+C is pressed during command execution"), ensure
any comment about acceptable codes is removed or updated, and keep the existing
helpers spawnTty, waitForOutput, writeTty, sendCtrlC and proc.exitPromise logic
intact.
test/unit/commands/rooms/messages/history.test.ts-154-176 (1)

154-176: ⚠️ Potential issue | 🟡 Minor

The --order part of this test is currently unverified.

The test name says it covers both limit and order, but it only asserts limit. If the command stops forwarding --order, this still passes. Please assert the mapped history option for the requested ordering as well.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@test/unit/commands/rooms/messages/history.test.ts` around lines 154 - 176,
The test currently only asserts the limit but not the ordering; update the test
to also assert that room.messages.history was called with the correct mapped
ordering for the CLI flag. After locating the mapping in the command
implementation (the code that translates the "--order oldestFirst" arg), add an
assertion like
expect(room.messages.history).toHaveBeenCalledWith(expect.objectContaining({
order: <mappedValueForOldestFirst> })), using the exact mapped value used by the
command, so both limit and order are verified when runCommand is invoked.
test/unit/commands/bench/publisher.test.ts-68-91 (1)

68-91: ⚠️ Potential issue | 🟡 Minor

Assert the requested send count explicitly.

With --messages 2, this still passes if the command reports the wrong total because it only checks that messagesSent exists. Please assert the exact value so the benchmark result contract is actually covered.

Suggested assertion tightening
       const result = JSON.parse(stdout);
       expect(result).toHaveProperty("type", "result");
       expect(result).toHaveProperty("command", "bench:publisher");
       expect(result).toHaveProperty("success", true);
-      expect(result).toHaveProperty("messagesSent");
+      expect(result).toHaveProperty("messagesSent", 2);
       expect(result).toHaveProperty("testId");
       expect(result).toHaveProperty("transport");
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@test/unit/commands/bench/publisher.test.ts` around lines 68 - 91, The test
currently only checks that messagesSent exists; update the assertion after
parsing stdout from runCommand for "bench:publisher" to assert the exact
requested send count (from the "--messages 2" flag) by asserting
result.messagesSent === 2 (use expect(result.messagesSent).toBe(2) or
equivalent) so the benchmark contract is enforced; locate this in the test using
runCommand and the parsed result variable `result`.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 880b8242-3b10-454a-8320-d39251c1903b

📥 Commits

Reviewing files that changed from the base of the PR and between 5f25a91 and 03f71c8.

📒 Files selected for processing (111)
  • .claude/skills/ably-new-command/SKILL.md
  • AGENTS.md
  • CONTRIBUTING.md
  • README.md
  • docs/Project-Structure.md
  • docs/Testing.md
  • package.json
  • test/README.md
  • test/tty/commands/interactive-sigint.test.ts
  • test/tty/tty-test-helper.ts
  • test/unit/commands/accounts/current.test.ts
  • test/unit/commands/accounts/list.test.ts
  • test/unit/commands/accounts/login.test.ts
  • test/unit/commands/accounts/logout.test.ts
  • test/unit/commands/accounts/switch.test.ts
  • test/unit/commands/apps/channel-rules/create.test.ts
  • test/unit/commands/apps/channel-rules/delete.test.ts
  • test/unit/commands/apps/channel-rules/list.test.ts
  • test/unit/commands/apps/channel-rules/update.test.ts
  • test/unit/commands/apps/create.test.ts
  • test/unit/commands/apps/current.test.ts
  • test/unit/commands/apps/delete.test.ts
  • test/unit/commands/apps/list.test.ts
  • test/unit/commands/apps/set-apns-p12.test.ts
  • test/unit/commands/apps/switch.test.ts
  • test/unit/commands/apps/update.test.ts
  • test/unit/commands/auth/issue-ably-token.test.ts
  • test/unit/commands/auth/issue-jwt-token.test.ts
  • test/unit/commands/auth/keys/create.test.ts
  • test/unit/commands/auth/keys/current.test.ts
  • test/unit/commands/auth/keys/get.test.ts
  • test/unit/commands/auth/keys/list.test.ts
  • test/unit/commands/auth/keys/revoke.test.ts
  • test/unit/commands/auth/keys/switch.test.ts
  • test/unit/commands/auth/keys/update.test.ts
  • test/unit/commands/bench/bench.test.ts
  • test/unit/commands/bench/publisher.test.ts
  • test/unit/commands/bench/subscriber.test.ts
  • test/unit/commands/channel-rule/create.test.ts
  • test/unit/commands/channel-rule/delete.test.ts
  • test/unit/commands/channel-rule/list.test.ts
  • test/unit/commands/channel-rule/update.test.ts
  • test/unit/commands/channels/inspect.test.ts
  • test/unit/commands/channels/list.test.ts
  • test/unit/commands/channels/occupancy/get.test.ts
  • test/unit/commands/channels/occupancy/subscribe.test.ts
  • test/unit/commands/channels/presence/enter.test.ts
  • test/unit/commands/channels/presence/subscribe.test.ts
  • test/unit/commands/channels/publish.test.ts
  • test/unit/commands/channels/subscribe.test.ts
  • test/unit/commands/config/path.test.ts
  • test/unit/commands/config/show.test.ts
  • test/unit/commands/connections/test.test.ts
  • test/unit/commands/integrations/create.test.ts
  • test/unit/commands/integrations/delete.test.ts
  • test/unit/commands/integrations/get.test.ts
  • test/unit/commands/integrations/list.test.ts
  • test/unit/commands/integrations/update.test.ts
  • test/unit/commands/interactive-sigint.test.ts
  • test/unit/commands/interactive.test.ts
  • test/unit/commands/login.test.ts
  • test/unit/commands/logs/channel-lifecycle/subscribe.test.ts
  • test/unit/commands/logs/connection-lifecycle/history.test.ts
  • test/unit/commands/logs/connection-lifecycle/subscribe.test.ts
  • test/unit/commands/logs/history.test.ts
  • test/unit/commands/logs/push/history.test.ts
  • test/unit/commands/logs/push/subscribe.test.ts
  • test/unit/commands/logs/subscribe.test.ts
  • test/unit/commands/queues/create.test.ts
  • test/unit/commands/queues/delete.test.ts
  • test/unit/commands/queues/list.test.ts
  • test/unit/commands/rooms/features.test.ts
  • test/unit/commands/rooms/list.test.ts
  • test/unit/commands/rooms/messages.test.ts
  • test/unit/commands/rooms/messages/history.test.ts
  • test/unit/commands/rooms/messages/reactions/remove.test.ts
  • test/unit/commands/rooms/messages/reactions/send.test.ts
  • test/unit/commands/rooms/messages/reactions/subscribe.test.ts
  • test/unit/commands/rooms/messages/send.test.ts
  • test/unit/commands/rooms/messages/subscribe.test.ts
  • test/unit/commands/rooms/occupancy/get.test.ts
  • test/unit/commands/rooms/occupancy/subscribe.test.ts
  • test/unit/commands/rooms/presence/enter.test.ts
  • test/unit/commands/rooms/presence/subscribe.test.ts
  • test/unit/commands/rooms/reactions/send.test.ts
  • test/unit/commands/rooms/reactions/subscribe.test.ts
  • test/unit/commands/rooms/typing/keystroke.test.ts
  • test/unit/commands/rooms/typing/subscribe.test.ts
  • test/unit/commands/spaces/cursors/get-all.test.ts
  • test/unit/commands/spaces/cursors/set.test.ts
  • test/unit/commands/spaces/cursors/subscribe.test.ts
  • test/unit/commands/spaces/list.test.ts
  • test/unit/commands/spaces/locations/get-all.test.ts
  • test/unit/commands/spaces/locations/set.test.ts
  • test/unit/commands/spaces/locations/subscribe.test.ts
  • test/unit/commands/spaces/locks/acquire.test.ts
  • test/unit/commands/spaces/locks/get-all.test.ts
  • test/unit/commands/spaces/locks/get.test.ts
  • test/unit/commands/spaces/locks/subscribe.test.ts
  • test/unit/commands/spaces/members/enter.test.ts
  • test/unit/commands/spaces/members/subscribe.test.ts
  • test/unit/commands/spaces/spaces.test.ts
  • test/unit/commands/stats/account.test.ts
  • test/unit/commands/stats/app.test.ts
  • test/unit/commands/status.test.ts
  • test/unit/commands/support.test.ts
  • test/unit/commands/support/ask.test.ts
  • test/unit/commands/support/contact.test.ts
  • test/unit/commands/test/wait.test.ts
  • test/unit/commands/version.test.ts
  • vitest.config.ts

@umair-ably umair-ably marked this pull request as draft March 11, 2026 16:18
Copy link

Copilot AI left a comment

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 expands CLI test coverage across the command suite and introduces a new Vitest “tty” project (using node-pty) to reliably test interactive-mode SIGINT behavior in a real pseudo-terminal, plus related documentation and contributor workflow updates.

Changes:

  • Adds a new test/tty/ tier and pnpm test:tty script for PTY-backed interactive SIGINT tests.
  • Expands/standardizes unit test coverage across many commands (help output, flag visibility, argument validation, basic error handling).
  • Updates docs and contributor guidance to reflect the new testing tier and README regeneration steps.

Reviewed changes

Copilot reviewed 111 out of 111 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
vitest.config.ts Adds a new Vitest tty project configuration.
package.json Adds test:tty script to run the new project.
test/tty/tty-test-helper.ts Introduces PTY spawn/write/wait utilities for TTY tests.
test/tty/commands/interactive-sigint.test.ts Adds SIGINT/Ctrl+C behavior tests using real PTYs.
test/README.md Documents the new TTY test tier and how to run it.
docs/Testing.md Documents TTY tests purpose, constraints, and commands.
docs/Project-Structure.md Adds test/tty/ to project structure docs.
CONTRIBUTING.md Updates required workflow to include README regeneration + TTY tests for interactive changes.
AGENTS.md Updates “run in order” checklist and test structure to include TTY tests and README regeneration.
.claude/skills/ably-new-command/SKILL.md Updates contributor automation guidance to regenerate README separately.
README.md Regenerates CLI help/docs output with new flags/examples reflected.
test/unit/commands/version.test.ts Adds unit tests for version help/flags/JSON output.
test/unit/commands/test/wait.test.ts Adds unit tests for test:wait help/flags/required duration.
test/unit/commands/support/contact.test.ts Adds help/flags/error-handling checks.
test/unit/commands/support/ask.test.ts Adds new unit tests covering help/args/JSON output and API error cases.
test/unit/commands/support.test.ts Adds help output assertions and unknown subcommand handling.
test/unit/commands/status.test.ts Adds --json flag visibility test.
test/unit/commands/stats/app.test.ts Adds help/flags/error-handling checks.
test/unit/commands/stats/account.test.ts Adds help/flags/error-handling checks.
test/unit/commands/spaces/spaces.test.ts Adds help output checks and unknown-flag error case.
test/unit/commands/spaces/members/subscribe.test.ts Adds help/flags/error-handling and ensures duration-bounded runs.
test/unit/commands/spaces/members/enter.test.ts Adds help/flags checks.
test/unit/commands/spaces/locks/subscribe.test.ts Adds help checks.
test/unit/commands/spaces/locks/get.test.ts Adds help and error-handling checks.
test/unit/commands/spaces/locks/get-all.test.ts Adds help and error-handling checks.
test/unit/commands/spaces/locks/acquire.test.ts Adds help/arg/flags checks.
test/unit/commands/spaces/locations/subscribe.test.ts Adds help checks.
test/unit/commands/spaces/locations/set.test.ts Adds help/flags checks.
test/unit/commands/spaces/locations/get-all.test.ts Adds help and error-handling checks.
test/unit/commands/spaces/list.test.ts Adds help/flags/error-handling checks.
test/unit/commands/spaces/cursors/subscribe.test.ts Adds help and error-handling checks.
test/unit/commands/spaces/cursors/set.test.ts Adds help/flags checks.
test/unit/commands/spaces/cursors/get-all.test.ts Adds help checks.
test/unit/commands/rooms/typing/subscribe.test.ts Adds duration-bounded runs + help/flags/error-handling checks.
test/unit/commands/rooms/typing/keystroke.test.ts Adds help/arg/flags checks.
test/unit/commands/rooms/reactions/subscribe.test.ts Adds duration-bounded runs + help/flags/error-handling checks.
test/unit/commands/rooms/reactions/send.test.ts Adds help/arg/flags checks.
test/unit/commands/rooms/presence/subscribe.test.ts Adds duration-bounded runs + help/flags/error-handling checks.
test/unit/commands/rooms/presence/enter.test.ts Adds help/arg/flags checks.
test/unit/commands/rooms/occupancy/subscribe.test.ts Adds help/arg/flags/error-handling checks.
test/unit/commands/rooms/occupancy/get.test.ts Adds help/arg/flags checks.
test/unit/commands/rooms/messages/subscribe.test.ts Adds new unit tests for subscribe behavior + JSON envelope assertions.
test/unit/commands/rooms/messages/send.test.ts Adds new unit tests for send behavior, interpolation, delay enforcement, JSON output.
test/unit/commands/rooms/messages/history.test.ts Adds new unit tests for history retrieval, time flags, JSON output, validation.
test/unit/commands/rooms/messages/reactions/subscribe.test.ts Adds duration-bounded runs + help/flags/error-handling checks.
test/unit/commands/rooms/messages/reactions/send.test.ts Adds help checks.
test/unit/commands/rooms/messages/reactions/remove.test.ts Adds help checks.
test/unit/commands/rooms/messages/reactions/*.test.ts Adds help coverage for message reactions subcommands.
test/unit/commands/rooms/messages.test.ts Adds help/args/flags checks for rooms message subcommands.
test/unit/commands/rooms/list.test.ts Adds help/flags checks.
test/unit/commands/rooms/features.test.ts Adds help/args/flags/error-handling checks for several rooms feature commands.
test/unit/commands/queues/list.test.ts Adds help/flags checks.
test/unit/commands/queues/delete.test.ts Improves confirmation prompt tests + adds help/flags checks.
test/unit/commands/queues/create.test.ts Adds help checks.
test/unit/commands/logs/subscribe.test.ts Adds help checks.
test/unit/commands/logs/push/subscribe.test.ts Adds help/flags/error-handling checks.
test/unit/commands/logs/push/history.test.ts Adds help and error-handling checks.
test/unit/commands/logs/history.test.ts Adds help/flags/error-handling checks.
test/unit/commands/logs/connection-lifecycle/subscribe.test.ts Adds help/flags checks + duration-bounded runs.
test/unit/commands/logs/connection-lifecycle/history.test.ts Adds help and error-handling checks.
test/unit/commands/logs/channel-lifecycle/subscribe.test.ts Adds help checks + duration-bounded runs and flag coverage.
test/unit/commands/login.test.ts Adds new unit tests for login alias command help/flags/validation.
test/unit/commands/interactive.test.ts Removes flaky non-TTY Ctrl+C integration tests; points to TTY suite.
test/unit/commands/interactive-sigint.test.ts Removes skipped non-TTY SIGINT tests; points to TTY suite.
test/unit/commands/integrations/update.test.ts Adds help checks.
test/unit/commands/integrations/list.test.ts Adds new unit tests for listing integrations, JSON output, error cases.
test/unit/commands/integrations/get.test.ts Adds help checks.
test/unit/commands/integrations/delete.test.ts Adds help/arg validation checks.
test/unit/commands/integrations/create.test.ts Adds help/flags checks.
test/unit/commands/connections/test.test.ts Adds help/flags/error-handling checks.
test/unit/commands/config/show.test.ts Adds help checks.
test/unit/commands/config/path.test.ts Adds help and error-handling checks.
test/unit/commands/channels/subscribe.test.ts Adds duration-bounded runs + error-handling for missing mocks.
test/unit/commands/channels/publish.test.ts Adds help/arg/flags checks.
test/unit/commands/channels/presence/subscribe.test.ts Adds arg validation + duration-bounded runs + error-handling.
test/unit/commands/channels/presence/enter.test.ts Adds arg validation + error-handling checks.
test/unit/commands/channels/occupancy/subscribe.test.ts Adds duration-bounded runs + help/flags coverage.
test/unit/commands/channels/occupancy/get.test.ts Adds help/arg/flags/error-handling checks.
test/unit/commands/channels/list.test.ts Adds network-error handling test.
test/unit/commands/channels/inspect.test.ts Adds arg validation + --json flag visibility test.
test/unit/commands/channel-rule/update.test.ts Adds help/flags/error-handling checks for alias command.
test/unit/commands/channel-rule/list.test.ts Adds help/flags/error-handling checks for alias command.
test/unit/commands/channel-rule/delete.test.ts Adds help/flags/error-handling checks for alias command.
test/unit/commands/channel-rule/create.test.ts Adds help/flags/error-handling checks for alias command.
test/unit/commands/bench/subscriber.test.ts Adds new unit tests for subscriber benchmark help/args/flags.
test/unit/commands/bench/publisher.test.ts Adds new unit tests for publisher benchmark help/args/flags/JSON output.
test/unit/commands/bench/bench.test.ts Adds help/flags/error-handling checks around bench publisher coverage.
test/unit/commands/auth/keys/update.test.ts Adds help/arg/flags checks.
test/unit/commands/auth/keys/switch.test.ts Adds new unit tests for switching API keys + JSON output + errors.
test/unit/commands/auth/keys/revoke.test.ts Adds help/arg/flags checks.
test/unit/commands/auth/keys/list.test.ts Adds help/flags checks.
test/unit/commands/auth/keys/get.test.ts Adds help/arg/flags checks.
test/unit/commands/auth/keys/current.test.ts Adds help/flags checks.
test/unit/commands/auth/keys/create.test.ts Adds help/flags checks.
test/unit/commands/auth/issue-jwt-token.test.ts Adds help checks.
test/unit/commands/auth/issue-ably-token.test.ts Adds help checks.
test/unit/commands/apps/update.test.ts Adds help/arg/flags checks.
test/unit/commands/apps/switch.test.ts Adds new unit tests for switching apps + JSON output + errors.
test/unit/commands/apps/set-apns-p12.test.ts Adds help/arg/flags checks.
test/unit/commands/apps/list.test.ts Adds help/flags checks.
test/unit/commands/apps/delete.test.ts Adds help/arg/flags checks.
test/unit/commands/apps/current.test.ts Adds help/flags checks.
test/unit/commands/apps/create.test.ts Adds help/arg/flags checks.
test/unit/commands/apps/channel-rules/update.test.ts Adds help/arg/flags checks.
test/unit/commands/apps/channel-rules/list.test.ts Adds help/flags checks.
test/unit/commands/apps/channel-rules/delete.test.ts Adds help/arg/flags checks.
test/unit/commands/apps/channel-rules/create.test.ts Adds help/arg/flags checks.
test/unit/commands/accounts/switch.test.ts Adds help/flags/error-handling checks.
test/unit/commands/accounts/logout.test.ts Adds --json flag visibility check.
test/unit/commands/accounts/login.test.ts Adds --json flag visibility check.
test/unit/commands/accounts/list.test.ts Adds help/flags/error-handling checks.
test/unit/commands/accounts/current.test.ts Adds help/flags checks.

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

Copy link
Contributor

@sacOO7 sacOO7 left a comment

Choose a reason for hiding this comment

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

Okay, so I validated PR for

  1. A structured review covering:
  • Infrastructure changes
  • Test architecture
  • Conventions compliance
  • Inconsistencies across files
  • Potential bugs or fragile tests
  • Missing or incomplete test coverage
  • Documentation alignment with implementation
  1. Analyze the codebase for opportunities to improve maintainability, including:
  • Extracting repeated setup/teardown logic
  • Introducing shared test utilities
  • Creating base test classes or helpers
  • Reducing duplicated assertions or fixtures
  • Consolidating repeated describe/test structures
  • Improving test organization

Will share actionable findings for the same 👍

Copy link
Contributor

@sacOO7 sacOO7 left a comment

Choose a reason for hiding this comment

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

Thanks for addressing feedback, LGTM 👍

@umair-ably umair-ably merged commit 5eca645 into main Mar 12, 2026
10 checks passed
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