Skip to content

Commit b7ab615

Browse files
committed
AG-50993 ensure all qunit test files are running
Squashed commit of the following: commit 4833bb4 Author: slvvko <v.leleka@adguard.com> Date: Fri Feb 13 11:33:50 2026 -0500 fix imports commit e5ad661 Author: slvvko <v.leleka@adguard.com> Date: Fri Feb 13 11:31:43 2026 -0500 fix file and command name commit e85da13 Author: slvvko <v.leleka@adguard.com> Date: Fri Feb 13 11:30:11 2026 -0500 add auto fix flag for test lists checker commit a25b42a Author: slvvko <v.leleka@adguard.com> Date: Fri Feb 13 11:21:37 2026 -0500 fix logging commit f2f6cfc Author: slvvko <v.leleka@adguard.com> Date: Fri Feb 13 11:19:16 2026 -0500 script to verify all qunit test files are imported
1 parent 1b2011d commit b7ab615

4 files changed

Lines changed: 153 additions & 1 deletion

File tree

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,11 @@
1111
"test:qunit": "tsx scripts/test.js",
1212
"test:vitest": "vitest run",
1313
"test:smoke": "(cd tests/smoke/exports && ./test.sh)",
14-
"lint": "pnpm lint:code && pnpm lint:types && pnpm lint:md",
14+
"lint": "pnpm lint:code && pnpm lint:types && pnpm lint:md && pnpm lint:test-lists",
1515
"lint:code": "eslint --cache .",
1616
"lint:types": "tsc --noEmit",
1717
"lint:md": "markdownlint .",
18+
"lint:test-lists": "tsx scripts/lint-test-lists.ts",
1819
"lint-staged": "lint-staged",
1920
"wiki": "pnpm wiki:build-table && pnpm wiki:build-docs",
2021
"wiki:build-table": "tsx ./scripts/check-sources-updates.js && tsx ./scripts/build-compatibility-table.js",

