@@ -24,10 +24,9 @@ const baselineAccept = require("./scripts/build/baselineAccept");
24
24
const cmdLineOptions = require ( "./scripts/build/options" ) ;
25
25
const exec = require ( "./scripts/build/exec" ) ;
26
26
const browserify = require ( "./scripts/build/browserify" ) ;
27
- const debounce = require ( "./scripts/build/debounce" ) ;
28
27
const prepend = require ( "./scripts/build/prepend" ) ;
29
28
const { removeSourceMaps } = require ( "./scripts/build/sourcemaps" ) ;
30
- const { CancelSource , CancelError } = require ( "./scripts/build/cancellation " ) ;
29
+ const { CancellationTokenSource , CancelError, delay , Semaphore } = require ( "prex " ) ;
31
30
const { libraryTargets, generateLibs } = require ( "./scripts/build/lib" ) ;
32
31
const { runConsoleTests, cleanTestDirs, writeTestConfigFile, refBaseline, localBaseline, refRwcBaseline, localRwcBaseline } = require ( "./scripts/build/tests" ) ;
33
32
@@ -534,57 +533,80 @@ gulp.task(
534
533
[ "watch-diagnostics" , "watch-lib" ] . concat ( useCompilerDeps ) ,
535
534
( ) => project . watch ( tsserverProject , { typescript : useCompiler } ) ) ;
536
535
537
- gulp . task (
538
- "watch-local" ,
539
- /*help*/ false ,
540
- [ "watch-lib" , "watch-tsc" , "watch-services" , "watch-server" ] ) ;
541
-
542
536
gulp . task (
543
537
"watch-runner" ,
544
538
/*help*/ false ,
545
539
useCompilerDeps ,
546
540
( ) => project . watch ( testRunnerProject , { typescript : useCompiler } ) ) ;
547
541
548
- const watchPatterns = [
549
- runJs ,
550
- typescriptDts ,
551
- tsserverlibraryDts
552
- ] ;
542
+ gulp . task (
543
+ "watch-local" ,
544
+ "Watches for changes to projects in src/ (but does not execute tests)." ,
545
+ [ "watch-lib" , "watch-tsc" , "watch-services" , "watch-server" , "watch-runner" , "watch-lssl" ] ) ;
553
546
554
547
gulp . task (
555
548
"watch" ,
556
- "Watches for changes to the build inputs for built/local/run.js, then executes runtests-parallel ." ,
549
+ "Watches for changes to the build inputs for built/local/run.js, then runs tests ." ,
557
550
[ "build-rules" , "watch-runner" , "watch-services" , "watch-lssl" ] ,
558
551
( ) => {
559
- /** @type {CancelSource | undefined } */
560
- let runTestsSource ;
552
+ const sem = new Semaphore ( 1 ) ;
561
553
562
- const fn = debounce ( ( ) => {
563
- runTests ( ) . catch ( error => {
564
- if ( error instanceof CancelError ) {
565
- log . warn ( "Operation was canceled" ) ;
566
- }
567
- else {
568
- log . error ( error ) ;
569
- }
570
- } ) ;
571
- } , /*timeout*/ 100 , { max : 500 } ) ;
572
-
573
- gulp . watch ( watchPatterns , ( ) => project . wait ( ) . then ( fn ) ) ;
554
+ gulp . watch ( [ runJs , typescriptDts , tsserverlibraryDts ] , ( ) => {
555
+ runTests ( ) ;
556
+ } ) ;
574
557
575
558
// NOTE: gulp.watch is far too slow when watching tests/cases/**/* as it first enumerates *every* file
576
559
const testFilePattern = / ( \. t s | [ \\ / ] t s c o n f i g \. j s o n ) $ / ;
577
560
fs . watch ( "tests/cases" , { recursive : true } , ( _ , file ) => {
578
- if ( testFilePattern . test ( file ) ) project . wait ( ) . then ( fn ) ;
561
+ if ( testFilePattern . test ( file ) ) runTests ( ) ;
579
562
} ) ;
580
563
581
- function runTests ( ) {
582
- if ( runTestsSource ) runTestsSource . cancel ( ) ;
583
- runTestsSource = new CancelSource ( ) ;
584
- return cmdLineOptions . tests || cmdLineOptions . failed
585
- ? runConsoleTests ( runJs , "mocha-fivemat-progress-reporter" , /*runInParallel*/ false , /*watchMode*/ true , runTestsSource . token )
586
- : runConsoleTests ( runJs , "min" , /*runInParallel*/ true , /*watchMode*/ true , runTestsSource . token ) ;
587
- }
564
+ async function runTests ( ) {
565
+ try {
566
+ // Ensure only one instance of the test runner is running at any given time.
567
+ if ( sem . count > 0 ) {
568
+ await sem . wait ( ) ;
569
+ try {
570
+ // Wait for any concurrent recompilations to complete...
571
+ try {
572
+ await delay ( 100 ) ;
573
+ while ( project . hasRemainingWork ( ) ) {
574
+ await project . waitForWorkToComplete ( ) ;
575
+ await delay ( 500 ) ;
576
+ }
577
+ }
578
+ catch ( e ) {
579
+ if ( e instanceof CancelError ) return ;
580
+ throw e ;
581
+ }
582
+
583
+ // cancel any pending or active test run if a new recompilation is triggered
584
+ const source = new CancellationTokenSource ( ) ;
585
+ project . waitForWorkToStart ( ) . then ( ( ) => {
586
+ source . cancel ( ) ;
587
+ } ) ;
588
+
589
+ if ( cmdLineOptions . tests || cmdLineOptions . failed ) {
590
+ await runConsoleTests ( runJs , "mocha-fivemat-progress-reporter" , /*runInParallel*/ false , /*watchMode*/ true , source . token ) ;
591
+ }
592
+ else {
593
+ await runConsoleTests ( runJs , "min" , /*runInParallel*/ true , /*watchMode*/ true , source . token ) ;
594
+ }
595
+ }
596
+ finally {
597
+ sem . release ( ) ;
598
+ }
599
+ }
600
+ }
601
+ catch ( e ) {
602
+ if ( e instanceof CancelError ) {
603
+ log . warn ( "Operation was canceled" ) ;
604
+ }
605
+ else {
606
+ log . error ( e ) ;
607
+ }
608
+ }
609
+ } ;
588
610
} ) ;
589
611
590
612
gulp . task ( "clean-built" , /*help*/ false , [ `clean:${ diagnosticInformationMapTs } ` ] , ( ) => del ( [ "built" ] ) ) ;
0 commit comments