UNPKG

agentsqripts

Version:

Comprehensive static code analysis toolkit for identifying technical debt, security vulnerabilities, performance issues, and code quality problems

234 lines (191 loc) 9.7 kB
/** * @file Unit tests for analyzer helper utilities * @description Tests common analyzer functions used across all analysis modules */ const { validateAnalysisOptions, mergeAnalysisResults, calculateSeverityCounts, generateAnalysisSummary, filterIssuesBySeverity, sortIssuesByPriority } = require('./analyzerHelpers'); const qtests = require('qtests'); /** * Test runner for analyzer helpers */ async function runTests() { console.log('=== Testing Analyzer Helper Utilities ==='); const results = { total: 0, passed: 0 }; // Test validateAnalysisOptions function results.total++; try { const validOptions = { extensions: ['.js', '.ts'], excludePatterns: ['node_modules'], severity: 'MEDIUM' }; const invalidOptions = { extensions: 'not-array', severity: 'INVALID_SEVERITY' }; const emptyOptions = {}; const validResult = validateAnalysisOptions(validOptions); const invalidResult = validateAnalysisOptions(invalidOptions); const emptyResult = validateAnalysisOptions(emptyOptions); qtests.assert(validResult.isValid === true, 'validateAnalysisOptions should accept valid options'); qtests.assert(Array.isArray(validResult.errors) && validResult.errors.length === 0, 'Valid options should have no errors'); qtests.assert(invalidResult.isValid === false, 'validateAnalysisOptions should reject invalid options'); qtests.assert(Array.isArray(invalidResult.errors) && invalidResult.errors.length > 0, 'Invalid options should have errors'); qtests.assert(emptyResult.isValid === true, 'validateAnalysisOptions should accept empty options (defaults)'); console.log('✓ validateAnalysisOptions correctly validates analysis options'); results.passed++; } catch (error) { console.log(`✗ validateAnalysisOptions test failed: ${error.message}`); } // Test mergeAnalysisResults function results.total++; try { const result1 = { summary: { totalIssues: 5, severityBreakdown: { HIGH: 2, MEDIUM: 2, LOW: 1 } }, issues: [ { id: 1, severity: 'HIGH', type: 'security' }, { id: 2, severity: 'MEDIUM', type: 'performance' } ] }; const result2 = { summary: { totalIssues: 3, severityBreakdown: { HIGH: 1, MEDIUM: 1, LOW: 1 } }, issues: [ { id: 3, severity: 'HIGH', type: 'bug' }, { id: 4, severity: 'LOW', type: 'style' } ] }; const merged = mergeAnalysisResults([result1, result2]); qtests.assert(typeof merged === 'object', 'mergeAnalysisResults should return object'); qtests.assert(merged.summary.totalIssues === 8, 'Should merge total issue counts'); qtests.assert(merged.summary.severityBreakdown.HIGH === 3, 'Should merge HIGH severity counts'); qtests.assert(merged.summary.severityBreakdown.MEDIUM === 3, 'Should merge MEDIUM severity counts'); qtests.assert(merged.summary.severityBreakdown.LOW === 2, 'Should merge LOW severity counts'); qtests.assert(Array.isArray(merged.issues) && merged.issues.length === 4, 'Should merge issues arrays'); console.log('✓ mergeAnalysisResults correctly merges multiple analysis results'); results.passed++; } catch (error) { console.log(`✗ mergeAnalysisResults test failed: ${error.message}`); } // Test calculateSeverityCounts function results.total++; try { const testIssues = [ { severity: 'HIGH', type: 'security' }, { severity: 'HIGH', type: 'bug' }, { severity: 'MEDIUM', type: 'performance' }, { severity: 'MEDIUM', type: 'maintainability' }, { severity: 'LOW', type: 'style' }, { severity: 'CRITICAL', type: 'security' } ]; const counts = calculateSeverityCounts(testIssues); qtests.assert(typeof counts === 'object', 'calculateSeverityCounts should return object'); qtests.assert(counts.HIGH === 2, 'Should count HIGH severity issues correctly'); qtests.assert(counts.MEDIUM === 2, 'Should count MEDIUM severity issues correctly'); qtests.assert(counts.LOW === 1, 'Should count LOW severity issues correctly'); qtests.assert(counts.CRITICAL === 1, 'Should count CRITICAL severity issues correctly'); qtests.assert(counts.total === 6, 'Should count total issues correctly'); console.log('✓ calculateSeverityCounts correctly counts issues by severity'); results.passed++; } catch (error) { console.log(`✗ calculateSeverityCounts test failed: ${error.message}`); } // Test generateAnalysisSummary function results.total++; try { const testIssues = [ { severity: 'HIGH', category: 'Security', impact: 9 }, { severity: 'MEDIUM', category: 'Performance', impact: 6 }, { severity: 'LOW', category: 'Style', impact: 3 } ]; const summary = generateAnalysisSummary(testIssues, 5, 'Test Analysis'); qtests.assert(typeof summary === 'object', 'generateAnalysisSummary should return object'); qtests.assert(summary.totalFiles === 5, 'Should include total files count'); qtests.assert(summary.totalIssues === 3, 'Should count total issues'); qtests.assert(summary.analysisType === 'Test Analysis', 'Should include analysis type'); qtests.assert(typeof summary.severityBreakdown === 'object', 'Should include severity breakdown'); qtests.assert(typeof summary.categoryBreakdown === 'object', 'Should include category breakdown'); qtests.assert(typeof summary.averageImpact === 'number', 'Should calculate average impact'); console.log('✓ generateAnalysisSummary correctly generates comprehensive summary'); results.passed++; } catch (error) { console.log(`✗ generateAnalysisSummary test failed: ${error.message}`); } // Test filterIssuesBySeverity function results.total++; try { const testIssues = [ { severity: 'CRITICAL', type: 'security' }, { severity: 'HIGH', type: 'bug' }, { severity: 'MEDIUM', type: 'performance' }, { severity: 'LOW', type: 'style' } ]; const highAndAbove = filterIssuesBySeverity(testIssues, 'HIGH'); const mediumAndAbove = filterIssuesBySeverity(testIssues, 'MEDIUM'); const criticalOnly = filterIssuesBySeverity(testIssues, 'CRITICAL'); qtests.assert(Array.isArray(highAndAbove), 'filterIssuesBySeverity should return array'); qtests.assert(highAndAbove.length === 2, 'Should include HIGH and CRITICAL severities'); qtests.assert(mediumAndAbove.length === 3, 'Should include MEDIUM, HIGH, and CRITICAL severities'); qtests.assert(criticalOnly.length === 1, 'Should include only CRITICAL severity'); qtests.assert(highAndAbove.every(issue => ['HIGH', 'CRITICAL'].includes(issue.severity)), 'Should filter correctly by severity threshold'); console.log('✓ filterIssuesBySeverity correctly filters issues by severity level'); results.passed++; } catch (error) { console.log(`✗ filterIssuesBySeverity test failed: ${error.message}`); } // Test sortIssuesByPriority function results.total++; try { const testIssues = [ { severity: 'LOW', impact: 3, effort: 1 }, { severity: 'HIGH', impact: 8, effort: 3 }, { severity: 'MEDIUM', impact: 5, effort: 2 }, { severity: 'CRITICAL', impact: 10, effort: 4 } ]; const sortedBySeverity = sortIssuesByPriority(testIssues, 'severity'); const sortedByImpact = sortIssuesByPriority(testIssues, 'impact'); const sortedByEffort = sortIssuesByPriority(testIssues, 'effort'); qtests.assert(Array.isArray(sortedBySeverity), 'sortIssuesByPriority should return array'); qtests.assert(sortedBySeverity[0].severity === 'CRITICAL', 'Should sort by severity (CRITICAL first)'); qtests.assert(sortedBySeverity[3].severity === 'LOW', 'Should sort by severity (LOW last)'); qtests.assert(sortedByImpact[0].impact === 10, 'Should sort by impact (highest first)'); qtests.assert(sortedByImpact[3].impact === 3, 'Should sort by impact (lowest last)'); qtests.assert(sortedByEffort[0].effort === 1, 'Should sort by effort (lowest first for easy fixes)'); qtests.assert(sortedByEffort[3].effort === 4, 'Should sort by effort (highest last)'); console.log('✓ sortIssuesByPriority correctly sorts issues by different criteria'); results.passed++; } catch (error) { console.log(`✗ sortIssuesByPriority test failed: ${error.message}`); } // Test edge cases and error handling results.total++; try { // Test empty arrays const emptyMerge = mergeAnalysisResults([]); qtests.assert(emptyMerge.summary.totalIssues === 0, 'Should handle empty results array'); const emptyCounts = calculateSeverityCounts([]); qtests.assert(emptyCounts.total === 0, 'Should handle empty issues array'); const emptyFilter = filterIssuesBySeverity([], 'HIGH'); qtests.assert(emptyFilter.length === 0, 'Should handle empty issues array for filtering'); // Test invalid severity const invalidFilter = filterIssuesBySeverity([{ severity: 'INVALID' }], 'HIGH'); qtests.assert(Array.isArray(invalidFilter), 'Should handle invalid severity gracefully'); console.log('✓ Analyzer helpers handle edge cases and invalid inputs gracefully'); results.passed++; } catch (error) { console.log(`✗ Edge cases test failed: ${error.message}`); } console.log(`=== Analyzer Helpers Test Results ===`); console.log(`Tests passed: ${results.passed}/${results.total}`); console.log(`Success rate: ${((results.passed / results.total) * 100).toFixed(1)}%`); return results; } module.exports = { runTests };