remove the watch mode concept, combine both watchers
This commit is contained in:
parent
c7b8a7b766
commit
52b0811c55
|
|
@ -61,7 +61,7 @@ export async function runDevServer(config: FullConfigInternal): Promise<() => Pr
|
|||
projectOutputs.add(p.project.outputDir);
|
||||
}
|
||||
|
||||
const globalWatcher = new Watcher('deep', async () => {
|
||||
const globalWatcher = new Watcher(async () => {
|
||||
const registry: ComponentRegistry = new Map();
|
||||
await populateComponentsFromTests(registry);
|
||||
// compare componentRegistry to registry key sets.
|
||||
|
|
|
|||
|
|
@ -21,26 +21,24 @@ export type FSEvent = { event: 'add' | 'addDir' | 'change' | 'unlink' | 'unlinkD
|
|||
|
||||
export class Watcher {
|
||||
private _onChange: (events: FSEvent[]) => void;
|
||||
private _watchedFiles: string[] = [];
|
||||
private _watchedPaths: string[] = [];
|
||||
private _ignoredFolders: string[] = [];
|
||||
private _collector: FSEvent[] = [];
|
||||
private _fsWatcher: FSWatcher | undefined;
|
||||
private _throttleTimer: NodeJS.Timeout | undefined;
|
||||
private _mode: 'flat' | 'deep';
|
||||
|
||||
constructor(mode: 'flat' | 'deep', onChange: (events: FSEvent[]) => void) {
|
||||
this._mode = mode;
|
||||
constructor(onChange: (events: FSEvent[]) => void) {
|
||||
this._onChange = onChange;
|
||||
}
|
||||
|
||||
update(watchedFiles: string[], ignoredFolders: string[], reportPending: boolean) {
|
||||
if (JSON.stringify([this._watchedFiles, this._ignoredFolders]) === JSON.stringify(watchedFiles, ignoredFolders))
|
||||
update(watchedPaths: string[], ignoredFolders: string[], reportPending: boolean) {
|
||||
if (JSON.stringify([this._watchedPaths, this._ignoredFolders]) === JSON.stringify(watchedPaths, ignoredFolders))
|
||||
return;
|
||||
|
||||
if (reportPending)
|
||||
this._reportEventsIfAny();
|
||||
|
||||
this._watchedFiles = watchedFiles;
|
||||
this._watchedPaths = watchedPaths;
|
||||
this._ignoredFolders = ignoredFolders;
|
||||
void this._fsWatcher?.close();
|
||||
this._fsWatcher = undefined;
|
||||
|
|
@ -48,17 +46,13 @@ export class Watcher {
|
|||
clearTimeout(this._throttleTimer);
|
||||
this._throttleTimer = undefined;
|
||||
|
||||
if (!this._watchedFiles.length)
|
||||
if (!this._watchedPaths.length)
|
||||
return;
|
||||
|
||||
const ignored = [...this._ignoredFolders, '**/node_modules/**'];
|
||||
this._fsWatcher = chokidar.watch(watchedFiles, { ignoreInitial: true, ignored }).on('all', async (event, file) => {
|
||||
this._fsWatcher = chokidar.watch(watchedPaths, { ignoreInitial: true, ignored }).on('all', async (event, file) => {
|
||||
if (this._throttleTimer)
|
||||
clearTimeout(this._throttleTimer);
|
||||
if (this._mode === 'flat' && event !== 'add' && event !== 'change')
|
||||
return;
|
||||
if (this._mode === 'deep' && event !== 'add' && event !== 'change' && event !== 'unlink' && event !== 'addDir' && event !== 'unlinkDir')
|
||||
return;
|
||||
this._collector.push({ event, file });
|
||||
this._throttleTimer = setTimeout(() => this._reportEventsIfAny(), 250);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ import { TestRun, createTaskRunnerForList, createTaskRunnerForTestServer, create
|
|||
import { open } from 'playwright-core/lib/utilsBundle';
|
||||
import ListReporter from '../reporters/list';
|
||||
import { SigIntWatcher } from './sigIntWatcher';
|
||||
import { type FSEvent, Watcher } from '../fsWatcher';
|
||||
import { Watcher } from '../fsWatcher';
|
||||
import type { ReportEntry, TestServerInterface, TestServerInterfaceEventEmitters } from '../isomorphic/testServerInterface';
|
||||
import { Runner } from './runner';
|
||||
import type { ConfigCLIOverrides } from '../common/ipc';
|
||||
|
|
@ -64,8 +64,12 @@ class TestServer {
|
|||
|
||||
class TestServerDispatcher implements TestServerInterface {
|
||||
private _configLocation: ConfigLocation;
|
||||
private _globalWatcher: Watcher;
|
||||
private _testWatcher: Watcher;
|
||||
|
||||
private _watcher: Watcher;
|
||||
private _watchedProjectDirs = new Set<string>();
|
||||
private _ignoredProjectOutputs = new Set<string>();
|
||||
private _watchedTestDependencies = new Set<string>();
|
||||
|
||||
private _testRun: { run: Promise<reporterTypes.FullResult['status']>, stop: ManualPromise<void> } | undefined;
|
||||
readonly transport: Transport;
|
||||
private _queue = Promise.resolve();
|
||||
|
|
@ -86,17 +90,14 @@ class TestServerDispatcher implements TestServerInterface {
|
|||
gracefullyProcessExitDoNotHang(0);
|
||||
},
|
||||
};
|
||||
this._globalWatcher = new Watcher('deep', events => this._checkForChangedTestFiles(events));
|
||||
this._testWatcher = new Watcher('flat', events => this._checkForChangedTestFiles(events));
|
||||
this._watcher = new Watcher(events => {
|
||||
const collector = new Set<string>();
|
||||
events.forEach(f => collectAffectedTestFiles(f.file, collector));
|
||||
this._dispatchEvent('testFilesChanged', { testFiles: [...collector] });
|
||||
});
|
||||
this._dispatchEvent = (method, params) => this.transport.sendEvent?.(method, params);
|
||||
}
|
||||
|
||||
private _checkForChangedTestFiles(events: FSEvent[]) {
|
||||
const collector = new Set<string>();
|
||||
events.forEach(f => collectAffectedTestFiles(f.file, collector));
|
||||
this._dispatchEvent('testFilesChanged', { testFiles: [...collector] });
|
||||
}
|
||||
|
||||
private async _wireReporter(messageSink: (message: any) => void) {
|
||||
return await createReporterForTestServer(this._serializer, messageSink);
|
||||
}
|
||||
|
|
@ -281,24 +282,28 @@ class TestServerDispatcher implements TestServerInterface {
|
|||
await taskRunner.reporter.onEnd({ status });
|
||||
await taskRunner.reporter.onExit();
|
||||
|
||||
const projectDirs = new Set<string>();
|
||||
const projectOutputs = new Set<string>();
|
||||
this._watchedProjectDirs = new Set();
|
||||
this._ignoredProjectOutputs = new Set();
|
||||
for (const p of config.projects) {
|
||||
projectDirs.add(p.project.testDir);
|
||||
projectOutputs.add(p.project.outputDir);
|
||||
this._watchedProjectDirs.add(p.project.testDir);
|
||||
this._ignoredProjectOutputs.add(p.project.outputDir);
|
||||
}
|
||||
|
||||
const result = await resolveCtDirs(config);
|
||||
if (result) {
|
||||
projectDirs.add(result.templateDir);
|
||||
projectOutputs.add(result.outDir);
|
||||
this._watchedProjectDirs.add(result.templateDir);
|
||||
this._ignoredProjectOutputs.add(result.outDir);
|
||||
}
|
||||
|
||||
if (this._watchTestDirs)
|
||||
this._globalWatcher.update([...projectDirs], [...projectOutputs], false);
|
||||
this.updateWatcher(false);
|
||||
return { report, status };
|
||||
}
|
||||
|
||||
private updateWatcher(reportPending: boolean) {
|
||||
this._watcher.update([...this._watchedProjectDirs, ...this._watchedTestDependencies], [...this._ignoredProjectOutputs], reportPending);
|
||||
}
|
||||
|
||||
async runTests(params: Parameters<TestServerInterface['runTests']>[0]): ReturnType<TestServerInterface['runTests']> {
|
||||
let result: Awaited<ReturnType<TestServerInterface['runTests']>> = { status: 'passed' };
|
||||
this._queue = this._queue.then(async () => {
|
||||
|
|
@ -366,12 +371,12 @@ class TestServerDispatcher implements TestServerInterface {
|
|||
}
|
||||
|
||||
async watch(params: { fileNames: string[]; }) {
|
||||
const files = new Set<string>();
|
||||
this._watchedTestDependencies = new Set();
|
||||
for (const fileName of params.fileNames) {
|
||||
files.add(fileName);
|
||||
dependenciesForTestFile(fileName).forEach(file => files.add(file));
|
||||
this._watchedTestDependencies.add(fileName);
|
||||
dependenciesForTestFile(fileName).forEach(file => this._watchedTestDependencies.add(file));
|
||||
}
|
||||
this._testWatcher.update([...files], [], true);
|
||||
this.updateWatcher(true);
|
||||
}
|
||||
|
||||
async findRelatedTestFiles(params: Parameters<TestServerInterface['findRelatedTestFiles']>[0]): ReturnType<TestServerInterface['findRelatedTestFiles']> {
|
||||
|
|
|
|||
Loading…
Reference in a new issue