init
This commit is contained in:
138
.opencode/plugin/scout-block/tests/test-path-extractor.cjs
Executable file
138
.opencode/plugin/scout-block/tests/test-path-extractor.cjs
Executable file
@@ -0,0 +1,138 @@
|
||||
#!/usr/bin/env node
|
||||
/**
|
||||
* test-path-extractor.cjs - Unit tests for path-extractor module
|
||||
*/
|
||||
|
||||
const { extractFromToolInput, extractFromCommand, looksLikePath } = require('../path-extractor.cjs');
|
||||
|
||||
const toolInputTests = [
|
||||
{
|
||||
input: { file_path: 'packages/web/src/index.js' },
|
||||
expected: ['packages/web/src/index.js'],
|
||||
desc: 'file_path extraction'
|
||||
},
|
||||
{
|
||||
input: { path: 'node_modules' },
|
||||
expected: ['node_modules'],
|
||||
desc: 'path extraction'
|
||||
},
|
||||
{
|
||||
input: { pattern: '**/node_modules/**' },
|
||||
expected: ['**/node_modules/**'],
|
||||
desc: 'pattern extraction'
|
||||
},
|
||||
{
|
||||
input: { command: 'ls packages/web/node_modules' },
|
||||
hasPath: 'packages/web/node_modules',
|
||||
desc: 'command path extraction'
|
||||
},
|
||||
{
|
||||
input: { file_path: '/home/user/project/node_modules/pkg/index.js' },
|
||||
expected: ['/home/user/project/node_modules/pkg/index.js'],
|
||||
desc: 'absolute path extraction'
|
||||
},
|
||||
{
|
||||
input: { file_path: 'packages/web/node_modules/react/package.json', path: 'src' },
|
||||
hasPath: 'packages/web/node_modules',
|
||||
desc: 'multiple params extraction'
|
||||
}
|
||||
];
|
||||
|
||||
const commandTests = [
|
||||
{ cmd: 'ls packages/web/node_modules', hasPath: 'packages/web/node_modules', desc: 'ls with subfolder' },
|
||||
{ cmd: 'cat "path with spaces/file.js"', hasPath: 'path with spaces/file.js', desc: 'quoted path' },
|
||||
{ cmd: "cat 'single/quoted/path.js'", hasPath: 'single/quoted/path.js', desc: 'single quoted path' },
|
||||
{ cmd: 'cd apps/api/node_modules && ls', hasPath: 'apps/api/node_modules', desc: 'cd with chained command' },
|
||||
{ cmd: 'rm -rf node_modules', hasPath: 'node_modules', desc: 'rm with flags' },
|
||||
{ cmd: 'cp -r dist/ backup/', hasPath: 'dist', desc: 'cp with flags' },
|
||||
|
||||
// Note: Build commands may extract 'build' as a blocked dir name, but this is handled
|
||||
// at the dispatcher level (build commands bypass path checking entirely).
|
||||
// The path extractor correctly identifies blocked dir names like 'build'.
|
||||
{ cmd: 'npm run build', hasPath: 'build', desc: 'npm run build (extracts build)' },
|
||||
{ cmd: 'pnpm build', hasPath: 'build', desc: 'pnpm build (extracts build)' },
|
||||
{ cmd: 'cd build', hasPath: 'build', desc: 'cd build (extracts build)' },
|
||||
{ cmd: 'yarn test', hasPath: null, desc: 'yarn test (no blocked paths)' },
|
||||
{ cmd: 'npm install', hasPath: null, desc: 'npm install (no blocked paths)' },
|
||||
];
|
||||
|
||||
const looksLikePathTests = [
|
||||
{ str: 'packages/web/src', expected: true, desc: 'relative path with slashes' },
|
||||
{ str: '/home/user/project', expected: true, desc: 'absolute path' },
|
||||
{ str: './src/index.js', expected: true, desc: 'dot-relative path' },
|
||||
{ str: '../parent/file.js', expected: true, desc: 'parent-relative path' },
|
||||
{ str: 'file.txt', expected: true, desc: 'file with extension' },
|
||||
{ str: 'node_modules', expected: true, desc: 'blocked dir name' },
|
||||
{ str: 'ls', expected: false, desc: 'command word' },
|
||||
{ str: 'npm', expected: false, desc: 'package manager' },
|
||||
{ str: '-rf', expected: false, desc: 'flag' },
|
||||
{ str: '123', expected: false, desc: 'number' },
|
||||
];
|
||||
|
||||
console.log('Testing path-extractor module...\n');
|
||||
|
||||
let passed = 0;
|
||||
let failed = 0;
|
||||
|
||||
// Tool input tests
|
||||
console.log('--- Tool Input Tests ---');
|
||||
for (const test of toolInputTests) {
|
||||
const result = extractFromToolInput(test.input);
|
||||
let success;
|
||||
|
||||
if (test.expected) {
|
||||
success = test.expected.every(e => result.includes(e));
|
||||
} else if (test.hasPath) {
|
||||
success = result.some(p => p.includes(test.hasPath));
|
||||
}
|
||||
|
||||
if (success) {
|
||||
console.log(`\x1b[32m✓\x1b[0m ${test.desc}`);
|
||||
passed++;
|
||||
} else {
|
||||
console.log(`\x1b[31m✗\x1b[0m ${test.desc}: got ${JSON.stringify(result)}`);
|
||||
failed++;
|
||||
}
|
||||
}
|
||||
|
||||
// Command tests
|
||||
console.log('\n--- Command Tests ---');
|
||||
for (const test of commandTests) {
|
||||
const result = extractFromCommand(test.cmd);
|
||||
let success;
|
||||
|
||||
if (test.hasPath === null) {
|
||||
// Build commands should extract few/no blocked-related paths
|
||||
success = result.length === 0 || !result.some(p =>
|
||||
p.includes('node_modules') || p.includes('dist') || p.includes('build')
|
||||
);
|
||||
} else {
|
||||
success = result.some(p => p.includes(test.hasPath));
|
||||
}
|
||||
|
||||
if (success) {
|
||||
console.log(`\x1b[32m✓\x1b[0m ${test.desc}: ${JSON.stringify(result)}`);
|
||||
passed++;
|
||||
} else {
|
||||
console.log(`\x1b[31m✗\x1b[0m ${test.desc}: expected path containing '${test.hasPath}', got ${JSON.stringify(result)}`);
|
||||
failed++;
|
||||
}
|
||||
}
|
||||
|
||||
// looksLikePath tests
|
||||
console.log('\n--- looksLikePath Tests ---');
|
||||
for (const test of looksLikePathTests) {
|
||||
const result = looksLikePath(test.str);
|
||||
const success = result === test.expected;
|
||||
|
||||
if (success) {
|
||||
console.log(`\x1b[32m✓\x1b[0m ${test.desc}: '${test.str}' -> ${result}`);
|
||||
passed++;
|
||||
} else {
|
||||
console.log(`\x1b[31m✗\x1b[0m ${test.desc}: expected ${test.expected}, got ${result}`);
|
||||
failed++;
|
||||
}
|
||||
}
|
||||
|
||||
console.log(`\nResults: ${passed} passed, ${failed} failed`);
|
||||
process.exit(failed > 0 ? 1 : 0);
|
||||
Reference in New Issue
Block a user