scripts/lint-test-lists.ts

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
import { readdirSync, readFileSync, writeFileSync } from 'fs';
2+
import { join } from 'path';
3+
import { program } from 'commander';
4+
5+
const { error: logError, log } = console;
6+
7+
/**
8+
* Test directories that use an index.test.js barrel file
9+
* to register all individual test/spec files.
10+
*/
11+
const TEST_DIRS_TO_CHECK = [
12+
'tests/scriptlets',
13+
'tests/redirects',
14+
];
15+
16+
/**
17+
* Index file name pattern.
18+
*/
19+
const INDEX_FILE_NAME = 'index.test.js';
20+
21+
/**
22+
* QUnit test file name pattern.
23+
*
24+
* Note: `.spec.js` files are not included in the test list
25+
* because they are run by Vitest, not QUnit.
26+
*/
27+
const TEST_FILE_NAME_PATTERN = /\.test\.js$/;
28+
29+
/**
30+
* Regexp to match lines like `import './foo.test';`
31+
*/
32+
const IMPORT_LINE_REGEX = /import\s+['"]\.\/([^'"]+\.test)['"]/g;
33+
34+
/**
35+
* Extracts imported file stems (without extension) from an index file.
36+
*
37+
* @param indexPath Absolute path to the index file.
38+
*
39+
* @returns Set of imported stems, e.g. "prevent-xhr.test".
40+
*/
41+
const getImportedStems = (indexPath: string): Set<string> => {
42+
const content = readFileSync(indexPath, 'utf-8');
43+
const stems = new Set<string>();
44+
45+
const matches = content.matchAll(IMPORT_LINE_REGEX);
46+
47+
for (const match of matches) {
48+
stems.add(match[1]);
49+
}
50+
51+
return stems;
52+
};
53+
54+
/**
55+
* Appends missing import lines to the end of the index file.
56+
*
57+
* @param indexPath Absolute path to the index file.
58+
* @param stems Array of missing stems to append, e.g. ["prevent-xhr.test"].
59+
*/
60+
const appendImports = (indexPath: string, stems: string[]): void => {
61+
const lines = stems.map((stem) => `import './${stem}';`);
62+
63+
const content = readFileSync(indexPath, 'utf-8');
64+
65+
const separator = content.endsWith('\n') ? '' : '\n';
66+
67+
writeFileSync(indexPath, `${content}${separator}${lines.join('\n')}\n`);
68+
};
69+
70+
/**
71+
* Checks that all QUnit test files are imported in the index files.
72+
* When `autoFix` is true, missing imports are appended automatically.
73+
*
74+
* @param autoFix Whether to auto-fix by appending missing imports.
75+
*/
76+
const lintTestLists = (autoFix: boolean): void => {
77+
let hasErrors = false;
78+
79+
for (const dir of TEST_DIRS_TO_CHECK) {
80+
const absDir = join(process.cwd(), dir);
81+
const indexPath = join(absDir, INDEX_FILE_NAME);
82+
83+
let importedStems: Set<string>;
84+
try {
85+
importedStems = getImportedStems(indexPath);
86+
} catch (e: unknown) {
87+
const message = e instanceof Error ? e.message : String(e);
88+
logError(`Could not read ${dir}/${INDEX_FILE_NAME}: ${message}`);
89+
hasErrors = true;
90+
continue;
91+
}
92+
93+
const missingImports = readdirSync(absDir).reduce<string[]>((acc, f) => {
94+
if (
95+
TEST_FILE_NAME_PATTERN.test(f)
96+
&& f !== INDEX_FILE_NAME
97+
) {
98+
const stem = f.replace(/\.js$/, '');
99+
100+
if (!importedStems.has(stem)) {
101+
acc.push(stem);
102+
}
103+
}
104+
return acc;
105+
}, []);
106+
107+
if (missingImports.length > 0) {
108+
if (autoFix) {
109+
appendImports(indexPath, missingImports);
110+
log(`Fixed ${dir}/${INDEX_FILE_NAME}: added ${missingImports.length} import(s).`);
111+
} else {
112+
hasErrors = true;
113+
logError(`\n${dir}/${INDEX_FILE_NAME} is missing ${missingImports.length} import(s):`);
114+
for (const stem of missingImports) {
115+
logError(` - import './${stem}';`);
116+
}
117+
}
118+
}
119+
}
120+
121+
if (hasErrors) {
122+
logError('\n⚠️ Please add the missing imports to the corresponding index file.\n');
123+
logError("You can run 'pnpm lint:test-lists --fix' to automatically add missing imports.\n");
124+
process.exit(1);
125+
} else {
126+
log('✅ All test files are registered in their index files.');
127+
}
128+
};
129+
130+
program
131+
.option('--fix', 'automatically add missing imports to index files')
132+
.parse();
133+
134+
const { fix } = program.opts<{ fix: boolean }>();
135+
136+
lintTestLists(fix);

tests/redirects/index.test.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,4 @@ import './didomi-loader.test';
1818
import './prebid-ads.test';
1919
import './naver-wcslog.test';
2020
import './pardot-1.0.test';
21+
import './noeval.test';

tests/scriptlets/index.test.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,3 +61,17 @@ import './trusted-suppress-native-method.test';
6161
import './prevent-canvas.test';
6262
import './trusted-replace-argument.test';
6363
import './remove-request-query-parameter.test';
64+
import './call-nothrow.test';
65+
import './evaldata-prune.test';
66+
import './href-sanitizer.test';
67+
import './json-prune-fetch-response.test';
68+
import './json-prune-xhr-response.test';
69+
import './no-protected-audience.test';
70+
import './prevent-constructor.test';
71+
import './prevent-innerHTML.test';
72+
import './set-cookie-reload.test';
73+
import './spoof-css.test';
74+
import './trusted-create-element.test';
75+
import './trusted-dispatch-event.test';
76+
import './trusted-replace-outbound-text.test';
77+
import './trusted-set-attr.test';

0 commit comments

Comments
 (0)