agentsqripts
Version:
Comprehensive static code analysis toolkit for identifying technical debt, security vulnerabilities, performance issues, and code quality problems
193 lines (161 loc) • 7.9 kB
JavaScript
/**
* @file Unit tests for common data processing patterns
* @description Tests filtering, grouping, counting, sorting, and percentage calculation utilities
*/
const { filterBy, groupBy, countBy, sortBy, calculatePercentage } = require('./commonPatterns');
const qtests = require('qtests');
/**
* Test runner for common patterns
*/
async function runTests() {
console.log('=== Testing Common Data Processing Patterns ===');
const results = {
total: 0,
passed: 0
};
// Test filterBy function
results.total++;
try {
const testData = [
{ name: 'Alice', age: 25, active: true },
{ name: 'Bob', age: 30, active: false },
{ name: 'Charlie', age: 35, active: true },
{ name: 'Diana', age: 28, active: false }
];
const activeUsers = filterBy(testData, (user) => user.active);
const youngUsers = filterBy(testData, (user) => user.age < 30);
qtests.assert(Array.isArray(activeUsers), 'filterBy should return array');
qtests.assert(activeUsers.length === 2, 'filterBy should filter correctly');
qtests.assert(activeUsers.every(user => user.active), 'filterBy should include only matching items');
qtests.assert(youngUsers.length === 2, 'filterBy should work with different criteria');
console.log('✓ filterBy correctly filters data by criteria');
results.passed++;
} catch (error) {
console.log(`✗ filterBy test failed: ${error.message}`);
}
// Test groupBy function
results.total++;
try {
const testData = [
{ category: 'fruit', name: 'apple' },
{ category: 'vegetable', name: 'carrot' },
{ category: 'fruit', name: 'banana' },
{ category: 'vegetable', name: 'lettuce' },
{ category: 'fruit', name: 'orange' }
];
const groupedByCategory = groupBy(testData, (item) => item.category);
const groupedByFirstLetter = groupBy(testData, (item) => item.name[0]);
qtests.assert(typeof groupedByCategory === 'object', 'groupBy should return object');
qtests.assert(Object.keys(groupedByCategory).length === 2, 'groupBy should create correct number of groups');
qtests.assert(Array.isArray(groupedByCategory.fruit), 'groupBy should create arrays for groups');
qtests.assert(groupedByCategory.fruit.length === 3, 'groupBy should group items correctly');
qtests.assert(groupedByCategory.vegetable.length === 2, 'groupBy should group all matching items');
console.log('✓ groupBy correctly groups data by key function');
results.passed++;
} catch (error) {
console.log(`✗ groupBy test failed: ${error.message}`);
}
// Test countBy function
results.total++;
try {
const testData = [
{ severity: 'HIGH' },
{ severity: 'MEDIUM' },
{ severity: 'HIGH' },
{ severity: 'LOW' },
{ severity: 'HIGH' },
{ severity: 'MEDIUM' }
];
const severityCounts = countBy(testData, (item) => item.severity);
const totalCount = countBy(testData, () => 'all');
qtests.assert(typeof severityCounts === 'object', 'countBy should return object');
qtests.assert(severityCounts.HIGH === 3, 'countBy should count HIGH severity correctly');
qtests.assert(severityCounts.MEDIUM === 2, 'countBy should count MEDIUM severity correctly');
qtests.assert(severityCounts.LOW === 1, 'countBy should count LOW severity correctly');
qtests.assert(totalCount.all === 6, 'countBy should count total items correctly');
console.log('✓ countBy correctly counts items by criteria');
results.passed++;
} catch (error) {
console.log(`✗ countBy test failed: ${error.message}`);
}
// Test sortBy function
results.total++;
try {
const testData = [
{ name: 'Charlie', score: 85 },
{ name: 'Alice', score: 95 },
{ name: 'Bob', score: 75 },
{ name: 'Diana', score: 90 }
];
const sortedByScore = sortBy(testData, (item) => item.score);
const sortedByName = sortBy(testData, (item) => item.name);
const sortedByScoreDesc = sortBy(testData, (item) => item.score, 'desc');
qtests.assert(Array.isArray(sortedByScore), 'sortBy should return array');
qtests.assert(sortedByScore[0].score === 75, 'sortBy should sort in ascending order by default');
qtests.assert(sortedByScore[3].score === 95, 'sortBy should place highest value last in ascending');
qtests.assert(sortedByScoreDesc[0].score === 95, 'sortBy should sort in descending order when specified');
qtests.assert(sortedByName[0].name === 'Alice', 'sortBy should sort strings alphabetically');
console.log('✓ sortBy correctly sorts data by key function');
results.passed++;
} catch (error) {
console.log(`✗ sortBy test failed: ${error.message}`);
}
// Test calculatePercentage function
results.total++;
try {
const percentage1 = calculatePercentage(25, 100);
const percentage2 = calculatePercentage(3, 7);
const percentage3 = calculatePercentage(0, 100);
const percentage4 = calculatePercentage(100, 100);
qtests.assert(typeof percentage1 === 'number', 'calculatePercentage should return number');
qtests.assert(percentage1 === 25, 'calculatePercentage should calculate simple percentages');
qtests.assert(Math.abs(percentage2 - 42.86) < 0.01, 'calculatePercentage should handle decimal results');
qtests.assert(percentage3 === 0, 'calculatePercentage should handle zero numerator');
qtests.assert(percentage4 === 100, 'calculatePercentage should handle equal values');
console.log('✓ calculatePercentage correctly calculates percentages');
results.passed++;
} catch (error) {
console.log(`✗ calculatePercentage test failed: ${error.message}`);
}
// Test calculatePercentage edge cases
results.total++;
try {
const zeroDenominator = calculatePercentage(50, 0);
const negativePart = calculatePercentage(-10, 100);
const negativeWhole = calculatePercentage(10, -100);
qtests.assert(zeroDenominator === 0, 'calculatePercentage should handle zero denominator');
qtests.assert(negativePart === -10, 'calculatePercentage should handle negative numerator');
qtests.assert(negativeWhole === -10, 'calculatePercentage should handle negative denominator');
console.log('✓ calculatePercentage correctly handles edge cases');
results.passed++;
} catch (error) {
console.log(`✗ calculatePercentage edge cases test failed: ${error.message}`);
}
// Test chaining operations
results.total++;
try {
const testData = [
{ category: 'bug', severity: 'HIGH', impact: 10 },
{ category: 'bug', severity: 'MEDIUM', impact: 5 },
{ category: 'perf', severity: 'HIGH', impact: 8 },
{ category: 'bug', severity: 'LOW', impact: 2 },
{ category: 'perf', severity: 'MEDIUM', impact: 6 }
];
// Chain operations: filter bugs, sort by impact, group by severity
const bugs = filterBy(testData, (item) => item.category === 'bug');
const sortedBugs = sortBy(bugs, (item) => item.impact, 'desc');
const groupedBugs = groupBy(sortedBugs, (item) => item.severity);
qtests.assert(bugs.length === 3, 'Chained operations should work with filterBy');
qtests.assert(sortedBugs[0].impact === 10, 'Chained operations should work with sortBy');
qtests.assert(Object.keys(groupedBugs).length === 3, 'Chained operations should work with groupBy');
console.log('✓ Common patterns can be chained together effectively');
results.passed++;
} catch (error) {
console.log(`✗ Chaining operations test failed: ${error.message}`);
}
console.log(`=== Common Patterns 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 };