Upgrade Ava to v4

This commit is contained in:
Henry Mercer 2022-02-01 18:01:11 +00:00
parent 9a40cc5274
commit ce89f1b611
1153 changed files with 27264 additions and 95308 deletions

111
node_modules/ava/lib/watcher.js generated vendored
View file

@ -1,18 +1,26 @@
'use strict';
const nodePath = require('path');
const debug = require('debug')('ava:watcher');
const chokidar = require('chokidar');
const diff = require('lodash/difference');
const flatten = require('lodash/flatten');
const chalk = require('./chalk').get();
const {applyTestFileFilter, classify, getChokidarIgnorePatterns} = require('./globs');
const {levels: providerLevels} = require('./provider-manager');
import nodePath from 'node:path';
function rethrowAsync(err) {
import chokidar_ from 'chokidar';
import createDebug from 'debug';
import {chalk} from './chalk.js';
import {applyTestFileFilter, classify, getChokidarIgnorePatterns} from './globs.js';
let chokidar = chokidar_;
export function _testOnlyReplaceChokidar(replacement) {
chokidar = replacement;
}
let debug = createDebug('ava:watcher');
export function _testOnlyReplaceDebug(replacement) {
debug = replacement('ava:watcher');
}
function rethrowAsync(error) {
// Don't swallow exceptions. Note that any
// expected error should already have been logged
setImmediate(() => {
throw err;
throw error;
});
}
@ -77,7 +85,7 @@ class TestDependency {
}
}
class Watcher {
export default class Watcher {
constructor({api, filter = [], globs, projectDir, providers, reporter}) {
this.debouncer = new Debouncer(this);
@ -88,7 +96,7 @@ class Watcher {
const patternFilters = filter.map(({pattern}) => pattern);
this.providers = providers.filter(({level}) => level >= providerLevels.pathRewrites);
this.providers = providers;
this.run = (specificFiles = [], updateSnapshots = false) => {
const clearLogOnNextRun = this.clearLogOnNextRun && this.runVector > 0;
if (this.runVector > 0) {
@ -104,12 +112,18 @@ class Watcher {
if (runOnlyExclusive) {
// The test files that previously contained exclusive tests are always
// run, together with the remaining specific files.
const remainingFiles = diff(specificFiles, exclusiveFiles);
specificFiles = this.filesWithExclusiveTests.concat(remainingFiles);
const remainingFiles = specificFiles.filter(file => !exclusiveFiles.includes(file));
specificFiles = [...this.filesWithExclusiveTests, ...remainingFiles];
}
if (filter.length > 0) {
specificFiles = applyTestFileFilter({cwd: projectDir, filter: patternFilters, testFiles: specificFiles});
specificFiles = applyTestFileFilter({
cwd: projectDir,
expandDirectories: false,
filter: patternFilters,
testFiles: specificFiles,
treatFilterPatternsAsFiles: false,
});
}
this.pruneFailures(specificFiles);
@ -125,21 +139,21 @@ class Watcher {
previousFailures: this.sumPreviousFailures(this.runVector),
runOnlyExclusive,
runVector: this.runVector,
updateSnapshots: updateSnapshots === true
}
updateSnapshots: updateSnapshots === true,
},
})
.then(runStatus => { // eslint-disable-line promise/prefer-await-to-then
.then(runStatus => {
reporter.endRun();
reporter.lineWriter.writeLine(END_MESSAGE);
if (this.clearLogOnNextRun && (
runStatus.stats.failedHooks > 0 ||
runStatus.stats.failedTests > 0 ||
runStatus.stats.failedWorkers > 0 ||
runStatus.stats.internalErrors > 0 ||
runStatus.stats.timeouts > 0 ||
runStatus.stats.uncaughtExceptions > 0 ||
runStatus.stats.unhandledRejections > 0
runStatus.stats.failedHooks > 0
|| runStatus.stats.failedTests > 0
|| runStatus.stats.failedWorkers > 0
|| runStatus.stats.internalErrors > 0
|| runStatus.stats.timeouts > 0
|| runStatus.stats.uncaughtExceptions > 0
|| runStatus.stats.unhandledRejections > 0
)) {
this.clearLogOnNextRun = false;
}
@ -150,6 +164,7 @@ class Watcher {
this.testDependencies = [];
this.trackTestDependencies(api);
this.temporaryFiles = new Set();
this.touchedFiles = new Set();
this.trackTouchedFiles(api);
@ -168,7 +183,7 @@ class Watcher {
chokidar.watch(['**/*'], {
cwd: this.globs.cwd,
ignored: getChokidarIgnorePatterns(this.globs),
ignoreInitial: true
ignoreInitial: true,
}).on('all', (event, path) => {
if (event === 'add' || event === 'change' || event === 'unlink') {
debug('Detected %s of %s', event, path);
@ -231,9 +246,13 @@ class Watcher {
return;
}
for (const file of evt.files) {
for (const file of evt.files.changedFiles) {
this.touchedFiles.add(file);
}
for (const file of evt.files.temporaryFiles) {
this.temporaryFiles.add(file);
}
});
});
}
@ -307,7 +326,7 @@ class Watcher {
this.filesWithFailures.push({
file,
vector,
count: 1
count: 1,
});
}
}
@ -379,6 +398,14 @@ class Watcher {
return false;
}
// Unlike touched files, temporary files are never cleared. We may see
// adds and unlinks detected separately, so we track the temporary files
// as long as AVA is running.
if (this.temporaryFiles.has(path)) {
debug('Ignoring known temporary file %s', path);
return false;
}
return true;
});
@ -394,21 +421,23 @@ class Watcher {
}
const dirtyHelpersAndSources = [];
const dirtyTests = [];
const addedOrChangedTests = [];
const unlinkedTests = [];
for (const filePath of dirtyPaths) {
const {isIgnoredByWatcher, isTest} = classify(filePath, this.globs);
if (!isIgnoredByWatcher) {
if (isTest) {
dirtyTests.push(filePath);
if (dirtyStates[filePath] === 'unlink') {
unlinkedTests.push(filePath);
} else {
addedOrChangedTests.push(filePath);
}
} else {
dirtyHelpersAndSources.push(filePath);
}
}
}
const addedOrChangedTests = dirtyTests.filter(path => dirtyStates[path] !== 'unlink');
const unlinkedTests = diff(dirtyTests, addedOrChangedTests);
this.cleanUnlinkedTests(unlinkedTests);
// No need to rerun tests if the only change is that tests were deleted
@ -423,12 +452,10 @@ class Watcher {
}
// Try to find tests that depend on the changed source files
const testsByHelpersOrSource = dirtyHelpersAndSources.map(path => {
return this.testDependencies.filter(dep => dep.contains(path)).map(dep => {
debug('%s is a dependency of %s', path, dep.file);
return dep.file;
});
}, this).filter(tests => tests.length > 0);
const testsByHelpersOrSource = dirtyHelpersAndSources.map(path => this.testDependencies.filter(dep => dep.contains(path)).map(dep => {
debug('%s is a dependency of %s', path, dep.file);
return dep.file;
})).filter(tests => tests.length > 0);
// Rerun all tests if source files were changed that could not be traced to
// specific tests
@ -440,8 +467,6 @@ class Watcher {
}
// Run all affected tests
this.run([...new Set(addedOrChangedTests.concat(flatten(testsByHelpersOrSource)))]);
this.run([...new Set([addedOrChangedTests, testsByHelpersOrSource].flat(2))]);
}
}
module.exports = Watcher;