mirror of
https://github.com/affaan-m/ECC.git
synced 2026-10-14 12:15:29 +02:00
On a Windows machine with Claude Code installed natively, Git for Windows,
and the ECC plugin installed, `node tests/run-all.js` on main fails 44 tests
in 7 files. Linux CI never sees them. Three of the four causes are test
isolation gaps, fixed here (43 tests):
- claude-plugin-setup, claude-scope-migration, setup (38): fixtures put a
fake claude.cmd first on PATH, but on Windows spawning a bare `claude`
resolves only .com/.exe, so a native ~/.local/bin/claude.exe ran instead
of the fake. Fixture PATHs now drop entries holding claude.exe/claude.com.
- ecc-universal-bin, eval-harness-package (4): tar received an absolute
C:\ archive path, which Git Bash's GNU tar reads as a host:path remote
spec ("Cannot connect to C: resolve failed"). Extract from inside the
destination with a relative, forward-slash archive name, which both GNU
tar and bsdtar accept.
- harness-audit (1): the cache-layout test overrode HOME only, while
findPluginInstall also reads USERPROFILE and os.homedir(), so the real
installed plugin won over the fixture. Override USERPROFILE too.
The two helpers live in tests/lib/helpers/windows-test-env.js with a
platform-independent test, so Linux CI holds both invariants too.
The 44th failure, plugin-hook-bootstrap's no-bash test, is a production
bug rather than a test leak: System32\bash.exe launches an installed WSL
distro, which passes the bash probe. It gets a separate fix.
63 lines
2.5 KiB
JavaScript
63 lines
2.5 KiB
JavaScript
/**
|
|
* Tests for tests/lib/helpers/windows-test-env.js
|
|
*
|
|
* Run with: node tests/lib/windows-test-env.test.js
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
const assert = require('assert');
|
|
const fs = require('fs');
|
|
const os = require('os');
|
|
const path = require('path');
|
|
|
|
const { test, banner, summary } = require('./helpers/mini-test-runner');
|
|
const { withoutShadowingClaude, toRelativeTarPath } = require('./helpers/windows-test-env');
|
|
|
|
banner('windows-test-env helper');
|
|
|
|
let passed = 0;
|
|
let failed = 0;
|
|
|
|
const root = fs.mkdtempSync(path.join(os.tmpdir(), 'windows-test-env-'));
|
|
const exeDir = path.join(root, 'native-install');
|
|
const comDir = path.join(root, 'com-install');
|
|
const cmdDir = path.join(root, 'npm-global');
|
|
const plainDir = path.join(root, 'tools');
|
|
for (const dir of [exeDir, comDir, cmdDir, plainDir]) fs.mkdirSync(dir);
|
|
fs.writeFileSync(path.join(exeDir, 'claude.exe'), '');
|
|
fs.writeFileSync(path.join(comDir, 'claude.com'), '');
|
|
// A .cmd shim cannot shadow a fake .cmd placed earlier on PATH, so it stays.
|
|
fs.writeFileSync(path.join(cmdDir, 'claude.cmd'), '');
|
|
|
|
try {
|
|
if (test('drops PATH entries holding claude.exe or claude.com on Windows', () => {
|
|
const pathValue = [plainDir, exeDir, cmdDir, comDir].join(';');
|
|
assert.strictEqual(withoutShadowingClaude(pathValue, 'win32'), [plainDir, cmdDir].join(';'));
|
|
})) passed++; else failed++;
|
|
|
|
if (test('drops empty entries and tolerates a missing PATH on Windows', () => {
|
|
assert.strictEqual(withoutShadowingClaude(`;${plainDir};;`, 'win32'), plainDir);
|
|
assert.strictEqual(withoutShadowingClaude(undefined, 'win32'), '');
|
|
})) passed++; else failed++;
|
|
|
|
if (test('leaves PATH untouched off Windows', () => {
|
|
const pathValue = [plainDir, exeDir].join(':');
|
|
assert.strictEqual(withoutShadowingClaude(pathValue, 'linux'), pathValue);
|
|
assert.strictEqual(withoutShadowingClaude(undefined, 'darwin'), '');
|
|
})) passed++; else failed++;
|
|
|
|
if (test('names an archive relatively with forward slashes and no drive letter', () => {
|
|
const cwd = path.join(root, 'extract', 'node_modules');
|
|
const archive = path.join(root, 'pkg-1.0.0.tgz');
|
|
const relative = toRelativeTarPath(cwd, archive);
|
|
assert.ok(!relative.includes(':'), `tar reads a colon as host:path: ${relative}`);
|
|
assert.ok(!relative.includes('\\'), `expected forward slashes: ${relative}`);
|
|
assert.strictEqual(path.resolve(cwd, relative), archive);
|
|
})) passed++; else failed++;
|
|
} finally {
|
|
fs.rmSync(root, { recursive: true, force: true });
|
|
}
|
|
|
|
summary(passed, failed);
|