-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtest.mjs
More file actions
99 lines (86 loc) · 4.77 KB
/
Copy pathtest.mjs
File metadata and controls
99 lines (86 loc) · 4.77 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
// One runnable check: fails if capture, recovery, chain-walking, drift
// tracking, batched reads, --md export, hook install, or exit codes break.
import { execFileSync } from 'node:child_process';
import { mkdtempSync, writeFileSync, rmSync, existsSync } from 'node:fs';
import { tmpdir } from 'node:os';
import { join } from 'node:path';
import { fileURLToPath } from 'node:url';
import assert from 'node:assert/strict';
const WHY = fileURLToPath(new URL('./why.mjs', import.meta.url));
const repo = mkdtempSync(join(tmpdir(), 'wherefore-'));
const sh = (cmd, args) => execFileSync(cmd, args, { cwd: repo, encoding: 'utf8' });
const git = (...a) => sh('git', a);
const why = (...a) => sh(process.execPath, [WHY, ...a]);
git('init', '-q', '-b', 'main');
git('config', 'user.name', 'Test');
git('config', 'user.email', 't@t');
git('config', 'commit.gpgsign', 'false');
writeFileSync(join(repo, 'a.txt'), 'first line\nsecond line\n');
git('add', '.');
git('commit', '-q', '-m', 'add a.txt', '-m', 'Why: trailers should surface in show');
// 1. Why: trailer surfaces via blame
assert.match(why('show', 'a.txt:1'), /trailers should surface/);
// 2. note entry surfaces
why('add', '-f', 'a.txt:1', '-m', 'note reasons also surface', '-t', 'test');
assert.match(why('show', 'a.txt:1'), /note reasons also surface/);
// 3. chain survives a silent edit; the edited anchor range is marked, not hidden
writeFileSync(join(repo, 'a.txt'), 'first line, edited\nsecond line\n');
git('commit', '-aqm', 'silent edit');
const out3 = why('show', 'a.txt:1');
assert.match(out3, /trailers should surface/);
assert.match(out3, /no recorded why/); // the silent commit is counted, not hidden
assert.match(out3, /edited since/); // drift tracking flags the rewritten range
// 4. drift: an anchored range follows the code when lines shift beneath it,
// and off-chain anchors (note commit never touched the line) still surface
why('add', '-f', 'a.txt:2', '-m', 'anchored to second line');
writeFileSync(join(repo, 'a.txt'), 'zeroth line\nfirst line, edited\nsecond line\n');
git('commit', '-aqm', 'prepend a line');
const out4 = why('show', 'a.txt:3');
assert.match(out4, /anchored to second line/); // found at its NEW position
assert.match(out4, /lines 2→3/); // drift is displayed
assert.doesNotMatch(why('show', 'a.txt:1'), /anchored to second line/); // clean ranges exclude
// 5. log lists both sources; --json parses; --md emits an appendable section
const rows = JSON.parse(why('log', '--json'));
assert.equal(rows.filter(r => r.source === 'trailer').length, 1);
assert.equal(rows.filter(r => r.source === 'note').length, 2);
const md = why('log', '--md');
assert.match(md, /^## Decision ledger/);
assert.match(md, /- \*\*\d{4}-\d{2}-\d{2}\*\* — /);
// 6. an unrecorded location exits 2 — "not in the ledger" is a first-class answer
writeFileSync(join(repo, 'b.txt'), 'no why here\n');
git('add', 'b.txt');
git('commit', '-qm', 'plain commit');
let code = 0;
try { why('show', 'b.txt:1'); } catch (e) { code = e.status; }
assert.equal(code, 2);
// 7. hook install writes the pre-push hook once, refuses to clobber
why('hook', 'install');
assert.ok(existsSync(join(repo, '.git', 'hooks', 'pre-push')));
assert.throws(() => why('hook', 'install'));
// 8. search: full-text over the ledger, no path required
assert.match(why('search', 'anchored to second line'), /anchored to second line/);
assert.match(why('search', 'nope-does-not-exist'), /no recorded whys matching/);
// 9. fleet: aggregates the ledger across every repo under a root directory
const fleetRoot = mkdtempSync(join(tmpdir(), 'wherefore-fleet-'));
for (const name of ['repo-a', 'repo-b']) {
const dir = join(fleetRoot, name);
execFileSync('git', ['init', '-q', '-b', 'main', dir], { cwd: fleetRoot, encoding: 'utf8' });
const g = (...a) => execFileSync('git', ['-C', dir, ...a], { cwd: fleetRoot, encoding: 'utf8' });
g('config', 'user.name', 'Test');
g('config', 'user.email', 't@t');
g('config', 'commit.gpgsign', 'false');
writeFileSync(join(dir, 'f.txt'), `${name}\n`);
g('add', '.');
g('commit', '-q', '-m', `init ${name}`, '-m', `Why: unique-fleet-marker in ${name}`);
}
const fleetOut = execFileSync(process.execPath, [WHY, 'fleet', 'unique-fleet-marker'], { cwd: fleetRoot, encoding: 'utf8' });
assert.match(fleetOut, /repo-a/);
assert.match(fleetOut, /repo-b/);
const fleetRows = JSON.parse(
execFileSync(process.execPath, [WHY, 'fleet', 'unique-fleet-marker', '--json'], { cwd: fleetRoot, encoding: 'utf8' }),
);
assert.equal(fleetRows.length, 2);
assert.deepEqual(fleetRows.map(r => r.repo).sort(), ['repo-a', 'repo-b']);
try { rmSync(fleetRoot, { recursive: true, force: true }); } catch { /* Windows file locks */ }
try { rmSync(repo, { recursive: true, force: true }); } catch { /* Windows file locks */ }
console.log('ok — all wherefore checks passed');