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
JavaScript
/**
* @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 };