refactored tests

This commit is contained in:
Woody 2024-01-17 16:24:13 +01:00
parent 73d48c8ac4
commit e0facf35c8
No known key found for this signature in database
GPG Key ID: 9872D7F5072789B2
2 changed files with 96 additions and 120 deletions

View File

@ -1,6 +1,7 @@
'use strict'; 'use strict';
const assert = require('node:assert'); const assert = require('node:assert');
const { describe, it, before, after, afterEach, mock, test, run } = require('node:test'); const { describe, it, before, after } = require('node:test');
const fs = require('fs'); const fs = require('fs');
const path = require('path'); const path = require('path');
const child_process = require('child_process'); const child_process = require('child_process');
@ -10,15 +11,13 @@ const execPromise = util.promisify(child_process.exec);
process.env.NODE_ENV = 'test'; // Set the environment to testing process.env.NODE_ENV = 'test'; // Set the environment to testing
const cdata = require('./cdata.js'); const cdata = require('./cdata.js');
describe('Functions', () => { describe('Function', () => {
const testFolderPath = path.join(__dirname, 'testFolder'); const testFolderPath = path.join(__dirname, 'testFolder');
const oldFilePath = path.join(testFolderPath, 'oldFile.txt'); const oldFilePath = path.join(testFolderPath, 'oldFile.txt');
const newFilePath = path.join(testFolderPath, 'newFile.txt'); const newFilePath = path.join(testFolderPath, 'newFile.txt');
// Create a temporary file before the test // Create a temporary file before the test
before(() => { before(() => {
fs.writeFileSync('temp.txt', 'Hello World');
// Create test folder // Create test folder
if (!fs.existsSync(testFolderPath)) { if (!fs.existsSync(testFolderPath)) {
fs.mkdirSync(testFolderPath); fs.mkdirSync(testFolderPath);
@ -35,53 +34,53 @@ describe('Functions', () => {
fs.writeFileSync(newFilePath, 'This is a new file.'); fs.writeFileSync(newFilePath, 'This is a new file.');
}); });
// delete the temporary file after the test // delete the temporary files after the test
after(() => { after(() => {
fs.unlinkSync('temp.txt');
// Delete test folder
if (fs.existsSync(testFolderPath)) {
fs.rmSync(testFolderPath, { recursive: true }); fs.rmSync(testFolderPath, { recursive: true });
}
}); });
describe('isFileNewerThan', async () => { describe('isFileNewerThan', async () => {
it('should return true if the file is newer than the provided time', async () => { it('should return true if the file is newer than the provided time', async () => {
const pastTime = Date.now() - 10000; // 10 seconds ago const pastTime = Date.now() - 10000; // 10 seconds ago
assert.strictEqual(cdata.isFileNewerThan('temp.txt', pastTime), true); assert.strictEqual(cdata.isFileNewerThan(newFilePath, pastTime), true);
}); });
it('should return false if the file is older than the provided time', async () => { it('should return false if the file is older than the provided time', async () => {
const futureTime = Date.now() + 10000; // 10 seconds in the future assert.strictEqual(cdata.isFileNewerThan(oldFilePath, Date.now()), false);
assert.strictEqual(cdata.isFileNewerThan('temp.txt', futureTime), false);
}); });
it('should return false if the file does not exist', async () => { it('should throw an exception if the file does not exist', async () => {
assert.strictEqual(cdata.isFileNewerThan('nonexistent.txt', Date.now()), false); assert.throws(() => {
cdata.isFileNewerThan('nonexistent.txt', Date.now());
});
}); });
}); });
describe('isAnyFileInFolderNewerThan', async () => { describe('isAnyFileInFolderNewerThan', async () => {
it('should return true if a file in the folder is newer than the given time', async () => { it('should return true if a file in the folder is newer than the given time', async () => {
const folderPath = path.join(__dirname, 'testFolder'); const time = fs.statSync(path.join(testFolderPath, 'oldFile.txt')).mtime;
const time = fs.statSync(path.join(folderPath, 'oldFile.txt')).mtime; assert.strictEqual(cdata.isAnyFileInFolderNewerThan(testFolderPath, time), true);
assert.strictEqual(cdata.isAnyFileInFolderNewerThan(folderPath, time), true);
}); });
it('should return false if no files in the folder are newer than the given time', async () => { it('should return false if no files in the folder are newer than the given time', async () => {
const folderPath = path.join(__dirname, 'testFolder'); assert.strictEqual(cdata.isAnyFileInFolderNewerThan(testFolderPath, new Date()), false);
const time = new Date(); });
assert.strictEqual(cdata.isAnyFileInFolderNewerThan(folderPath, time), false);
it('should throw an exception if the folder does not exist', async () => {
assert.throws(() => {
cdata.isAnyFileInFolderNewerThan('nonexistent', new Date());
});
}); });
}); });
}); });
describe('General functionality', () => { describe('Script', () => {
const folderPath = 'wled00'; const folderPath = 'wled00';
const dataPath = path.join(folderPath, 'data'); const dataPath = path.join(folderPath, 'data');
before(() => { before(() => {
process.env.NODE_ENV = 'production'; process.env.NODE_ENV = 'production';
// Backup files
fs.cpSync("wled00/data", "wled00Backup", { recursive: true }); fs.cpSync("wled00/data", "wled00Backup", { recursive: true });
fs.cpSync("tools/cdata.js", "cdata.bak.js"); fs.cpSync("tools/cdata.js", "cdata.bak.js");
}); });
@ -93,26 +92,54 @@ describe('General functionality', () => {
fs.renameSync("cdata.bak.js", "tools/cdata.js"); fs.renameSync("cdata.bak.js", "tools/cdata.js");
}); });
describe('Script', () => {
it('should create html_*.h files if they are missing', async () => {
// delete all html_*.h files // delete all html_*.h files
let files = await fs.promises.readdir(folderPath); async function deleteBuiltFiles() {
const files = await fs.promises.readdir(folderPath);
await Promise.all(files.map(file => { await Promise.all(files.map(file => {
if (file.startsWith('html_') && path.extname(file) === '.h') { if (file.startsWith('html_') && path.extname(file) === '.h') {
return fs.promises.unlink(path.join(folderPath, file)); return fs.promises.unlink(path.join(folderPath, file));
} }
})); }));
}
// run script cdata.js and wait for it to finish
await execPromise('node tools/cdata.js');
// check if html_*.h files were created // check if html_*.h files were created
files = await fs.promises.readdir(folderPath); async function checkIfBuiltFilesExist() {
const files = await fs.promises.readdir(folderPath);
const htmlFiles = files.filter(file => file.startsWith('html_') && path.extname(file) === '.h'); const htmlFiles = files.filter(file => file.startsWith('html_') && path.extname(file) === '.h');
assert(htmlFiles.length > 0, 'html_*.h files were not created'); assert(htmlFiles.length > 0, 'html_*.h files were not created');
}
async function runAndCheckIfBuiltFilesExist() {
await execPromise('node tools/cdata.js');
await checkIfBuiltFilesExist();
}
async function testFileModification(sourceFilePath, resultFile) {
// run cdata.js to ensure html_*.h files are created
await execPromise('node tools/cdata.js');
// modify file
fs.appendFileSync(sourceFilePath, ' ');
// delay for 1 second to ensure the modified time is different
await new Promise(resolve => setTimeout(resolve, 1000));
// run script cdata.js again and wait for it to finish
await execPromise('node tools/cdata.js');
// check if web ui was rebuilt
const stats = fs.statSync(path.join(folderPath, resultFile));
const modifiedTime = stats.mtimeMs;
const currentTime = Date.now();
assert(currentTime - modifiedTime < 500, resultFile + ' was not modified');
}
describe('should build if', () => {
it('html_*.h files are missing', async () => {
await deleteBuiltFiles();
await runAndCheckIfBuiltFilesExist();
}); });
it('should rebuild if 1 or more html_*.h files are missing', async () => { it('1 or more html_*.h files are missing', async () => {
// run script cdata.js and wait for it to finish // run script cdata.js and wait for it to finish
await execPromise('node tools/cdata.js'); await execPromise('node tools/cdata.js');
@ -124,23 +151,33 @@ describe('General functionality', () => {
await fs.promises.unlink(path.join(folderPath, randomFile)); await fs.promises.unlink(path.join(folderPath, randomFile));
} }
// run script cdata.js and wait for it to finish await runAndCheckIfBuiltFilesExist();
await execPromise('node tools/cdata.js');
// check if html_*.h files were created
files = await fs.promises.readdir(folderPath);
htmlFiles = files.filter(file => file.startsWith('html_') && path.extname(file) === '.h');
assert(htmlFiles.length > 0, 'html_*.h files were not created');
}); });
it('should not rebuild if the files are already built', async () => { it('a file changes', async () => {
// delete all html_*.h files await testFileModification(path.join(dataPath, 'index.htm'), 'html_ui.h');
let files = await fs.promises.readdir(folderPath); });
await Promise.all(files.map(file => {
if (file.startsWith('html_') && path.extname(file) === '.h') { it('a inlined file changes', async () => {
return fs.promises.unlink(path.join(folderPath, file)); await testFileModification(path.join(dataPath, 'index.js'), 'html_ui.h');
} });
}));
it('a settings file changes', async () => {
await testFileModification(path.join(dataPath, 'settings_leds.htm'), 'html_ui.h');
});
it('the favicon changes', async () => {
await testFileModification(path.join(dataPath, 'favicon.ico'), 'html_ui.h');
});
it('cdata.js changes', async () => {
await testFileModification('tools/cdata.js', 'html_ui.h');
});
});
describe('should not build if', () => {
it('the files are already built', async () => {
await deleteBuiltFiles();
// run script cdata.js and wait for it to finish // run script cdata.js and wait for it to finish
let startTime = Date.now(); let startTime = Date.now();
@ -155,62 +192,5 @@ describe('General functionality', () => {
// check if second run was faster than the first (must be at least 2x faster) // check if second run was faster than the first (must be at least 2x faster)
assert(secondRunTime < firstRunTime / 2, 'html_*.h files were rebuilt'); assert(secondRunTime < firstRunTime / 2, 'html_*.h files were rebuilt');
}); });
it('should rebuild if a file changes', async () => {
// run script cdata.js and wait for it to finish
await execPromise('node tools/cdata.js');
// modify index.htm
fs.appendFileSync(path.join(dataPath, 'index.htm'), ' ');
// delay for 1 second to ensure the modified time is different
await new Promise(resolve => setTimeout(resolve, 1000));
// run script cdata.js and wait for it to finish
await execPromise('node tools/cdata.js');
// check if html_ui.h was modified
const stats = fs.statSync(path.join(folderPath, 'html_ui.h'));
const modifiedTime = stats.mtimeMs;
const currentTime = Date.now();
assert(currentTime - modifiedTime < 500, 'html_ui.h was not modified');
});
it('should rebuild if a inlined file changes', async () => {
// run script cdata.js and wait for it to finish
await execPromise('node tools/cdata.js');
// modify index.htm
fs.appendFileSync(path.join(dataPath, 'index.js'), ' ');
// delay for 1 second to ensure the modified time is different
await new Promise(resolve => setTimeout(resolve, 1000));
// run script cdata.js and wait for it to finish
await execPromise('node tools/cdata.js');
// check if html_ui.h was modified
const stats = fs.statSync(path.join(folderPath, 'html_ui.h'));
const modifiedTime = stats.mtimeMs;
const currentTime = Date.now();
assert(currentTime - modifiedTime < 500, 'html_ui.h was not modified');
});
it('should rebuild if a cdata.js has been modified', async () => {
// run script cdata.js and wait for it to finish
await execPromise('node tools/cdata.js');
// modify index.htm
fs.appendFileSync('tools/cdata.js', ' ');
// delay for 1 second to ensure the modified time is different
await new Promise(resolve => setTimeout(resolve, 1000));
// run script cdata.js and wait for it to finish
await execPromise('node tools/cdata.js');
// check if html_ui.h was modified
const stats = fs.statSync(path.join(folderPath, 'html_ui.h'));
const modifiedTime = stats.mtimeMs;
const currentTime = Date.now();
assert(currentTime - modifiedTime < 500, 'html_ui.h was not modified');
});
}); });
}); });

View File

@ -188,13 +188,8 @@ async function writeChunks(srcDir, specs, resultFile) {
// Check if a file is newer than a given time // Check if a file is newer than a given time
function isFileNewerThan(filePath, time) { function isFileNewerThan(filePath, time) {
try {
const stats = fs.statSync(filePath); const stats = fs.statSync(filePath);
return stats.mtimeMs > time; return stats.mtimeMs > time;
} catch (e) {
console.error(`Failed to get stats for file ${filePath}:`, e);
return false;
}
} }
// Check if any file in a folder (or its subfolders) is newer than a given time // Check if any file in a folder (or its subfolders) is newer than a given time
@ -219,8 +214,9 @@ function isAlreadyBuilt(folderPath) {
for (const file of output) { for (const file of output) {
try { try {
lastBuildTime = Math.min(lastBuildTime, fs.statSync(file).mtimeMs); lastBuildTime = Math.min(lastBuildTime, fs.statSync(file).mtimeMs);
} } catch (e) {
catch (e) { if (e.code !== 'ENOENT') throw e;
console.info("File " + file + " does not exist. Rebuilding...");
return false; return false;
} }
} }