diff --git a/.github/workflows/wled-ci.yml b/.github/workflows/wled-ci.yml index 7d27717dd..c38ab7d1e 100644 --- a/.github/workflows/wled-ci.yml +++ b/.github/workflows/wled-ci.yml @@ -94,3 +94,16 @@ jobs: *.bin env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + + Test-cdata: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Use Node.js + uses: actions/setup-node@v3 + with: + node-version: '20.x' + cache: 'npm' + - run: npm ci + - run: npm test \ No newline at end of file diff --git a/package.json b/package.json index 7394ecad4..f490f7635 100644 --- a/package.json +++ b/package.json @@ -9,6 +9,7 @@ }, "scripts": { "build": "node tools/cdata.js", + "test": "node --test", "dev": "nodemon -e js,html,htm,css,png,jpg,gif,ico,js -w tools/ -w wled00/data/ -x node tools/cdata.js" }, "repository": { diff --git a/tools/cdata-test.js b/tools/cdata-test.js index 81a8d8142..4fb8ba7e8 100644 --- a/tools/cdata-test.js +++ b/tools/cdata-test.js @@ -1,75 +1,100 @@ +'use strict'; const assert = require('node:assert'); -const { describe, it, before, after, mock, test } = require('node:test'); +const { describe, it, before, after, afterEach, mock, test, run } = require('node:test'); const fs = require('fs'); const path = require('path'); +const child_process = require('child_process'); +const util = require('util'); +const execPromise = util.promisify(child_process.exec); + +process.env.NODE_ENV = 'test'; // Set the environment to testing const cdata = require('./cdata.js'); -describe('Caching', function () { - describe('isFileNewerThan', function () { - before(function () { - // Create a temporary file before the test - fs.writeFileSync('temp.txt', 'Hello World'); - }); +describe('Caching', () => { + const testFolderPath = path.join(__dirname, 'testFolder'); + const oldFilePath = path.join(testFolderPath, 'oldFile.txt'); + const newFilePath = path.join(testFolderPath, 'newFile.txt'); - it('should return true if the file is newer than the provided time', function () { + // Create a temporary file before the test + before(() => { + fs.writeFileSync('temp.txt', 'Hello World'); + + // Create test folder + if (!fs.existsSync(testFolderPath)) { + fs.mkdirSync(testFolderPath); + } + + // Create an old file + fs.writeFileSync(oldFilePath, 'This is an old file.'); + // Modify the 'mtime' to simulate an old file + const oldTime = new Date(); + oldTime.setFullYear(oldTime.getFullYear() - 1); + fs.utimesSync(oldFilePath, oldTime, oldTime); + + // Create a new file + fs.writeFileSync(newFilePath, 'This is a new file.'); + }); + // delete the temporary file after the test + after(() => { + fs.unlinkSync('temp.txt'); + + // Delete test folder + if (fs.existsSync(testFolderPath)) { + fs.rmSync(testFolderPath, { recursive: true }); + } + }); + + describe('isFileNewerThan', async () => { + it('should return true if the file is newer than the provided time', async () => { const pastTime = Date.now() - 10000; // 10 seconds ago - assert.equal(cdata.isFileNewerThan('temp.txt', pastTime), true); + assert.strictEqual(cdata.isFileNewerThan('temp.txt', pastTime), true); }); - it('should return false if the file is older than the provided time', function () { + 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.equal(cdata.isFileNewerThan('temp.txt', futureTime), false); + assert.strictEqual(cdata.isFileNewerThan('temp.txt', futureTime), false); }); - it('should return false if the file does not exist', function () { - assert.equal(cdata.isFileNewerThan('nonexistent.txt', Date.now()), false); - }); - - // delete the temporary file after the test - after(function () { - fs.unlinkSync('temp.txt'); + it('should return false if the file does not exist', async () => { + assert.strictEqual(cdata.isFileNewerThan('nonexistent.txt', Date.now()), false); }); }); - describe('isAnyFileInFolderNewerThan', function () { - const testFolderPath = path.join(__dirname, 'testFolder'); - const oldFilePath = path.join(testFolderPath, 'oldFile.txt'); - const newFilePath = path.join(testFolderPath, 'newFile.txt'); - - before(function () { - // Create test folder - if (!fs.existsSync(testFolderPath)) { - fs.mkdirSync(testFolderPath); - } - - // Create an old file - fs.writeFileSync(oldFilePath, 'This is an old file.'); - // Modify the 'mtime' to simulate an old file - const oldTime = new Date(); - oldTime.setFullYear(oldTime.getFullYear() - 1); - fs.utimesSync(oldFilePath, oldTime, oldTime); - - // Create a new file - fs.writeFileSync(newFilePath, 'This is a new file.'); - }); - - it('should return true if a file in the folder is newer than the given time', function () { + describe('isAnyFileInFolderNewerThan', 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(folderPath, 'oldFile.txt')).mtime; assert.strictEqual(cdata.isAnyFileInFolderNewerThan(folderPath, time), true); }); - it('should return false if no files in the folder are newer than the given time', function () { + it('should return false if no files in the folder are newer than the given time', async () => { const folderPath = path.join(__dirname, 'testFolder'); const time = new Date(); assert.strictEqual(cdata.isAnyFileInFolderNewerThan(folderPath, time), false); }); + }); +}); - after(function () { - // Delete test folder - if (fs.existsSync(testFolderPath)) { - fs.rmSync(testFolderPath, { recursive: true }); - } +describe('General functionality', () => { + describe('Script', () => { + it('should create html_*.h files if they are missing', async () => { + // delete all html_*.h files + const folderPath = 'wled00'; + let files = await fs.promises.readdir(folderPath); + await Promise.all(files.map(file => { + if (file.startsWith('html_') && path.extname(file) === '.h') { + return fs.promises.unlink(path.join(folderPath, file)); + } + })); + + // run script cdata.js and wait for it to finish + process.env.NODE_ENV = 'production'; + await execPromise('node tools/cdata.js'); + + // check if html_*.h files were created + files = await fs.promises.readdir(folderPath); + const htmlFiles = files.filter(file => file.startsWith('html_') && path.extname(file) === '.h'); + assert(htmlFiles.length > 0, 'html_*.h files were not created'); }); }); }); \ No newline at end of file diff --git a/tools/cdata.js b/tools/cdata.js index afe6d9bd0..76eb322c7 100644 --- a/tools/cdata.js +++ b/tools/cdata.js @@ -233,6 +233,7 @@ function isAnyFileInFolderNewerThan(folderPath, time) { return false; } +// Check if the web UI is already built function isAlreadyBuilt(folderPath) { let lastBuildTime = Infinity; @@ -248,6 +249,11 @@ function isAlreadyBuilt(folderPath) { return !isAnyFileInFolderNewerThan(folderPath, lastBuildTime); } +// Don't run this script if we're in a test environment +if (process.env.NODE_ENV === 'test') { + return; +} + if (isAlreadyBuilt("wled00/data") && process.argv[2] !== '--force' && process.argv[2] !== '-f') { console.info("Web UI is already built"); return;