Skip to content

fix: very_good test --recursive applies positional test targets to every package #1704

Description

@HadiHassan22

Description

Positional test targets are forwarded verbatim into every per-package run when --recursive is set, so a relative path can only resolve in one package and fails to load in all the others.

_runCommand in lib/src/cli/flutter_cli.dart fans out one run per discovered pubspec.yaml, each with that package as its working directory:

final processes = _Cmd.runWhere<T>(
  run: (entity) => cmd(entity.parent.path),
  where: (entity) => !ignore.excludes(entity) && _isPubspec(entity),
  cwd: cwd,
);

TestCLIRunner.test then passes the same arguments (which carry argResults.rest) into each of those runs unchanged.

Steps To Reproduce

  1. Create a monorepo with two packages, each with its own test:
my_monorepo/
  packages/
    a/pubspec.yaml   test/a_test.dart
    b/pubspec.yaml   test/b_test.dart
  1. From my_monorepo, run:
very_good dart test -r test/a_test.dart
  1. packages/a passes. packages/b tries to load packages/b/test/a_test.dart, which does not exist, fails to load, and the command exits 69.

Expected Behavior

Either of the following would be reasonable:

  1. Reject the combination. --recursive and positional test targets describe mutually exclusive models of the working directory: a target is only meaningful relative to a single package root, and --recursive means there is not one. Failing fast with a message pointing at the right invocation is more useful than N-1 load errors around one incidental success.

  2. Resolve targets against the invocation directory. Interpret each target relative to the original cwd, then pass each package only the targets that fall inside it, skipping packages with no matches. This would make very_good test -r packages/a/test/x_test.dart packages/b/test/y_test.dart do the obvious thing, but it needs decisions about targets that match no package or sit outside all of them.

Option 1 is the smaller change. TestCLIRunner.test already receives both recursive and the arguments, and TestCLIRunner.isTargettingTestFiles already exists as the predicate, so the check has a natural home at the point both very_good test and very_good dart test route through.

Additional Context

This came out of review on #1676, which adds a paths argument to the MCP test tool and so exposes both knobs side by side in a single call. That PR currently guards the combination in the MCP handler, but the invariant belongs to the test command rather than the transport — a guard here would cover both entry points and shell users.

Happy to open a PR once there is agreement on which direction you prefer.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    Status
    Needs Triage

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions