qunitx-cli 0.9.2 → 0.9.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/{cli.js → cli.ts} +7 -7
- package/deno.lock +6 -2
- package/lib/commands/{generate.js → generate.ts} +4 -4
- package/lib/commands/{help.js → help.ts} +1 -1
- package/lib/commands/{init.js → init.ts} +15 -7
- package/lib/commands/run/{tests-in-browser.js → tests-in-browser.ts} +28 -14
- package/lib/commands/{run.js → run.ts} +25 -17
- package/lib/servers/{http.js → http.ts} +84 -33
- package/lib/setup/bind-server-to-port.ts +14 -0
- package/lib/setup/{browser.js → browser.ts} +14 -18
- package/lib/setup/config.ts +55 -0
- package/lib/setup/{file-watcher.js → file-watcher.ts} +19 -5
- package/lib/setup/{fs-tree.js → fs-tree.ts} +16 -16
- package/lib/setup/{keyboard-events.js → keyboard-events.ts} +10 -5
- package/lib/setup/{test-file-paths.js → test-file-paths.ts} +20 -32
- package/lib/setup/{web-server.js → web-server.ts} +13 -16
- package/lib/setup/{write-output-static-files.js → write-output-static-files.ts} +6 -2
- package/lib/tap/{display-final-result.js → display-final-result.ts} +6 -3
- package/lib/tap/{display-test-result.js → display-test-result.ts} +22 -6
- package/lib/tap/{dump-yaml.js → dump-yaml.ts} +19 -5
- package/lib/types.ts +61 -0
- package/lib/utils/{chromium-args.js → chromium-args.ts} +1 -1
- package/lib/utils/{color.js → color.ts} +24 -11
- package/lib/utils/{early-chrome.js → early-chrome.ts} +5 -5
- package/lib/utils/{find-chrome.js → find-chrome.ts} +2 -2
- package/lib/utils/{find-internal-assets-from-html.js → find-internal-assets-from-html.ts} +1 -1
- package/lib/utils/{find-project-root.js → find-project-root.ts} +4 -4
- package/lib/utils/{indent-string.js → indent-string.ts} +6 -2
- package/lib/utils/{listen-to-keyboard-key.js → listen-to-keyboard-key.ts} +11 -7
- package/lib/utils/{parse-cli-flags.js → parse-cli-flags.ts} +21 -8
- package/lib/utils/{path-exists.js → path-exists.ts} +2 -2
- package/lib/utils/{perf-logger.js → perf-logger.ts} +1 -1
- package/lib/utils/{pre-launch-chrome.js → pre-launch-chrome.ts} +5 -1
- package/lib/utils/{read-boilerplate.js → read-boilerplate.ts} +1 -1
- package/lib/utils/{resolve-port-number-for.js → resolve-port-number-for.ts} +2 -2
- package/lib/utils/{run-user-module.js → run-user-module.ts} +6 -2
- package/lib/utils/{search-in-parent-directories.js → search-in-parent-directories.ts} +5 -2
- package/lib/utils/{time-counter.js → time-counter.ts} +2 -2
- package/package.json +14 -14
- package/lib/setup/bind-server-to-port.js +0 -9
- package/lib/setup/config.js +0 -48
- /package/lib/setup/{default-project-config-values.js → default-project-config-values.ts} +0 -0
|
@@ -6,7 +6,7 @@ const LINK_HREF_REGEX = /<link[^>]+\bhref=['"]([^'"]+)['"]/gi;
|
|
|
6
6
|
* Parses an HTML string and returns all internal (non-absolute-URL) `<script src>` and `<link href>` paths.
|
|
7
7
|
* @returns {string[]}
|
|
8
8
|
*/
|
|
9
|
-
export default function findInternalAssetsFromHTML(htmlContent) {
|
|
9
|
+
export default function findInternalAssetsFromHTML(htmlContent: string): string[] {
|
|
10
10
|
const links = [...htmlContent.matchAll(LINK_HREF_REGEX)]
|
|
11
11
|
.map((m) => m[1])
|
|
12
12
|
.filter((uri) => !ABSOLUTE_URL_REGEX.test(uri));
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
import process from 'node:process';
|
|
2
|
-
import searchInParentDirectories from './search-in-parent-directories.
|
|
2
|
+
import searchInParentDirectories from './search-in-parent-directories.ts';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Walks up parent directories from `cwd` to find the nearest `package.json` and returns its directory path.
|
|
6
6
|
* @returns {Promise<string>}
|
|
7
7
|
*/
|
|
8
|
-
export default async function findProjectRoot() {
|
|
8
|
+
export default async function findProjectRoot(): Promise<string> {
|
|
9
9
|
try {
|
|
10
10
|
const absolutePath = await searchInParentDirectories('.', 'package.json');
|
|
11
|
-
if (!absolutePath
|
|
11
|
+
if (!absolutePath!.includes('package.json')) {
|
|
12
12
|
throw new Error('package.json mising');
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
-
return absolutePath
|
|
15
|
+
return absolutePath!.replace('/package.json', '');
|
|
16
16
|
} catch (_error) {
|
|
17
17
|
console.log('couldnt find projects package.json, did you run $ npm init ??');
|
|
18
18
|
process.exit(1);
|
|
@@ -2,12 +2,16 @@
|
|
|
2
2
|
* Prepends `count` repetitions of `indent` (default: one space) to each non-empty line of `string`.
|
|
3
3
|
* @example
|
|
4
4
|
* ```js
|
|
5
|
-
* import indentString from './lib/utils/indent-string.
|
|
5
|
+
* import indentString from './lib/utils/indent-string.ts';
|
|
6
6
|
* console.assert(indentString('hello\nworld', 2) === ' hello\n world');
|
|
7
7
|
* ```
|
|
8
8
|
* @returns {string}
|
|
9
9
|
*/
|
|
10
|
-
export default function indentString(
|
|
10
|
+
export default function indentString(
|
|
11
|
+
string: string,
|
|
12
|
+
count: number = 1,
|
|
13
|
+
options: { indent?: string; includeEmptyLines?: boolean } = {},
|
|
14
|
+
): string {
|
|
11
15
|
const { indent = ' ', includeEmptyLines = false } = options;
|
|
12
16
|
|
|
13
17
|
if (count <= 0) {
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import process from 'node:process';
|
|
2
2
|
|
|
3
3
|
const stdin = process.stdin;
|
|
4
|
-
const targetInputs
|
|
5
|
-
|
|
4
|
+
const targetInputs: Record<string, { caseSensitive: boolean; closure: (input: string) => void }> =
|
|
5
|
+
{};
|
|
6
|
+
const inputs: (string | undefined)[] = [];
|
|
6
7
|
let listenerAdded = false;
|
|
7
8
|
|
|
8
9
|
/**
|
|
@@ -10,10 +11,10 @@ let listenerAdded = false;
|
|
|
10
11
|
* @returns {void}
|
|
11
12
|
*/
|
|
12
13
|
export default function listenToKeyboardKey(
|
|
13
|
-
inputString,
|
|
14
|
-
closure,
|
|
15
|
-
options = { caseSensitive: false },
|
|
16
|
-
) {
|
|
14
|
+
inputString: string,
|
|
15
|
+
closure: (input: string) => void,
|
|
16
|
+
options: { caseSensitive: boolean } = { caseSensitive: false },
|
|
17
|
+
): void {
|
|
17
18
|
if (!stdin.isTTY) return;
|
|
18
19
|
stdin.setRawMode(true);
|
|
19
20
|
stdin.resume();
|
|
@@ -44,7 +45,10 @@ export default function listenToKeyboardKey(
|
|
|
44
45
|
targetInputs[inputString.toUpperCase()] = Object.assign(options, { closure });
|
|
45
46
|
}
|
|
46
47
|
|
|
47
|
-
function targetListenerConformsToCase(
|
|
48
|
+
function targetListenerConformsToCase(
|
|
49
|
+
targetListener: { caseSensitive: boolean },
|
|
50
|
+
inputString: string,
|
|
51
|
+
): boolean {
|
|
48
52
|
if (targetListener.caseSensitive) {
|
|
49
53
|
return inputString === inputString.toUpperCase();
|
|
50
54
|
}
|
|
@@ -1,9 +1,24 @@
|
|
|
1
1
|
// { inputs: [], debug: true, watch: true, failFast: true, htmlPaths: [], output }
|
|
2
|
+
interface ParsedFlags {
|
|
3
|
+
inputs: string[];
|
|
4
|
+
debug?: boolean;
|
|
5
|
+
watch?: boolean;
|
|
6
|
+
failFast?: boolean;
|
|
7
|
+
timeout?: number;
|
|
8
|
+
output?: string;
|
|
9
|
+
htmlPaths?: string[];
|
|
10
|
+
port?: number;
|
|
11
|
+
extensions?: string[];
|
|
12
|
+
browser?: 'chromium' | 'firefox' | 'webkit';
|
|
13
|
+
before?: string | false;
|
|
14
|
+
after?: string | false;
|
|
15
|
+
}
|
|
16
|
+
|
|
2
17
|
/**
|
|
3
18
|
* Parses `process.argv` into a qunitx flag object (`inputs`, `debug`, `watch`, `failFast`, `timeout`, `output`, `port`, `before`, `after`).
|
|
4
19
|
* @returns {object}
|
|
5
20
|
*/
|
|
6
|
-
export default function parseCliFlags(projectRoot) {
|
|
21
|
+
export default function parseCliFlags(projectRoot: string): ParsedFlags {
|
|
7
22
|
const providedFlags = process.argv.slice(2).reduce(
|
|
8
23
|
(result, arg) => {
|
|
9
24
|
if (arg.startsWith('--debug')) {
|
|
@@ -41,7 +56,7 @@ export default function parseCliFlags(projectRoot) {
|
|
|
41
56
|
);
|
|
42
57
|
process.exit(1);
|
|
43
58
|
}
|
|
44
|
-
return Object.assign(result, { browser: value });
|
|
59
|
+
return Object.assign(result, { browser: value as 'chromium' | 'firefox' | 'webkit' });
|
|
45
60
|
} else if (arg.startsWith('--before')) {
|
|
46
61
|
return Object.assign(result, { before: parseModule(arg.split('=')[1]) });
|
|
47
62
|
} else if (arg.startsWith('--after')) {
|
|
@@ -55,15 +70,13 @@ export default function parseCliFlags(projectRoot) {
|
|
|
55
70
|
|
|
56
71
|
return result;
|
|
57
72
|
},
|
|
58
|
-
{ inputs: new Set([]) },
|
|
73
|
+
{ inputs: new Set<string>([]) } as ParsedFlags & { inputs: Set<string> },
|
|
59
74
|
);
|
|
60
75
|
|
|
61
|
-
providedFlags
|
|
62
|
-
|
|
63
|
-
return providedFlags;
|
|
76
|
+
return { ...providedFlags, inputs: Array.from(providedFlags.inputs) };
|
|
64
77
|
}
|
|
65
78
|
|
|
66
|
-
function parseBoolean(result, defaultValue = true) {
|
|
79
|
+
function parseBoolean(result: string, defaultValue = true): boolean {
|
|
67
80
|
if (result === 'true') {
|
|
68
81
|
return true;
|
|
69
82
|
} else if (result === 'false') {
|
|
@@ -73,7 +86,7 @@ function parseBoolean(result, defaultValue = true) {
|
|
|
73
86
|
return defaultValue;
|
|
74
87
|
}
|
|
75
88
|
|
|
76
|
-
function parseModule(value) {
|
|
89
|
+
function parseModule(value: string): string | false {
|
|
77
90
|
if (['false', "'false'", '"false"', ''].includes(value)) {
|
|
78
91
|
return false;
|
|
79
92
|
}
|
|
@@ -4,13 +4,13 @@ import fs from 'node:fs/promises';
|
|
|
4
4
|
* Returns `true` if the given filesystem path is accessible, `false` otherwise.
|
|
5
5
|
* @example
|
|
6
6
|
* ```js
|
|
7
|
-
* import pathExists from './lib/utils/path-exists.
|
|
7
|
+
* import pathExists from './lib/utils/path-exists.ts';
|
|
8
8
|
* console.assert(await pathExists('/tmp') === true);
|
|
9
9
|
* console.assert(await pathExists('/tmp/nonexistent-qunitx-file') === false);
|
|
10
10
|
* ```
|
|
11
11
|
* @returns {Promise<boolean>}
|
|
12
12
|
*/
|
|
13
|
-
export default async function pathExists(path) {
|
|
13
|
+
export default async function pathExists(path: string): Promise<boolean> {
|
|
14
14
|
try {
|
|
15
15
|
await fs.access(path);
|
|
16
16
|
|
|
@@ -17,7 +17,7 @@ const processStart = isPerfTracing ? Date.now() : 0;
|
|
|
17
17
|
* @param {string} label
|
|
18
18
|
* @param {...*} details
|
|
19
19
|
*/
|
|
20
|
-
export function perfLog(label, ...details) {
|
|
20
|
+
export function perfLog(label: string, ...details: unknown[]): void {
|
|
21
21
|
if (!isPerfTracing) return;
|
|
22
22
|
const elapsed = Date.now() - processStart;
|
|
23
23
|
const suffix = details.length ? ' ' + details.join(' ') : '';
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { spawn } from 'node:child_process';
|
|
2
|
+
import type { EarlyChrome } from '../types.ts';
|
|
2
3
|
|
|
3
4
|
const CDP_URL_REGEX = /DevTools listening on (ws:\/\/[^\s]+)/;
|
|
4
5
|
|
|
@@ -8,7 +9,10 @@ const CDP_URL_REGEX = /DevTools listening on (ws:\/\/[^\s]+)/;
|
|
|
8
9
|
* fails to start, so callers can fall back to playwright's normal launch.
|
|
9
10
|
* @returns {Promise<{proc: ChildProcess, cdpEndpoint: string} | null>}
|
|
10
11
|
*/
|
|
11
|
-
export default function preLaunchChrome(
|
|
12
|
+
export default function preLaunchChrome(
|
|
13
|
+
chromePath: string | null | undefined,
|
|
14
|
+
args: string[],
|
|
15
|
+
): Promise<EarlyChrome | null> {
|
|
12
16
|
if (!chromePath) return Promise.resolve(null);
|
|
13
17
|
|
|
14
18
|
return new Promise((resolve) => {
|
|
@@ -8,7 +8,7 @@ const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
|
8
8
|
* Reads a boilerplate file by relative path, using the SEA asset store when running as a Node.js binary.
|
|
9
9
|
* @returns {Promise<string>}
|
|
10
10
|
*/
|
|
11
|
-
export default async function readBoilerplate(relativePath) {
|
|
11
|
+
export default async function readBoilerplate(relativePath: string): Promise<string> {
|
|
12
12
|
const sea = await import('node:sea').catch(() => null);
|
|
13
13
|
if (sea?.isSea()) return sea.getAsset(relativePath, 'utf8');
|
|
14
14
|
return (await fs.readFile(join(__dirname, '../../templates', relativePath))).toString();
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Returns `portNumber` if it is free, otherwise recursively tries `portNumber + 1` until a free port is found.
|
|
3
3
|
* @returns {Promise<number>}
|
|
4
4
|
*/
|
|
5
|
-
export default async function resolvePortNumberFor(portNumber) {
|
|
5
|
+
export default async function resolvePortNumberFor(portNumber: number): Promise<number> {
|
|
6
6
|
if (await portIsAvailable(portNumber)) {
|
|
7
7
|
return portNumber;
|
|
8
8
|
}
|
|
@@ -10,7 +10,7 @@ export default async function resolvePortNumberFor(portNumber) {
|
|
|
10
10
|
return await resolvePortNumberFor(portNumber + 1);
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
-
async function portIsAvailable(portNumber) {
|
|
13
|
+
async function portIsAvailable(portNumber: number): Promise<boolean> {
|
|
14
14
|
const net = await import('net');
|
|
15
15
|
return new Promise((resolve) => {
|
|
16
16
|
const server = net.createServer();
|
|
@@ -1,10 +1,14 @@
|
|
|
1
|
-
import { red } from './color.
|
|
1
|
+
import { red } from './color.ts';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Dynamically imports `modulePath` and calls its default export with `params`; exits with code 1 on error.
|
|
5
5
|
* @returns {Promise<void>}
|
|
6
6
|
*/
|
|
7
|
-
export default async function runUserModule(
|
|
7
|
+
export default async function runUserModule(
|
|
8
|
+
modulePath: string,
|
|
9
|
+
params: unknown,
|
|
10
|
+
scriptPosition: string,
|
|
11
|
+
): Promise<void> {
|
|
8
12
|
try {
|
|
9
13
|
const func = await import(modulePath);
|
|
10
14
|
if (func) {
|
|
@@ -1,10 +1,13 @@
|
|
|
1
|
-
import pathExists from './path-exists.
|
|
1
|
+
import pathExists from './path-exists.ts';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Recursively searches `directory` and its ancestors for a file or folder named `targetEntry`; returns the absolute path or `undefined`.
|
|
5
5
|
* @returns {Promise<string|undefined>}
|
|
6
6
|
*/
|
|
7
|
-
async function searchInParentDirectories(
|
|
7
|
+
async function searchInParentDirectories(
|
|
8
|
+
directory: string,
|
|
9
|
+
targetEntry: string,
|
|
10
|
+
): Promise<string | undefined> {
|
|
8
11
|
const resolvedDirectory = directory === '.' ? process.cwd() : directory;
|
|
9
12
|
|
|
10
13
|
if (await pathExists(`${resolvedDirectory}/${targetEntry}`)) {
|
|
@@ -2,14 +2,14 @@
|
|
|
2
2
|
* Returns a timer object with a `startTime` Date and a `stop()` method that returns elapsed milliseconds.
|
|
3
3
|
* @example
|
|
4
4
|
* ```js
|
|
5
|
-
* import timeCounter from './lib/utils/time-counter.
|
|
5
|
+
* import timeCounter from './lib/utils/time-counter.ts';
|
|
6
6
|
* const t = timeCounter();
|
|
7
7
|
* const ms = t.stop();
|
|
8
8
|
* console.assert(ms >= 0);
|
|
9
9
|
* ```
|
|
10
10
|
* @returns {{ startTime: Date, stop: () => number }}
|
|
11
11
|
*/
|
|
12
|
-
export default function timeCounter() {
|
|
12
|
+
export default function timeCounter(): { startTime: Date; stop: () => number } {
|
|
13
13
|
const startTime = new Date();
|
|
14
14
|
|
|
15
15
|
return {
|
package/package.json
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "qunitx-cli",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.9.
|
|
4
|
+
"version": "0.9.4",
|
|
5
5
|
"description": "Browser runner for QUnitx: run your qunitx tests in google-chrome",
|
|
6
|
-
"main": "cli.
|
|
6
|
+
"main": "cli.ts",
|
|
7
7
|
"author": "Izel Nakri",
|
|
8
8
|
"license": "MIT",
|
|
9
9
|
"keywords": [
|
|
@@ -15,27 +15,27 @@
|
|
|
15
15
|
"qunitx"
|
|
16
16
|
],
|
|
17
17
|
"scripts": {
|
|
18
|
-
"bin": "chmod +x cli.
|
|
19
|
-
"format": "prettier --check \"lib/**/*.
|
|
20
|
-
"format:fix": "prettier --write \"lib/**/*.
|
|
21
|
-
"lint": "deno lint lib/ cli.
|
|
18
|
+
"bin": "chmod +x cli.ts && ./cli.ts",
|
|
19
|
+
"format": "prettier --check \"lib/**/*.ts\" \"test/**/*.ts\" \"*.ts\" \"package.json\" \".github/**/*.yml\"",
|
|
20
|
+
"format:fix": "prettier --write \"lib/**/*.ts\" \"test/**/*.ts\" \"*.ts\" \"package.json\" \".github/**/*.yml\"",
|
|
21
|
+
"lint": "deno lint lib/ cli.ts",
|
|
22
22
|
"lint:docs": "node scripts/lint-docs.js",
|
|
23
|
-
"docs": "deno doc --html --name=\"qunitx-cli\" --output=docs/lib 'lib/**/*.
|
|
23
|
+
"docs": "deno doc --html --name=\"qunitx-cli\" --output=docs/lib 'lib/**/*.ts' README.md",
|
|
24
24
|
"changelog:unreleased": "git-cliff --unreleased --strip all",
|
|
25
25
|
"changelog:preview": "git-cliff",
|
|
26
26
|
"changelog:update": "git-cliff --output CHANGELOG.md",
|
|
27
27
|
"postinstall": "deno install --allow-scripts=npm:playwright-core || true",
|
|
28
|
-
"test": "node test/setup.
|
|
29
|
-
"test:browser": "node test/setup.
|
|
30
|
-
"test:sanity-first": "./cli.
|
|
31
|
-
"test:sanity-second": "./cli.
|
|
28
|
+
"test": "node --experimental-strip-types test/setup.ts && FORCE_COLOR=0 node --experimental-strip-types --test --test-concurrency=$(node -p 'require(\"os\").availableParallelism()') test/**/*-test.ts",
|
|
29
|
+
"test:browser": "node --experimental-strip-types test/setup.ts && FORCE_COLOR=0 node --experimental-strip-types --test --test-concurrency=$(node -p 'require(\"os\").availableParallelism()') test/flags/*-test.ts test/inputs/*-test.ts",
|
|
30
|
+
"test:sanity-first": "./cli.ts test/helpers/failing-tests.js test/helpers/failing-tests.ts",
|
|
31
|
+
"test:sanity-second": "./cli.ts test/helpers/passing-tests.js test/helpers/passing-tests.ts"
|
|
32
32
|
},
|
|
33
33
|
"engines": {
|
|
34
34
|
"node": ">=24.0.0",
|
|
35
35
|
"deno": ">=2.7.0"
|
|
36
36
|
},
|
|
37
37
|
"bin": {
|
|
38
|
-
"qunitx": "cli.
|
|
38
|
+
"qunitx": "cli.ts"
|
|
39
39
|
},
|
|
40
40
|
"repository": {
|
|
41
41
|
"type": "git",
|
|
@@ -43,7 +43,6 @@
|
|
|
43
43
|
},
|
|
44
44
|
"dependencies": {
|
|
45
45
|
"esbuild": "^0.27.3",
|
|
46
|
-
"picomatch": "^4.0.4",
|
|
47
46
|
"playwright-core": "^1.58.2",
|
|
48
47
|
"ws": "^8.20.0"
|
|
49
48
|
},
|
|
@@ -52,7 +51,8 @@
|
|
|
52
51
|
"express": "^5.2.1",
|
|
53
52
|
"js-yaml": "^4.1.1",
|
|
54
53
|
"prettier": "^3.8.1",
|
|
55
|
-
"qunitx": "^1.0.4"
|
|
54
|
+
"qunitx": "^1.0.4",
|
|
55
|
+
"typescript": "^5.0.0"
|
|
56
56
|
},
|
|
57
57
|
"volta": {
|
|
58
58
|
"node": "24.14.0"
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Binds an HTTPServer to an OS-assigned port and writes the resolved port back to `config.port`.
|
|
3
|
-
* @returns {Promise<object>}
|
|
4
|
-
*/
|
|
5
|
-
export default async function bindServerToPort(server, config) {
|
|
6
|
-
await server.listen(0);
|
|
7
|
-
config.port = server._server.address().port;
|
|
8
|
-
return server;
|
|
9
|
-
}
|
package/lib/setup/config.js
DELETED
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
import fs from 'node:fs/promises';
|
|
2
|
-
import defaultProjectConfigValues from './default-project-config-values.js';
|
|
3
|
-
import findProjectRoot from '../utils/find-project-root.js';
|
|
4
|
-
import setupFSTree from './fs-tree.js';
|
|
5
|
-
import setupTestFilePaths from './test-file-paths.js';
|
|
6
|
-
import parseCliFlags from '../utils/parse-cli-flags.js';
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Builds the merged qunitx config from package.json settings and CLI flags.
|
|
10
|
-
* @returns {Promise<object>}
|
|
11
|
-
*/
|
|
12
|
-
export default async function setupConfig() {
|
|
13
|
-
const projectRoot = await findProjectRoot();
|
|
14
|
-
const cliConfigFlags = parseCliFlags(projectRoot);
|
|
15
|
-
const projectPackageJSON = await readConfigFromPackageJSON(projectRoot);
|
|
16
|
-
const inputs = cliConfigFlags.inputs.concat(readInputsFromPackageJSON(projectPackageJSON));
|
|
17
|
-
const config = {
|
|
18
|
-
...defaultProjectConfigValues,
|
|
19
|
-
htmlPaths: [],
|
|
20
|
-
...projectPackageJSON.qunitx,
|
|
21
|
-
...cliConfigFlags,
|
|
22
|
-
projectRoot,
|
|
23
|
-
inputs,
|
|
24
|
-
testFileLookupPaths: setupTestFilePaths(projectRoot, inputs),
|
|
25
|
-
lastFailedTestFiles: null,
|
|
26
|
-
lastRanTestFiles: null,
|
|
27
|
-
};
|
|
28
|
-
config.htmlPaths = normalizeHTMLPaths(config.projectRoot, config.htmlPaths);
|
|
29
|
-
config.fsTree = await setupFSTree(config.testFileLookupPaths, config);
|
|
30
|
-
|
|
31
|
-
return config;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
async function readConfigFromPackageJSON(projectRoot) {
|
|
35
|
-
const packageJSON = await fs.readFile(`${projectRoot}/package.json`);
|
|
36
|
-
|
|
37
|
-
return JSON.parse(packageJSON.toString());
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
function normalizeHTMLPaths(projectRoot, htmlPaths) {
|
|
41
|
-
return Array.from(new Set(htmlPaths.map((htmlPath) => `${projectRoot}/${htmlPath}`)));
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
function readInputsFromPackageJSON(packageJSON) {
|
|
45
|
-
const qunitx = packageJSON.qunitx;
|
|
46
|
-
|
|
47
|
-
return qunitx && qunitx.inputs ? qunitx.inputs : [];
|
|
48
|
-
}
|
|
File without changes
|