Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions frontend/src/test/run-tests-plan.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,21 @@ describe('frontend test runner planning', () => {
expect(usesMockModule(plain)).toBe(false);
});

it('ignores mock.module text inside comments and string literals', () => {
tempDir = mkdtempSync(path.join(tmpdir(), 'sentris-test-plan-'));
const file = path.join(tempDir, 'fixture.test.ts');

writeFileSync(
file,
[
'const fixture = "mock.module(\'@/store\', () => ({}));";',
"// mock.module('@/commented', () => ({}));",
].join('\n'),
);

expect(usesMockModule(file)).toBe(false);
});

it('batches adjacent non-mocked files while isolating mock.module files', () => {
const files = [
'src/a.test.ts',
Expand Down
45 changes: 43 additions & 2 deletions frontend/src/test/run-tests-plan.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { readFileSync, readdirSync } from 'node:fs';
import path from 'node:path';
import * as ts from 'typescript';

const TEST_FILE_PATTERN = /\.(test|spec)\.[jt]sx?$/;
const MOCK_MODULE_PATTERN = /\bmock\.module\s*\(/;

export interface FrontendTestRun {
label: string;
Expand Down Expand Up @@ -36,8 +36,49 @@ export function toPosixRelative(filePath: string, cwd = process.cwd()): string {
return path.relative(cwd, filePath).split(path.sep).join(path.posix.sep);
}

function getScriptKind(filePath: string): ts.ScriptKind {
switch (path.extname(filePath).toLowerCase()) {
case '.tsx':
return ts.ScriptKind.TSX;
case '.jsx':
return ts.ScriptKind.JSX;
case '.js':
return ts.ScriptKind.JS;
default:
return ts.ScriptKind.TS;
}
}

export function usesMockModule(filePath: string): boolean {
return MOCK_MODULE_PATTERN.test(readFileSync(filePath, 'utf8'));
const sourceFile = ts.createSourceFile(
filePath,
readFileSync(filePath, 'utf8'),
ts.ScriptTarget.Latest,
false,
getScriptKind(filePath),
);

let found = false;

const visit = (node: ts.Node): void => {
if (found) return;

if (
ts.isCallExpression(node) &&
ts.isPropertyAccessExpression(node.expression) &&
ts.isIdentifier(node.expression.expression) &&
node.expression.expression.text === 'mock' &&
node.expression.name.text === 'module'
) {
found = true;
return;
}

ts.forEachChild(node, visit);
};

visit(sourceFile);
return found;
}

export function planFrontendTestRuns(
Expand Down
Loading