/ tests / test-scaffolding-fixes.js
test-scaffolding-fixes.js
  1  /**
  2   * Quick unit tests for scaffolding fixes
  3   * Tests the new methods without database dependencies
  4   */
  5  
  6  import { test, describe } from 'node:test';
  7  import assert from 'node:assert';
  8  import { TriageAgent } from '../src/agents/triage.js';
  9  import { QAAgent } from '../src/agents/qa.js';
 10  
 11  describe('Scaffolding Fixes - Triage Agent', () => {
 12    const agent = new TriageAgent();
 13  
 14    describe('calculatePriority', () => {
 15      test('assigns highest priority to critical errors', () => {
 16        const task = {
 17          id: 1,
 18          created_at: new Date(Date.now() - 48 * 60 * 60 * 1000).toISOString(),
 19        };
 20  
 21        const context = {
 22          frequency: 150,
 23          severity: 'critical',
 24          stage: 'scoring',
 25          error_type: 'database_connection',
 26        };
 27  
 28        const priority = agent.calculatePriority(task, context);
 29        assert.strictEqual(priority, 1);
 30      });
 31  
 32      test('assigns medium priority to low-frequency errors', () => {
 33        const task = {
 34          id: 1,
 35          created_at: new Date().toISOString(),
 36        };
 37  
 38        const context = {
 39          frequency: 1,
 40          severity: 'low',
 41          stage: 'outreach',
 42        };
 43  
 44        const priority = agent.calculatePriority(task, context);
 45        assert.strictEqual(priority, 5);
 46      });
 47  
 48      test('clamps priority to 1-10 range', () => {
 49        const task = {
 50          id: 1,
 51          created_at: new Date().toISOString(),
 52        };
 53  
 54        const maxContext = {
 55          frequency: 200,
 56          severity: 'critical',
 57          stage: 'scoring',
 58          error_type: 'security_breach',
 59        };
 60  
 61        const minContext = {};
 62  
 63        const maxPriority = agent.calculatePriority(task, maxContext);
 64        const minPriority = agent.calculatePriority(task, minContext);
 65  
 66        assert.ok(maxPriority >= 1 && maxPriority <= 10);
 67        assert.ok(minPriority >= 1 && minPriority <= 10);
 68      });
 69    });
 70  
 71    describe('calculateSimilarity', () => {
 72      test('returns 1.0 for identical strings', () => {
 73        const error = 'TypeError: Cannot read property length';
 74        const similarity = agent.calculateSimilarity(error, error);
 75        assert.strictEqual(similarity, 1.0);
 76      });
 77  
 78      test('returns 0 for empty strings', () => {
 79        assert.strictEqual(agent.calculateSimilarity('', 'error'), 0);
 80        assert.strictEqual(agent.calculateSimilarity('error', ''), 0);
 81      });
 82  
 83      test('returns 1 for two empty strings', () => {
 84        assert.strictEqual(agent.calculateSimilarity('', ''), 1);
 85      });
 86  
 87      test('returns high similarity for similar errors', () => {
 88        const error1 = 'database connection timeout';
 89        const error2 = 'database connection failed';
 90  
 91        const similarity = agent.calculateSimilarity(error1, error2);
 92        assert.ok(similarity > 0.6);
 93      });
 94  
 95      test('returns low similarity for different errors', () => {
 96        const error1 = 'TypeError: Cannot read property';
 97        const error2 = 'ReferenceError: fetch is not defined';
 98  
 99        const similarity = agent.calculateSimilarity(error1, error2);
100        assert.ok(similarity < 0.5);
101      });
102    });
103  });
104  
105  describe('Scaffolding Fixes - QA Agent', () => {
106    const agent = new QAAgent();
107  
108    describe('addMissingImport', () => {
109      test('adds node:test import for test identifier', () => {
110        const code = `test('my test', async (t) => {\n  // test code\n});`;
111        const result = agent.addMissingImport(code, 'test');
112  
113        assert.ok(result.includes("import { test } from 'node:test';"));
114        assert.ok(result.includes("test('my test'"));
115      });
116  
117      test('adds node:assert default import', () => {
118        const code = `test('my test', () => {\n  // use assert\n});`;
119        const result = agent.addMissingImport(code, 'assert');
120  
121        assert.ok(result.includes("import assert from 'node:assert';"));
122        assert.ok(!result.includes('{ assert }')); // Default import, not named
123      });
124  
125      test('adds to existing import', () => {
126        const code = `import { test } from 'node:test';\n\ntest('my test', () => {});`;
127        const result = agent.addMissingImport(code, 'describe');
128  
129        assert.ok(result.includes('test, describe'));
130        assert.strictEqual(result.match(/import.*from 'node:test'/g).length, 1);
131      });
132  
133      test('returns unchanged if already imported', () => {
134        const code = `import { test } from 'node:test';\n\ntest('my test', () => {});`;
135        const result = agent.addMissingImport(code, 'test');
136  
137        assert.strictEqual(result, code);
138      });
139  
140      test('detects CommonJS style', () => {
141        const code = `const test = require('node:test');\ntest('my test', () => {});`;
142        const result = agent.addMissingImport(code, 'assert');
143  
144        assert.ok(result.includes('require'));
145        assert.ok(!result.includes('import'));
146      });
147  
148      test('adds comment for unknown identifiers', () => {
149        const code = `test('my test', () => {});`;
150        const result = agent.addMissingImport(code, 'unknownIdentifier');
151  
152        assert.ok(result.includes('// TODO: Add import for unknownIdentifier (unknown module)'));
153      });
154  
155      test('handles fs/promises imports', () => {
156        const code = `test('my test', async () => {});`;
157        const result = agent.addMissingImport(code, 'readFile');
158  
159        assert.ok(result.includes("import { readFile } from 'fs/promises';"));
160      });
161  
162      test('handles path imports', () => {
163        const code = `test('my test', () => {});`;
164        const result = agent.addMissingImport(code, 'join');
165  
166        assert.ok(result.includes("import { join } from 'path';"));
167      });
168  
169      test('handles better-sqlite3 default import', () => {
170        const code = `test('my test', () => {});`;
171        const result = agent.addMissingImport(code, 'Database');
172  
173        assert.ok(result.includes("import Database from 'better-sqlite3';"));
174        assert.ok(!result.includes('{ Database }'));
175      });
176    });
177  });