pipe/test/verify_default_baseline_test.dart
trvon adf898be19
feat(verify): default --baseline to <path>/.pipe-baseline.json
`pipe verify .` failed with "verify needs --baseline" even in a repo
whose baseline sits where the README's CI recipe writes it. nuwayze's
scripts/testing/pipe_state_flow_gate.sh commits exactly that file,
.pipe-baseline.json at the repo root, so every verify there had to
repeat the path.

Without --baseline, verify now reads <path>/.pipe-baseline.json when it
exists and says so on stderr ("pipe: no --baseline given; using ..."),
so a run never silently picks a file nobody named. With neither, the
error names both remedies: pass --baseline, or write the conventional
file with `pipe check <path> --write-baseline <path>/.pipe-baseline.json`
before the fix. pipe had no baseline-name constant; defaultBaselineName
is now the one place it is spelled.

Tests (test/verify_default_baseline_test.dart): an explicit --baseline
wins and announces nothing; the conventional file is used and
announced; with neither the error carries both remedies; and end to
end, `pipe verify <copy>` against a baseline written at the copy's
root reads it (--expect-resolved fails on the 28 still-present
findings). README and docs/usage.md show the shorter form.

On nuwayze-w3, `pipe verify /Users/.../nuwayze-w3` with no flag reads
its .pipe-baseline.json (65 accepted findings). 225 tests pass.
2026-09-25 20:11:34 -06:00

104 lines
3.3 KiB
Dart

import 'dart:io';
import 'package:path/path.dart' as p;
import 'package:pipe/pipe.dart';
import 'package:pipe/src/cli.dart';
import 'package:test/test.dart';
/// A copy of the rule fixture, so a baseline can be written at its root.
String _fixtureCopy() {
final from = Directory('test/fixtures/stuck_loading');
final to = Directory.systemTemp.createTempSync('pipe-verify-default');
for (final entity in from.listSync(recursive: true)) {
final target = p.join(to.path, p.relative(entity.path, from: from.path));
if (entity is Directory) {
Directory(target).createSync(recursive: true);
} else if (entity is File) {
File(target)
..createSync(recursive: true)
..writeAsBytesSync(entity.readAsBytesSync());
}
}
return to.path;
}
void main() {
// `pipe verify .` used to fail with "verify needs --baseline" even in a repo
// whose baseline sits at the conventional path the README's CI recipe
// writes (nuwayze's scripts/testing/pipe_state_flow_gate.sh).
group('resolveVerifyBaseline', () {
late Directory temp;
setUp(() => temp = Directory.systemTemp.createTempSync('pipe-verify-bl'));
tearDown(() => temp.deleteSync(recursive: true));
test('an explicit --baseline wins, with nothing announced', () {
File(p.join(temp.path, defaultBaselineName)).writeAsStringSync('{}');
final log = StringBuffer();
expect(
resolveVerifyBaseline('other.json', temp.path, log: log),
'other.json',
);
expect(log.toString(), isEmpty);
});
test('without --baseline the conventional file is used and announced', () {
final conventional = p.join(temp.path, defaultBaselineName);
File(conventional).writeAsStringSync('{}');
final log = StringBuffer();
expect(resolveVerifyBaseline(null, temp.path, log: log), conventional);
expect(log.toString(), contains('using $conventional'));
});
test('without either, the error names both remedies', () {
expect(
() => resolveVerifyBaseline(null, temp.path, log: StringBuffer()),
throwsA(
isA<PipeException>()
.having((e) => e.message, 'message', contains('--baseline'))
.having(
(e) => e.remedy,
'remedy',
allOf(
contains('--baseline'),
contains(p.join(temp.path, defaultBaselineName)),
),
),
),
);
});
});
test('pipe verify <path> reads <path>/.pipe-baseline.json', () async {
final root = _fixtureCopy();
try {
final baseline = p.join(root, defaultBaselineName);
expect(
await PipeRunner().run([
'check',
root,
'--write-baseline',
baseline,
'-c',
'1',
]),
0,
);
// Nothing changed since the baseline, so every accepted finding remains
// and --expect-resolved fails: proof the default baseline was read,
// since an empty one would have nothing to expect.
expect(
await PipeRunner().run([
'verify',
root,
'--expect-resolved',
'-c',
'1',
]),
1,
);
} finally {
Directory(root).deleteSync(recursive: true);
}
});
}