test runner | test cells | | Search

This code sets up a file watcher that automatically re-runs JavaScript tests whenever changes are detected in specified files, allowing for continuous testing during development.

Run example

npm run import -- "test runner"

test runner

var chokidar = require("chokidar");
var importer = require('../Core');
var testCells = importer.import("test cells");

// TODO: code analysis to combine blocks into modules?

var rateLimiter, done = true;
function testWatcher(files, tests) {
    files = typeof files === 'string' ? [files] : files;
    console.log('watching ' + files + ' - ' + path.resolve('.'))
    var watcher = chokidar.watch(files, {
        interval: 1000,
        atomic: 1000,
        awaitWriteFinish: true
    });
    watcher.on("change", function(event, path) {
        if(!done) {
            return;
        }
        console.log('running all tests');
        done = false;
        return testCells(tests).then(() => (done = true))
    });
    testCells(tests);
    
    var stdin = process.openStdin();
    stdin.addListener("data", function(d) {
        stdin.close();
    });
}
module.exports = testWatcher;

What the code could have been:

const chokidar = require('chokidar');
const path = require('path');
const importer = require('../Core');
const { testCells } = importer;

const rateLimiter = null; // initialized but not used
let done = true;

/**
 * Watches for file changes and runs tests accordingly.
 * @param {Array|string} files - files or a single file to watch
 * @param {Array} tests - tests to run
 */
async function testWatcher(files, tests) {
    files = Array.isArray(files)? files : [files];
    console.log(`Watching ${files.join(', ')} - ${path.resolve('.')}`);

    const watcher = chokidar.watch(files, {
        interval: 1000,
        atomic: true, // deprecated, use awaitWriteFinish instead
        awaitWriteFinish: true
    });

    watcher.on('change', async (event, path) => {
        if (!done) {
            return;
        }
        console.log('Running all tests');
        done = false;
        try {
            await testCells(tests);
        } catch (error) {
            console.error('Error running tests:', error);
        } finally {
            done = true;
        }
    });

    try {
        await testCells(tests);
    } catch (error) {
        console.error('Error running tests:', error);
    }
}

// Use a stream to close the stdin stream
const readline = require('readline');
const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout
});

rl.on('line', () => {
    rl.close();
});

module.exports = testWatcher;

This code sets up a file watcher that automatically re-runs tests whenever changes are detected in specified files.

Here's a breakdown:

  1. Dependencies:

  2. Initialization:

  3. File Watching:

  4. Change Handling:

  5. Manual Trigger:

In essence, this code provides a way to continuously monitor files for changes and automatically re-run tests whenever modifications are detected.