Skip to content

Commit

Permalink
CLI: Add support for watching .ts files when TypeScript is used
Browse files Browse the repository at this point in the history
Change `run.watch()` to also apply the `--require` file, so that we
can observe any changes to `require.extensions`.

Fixes #1669.
  • Loading branch information
Krinkle committed Feb 15, 2022
1 parent c7a3cbf commit b7c127c
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 6 deletions.
24 changes: 18 additions & 6 deletions src/cli/run.js
Expand Up @@ -8,7 +8,8 @@ const requireQUnit = require( "./require-qunit" );
const utils = require( "./utils" );
const { findReporter } = require( "./find-reporter" );

const RESTART_DEBOUNCE_LENGTH = 200;
const DEBOUNCE_WATCH_LENGTH = 60;
const DEBOUNCE_RESTART_LENGTH = 200 - DEBOUNCE_WATCH_LENGTH;

const changedPendingPurge = [];

Expand Down Expand Up @@ -158,7 +159,7 @@ run.restart = function( args ) {
}

run.abort( () => run.apply( null, args ) );
}, RESTART_DEBOUNCE_LENGTH );
}, DEBOUNCE_RESTART_LENGTH );
};

run.abort = function( callback ) {
Expand All @@ -179,22 +180,33 @@ run.abort = function( callback ) {
}
};

run.watch = function watch() {
run.watch = function watch( _, options ) {
const watch = require( "node-watch" );
const args = Array.prototype.slice.call( arguments );
const baseDir = process.cwd();

// Include ".json" for test suites that use a data files,
QUnit = requireQUnit();
global.QUnit = QUnit;
options.requires.forEach( requireFromCWD );

// Include TypeScript when in use (automatically via require.extensions),
// https://github.com/qunitjs/qunit/issues/1669.
//
// Include ".json" (part of require.extensions) for test suites that use a data files,
// and for changes to package.json that may affect how a file is parsed (e.g. type=module).
const includeExts = [ ".js", ".json", ".cjs", ".mjs" ];
//
// Include ".cjs" and ".mjs", which Node.js doesn't expose via require.extensions by default.
//
// eslint-disable-next-line node/no-deprecated-api
const includeExts = Object.keys( require.extensions ).concat( [ ".cjs", ".mjs" ] );
const ignoreDirs = [ ".git", "node_modules" ];

const watcher = watch( baseDir, {
persistent: true,
recursive: true,

// Bare minimum delay, we have another debounce in run.restart().
delay: 10,
delay: DEBOUNCE_WATCH_LENGTH,
filter: ( fullpath, skip ) => {
if ( /\/node_modules\//.test( fullpath ) ||
ignoreDirs.includes( path.basename( fullpath ) )
Expand Down
36 changes: 36 additions & 0 deletions test/cli/cli-watch.js
Expand Up @@ -225,6 +225,42 @@ QUnit.module( "CLI Watch", function( hooks ) {
assert.equal( result.stdout, expectedWatchOutput[ "file-extensions" ] );
} );

// Skip in coverage mode since NYC adds non-default extensions
QUnit[ process.env.NYC_PROCESS_ID ? "skip" : "test" ]( "TypeScript file extension", async assert => {
fixturify.writeSync( fixturePath, {
"register.js": "require.extensions['.ts'] = function() {};",
"tests": {
"setup.js": "QUnit.on('runEnd', function() { process.send('runEnd'); });",
"foo.js": "QUnit.test('foo', function(assert) { assert.true(true); });"
}
} );

const command = [ "qunit", "--watch", "--require", "./watching/register", "watching/tests" ];
const result = await executeIpc(
command,
execution => {
execution.once( "message", () => {
fixturify.writeSync( fixturePath, {
"x.js": "-",
"x.ts": "-",
"tests": {
"foo.js": "QUnit.test('foo2', function(assert) { assert.true(true); });",
"setup.js": "QUnit.on('runEnd', function() { process.send('runEnd2'); });"
}
} );

execution.once( "message", () => {
kill( execution );
} );
} );
}
);

assert.equal( result.code, 0 );
assert.equal( result.stderr, "" );
assert.equal( result.stdout, expectedWatchOutput[ "file-extension-ts" ] );
} );

QUnit.test( "aborts and restarts when in middle of run", async assert => {

// A proper abort finishes the currently running test and runs any remaining
Expand Down
21 changes: 21 additions & 0 deletions test/cli/fixtures/expected/watch-tap-outputs.js
Expand Up @@ -85,6 +85,27 @@ ok 1 foo2
# skip 0
# todo 0
# fail 0
Stopping QUnit...`,

"file-extension-ts": `TAP version 13
ok 1 foo
1..1
# pass 1
# skip 0
# todo 0
# fail 0
File update: watching/x.js
File update: watching/x.ts
File update: watching/tests/foo.js
File update: watching/tests/setup.js
Restarting...
TAP version 13
ok 1 foo2
1..1
# pass 1
# skip 0
# todo 0
# fail 0
Stopping QUnit...`,

"change-file-mid-run": `TAP version 13
Expand Down

0 comments on commit b7c127c

Please sign in to comment.