Skip to content

Commit 7f292de

Browse files
committed
[compiler] Improve snap, no more testfilter.txt file
1 parent 28f77b4 commit 7f292de

4 files changed

Lines changed: 113 additions & 111 deletions

File tree

compiler/packages/snap/src/constants.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,5 +26,3 @@ export const FIXTURES_PATH = path.join(
2626
'compiler',
2727
);
2828
export const SNAPSHOT_EXTENSION = '.expect.md';
29-
export const FILTER_FILENAME = 'testfilter.txt';
30-
export const FILTER_PATH = path.join(PROJECT_ROOT, FILTER_FILENAME);

compiler/packages/snap/src/fixture-utils.ts

Lines changed: 1 addition & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
import fs from 'fs/promises';
99
import * as glob from 'glob';
1010
import path from 'path';
11-
import {FILTER_PATH, FIXTURES_PATH, SNAPSHOT_EXTENSION} from './constants';
11+
import {FIXTURES_PATH, SNAPSHOT_EXTENSION} from './constants';
1212

1313
const INPUT_EXTENSIONS = [
1414
'.js',
@@ -22,19 +22,9 @@ const INPUT_EXTENSIONS = [
2222
];
2323

2424
export type TestFilter = {
25-
debug: boolean;
2625
paths: Array<string>;
2726
};
2827

29-
async function exists(file: string): Promise<boolean> {
30-
try {
31-
await fs.access(file);
32-
return true;
33-
} catch {
34-
return false;
35-
}
36-
}
37-
3828
function stripExtension(filename: string, extensions: Array<string>): string {
3929
for (const ext of extensions) {
4030
if (filename.endsWith(ext)) {
@@ -44,37 +34,6 @@ function stripExtension(filename: string, extensions: Array<string>): string {
4434
return filename;
4535
}
4636

47-
export async function readTestFilter(): Promise<TestFilter | null> {
48-
if (!(await exists(FILTER_PATH))) {
49-
throw new Error(`testfilter file not found at \`${FILTER_PATH}\``);
50-
}
51-
52-
const input = await fs.readFile(FILTER_PATH, 'utf8');
53-
const lines = input.trim().split('\n');
54-
55-
let debug: boolean = false;
56-
const line0 = lines[0];
57-
if (line0 != null) {
58-
// Try to parse pragmas
59-
let consumedLine0 = false;
60-
if (line0.indexOf('@only') !== -1) {
61-
consumedLine0 = true;
62-
}
63-
if (line0.indexOf('@debug') !== -1) {
64-
debug = true;
65-
consumedLine0 = true;
66-
}
67-
68-
if (consumedLine0) {
69-
lines.shift();
70-
}
71-
}
72-
return {
73-
debug,
74-
paths: lines.filter(line => !line.trimStart().startsWith('//')),
75-
};
76-
}
77-
7837
export function getBasename(fixture: TestFixture): string {
7938
return stripExtension(path.basename(fixture.inputPath), INPUT_EXTENSIONS);
8039
}

compiler/packages/snap/src/runner-watch.ts

Lines changed: 78 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@
88
import watcher from '@parcel/watcher';
99
import path from 'path';
1010
import ts from 'typescript';
11-
import {FILTER_FILENAME, FIXTURES_PATH, PROJECT_ROOT} from './constants';
12-
import {TestFilter, readTestFilter} from './fixture-utils';
11+
import {FIXTURES_PATH, PROJECT_ROOT} from './constants';
12+
import {TestFilter} from './fixture-utils';
1313
import {execSync} from 'child_process';
1414

1515
export function watchSrc(
@@ -117,6 +117,10 @@ export type RunnerState = {
117117
lastUpdate: number;
118118
mode: RunnerMode;
119119
filter: TestFilter | null;
120+
debug: boolean;
121+
// Input mode for interactive pattern entry
122+
inputMode: 'none' | 'pattern';
123+
inputBuffer: string;
120124
};
121125

122126
function subscribeFixtures(
@@ -142,26 +146,6 @@ function subscribeFixtures(
142146
});
143147
}
144148

145-
function subscribeFilterFile(
146-
state: RunnerState,
147-
onChange: (state: RunnerState) => void,
148-
) {
149-
watcher.subscribe(PROJECT_ROOT, async (err, events) => {
150-
if (err) {
151-
console.error(err);
152-
process.exit(1);
153-
} else if (
154-
events.findIndex(event => event.path.includes(FILTER_FILENAME)) !== -1
155-
) {
156-
if (state.mode.filter) {
157-
state.filter = await readTestFilter();
158-
state.mode.action = RunnerAction.Test;
159-
onChange(state);
160-
}
161-
}
162-
});
163-
}
164-
165149
function subscribeTsc(
166150
state: RunnerState,
167151
onChange: (state: RunnerState) => void,
@@ -200,15 +184,67 @@ function subscribeKeyEvents(
200184
onChange: (state: RunnerState) => void,
201185
) {
202186
process.stdin.on('keypress', async (str, key) => {
187+
// Handle input mode (pattern entry)
188+
if (state.inputMode !== 'none') {
189+
if (key.name === 'return') {
190+
// Enter pressed - process input
191+
const pattern = state.inputBuffer.trim();
192+
state.inputMode = 'none';
193+
state.inputBuffer = '';
194+
process.stdout.write('\n');
195+
196+
if (pattern !== '') {
197+
// Set the pattern as filter
198+
state.filter = {paths: [pattern]};
199+
state.mode.filter = true;
200+
state.mode.action = RunnerAction.Test;
201+
onChange(state);
202+
}
203+
// If empty, just exit input mode without changes
204+
return;
205+
} else if (key.name === 'escape') {
206+
// Cancel input mode
207+
state.inputMode = 'none';
208+
state.inputBuffer = '';
209+
process.stdout.write(' (cancelled)\n');
210+
return;
211+
} else if (key.name === 'backspace') {
212+
if (state.inputBuffer.length > 0) {
213+
state.inputBuffer = state.inputBuffer.slice(0, -1);
214+
// Erase character: backspace, space, backspace
215+
process.stdout.write('\b \b');
216+
}
217+
return;
218+
} else if (str && !key.ctrl && !key.meta) {
219+
// Regular character - accumulate and echo
220+
state.inputBuffer += str;
221+
process.stdout.write(str);
222+
return;
223+
}
224+
return; // Ignore other keys in input mode
225+
}
226+
227+
// Normal mode keypress handling
203228
if (key.name === 'u') {
204229
// u => update fixtures
205230
state.mode.action = RunnerAction.Update;
206231
} else if (key.name === 'q') {
207232
process.exit(0);
208-
} else if (key.name === 'f') {
209-
state.mode.filter = !state.mode.filter;
210-
state.filter = state.mode.filter ? await readTestFilter() : null;
233+
} else if (key.name === 'a') {
234+
// a => exit filter mode and run all tests
235+
state.mode.filter = false;
236+
state.filter = null;
237+
state.mode.action = RunnerAction.Test;
238+
} else if (key.name === 'd') {
239+
// d => toggle debug logging
240+
state.debug = !state.debug;
211241
state.mode.action = RunnerAction.Test;
242+
} else if (key.name === 'p') {
243+
// p => enter pattern input mode
244+
state.inputMode = 'pattern';
245+
state.inputBuffer = '';
246+
process.stdout.write('Pattern: ');
247+
return; // Don't trigger onChange yet
212248
} else {
213249
// any other key re-runs tests
214250
state.mode.action = RunnerAction.Test;
@@ -219,21 +255,33 @@ function subscribeKeyEvents(
219255

220256
export async function makeWatchRunner(
221257
onChange: (state: RunnerState) => void,
222-
filterMode: boolean,
258+
debugMode: boolean,
259+
initialPattern?: string,
223260
): Promise<void> {
224-
const state = {
261+
// Determine initial filter state
262+
let filter: TestFilter | null = null;
263+
let filterEnabled = false;
264+
265+
if (initialPattern) {
266+
filter = {paths: [initialPattern]};
267+
filterEnabled = true;
268+
}
269+
270+
const state: RunnerState = {
225271
compilerVersion: 0,
226272
isCompilerBuildValid: false,
227273
lastUpdate: -1,
228274
mode: {
229275
action: RunnerAction.Test,
230-
filter: filterMode,
276+
filter: filterEnabled,
231277
},
232-
filter: filterMode ? await readTestFilter() : null,
278+
filter,
279+
debug: debugMode,
280+
inputMode: 'none',
281+
inputBuffer: '',
233282
};
234283

235284
subscribeTsc(state, onChange);
236285
subscribeFixtures(state, onChange);
237286
subscribeKeyEvents(state, onChange);
238-
subscribeFilterFile(state, onChange);
239287
}

0 commit comments

Comments
 (0)