mirror of
https://github.com/teamchong/pxpipe.git
synced 2026-07-22 02:02:51 +02:00
16960b8230
- docs-integrity: normalize walker paths to forward slashes so keys match on Windows - export-git-e2e: run tsx's JS entry via node instead of the .bin/.cmd shim (same pattern as #63) - vitest: 30s testTimeout for CPU-bound PNG-render tests on slower machines (build.mjs portion of the original branch dropped — superseded by #63)
68 lines
3.3 KiB
TypeScript
68 lines
3.3 KiB
TypeScript
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
|
|
import { spawnSync } from 'node:child_process';
|
|
import * as fs from 'node:fs';
|
|
import * as path from 'node:path';
|
|
import * as os from 'node:os';
|
|
import { fileURLToPath } from 'node:url';
|
|
|
|
// End-to-end coverage of the real `pxpipe export --git` path (the bug PR-4 fixed
|
|
// was in collectSource's untracked branch, not in the readExportTextFile helper).
|
|
// Runs the actual CLI via tsx against a throwaway git repo and asserts the
|
|
// untracked-file filtering. Kept in its own file because it spawns a subprocess.
|
|
const repoRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
|
|
// tsx's JS entry, run via process.execPath: the .bin/tsx shim is a .cmd on
|
|
// Windows, which spawnSync can't execute without a shell.
|
|
const tsxCli = path.join(repoRoot, 'node_modules', 'tsx', 'dist', 'cli.mjs');
|
|
|
|
function git(cwd: string, args: string[]): void {
|
|
const r = spawnSync('git', args, { cwd, encoding: 'utf8' });
|
|
if (r.status !== 0) throw new Error(`git ${args.join(' ')} failed: ${r.stderr}`);
|
|
}
|
|
|
|
describe('pxpipe export --git (end-to-end)', () => {
|
|
let repo: string;
|
|
let outDir: string;
|
|
beforeEach(() => {
|
|
repo = fs.mkdtempSync(path.join(os.tmpdir(), 'pxpipe-git-e2e-'));
|
|
outDir = fs.mkdtempSync(path.join(os.tmpdir(), 'pxpipe-git-out-'));
|
|
git(repo, ['init', '-q']);
|
|
git(repo, ['config', 'user.email', 't@t.t']);
|
|
git(repo, ['config', 'user.name', 't']);
|
|
// Tracked baseline so `git diff HEAD` has a HEAD to diff against.
|
|
fs.writeFileSync(path.join(repo, 'tracked.ts'), 'export const tracked = 1;\n');
|
|
git(repo, ['add', 'tracked.ts']);
|
|
git(repo, ['commit', '-q', '-m', 'base']);
|
|
// Untracked files exercising the three untracked-path gates:
|
|
fs.writeFileSync(path.join(repo, 'keep.ts'), 'export const keep = 42;\n'); // included
|
|
fs.writeFileSync(path.join(repo, 'skip.md'), 'x'.repeat(5000)); // excluded by --include *.ts
|
|
fs.writeFileSync(path.join(repo, 'huge.ts'), 'a'.repeat(1_000_001)); // oversized
|
|
fs.writeFileSync(path.join(repo, 'bin.ts'), Buffer.from([0x41, 0x00, 0x42])); // binary
|
|
});
|
|
afterEach(() => {
|
|
fs.rmSync(repo, { recursive: true, force: true });
|
|
fs.rmSync(outDir, { recursive: true, force: true });
|
|
});
|
|
|
|
it('applies --include, the size cap, and the binary sniff to untracked files', () => {
|
|
const run = spawnSync(
|
|
process.execPath,
|
|
[tsxCli, 'src/node.ts', 'export', '--git', repo, '--include', '*.ts', '--out', outDir, '--json'],
|
|
{ cwd: repoRoot, encoding: 'utf8', timeout: 120_000 },
|
|
);
|
|
expect(run.status, `stderr:\n${run.stderr}`).toBe(0);
|
|
|
|
// Oversized + binary untracked files are skipped, with a warning each.
|
|
expect(run.stderr).toContain('skipping oversized untracked file: huge.ts');
|
|
expect(run.stderr).toContain('skipping binary untracked file: bin.ts');
|
|
|
|
// The JSON report: only keep.ts's ~24 chars made it into the source (the
|
|
// 5000-char skip.md was excluded by --include *.ts; huge.ts by size). If any
|
|
// had leaked in, sourceChars would be in the thousands.
|
|
const line = run.stdout.trim().split('\n').find((l) => l.trim().startsWith('{'));
|
|
expect(line, `stdout:\n${run.stdout}`).toBeTruthy();
|
|
const report = JSON.parse(line!) as { sourceChars: number };
|
|
expect(report.sourceChars).toBeGreaterThan(0);
|
|
expect(report.sourceChars).toBeLessThan(500);
|
|
});
|
|
});
|