Report / test-suite.js
salekml's picture
Upload 7 files
7adf043 verified
#!/usr/bin/env node
/**
* Test Suite for Smart Academic Report Generator
* Validates all features and configurations
*/
const fs = require('fs');
const path = require('path');
// ANSI color codes for console output
const colors = {
reset: '\x1b[0m',
bright: '\x1b[1m',
green: '\x1b[32m',
red: '\x1b[31m',
yellow: '\x1b[33m',
blue: '\x1b[34m',
cyan: '\x1b[36m'
};
function log(message, color = 'reset') {
console.log(`${colors[color]}${message}${colors.reset}`);
}
function logSuccess(message) {
log(`✅ ${message}`, 'green');
}
function logError(message) {
log(`❌ ${message}`, 'red');
}
function logInfo(message) {
log(`ℹ️ ${message}`, 'cyan');
}
function logWarning(message) {
log(`⚠️ ${message}`, 'yellow');
}
function logHeader(message) {
log(`\n${'='.repeat(60)}`, 'blue');
log(message, 'bright');
log('='.repeat(60), 'blue');
}
// Test cases
const tests = {
passed: 0,
failed: 0,
total: 0
};
function runTest(testName, testFn) {
tests.total++;
try {
testFn();
tests.passed++;
logSuccess(`${testName}`);
return true;
} catch (error) {
tests.failed++;
logError(`${testName}`);
logError(` Error: ${error.message}`);
return false;
}
}
// Test 1: Check if required files exist
function testFilesExist() {
logHeader('Test 1: Checking Required Files');
const requiredFiles = [
'generate-academic-report.js',
'sample-config.json',
'package.json',
'README.md',
'QUICKSTART.md',
'index.html'
];
requiredFiles.forEach(file => {
runTest(`File exists: ${file}`, () => {
if (!fs.existsSync(file)) {
throw new Error(`File not found: ${file}`);
}
});
});
}
// Test 2: Validate sample configuration
function testSampleConfig() {
logHeader('Test 2: Validating Sample Configuration');
runTest('sample-config.json is valid JSON', () => {
const content = fs.readFileSync('sample-config.json', 'utf8');
const config = JSON.parse(content);
// Check required fields
const requiredFields = [
'studentName', 'studentId', 'department', 'university',
'courseTitle', 'courseCode', 'teacherName', 'reportTitle', 'topic'
];
requiredFields.forEach(field => {
if (!config[field]) {
throw new Error(`Missing required field: ${field}`);
}
});
});
}
// Test 3: Validate package.json
function testPackageJson() {
logHeader('Test 3: Validating package.json');
runTest('package.json is valid', () => {
const content = fs.readFileSync('package.json', 'utf8');
const pkg = JSON.parse(content);
if (!pkg.name) throw new Error('Missing package name');
if (!pkg.version) throw new Error('Missing version');
if (!pkg.dependencies) throw new Error('Missing dependencies');
if (!pkg.dependencies.docx) throw new Error('Missing docx dependency');
});
}
// Test 4: Check script permissions
function testScriptPermissions() {
logHeader('Test 4: Checking Script Permissions');
runTest('generate-academic-report.js is readable', () => {
try {
fs.accessSync('generate-academic-report.js', fs.constants.R_OK);
} catch (err) {
throw new Error('Script is not readable');
}
});
}
// Test 5: Validate configuration options
function testConfigurationOptions() {
logHeader('Test 5: Testing Configuration Options');
const testConfigs = [
{
name: 'Minimum config',
config: {
studentName: 'Test Student',
studentId: 'TEST-001',
department: 'Test Dept',
university: 'Test University',
courseTitle: 'Test Course',
courseCode: 'TST 101',
teacherName: 'Test Teacher',
reportTitle: 'Test Report',
topic: 'Test Topic'
}
},
{
name: 'Full config with all options',
config: {
studentName: 'Test Student',
studentId: 'TEST-001',
department: 'Test Dept',
university: 'Test University',
courseTitle: 'Test Course',
courseCode: 'TST 101',
teacherName: 'Test Teacher',
teacherDesignation: 'Professor',
submissionDate: '2026-02-14',
reportType: 'assignment',
reportTitle: 'Test Report',
topic: 'Test Topic',
includeAbstract: true,
includeTOC: true,
includeReferences: true,
pageNumbers: true,
fontFamily: 'Times New Roman',
fontSize: '12',
lineSpacing: '1.5'
}
}
];
testConfigs.forEach(({ name, config }) => {
runTest(`Config validation: ${name}`, () => {
const jsonStr = JSON.stringify(config, null, 2);
JSON.parse(jsonStr); // Validate it's proper JSON
});
});
}
// Test 6: Test different report types
function testReportTypes() {
logHeader('Test 6: Testing Report Types');
const reportTypes = [
'assignment',
'project',
'thesis',
'research',
'case-study',
'lab-report'
];
reportTypes.forEach(type => {
runTest(`Report type: ${type}`, () => {
// Just validate the type is a string
if (typeof type !== 'string') {
throw new Error(`Invalid report type: ${type}`);
}
});
});
}
// Test 7: Test font families
function testFontFamilies() {
logHeader('Test 7: Testing Font Families');
const fontFamilies = [
'Times New Roman',
'Arial',
'Calibri',
'Georgia'
];
fontFamilies.forEach(font => {
runTest(`Font family: ${font}`, () => {
if (typeof font !== 'string' || font.length === 0) {
throw new Error(`Invalid font family: ${font}`);
}
});
});
}
// Test 8: Test date formats
function testDateFormats() {
logHeader('Test 8: Testing Date Formats');
const testDates = [
{ date: '2026-02-14', valid: true, name: 'ISO format (YYYY-MM-DD)' },
{ date: '2026-12-31', valid: true, name: 'End of year' },
{ date: '2026-01-01', valid: true, name: 'Start of year' }
];
testDates.forEach(({ date, valid, name }) => {
runTest(`Date format: ${name}`, () => {
const d = new Date(date);
if (isNaN(d.getTime()) && valid) {
throw new Error(`Invalid date: ${date}`);
}
});
});
}
// Test 9: Output directory check
function testOutputDirectory() {
logHeader('Test 9: Checking Output Directory');
runTest('Output directory structure', () => {
const outputDir = '/mnt/user-data/outputs';
// Just check if we can create the path conceptually
const isValidPath = outputDir.startsWith('/');
if (!isValidPath) {
throw new Error('Invalid output path');
}
});
}
// Test 10: Documentation completeness
function testDocumentation() {
logHeader('Test 10: Checking Documentation');
const docs = [
{ file: 'README.md', minLength: 1000 },
{ file: 'QUICKSTART.md', minLength: 500 }
];
docs.forEach(({ file, minLength }) => {
runTest(`Documentation: ${file}`, () => {
const content = fs.readFileSync(file, 'utf8');
if (content.length < minLength) {
throw new Error(`${file} seems incomplete (${content.length} chars)`);
}
});
});
}
// Test 11: HTML interface validation
function testHTMLInterface() {
logHeader('Test 11: Validating HTML Interface');
runTest('index.html structure', () => {
const content = fs.readFileSync('index.html', 'utf8');
// Check for essential elements
const requiredElements = [
'<form',
'studentName',
'studentId',
'department',
'university',
'courseTitle',
'reportTitle',
'submit'
];
requiredElements.forEach(element => {
if (!content.includes(element)) {
throw new Error(`Missing element in HTML: ${element}`);
}
});
});
}
// Test 12: Configuration field types
function testConfigFieldTypes() {
logHeader('Test 12: Testing Configuration Field Types');
runTest('String fields validation', () => {
const stringFields = [
'studentName', 'studentId', 'department', 'university',
'courseTitle', 'courseCode', 'teacherName', 'reportTitle', 'topic'
];
stringFields.forEach(field => {
const value = 'Test Value';
if (typeof value !== 'string') {
throw new Error(`Field ${field} should be string`);
}
});
});
runTest('Boolean fields validation', () => {
const booleanFields = [
'includeAbstract', 'includeTOC', 'includeReferences', 'pageNumbers'
];
booleanFields.forEach(field => {
const value = true;
if (typeof value !== 'boolean') {
throw new Error(`Field ${field} should be boolean`);
}
});
});
}
// Main test execution
function runAllTests() {
console.clear();
logHeader('🎓 Smart Academic Report Generator - Test Suite');
logInfo('Running comprehensive tests...\n');
// Run all test suites
testFilesExist();
testSampleConfig();
testPackageJson();
testScriptPermissions();
testConfigurationOptions();
testReportTypes();
testFontFamilies();
testDateFormats();
testOutputDirectory();
testDocumentation();
testHTMLInterface();
testConfigFieldTypes();
// Print summary
logHeader('Test Summary');
log(`\nTotal Tests: ${tests.total}`, 'bright');
logSuccess(`Passed: ${tests.passed}`);
if (tests.failed > 0) {
logError(`Failed: ${tests.failed}`);
log(`\nSuccess Rate: ${((tests.passed / tests.total) * 100).toFixed(1)}%`, 'yellow');
process.exit(1);
} else {
log('\n🎉 All tests passed! System is ready to use.', 'green');
log('\nTo generate a report, run:', 'cyan');
log(' node generate-academic-report.js --config sample-config.json\n', 'bright');
process.exit(0);
}
}
// Run tests
if (require.main === module) {
runAllTests();
}
module.exports = { runAllTests };