Skip to main content
Glama
logic.test.cjs10.7 kB
const fs = require('fs').promises; const path = require('path'); // Test the ACTUAL pattern matching logic without ES module imports // Test utilities async function createTestFile(content) { const testPath = path.join(__dirname, 'temp', `test-${Date.now()}.js`); await fs.mkdir(path.dirname(testPath), { recursive: true }); await fs.writeFile(testPath, content); return testPath; } async function cleanup(filePaths) { for (const filePath of filePaths) { try { await fs.unlink(filePath); } catch (error) { // Ignore } } } // Core pattern matching functions - что РЕАЛЬНО должно работать async function extractByPattern(filePath, startPattern, endPattern, lineCount) { const content = await fs.readFile(filePath, 'utf-8'); const startIndex = content.indexOf(startPattern); if (startIndex === -1) { throw new Error(`Start pattern "${startPattern}" not found`); } if (endPattern) { const endIndex = content.indexOf(endPattern, startIndex + startPattern.length); if (endIndex === -1) { throw new Error(`End pattern "${endPattern}" not found after start pattern`); } return content.slice(startIndex, endIndex + endPattern.length); } else if (lineCount) { const lines = content.split('\n'); const startLine = content.slice(0, startIndex).split('\n').length - 1; const endLine = Math.min(startLine + lineCount, lines.length); return lines.slice(startLine, endLine).join('\n'); } else { const lines = content.split('\n'); const startLine = content.slice(0, startIndex).split('\n').length - 1; return lines[startLine]; } } async function insertByMarker(filePath, marker, content, position) { const existingContent = await fs.readFile(filePath, 'utf-8'); if (existingContent.indexOf(marker) === -1) { throw new Error(`Marker "${marker}" not found`); } let newContent; if (position === 'before') { newContent = existingContent.replace(marker, `${content}\n${marker}`); } else if (position === 'after') { newContent = existingContent.replace(marker, `${marker}\n${content}`); } else if (position === 'replace') { newContent = existingContent.replace(marker, content); } await fs.writeFile(filePath, newContent); } describe('Pattern Matching Logic Tests', () => { let testFiles = []; afterEach(async () => { await cleanup(testFiles); testFiles = []; }); test('Extract function with end pattern', async () => { const testCode = `// Test file function processData(input) { console.log('Processing:', input); return input.toUpperCase(); } function otherFunction() { return false; }`; const testFile = await createTestFile(testCode); testFiles = [testFile]; const result = await extractByPattern(testFile, 'function processData', '}'); expect(result).toMatchSnapshot(); expect(result).toContain('function processData'); expect(result).toContain('console.log'); expect(result).toContain('}'); expect(result).not.toContain('function otherFunction'); }); test('Extract with line count', async () => { const testCode = `// Header comment function test() { const a = 1; const b = 2; return a + b; } // Footer`; const testFile = await createTestFile(testCode); testFiles = [testFile]; const result = await extractByPattern(testFile, 'function test()', undefined, 3); expect(result).toMatchSnapshot(); expect(result.split('\n')).toHaveLength(3); expect(result).toContain('function test()'); expect(result).toContain('const a = 1'); }); test('Insert after marker', async () => { const testCode = `class Test { // Insert utilities here mainMethod() { return true; } }`; const testFile = await createTestFile(testCode); testFiles = [testFile]; await insertByMarker(testFile, '// Insert utilities here', 'function added() {}', 'after'); const result = await fs.readFile(testFile, 'utf-8'); expect(result).toMatchSnapshot(); expect(result).toContain('// Insert utilities here'); expect(result).toContain('function added() {}'); }); test('Replace marker', async () => { const testCode = `class Test { // TODO: Add methods here existingMethod() { return false; } }`; const testFile = await createTestFile(testCode); testFiles = [testFile]; await insertByMarker(testFile, '// TODO: Add methods here', 'function newMethod() { return true; }', 'replace'); const result = await fs.readFile(testFile, 'utf-8'); expect(result).toMatchSnapshot(); expect(result).not.toContain('// TODO: Add methods here'); expect(result).toContain('function newMethod()'); }); test('Error - pattern not found', async () => { const testFile = await createTestFile('function test() {}'); testFiles = [testFile]; await expect( extractByPattern(testFile, 'NONEXISTENT', undefined, 1) ).rejects.toThrow('not found'); }); test('Error - marker not found', async () => { const testFile = await createTestFile('function test() {}'); testFiles = [testFile]; await expect( insertByMarker(testFile, 'NONEXISTENT', 'content', 'after') ).rejects.toThrow('not found'); }); test('Extract single line by pattern', async () => { const testCode = `const a = 1; const b = 2; const TARGET_LINE = 'find me'; const c = 3;`; const testFile = await createTestFile(testCode); testFiles = [testFile]; const result = await extractByPattern(testFile, 'TARGET_LINE'); expect(result).toMatchSnapshot(); expect(result).toBe('const TARGET_LINE = \'find me\';'); }); test('Extract multiline block with comments', async () => { const testCode = `// Before block /* START_BLOCK */ function complexFunction(a, b, c) { // Complex logic here const result = a + b + c; return result; } /* END_BLOCK */ // After block`; const testFile = await createTestFile(testCode); testFiles = [testFile]; const result = await extractByPattern(testFile, '/* START_BLOCK */', '/* END_BLOCK */'); expect(result).toMatchSnapshot(); expect(result).toContain('/* START_BLOCK */'); expect(result).toContain('complexFunction'); expect(result).toContain('/* END_BLOCK */'); }); test('Extract class definition', async () => { const testCode = `import something from 'lib'; class MyClass { constructor(data) { this.data = data; } process() { return this.data.map(x => x * 2); } } export default MyClass;`; const testFile = await createTestFile(testCode); testFiles = [testFile]; const result = await extractByPattern(testFile, 'class MyClass', undefined, 8); expect(result).toMatchSnapshot(); expect(result).toContain('class MyClass'); expect(result).toContain('constructor'); expect(result).toContain('process()'); }); test('Insert before first line', async () => { const testCode = `function existing() { return true; }`; const testFile = await createTestFile(testCode); testFiles = [testFile]; await insertByMarker(testFile, 'function existing()', '// Added header comment', 'before'); const result = await fs.readFile(testFile, 'utf-8'); expect(result).toMatchSnapshot(); expect(result.startsWith('// Added header comment')); }); test('Insert complex content after marker', async () => { const testCode = `class Service { // INJECT_METHODS_HERE existing() { return 'exists'; } }`; const complexContent = `async fetchData(url) { try { const response = await fetch(url); return await response.json(); } catch (error) { throw new Error(\`Fetch failed: \${error.message}\`); } } validateData(data) { if (!data || typeof data !== 'object') { return false; } return Object.keys(data).length > 0; }`; const testFile = await createTestFile(testCode); testFiles = [testFile]; await insertByMarker(testFile, '// INJECT_METHODS_HERE', complexContent, 'after'); const result = await fs.readFile(testFile, 'utf-8'); expect(result).toMatchSnapshot(); expect(result).toContain('async fetchData'); expect(result).toContain('validateData'); }); test('Extract arrow function block', async () => { const testCode = `const utils = { // ARROW_FUNCTIONS_START processArray: (arr) => arr.filter(x => x > 0), formatString: (str) => str.trim().toLowerCase(), calculateSum: (numbers) => numbers.reduce((a, b) => a + b, 0) // ARROW_FUNCTIONS_END };`; const testFile = await createTestFile(testCode); testFiles = [testFile]; const result = await extractByPattern(testFile, '// ARROW_FUNCTIONS_START', '// ARROW_FUNCTIONS_END'); expect(result).toMatchSnapshot(); expect(result).toContain('processArray'); expect(result).toContain('=>'); }); test('Replace nested content', async () => { const testCode = `function wrapper() { // REPLACE_TARGET const old = 'remove this'; // END_REPLACE return 'keep this'; }`; const newContent = `const new = 'added this'; const also = 'and this too';`; const testFile = await createTestFile(testCode); testFiles = [testFile]; await insertByMarker(testFile, '// REPLACE_TARGET', newContent, 'replace'); const result = await fs.readFile(testFile, 'utf-8'); expect(result).toMatchSnapshot(); expect(result).not.toContain('// REPLACE_TARGET'); expect(result).toContain('added this'); }); test('Extract with special characters and regex patterns', async () => { const testCode = 'const regex = /function\\\\s+\\\\w+\\\\(/;\n' + 'const string = "function test() { return \'test\'; }";\n' + '// SPECIAL_PATTERN: ${}[]^.*+?|()\n' + 'const config = {\n' + ' pattern: "*.{js,ts,jsx,tsx}",\n' + ' exclude: ["node_modules/**", "dist/**"]\n' + '};'; const testFile = await createTestFile(testCode); testFiles = [testFile]; const result = await extractByPattern(testFile, '// SPECIAL_PATTERN', undefined, 3); expect(result).toMatchSnapshot(); expect(result).toContain('SPECIAL_PATTERN'); expect(result).toContain('pattern:'); }); test('Empty line extraction', async () => { const testCode = `line 1 // EMPTY_LINE_MARKER line 4`; const testFile = await createTestFile(testCode); testFiles = [testFile]; const result = await extractByPattern(testFile, '// EMPTY_LINE_MARKER', undefined, 1); expect(result).toMatchSnapshot(); expect(result).toBe('// EMPTY_LINE_MARKER'); }); });

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/witqq/clipboard-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server