qunitx 0.6.1 → 0.8.0
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/README.md +5 -7
- package/build.js +54 -0
- package/deno.json +2 -2
- package/deno.lock +7 -3752
- package/package.json +21 -40
- package/{index.js → shims/browser/index.js} +2 -4
- package/shims/{deno-assert.js → deno/assert.js} +2 -2
- package/shims/{deno.js → deno/index.js} +1 -1
- package/shims/{nodejs-assert.js → node/assert.js} +1 -0
- package/shims/{nodejs.js → node/index.js} +2 -2
- package/vendor/package.json +1 -4
- package/cli.js +0 -24
- package/deno/cli.js +0 -21
- package/deno-bridge.js +0 -16
- package/lib/boilerplates/default-project-config-values.js +0 -6
- package/lib/boilerplates/setup/tests.hbs +0 -15
- package/lib/boilerplates/setup/tsconfig.json +0 -109
- package/lib/boilerplates/test.js +0 -25
- package/lib/commands/generate.js +0 -33
- package/lib/commands/help.js +0 -38
- package/lib/commands/init.js +0 -70
- package/lib/commands/run/tests-in-browser.js +0 -162
- package/lib/commands/run/tests-in-node.js +0 -60
- package/lib/commands/run.js +0 -159
- package/lib/servers/http.js +0 -233
- package/lib/setup/bind-server-to-port.js +0 -14
- package/lib/setup/browser.js +0 -55
- package/lib/setup/config.js +0 -46
- package/lib/setup/file-watcher.js +0 -72
- package/lib/setup/fs-tree.js +0 -48
- package/lib/setup/keyboard-events.js +0 -57
- package/lib/setup/node-js-environment.js +0 -74
- package/lib/setup/test-file-paths.js +0 -79
- package/lib/setup/web-server.js +0 -241
- package/lib/setup/write-output-static-files.js +0 -22
- package/lib/tap/display-final-result.js +0 -15
- package/lib/tap/display-test-result.js +0 -73
- package/lib/utils/find-internal-assets-from-html.js +0 -16
- package/lib/utils/find-project-root.js +0 -16
- package/lib/utils/indent-string.js +0 -11
- package/lib/utils/listen-to-keyboard-key.js +0 -42
- package/lib/utils/parse-cli-flags.js +0 -59
- package/lib/utils/path-exists.js +0 -11
- package/lib/utils/resolve-port-number-for.js +0 -27
- package/lib/utils/run-user-module.js +0 -18
- package/lib/utils/search-in-parent-directories.js +0 -15
- package/lib/utils/time-counter.js +0 -8
- package/test-output.log +0 -781
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
import yaml from 'js-yaml'
|
|
2
|
-
import indentString from '../utils/indent-string.js';
|
|
3
|
-
|
|
4
|
-
// tape TAP output: ['operator', 'stack', 'at', 'expected', 'actual']
|
|
5
|
-
// ava TAP output: ['message', 'name', 'at', 'assertion', 'values'] // Assertion #5, message
|
|
6
|
-
export default function(COUNTER, details) { // NOTE: https://github.com/qunitjs/qunit/blob/master/src/html-reporter/diff.js
|
|
7
|
-
COUNTER.testCount++;
|
|
8
|
-
|
|
9
|
-
if (details.status === 'skipped') {
|
|
10
|
-
COUNTER.skipCount++;
|
|
11
|
-
console.log(`ok ${COUNTER.testCount}`, details.fullName.join(' | '), '# skip');
|
|
12
|
-
} else if (details.status === 'todo') {
|
|
13
|
-
console.log(`not ok ${COUNTER.testCount}`, details.fullName.join(' | '), '# skip');
|
|
14
|
-
} else if (details.status === 'failed') {
|
|
15
|
-
COUNTER.failCount++;
|
|
16
|
-
console.log(`not ok ${COUNTER.testCount}`, details.fullName.join(' | '), `# (${details.runtime.toFixed(0)} ms)`);
|
|
17
|
-
details.assertions.reduce((errorCount, assertion, index) => {
|
|
18
|
-
if (!assertion.passed && assertion.todo === false) {
|
|
19
|
-
COUNTER.errorCount++;
|
|
20
|
-
let stack = assertion.stack?.match(/\(.+\)/g);
|
|
21
|
-
|
|
22
|
-
console.log(' ---');
|
|
23
|
-
console.log(indentString(yaml.dump({
|
|
24
|
-
name: `Assertion #${index + 1}`, // TODO: check what happens on runtime errors
|
|
25
|
-
actual: assertion.actual ? JSON.parse(JSON.stringify(assertion.actual, getCircularReplacer())) : assertion.actual,
|
|
26
|
-
expected: assertion.expected ? JSON.parse(JSON.stringify(assertion.expected, getCircularReplacer())) : assertion.expected,
|
|
27
|
-
message: assertion.message || null,
|
|
28
|
-
stack: assertion.stack || null,
|
|
29
|
-
at: stack ? stack[0].replace('(file://', '').replace(')', '') : null
|
|
30
|
-
}), 4));
|
|
31
|
-
console.log(' ...');
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
return errorCount;
|
|
35
|
-
}, 0);
|
|
36
|
-
} else if (details.status === 'passed') {
|
|
37
|
-
COUNTER.passCount++;
|
|
38
|
-
console.log(`ok ${COUNTER.testCount}`, details.fullName.join(' | '), `# (${details.runtime.toFixed(0)} ms)`);
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
function getCircularReplacer() {
|
|
43
|
-
const ancestors = [];
|
|
44
|
-
return function (key, value) {
|
|
45
|
-
if (typeof value !== "object" || value === null) {
|
|
46
|
-
return value;
|
|
47
|
-
}
|
|
48
|
-
while (ancestors.length > 0 && ancestors.at(-1) !== this) {
|
|
49
|
-
ancestors.pop();
|
|
50
|
-
}
|
|
51
|
-
if (ancestors.includes(value)) {
|
|
52
|
-
return "[Circular]";
|
|
53
|
-
}
|
|
54
|
-
ancestors.push(value);
|
|
55
|
-
return value;
|
|
56
|
-
};
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
// not ok 10 test exited without ending: deepEqual true works
|
|
60
|
-
// ---
|
|
61
|
-
// operator: fail
|
|
62
|
-
// at: process.<anonymous> (/home/izelnakri/ava-test/node_modules/tape/index.js:85:19)
|
|
63
|
-
// stack: |-
|
|
64
|
-
// Error: test exited without ending: deepEqual true works
|
|
65
|
-
// at Test.assert [as _assert] (/home/izelnakri/ava-test/node_modules/tape/lib/test.js:269:54)
|
|
66
|
-
// at Test.bound [as _assert] (/home/izelnakri/ava-test/node_modules/tape/lib/test.js:90:32)
|
|
67
|
-
// at Test.fail (/home/izelnakri/ava-test/node_modules/tape/lib/test.js:363:10)
|
|
68
|
-
// at Test.bound [as fail] (/home/izelnakri/ava-test/node_modules/tape/lib/test.js:90:32)
|
|
69
|
-
// at Test._exit (/home/izelnakri/ava-test/node_modules/tape/lib/test.js:226:14)
|
|
70
|
-
// at Test.bound [as _exit] (/home/izelnakri/ava-test/node_modules/tape/lib/test.js:90:32)
|
|
71
|
-
// at process.<anonymous> (/home/izelnakri/ava-test/node_modules/tape/index.js:85:19)
|
|
72
|
-
// at process.emit (node:events:376:20)
|
|
73
|
-
// ...
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import cheerio from 'cheerio';
|
|
2
|
-
|
|
3
|
-
const ABSOLUTE_URL_REGEX = new RegExp('^(?:[a-z]+:)?//', 'i');
|
|
4
|
-
|
|
5
|
-
export default function findInternalAssetsFromHTML(htmlContent) {
|
|
6
|
-
const $ = cheerio.load(htmlContent);
|
|
7
|
-
const internalJSFiles = $('script[src]').toArray()
|
|
8
|
-
.map((scriptNode) => $(scriptNode).attr('src'))
|
|
9
|
-
.filter((uri) => !ABSOLUTE_URL_REGEX.test(uri));
|
|
10
|
-
const internalCSSFiles = $('link[href]').toArray()
|
|
11
|
-
.map((scriptNode) => $(scriptNode).attr('href'))
|
|
12
|
-
.filter((uri) => !ABSOLUTE_URL_REGEX.test(uri));
|
|
13
|
-
|
|
14
|
-
return internalCSSFiles.concat(internalJSFiles);
|
|
15
|
-
// TODO: maybe needs normalization ? .map((fileReferencePath) => fileReferencePath.replace('/assets', `${projectRoot}/tmp/assets`));
|
|
16
|
-
}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import searchInParentDirectories from './search-in-parent-directories.js';
|
|
2
|
-
|
|
3
|
-
export default async function() {
|
|
4
|
-
try {
|
|
5
|
-
let absolutePath = await searchInParentDirectories('.', 'package.json');
|
|
6
|
-
if (!absolutePath.includes('package.json')) {
|
|
7
|
-
throw new Error('package.json mising');
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
return absolutePath.replace('/package.json', '');
|
|
11
|
-
} catch (error) {
|
|
12
|
-
console.log('couldnt find projects package.json, did you run $ npm init ??');
|
|
13
|
-
process.exit(1);
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
export default function indentString(string, count = 1, options = {}) {
|
|
2
|
-
const { indent = ' ', includeEmptyLines = false } = options;
|
|
3
|
-
|
|
4
|
-
if (count <= 0) {
|
|
5
|
-
return string;
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
const regex = includeEmptyLines ? /^/gm : /^(?!\s*$)/gm;
|
|
9
|
-
|
|
10
|
-
return string.replace(regex, indent.repeat(count));
|
|
11
|
-
}
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
let stdin = process.stdin;
|
|
2
|
-
let targetInputs = {};
|
|
3
|
-
let inputs = [];
|
|
4
|
-
let listenerAdded = false;
|
|
5
|
-
|
|
6
|
-
export default function listenToKeyboardKey(inputString, closure, options = { caseSensitive: false }) {
|
|
7
|
-
stdin.setRawMode(true);
|
|
8
|
-
stdin.resume();
|
|
9
|
-
stdin.setEncoding('utf8');
|
|
10
|
-
if (!listenerAdded) {
|
|
11
|
-
stdin.on('data', function(key){
|
|
12
|
-
if (key === '\u0003') {
|
|
13
|
-
process.exit(); // so node process doesnt trap Control-C
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
inputs.shift();
|
|
17
|
-
inputs.push(key);
|
|
18
|
-
|
|
19
|
-
let inputString = inputs.join('');
|
|
20
|
-
let targetListener = targetInputs[inputString.toUpperCase()];
|
|
21
|
-
if (targetListener && targetListenerConformsToCase(targetListener, inputString)) {
|
|
22
|
-
targetListener.closure(inputString);
|
|
23
|
-
inputs.fill(undefined);
|
|
24
|
-
}
|
|
25
|
-
});
|
|
26
|
-
listenerAdded = true;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
if (inputString.length > inputs.length) {
|
|
30
|
-
inputs.length = inputString.length;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
targetInputs[inputString.toUpperCase()] = Object.assign(options, { closure });
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
function targetListenerConformsToCase(targetListener, inputString) {
|
|
37
|
-
if (targetListener.caseSensitive) {
|
|
38
|
-
return inputString === inputString.toUpperCase();
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
return true;
|
|
42
|
-
}
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
// { inputs: [], browser: true, debug: true, watch: true, failFast: true, htmlPaths: [], output }
|
|
2
|
-
export default async function(projectRoot) {
|
|
3
|
-
const providedFlags = process.argv.slice(2).reduce((result, arg) => {
|
|
4
|
-
if (arg.startsWith('--browser')) {
|
|
5
|
-
return Object.assign(result, { browser: parseBoolean(arg.split('=')[1]) });
|
|
6
|
-
} else if (arg.startsWith('--debug')) {
|
|
7
|
-
return Object.assign(result, { debug: parseBoolean(arg.split('=')[1]) });
|
|
8
|
-
} else if (arg.startsWith('--watch')) {
|
|
9
|
-
return Object.assign(result, { watch: parseBoolean(arg.split('=')[1]) });
|
|
10
|
-
} else if (arg.startsWith('--failfast') || arg.startsWith('--failFast')) {
|
|
11
|
-
return Object.assign(result, { failFast: parseBoolean(arg.split('=')[1]) });
|
|
12
|
-
} else if (arg.startsWith('--timeout')) {
|
|
13
|
-
return Object.assign(result, { timeout: arg.split('=')[1] || 10000 });
|
|
14
|
-
} else if (arg.startsWith('--output')) {
|
|
15
|
-
return Object.assign(result, { output: arg.split('=')[1] });
|
|
16
|
-
} else if (arg.endsWith('.html')) {
|
|
17
|
-
if (result.htmlPaths) {
|
|
18
|
-
result.htmlPaths.push(arg);
|
|
19
|
-
} else {
|
|
20
|
-
result.htmlPaths = [arg];
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
return result;
|
|
24
|
-
} else if (arg.startsWith('--port')) {
|
|
25
|
-
return Object.assign(result, { port: Number(arg.split('=')[1]) });
|
|
26
|
-
} else if (arg.startsWith('--before')) {
|
|
27
|
-
return Object.assign(result, { before: parseModule(arg.split('=')[1]) });
|
|
28
|
-
} else if (arg.startsWith('--after')) {
|
|
29
|
-
return Object.assign(result, { after: parseModule(arg.split('=')[1]) });
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
// maybe set watch depth via micromatch(so incl metadata)
|
|
33
|
-
result.inputs.add(arg.startsWith(projectRoot) ? arg : `${process.cwd()}/${arg}`);
|
|
34
|
-
|
|
35
|
-
return result;
|
|
36
|
-
}, { inputs: new Set([]) });
|
|
37
|
-
|
|
38
|
-
providedFlags.inputs = Array.from(providedFlags.inputs);
|
|
39
|
-
|
|
40
|
-
return providedFlags;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
function parseBoolean(result, defaultValue=true) {
|
|
44
|
-
if (result === 'true') {
|
|
45
|
-
return true;
|
|
46
|
-
} else if (result === 'false') {
|
|
47
|
-
return false;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
return defaultValue;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
function parseModule(value) {
|
|
54
|
-
if (['false', "'false'", '"false"', ''].includes(value)) {
|
|
55
|
-
return false;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
return value;
|
|
59
|
-
}
|
package/lib/utils/path-exists.js
DELETED
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
export default async function resolvePortNumberFor(portNumber) {
|
|
2
|
-
if (await portIsAvailable(portNumber)) {
|
|
3
|
-
return portNumber;
|
|
4
|
-
}
|
|
5
|
-
|
|
6
|
-
return (await resolvePortNumberFor(portNumber + 1));
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
function portIsAvailable(portNumber) {
|
|
10
|
-
return new Promise(async (resolve) => {
|
|
11
|
-
const net = await import('net');
|
|
12
|
-
const server = net.createServer();
|
|
13
|
-
|
|
14
|
-
server.once('error', function(err) {
|
|
15
|
-
if (err.code === 'EADDRINUSE') {
|
|
16
|
-
resolve(false);
|
|
17
|
-
}
|
|
18
|
-
});
|
|
19
|
-
|
|
20
|
-
server.once('listening', function() {
|
|
21
|
-
server.close();
|
|
22
|
-
resolve(true);
|
|
23
|
-
});
|
|
24
|
-
|
|
25
|
-
server.listen(portNumber);
|
|
26
|
-
});
|
|
27
|
-
}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import kleur from 'kleur';
|
|
2
|
-
|
|
3
|
-
export default async function runUserModule(modulePath, params, scriptPosition) {
|
|
4
|
-
try {
|
|
5
|
-
let func = await import(modulePath);
|
|
6
|
-
if (func) {
|
|
7
|
-
func.default ?
|
|
8
|
-
await func.default(params) :
|
|
9
|
-
typeof func === 'function' ? await func(params) : null;
|
|
10
|
-
}
|
|
11
|
-
} catch (error) {
|
|
12
|
-
console.log('#', kleur.red(`QUnitX ${scriptPosition} script failed:`));
|
|
13
|
-
console.trace(error);
|
|
14
|
-
console.error(error);
|
|
15
|
-
|
|
16
|
-
return process.exit(1);
|
|
17
|
-
}
|
|
18
|
-
}
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import pathExists from './path-exists.js';
|
|
2
|
-
|
|
3
|
-
async function searchInParentDirectories(directory, targetEntry) {
|
|
4
|
-
directory = directory === '.' ? process.cwd() : directory;
|
|
5
|
-
|
|
6
|
-
if (await pathExists(`${directory}/${targetEntry}`)) {
|
|
7
|
-
return `${directory}/${targetEntry}`;
|
|
8
|
-
} else if (directory === '') {
|
|
9
|
-
return;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
return await searchInParentDirectories(directory.slice(0, directory.lastIndexOf('/')), targetEntry);
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export default searchInParentDirectories;
|