Skip to content

fix(reftest): honour compare subcommand flags#684

Merged
softmarshmallow merged 1 commit intomainfrom
feature/nice-nightingale-ea7080
Apr 22, 2026
Merged

fix(reftest): honour compare subcommand flags#684
softmarshmallow merged 1 commit intomainfrom
feature/nice-nightingale-ea7080

Conversation

@softmarshmallow
Copy link
Copy Markdown
Member

@softmarshmallow softmarshmallow commented Apr 22, 2026

Summary

  • Fix: reftest compare <a> <b> --threshold 0 --json silently ignored both flags — the subcommand action received its declared defaults ("0.1" / false) regardless of what the user typed on the CLI.
  • Root cause: Commander v12 by-design behavior — when long option names collide between a root command (which has its own .action() handler) and a subcommand, CLI values bind to the root's option store; the subcommand's opts arg only exposes local defaults. Confirmed unchanged through v14 (tj/commander.js#2356, #2335) — upgrading isn't a fix.
  • Fix: read this.optsWithGlobals() inside the compare action (maintainer-recommended pattern). Added a comment explaining the Commander quirk.
  • Regression test: new __tests__/cli.test.ts spawns the built CLI via node dist/cli.js compare … and asserts --threshold, -t, and --json all wire through end-to-end.

Test plan

  • pnpm --filter @grida/reftest build
  • pnpm --filter @grida/reftest test — 49 pass (5 new + 44 pre-existing)
  • pnpm --filter @grida/reftest typecheck — clean
  • Manual repro: node dist/cli.js compare /tmp/a.png /tmp/b.png --threshold 0 --json now returns diff_pixels: 100 (was 0), and prints JSON (was plain text).

Summary by CodeRabbit

  • Tests

    • Added comprehensive regression tests for the compare command, covering threshold configuration, JSON and text output formats, and command-line flag aliases.
  • Bug Fixes

    • Fixed option handling to ensure command-line arguments properly override default settings in all scenarios.

The compare subcommand's --threshold and --json flags were silently
ignored — values stayed at subcommand defaults regardless of CLI input.

Root cause: Commander v12 by-design behavior when long option names
collide between a root command (with an .action() handler) and a
subcommand. CLI values bind to the root's option store; the subcommand
action receives only its local defaults. Upgrading commander doesn't
help — confirmed unchanged through v14 (tj/commander.js#2356).

Fix: read this.optsWithGlobals() inside the compare action, the pattern
the Commander maintainer recommends for this scenario. Add a regression
test that spawns the built CLI to verify --threshold, -t, and --json
all wire through.
@vercel
Copy link
Copy Markdown

vercel Bot commented Apr 22, 2026

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

Project Deployment Actions Updated (UTC)
docs Ready Ready Preview, Comment Apr 22, 2026 4:04pm
6 Skipped Deployments
Project Deployment Actions Updated (UTC)
code Ignored Ignored Apr 22, 2026 4:04pm
legacy Ignored Ignored Apr 22, 2026 4:04pm
backgrounds Skipped Skipped Apr 22, 2026 4:04pm
blog Skipped Skipped Apr 22, 2026 4:04pm
grida Skipped Skipped Apr 22, 2026 4:04pm
viewer Skipped Skipped Apr 22, 2026 4:04pm

Request Review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 22, 2026

Walkthrough

A new Vitest regression test suite for the CLI compare subcommand is added, validating threshold handling, JSON/plain-text output modes, and flag aliases. The CLI implementation is updated to use optsWithGlobals() to ensure proper option precedence in Commander v12.

Changes

Cohort / File(s) Summary
Test Suite
packages/grida-reftest/__tests__/cli.test.ts
New regression test file covering compare subcommand behavior: threshold defaults and overrides (--threshold, -t), JSON output formatting, plain-text output, and integration with temporary PNG fixtures.
CLI Implementation
packages/grida-reftest/src/cli.ts
Updated compare subcommand action callback to bind this: Command context and derive options via optsWithGlobals() instead of direct parameter, ensuring CLI-provided values take precedence over subcommand defaults in option-collision scenarios.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~15 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'fix(reftest): honour compare subcommand flags' clearly and concisely summarizes the main change: fixing the reftest compare subcommand to respect CLI flags that were being ignored.
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.

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

✨ 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/nice-nightingale-ea7080

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.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 260f4e6b8a

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +33 to +36
if (!fs.existsSync(CLI)) {
throw new Error(
`Built CLI not found at ${CLI}. Run \`pnpm --filter @grida/reftest build\` first.`
);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Remove dist build prerequisite from CLI tests

The new CLI regression suite hard-fails in beforeAll when ../dist/cli.js is absent, which makes pnpm --filter @grida/reftest test fail on a clean checkout even though the package test script only runs Vitest and does not build first. This introduces a brittle ordering dependency (build → test) into a unit-test target that previously ran standalone, so local and CI test runs that execute tests directly will now fail before assertions run.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown

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

🧹 Nitpick comments (1)
packages/grida-reftest/__tests__/cli.test.ts (1)

1-1: Clean up the temporary fixture directory after the suite.

The test writes PNGs into an OS temp directory but never removes it, so repeated local runs will accumulate reftest-cli-* directories.

Proposed cleanup
-import { describe, expect, it, beforeAll } from "vitest";
+import { afterAll, beforeAll, describe, expect, it } from "vitest";
@@
 describe("reftest CLI — compare subcommand", () => {
   let aPath: string;
   let bPath: string;
+  let dir: string | undefined;
 
   beforeAll(() => {
@@
-    const dir = fs.mkdtempSync(path.join(os.tmpdir(), "reftest-cli-"));
+    dir = fs.mkdtempSync(path.join(os.tmpdir(), "reftest-cli-"));
     aPath = path.join(dir, "a.png");
     bPath = path.join(dir, "b.png");
@@
     fs.writeFileSync(bPath, makeSolidPng(10, 10, [120, 120, 120, 255]));
   });
+
+  afterAll(() => {
+    if (dir) fs.rmSync(dir, { recursive: true, force: true });
+  });

Also applies to: 32-46

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

In `@packages/grida-reftest/__tests__/cli.test.ts` at line 1, Add a cleanup hook
to remove the OS temp fixture directory after the test suite: import afterAll
from vitest (consistent with the existing beforeAll), capture the temp fixture
directory variable used by the tests (e.g., tmpDir / fixtureDir) and in an
afterAll call remove it recursively (fs.rm or fs.promises.rm with { recursive:
true, force: true }) and handle any errors silently; place this afterAll in the
same test suite in packages/grida-reftest/__tests__/cli.test.ts so repeated runs
don't leave reftest-cli-* folders behind.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@packages/grida-reftest/__tests__/cli.test.ts`:
- Line 1: Add a cleanup hook to remove the OS temp fixture directory after the
test suite: import afterAll from vitest (consistent with the existing
beforeAll), capture the temp fixture directory variable used by the tests (e.g.,
tmpDir / fixtureDir) and in an afterAll call remove it recursively (fs.rm or
fs.promises.rm with { recursive: true, force: true }) and handle any errors
silently; place this afterAll in the same test suite in
packages/grida-reftest/__tests__/cli.test.ts so repeated runs don't leave
reftest-cli-* folders behind.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: af0bae82-f9a1-4262-80ec-4595f71ecb89

📥 Commits

Reviewing files that changed from the base of the PR and between d94eece and 260f4e6.

📒 Files selected for processing (2)
  • packages/grida-reftest/__tests__/cli.test.ts
  • packages/grida-reftest/src/cli.ts

@softmarshmallow softmarshmallow merged commit 344e722 into main Apr 22, 2026
14 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant