-
Notifications
You must be signed in to change notification settings - Fork 0
test/docs: add canonical repo fixture builder and review hygiene #317
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -1,10 +1,7 @@ | ||||||||||||||||||||||
| import { describe, it, expect, beforeEach, afterEach } from 'vitest'; | ||||||||||||||||||||||
| import { mkdtemp, rm, writeFile } from 'node:fs/promises'; | ||||||||||||||||||||||
| import { join } from 'node:path'; | ||||||||||||||||||||||
| import { tmpdir } from 'node:os'; | ||||||||||||||||||||||
| import { execSync } from 'node:child_process'; | ||||||||||||||||||||||
| import { initGraph } from '../src/graph.js'; | ||||||||||||||||||||||
| import { createEdge } from '../src/edges.js'; | ||||||||||||||||||||||
| import { repoFixture } from './helpers/repo-fixture.js'; | ||||||||||||||||||||||
| import { | ||||||||||||||||||||||
| extractFileContext, | ||||||||||||||||||||||
| extractCommitContext, | ||||||||||||||||||||||
|
|
@@ -14,27 +11,26 @@ import { | |||||||||||||||||||||
| } from '../src/context.js'; | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| describe('context', () => { | ||||||||||||||||||||||
| let repo; | ||||||||||||||||||||||
| let tempDir; | ||||||||||||||||||||||
| let graph; | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| beforeEach(async () => { | ||||||||||||||||||||||
| tempDir = await mkdtemp(join(tmpdir(), 'gitmind-test-')); | ||||||||||||||||||||||
| execSync('git init', { cwd: tempDir, stdio: 'ignore' }); | ||||||||||||||||||||||
| execSync('git config user.email "test@test.com"', { cwd: tempDir, stdio: 'ignore' }); | ||||||||||||||||||||||
| execSync('git config user.name "Test"', { cwd: tempDir, stdio: 'ignore' }); | ||||||||||||||||||||||
| repo = await repoFixture('context').build(); | ||||||||||||||||||||||
| tempDir = repo.root; | ||||||||||||||||||||||
| graph = await initGraph(tempDir); | ||||||||||||||||||||||
| }); | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| afterEach(async () => { | ||||||||||||||||||||||
| await rm(tempDir, { recursive: true, force: true }); | ||||||||||||||||||||||
| await repo.cleanup(); | ||||||||||||||||||||||
| }); | ||||||||||||||||||||||
|
Comment on lines
24
to
26
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Guard teardown when setup fails. If Suggested fix afterEach(async () => {
- await repo.cleanup();
+ if (repo) {
+ await repo.cleanup();
+ repo = undefined;
+ }
});📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||
|
|
||||||||||||||||||||||
| // ── extractFileContext ────────────────────────────────────── | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| it('extracts tracked files with inferred languages', async () => { | ||||||||||||||||||||||
| await writeFile(join(tempDir, 'app.js'), 'console.log("hello")'); | ||||||||||||||||||||||
| await writeFile(join(tempDir, 'README.md'), '# Hello'); | ||||||||||||||||||||||
| execSync('git add app.js README.md && git commit -m "init"', { cwd: tempDir, stdio: 'ignore' }); | ||||||||||||||||||||||
| await repo.write('app.js', 'console.log("hello")'); | ||||||||||||||||||||||
| await repo.write('README.md', '# Hello'); | ||||||||||||||||||||||
| await repo.commit('init'); | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| const files = extractFileContext(tempDir); | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
|
|
@@ -54,10 +50,10 @@ describe('context', () => { | |||||||||||||||||||||
| }); | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| it('respects the limit option', async () => { | ||||||||||||||||||||||
| await writeFile(join(tempDir, 'a.js'), ''); | ||||||||||||||||||||||
| await writeFile(join(tempDir, 'b.js'), ''); | ||||||||||||||||||||||
| await writeFile(join(tempDir, 'c.js'), ''); | ||||||||||||||||||||||
| execSync('git add a.js b.js c.js && git commit -m "init"', { cwd: tempDir, stdio: 'ignore' }); | ||||||||||||||||||||||
| await repo.write('a.js', ''); | ||||||||||||||||||||||
| await repo.write('b.js', ''); | ||||||||||||||||||||||
| await repo.write('c.js', ''); | ||||||||||||||||||||||
| await repo.commit('init'); | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| const files = extractFileContext(tempDir, { limit: 2 }); | ||||||||||||||||||||||
| expect(files).toHaveLength(2); | ||||||||||||||||||||||
|
|
@@ -66,11 +62,11 @@ describe('context', () => { | |||||||||||||||||||||
| // ── extractCommitContext ──────────────────────────────────── | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| it('extracts recent commits with files', async () => { | ||||||||||||||||||||||
| await writeFile(join(tempDir, 'app.js'), 'v1'); | ||||||||||||||||||||||
| execSync('git add app.js && git commit -m "feat: initial"', { cwd: tempDir, stdio: 'ignore' }); | ||||||||||||||||||||||
| await repo.write('app.js', 'v1'); | ||||||||||||||||||||||
| await repo.commit('feat: initial'); | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| await writeFile(join(tempDir, 'app.js'), 'v2'); | ||||||||||||||||||||||
| execSync('git add app.js && git commit -m "fix: update app"', { cwd: tempDir, stdio: 'ignore' }); | ||||||||||||||||||||||
| await repo.write('app.js', 'v2'); | ||||||||||||||||||||||
| await repo.commit('fix: update app'); | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| const commits = extractCommitContext(tempDir); | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
|
|
@@ -170,8 +166,8 @@ describe('context', () => { | |||||||||||||||||||||
| // ── extractContext orchestrator ───────────────────────────── | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| it('assembles full context with prompt', async () => { | ||||||||||||||||||||||
| await writeFile(join(tempDir, 'app.js'), 'console.log("hi")'); | ||||||||||||||||||||||
| execSync('git add app.js && git commit -m "init"', { cwd: tempDir, stdio: 'ignore' }); | ||||||||||||||||||||||
| await repo.write('app.js', 'console.log("hi")'); | ||||||||||||||||||||||
| await repo.commit('init'); | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| await createEdge(graph, { source: 'file:app.js', target: 'spec:main', type: 'implements' }); | ||||||||||||||||||||||
| const ctx = await extractContext(tempDir, graph); | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| /** | ||
| * Base repo catalog for repository-shaped tests. | ||
| */ | ||
|
|
||
| export function minimalDocsAndCodeBase() { | ||
| return async repo => { | ||
| await repo.writeFiles({ | ||
| 'README.md': '# Echo Service\n\nSee docs/overview.md and src/app.js.\n', | ||
| 'docs/overview.md': '# Overview\n\nThe service entry point lives in `src/app.js`.\n', | ||
| 'src/app.js': 'export function buildApp() {\n return { ok: true };\n}\n', | ||
| }); | ||
| await repo.commit('chore: scaffold minimal docs and code fixture'); | ||
| }; | ||
| } | ||
|
|
||
| export function adrLinkedServiceBase() { | ||
| return async repo => { | ||
| await repo.writeFiles({ | ||
| 'README.md': '# Auth Service\n\nSee docs/adr/0001-auth.md for the auth decision.\n', | ||
| 'docs/adr/0001-auth.md': '# ADR 0001: Auth\n\nWe use token-based auth in `src/auth.js`.\n', | ||
| 'src/auth.js': 'export function authenticate(token) {\n return token === "ok";\n}\n', | ||
| }); | ||
| await repo.commit('chore: scaffold adr-linked service fixture'); | ||
| }; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
New hygiene rule is documented but not mechanically enforced.
Lines 48–50 add the requirement, but the current
.github/pull_request_template.mdchecklist still has no explicit item for stale-thread cleanup / false-positive documentation. This leaves compliance as “best effort” instead of a review gate.🔧 Proposed enforcement update (PR template)
🤖 Prompt for AI Agents