qunitx 0.4.4 → 0.5.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.
@@ -1,9 +1,9 @@
1
- import fs from 'fs/promises';
1
+ import fs from 'node:fs/promises';
2
+ import { dirname } from 'node:path';
3
+ import { fileURLToPath } from 'node:url';
2
4
  import kleur from 'kleur';
3
5
  import findProjectRoot from '../utils/find-project-root.js';
4
6
  import pathExists from '../utils/path-exists.js';
5
- import { dirname } from 'path';
6
- import { fileURLToPath } from 'url';
7
7
 
8
8
  const __dirname = dirname(fileURLToPath(import.meta.url));
9
9
 
@@ -1,7 +1,7 @@
1
- import fs from 'fs/promises';
1
+ import fs from 'node:fs/promises';
2
+ import { dirname } from 'node:path';
3
+ import { fileURLToPath } from 'node:url';
2
4
  import kleur from 'kleur';
3
- import { dirname } from 'path';
4
- import { fileURLToPath } from 'url';
5
5
 
6
6
  const __dirname = dirname(fileURLToPath(import.meta.url));
7
7
  const highlight = (text) => kleur.magenta().bold(text);
@@ -1,8 +1,8 @@
1
- import fs from 'fs/promises';
2
- import path, { dirname } from 'path';
1
+ import fs from 'node:fs/promises';
2
+ import path, { dirname } from 'node:path';
3
+ import { fileURLToPath } from 'node:url';
3
4
  import findProjectRoot from '../utils/find-project-root.js';
4
5
  import pathExists from '../utils/path-exists.js';
5
- import { fileURLToPath } from 'url';
6
6
  import defaultProjectConfigValues from '../boilerplates/default-project-config-values.js';
7
7
 
8
8
  const __dirname = dirname(fileURLToPath(import.meta.url));
@@ -1,7 +1,7 @@
1
- import fs from 'fs/promises';
1
+ import fs from 'node:fs/promises';
2
+ import { dirname } from 'node:path';
3
+ import { fileURLToPath } from 'node:url';
2
4
  import kleur from 'kleur';
3
- import { dirname } from 'path';
4
- import { fileURLToPath } from 'url';
5
5
  import esbuild from 'esbuild';
6
6
  import timeCounter from '../../utils/time-counter.js';
7
7
  import runUserModule from '../../utils/run-user-module.js';
@@ -1,8 +1,7 @@
1
- import path from 'path';
2
- import fs from 'fs/promises';
1
+ import fs from 'node:fs/promises';
2
+ import { normalize, dirname } from 'node:path';
3
+ import { fileURLToPath } from 'node:url';
3
4
  import kleur from 'kleur';
4
- import { dirname } from 'path';
5
- import { fileURLToPath } from 'url';
6
5
  import runTestsInNode from './run/tests-in-node.js';
7
6
  import runTestsInBrowser from './run/tests-in-browser.js';
8
7
  import setupBrowser from '../setup/browser.js';
@@ -155,6 +154,6 @@ function normalizeInternalAssetPathFromHTML(projectRoot, assetPath, htmlPath) {
155
154
  let currentDirectory = htmlPath ? htmlPath.split('/').slice(0, -1).join('/') : projectRoot;
156
155
 
157
156
  return assetPath.startsWith('./')
158
- ? path.normalize(`${currentDirectory}/${assetPath.slice(2)}`)
159
- : path.normalize(`${currentDirectory}/${assetPath}`);
157
+ ? normalize(`${currentDirectory}/${assetPath.slice(2)}`)
158
+ : normalize(`${currentDirectory}/${assetPath}`);
160
159
  }
@@ -1,4 +1,4 @@
1
- import fs from 'fs/promises';
1
+ import fs from 'node:fs/promises';
2
2
  import kleur from 'kleur';
3
3
  import Puppeteer from 'puppeteer';
4
4
  import setupWebServer from './web-server.js';
@@ -10,9 +10,10 @@ export default async function setupBrowser(config = {
10
10
  let [server, browser] = await Promise.all([
11
11
  setupWebServer(config, cachedContent),
12
12
  Puppeteer.launch({
13
+ debugger: config.debug || false,
14
+ args: ['--no-sandbox', '--disable-gpu', '--remote-debugging-port=0', '--window-size=1440,900'],
13
15
  executablePath: process.env.CHROME_BIN || null,
14
16
  headless: 'new',
15
- args: ['--no-sandbox', '--disable-gpu', '--remote-debugging-port=0', '--window-size=1440,900']
16
17
  }),
17
18
  ]);
18
19
  let [page, ..._] = await Promise.all([
@@ -1,4 +1,4 @@
1
- import fs from 'fs/promises';
1
+ import fs from 'node:fs/promises';
2
2
  import defaultProjectConfigValues from '../boilerplates/default-project-config-values.js';
3
3
  import findProjectRoot from '../utils/find-project-root.js';
4
4
  import setupFSTree from './fs-tree.js';
@@ -1,5 +1,4 @@
1
- import kleur from 'kleur';
2
- import fs from 'fs/promises';
1
+ import fs from 'node:fs/promises';
3
2
  import picomatch from 'picomatch';
4
3
  import recursiveLookup from 'recursive-lookup';
5
4
 
@@ -1,11 +1,10 @@
1
+ import fs from 'node:fs/promises';
2
+ import path from 'node:path';
1
3
  import kleur from 'kleur';
2
- import path from 'path';
3
- import http from 'http';
4
4
  import express from 'nanoexpress';
5
- import fs from 'fs/promises';
5
+ import staticServe from '@nanoexpress/middleware-static-serve';
6
6
  import findInternalAssetsFromHTML from '../utils/find-internal-assets-from-html.js';
7
7
  import TAPDisplayTestResult from '../tap/display-test-result.js';
8
- import staticServe from '@nanoexpress/middleware-static-serve';
9
8
 
10
9
  export default async function setupWebServer(config = {
11
10
  port: 1234, debug: false, watch: false, timeout: 10000
@@ -221,14 +220,14 @@ function testRuntimeToInject(port, config) {
221
220
  });
222
221
 
223
222
  if ([1, 3].includes(window.socket.readyState)) {
224
- return window.setTimeout(() => window.QUnit.start(), 10);
223
+ return window.setTimeout(() => window.QUnit.start(), 25);
225
224
  } else {
226
225
  let connectionTrialCount = 0;
227
226
  let connectionInterval = window.setInterval(() => {
228
227
  if ([1, 3].includes(window.socket.readyState) || connectionTrialCount > 25) {
229
228
  window.clearInterval(connectionInterval);
230
229
 
231
- return window.setTimeout(() => window.QUnit.start(), 10);
230
+ return window.setTimeout(() => window.QUnit.start(), 25);
232
231
  }
233
232
 
234
233
  connectionTrialCount = connectionTrialCount + 1;
@@ -1,4 +1,4 @@
1
- import fs from 'fs/promises';
1
+ import fs from 'node:fs/promises';
2
2
 
3
3
  export default async function writeOutputStaticFiles({ projectRoot, output }, cachedContent) {
4
4
  let staticHTMLPromises = Object.keys(cachedContent.staticHTMLs).map(async (staticHTMLKey) => {
@@ -22,12 +22,12 @@ export default function(COUNTER, details) { // NOTE: https://github.com/qunitjs/
22
22
  console.log(' ---');
23
23
  console.log(indentString(yaml.dump({
24
24
  name: `Assertion #${index + 1}`, // TODO: check what happens on runtime errors
25
- actual: assertion.actual || null,
26
- expected: assertion.expected || null,
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
27
  message: assertion.message || null,
28
28
  stack: assertion.stack || null,
29
29
  at: stack ? stack[0].replace('(file://', '').replace(')', '') : null
30
- }).trim(), 4));
30
+ }), 4));
31
31
  console.log(' ...');
32
32
  }
33
33
 
@@ -39,6 +39,23 @@ export default function(COUNTER, details) { // NOTE: https://github.com/qunitjs/
39
39
  }
40
40
  }
41
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
+
42
59
  // not ok 10 test exited without ending: deepEqual true works
43
60
  // ---
44
61
  // operator: fail
@@ -3,7 +3,6 @@ let targetInputs = {};
3
3
  let inputs = [];
4
4
  let listenerAdded = false;
5
5
 
6
-
7
6
  export default function listenToKeyboardKey(inputString, closure, options = { caseSensitive: false }) {
8
7
  stdin.setRawMode(true);
9
8
  stdin.resume();
@@ -1,4 +1,4 @@
1
- import fs from 'fs/promises';
1
+ import fs from 'node:fs/promises';
2
2
 
3
3
  // { inputs: [], browser: true, debug: true, watch: true, failFast: true, htmlPaths: [], output }
4
4
  export default async function(projectRoot) {
@@ -1,4 +1,4 @@
1
- import fs from 'fs/promises';
1
+ import fs from 'node:fs/promises';
2
2
 
3
3
  export default async function pathExists(path) {
4
4
  try {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "qunitx",
3
3
  "type": "module",
4
- "version": "0.4.4",
4
+ "version": "0.5.0",
5
5
  "description": "Experimental improvements, suggestions for qunit CLI",
6
6
  "author": "Izel Nakri",
7
7
  "license": "MIT",
@@ -10,12 +10,23 @@
10
10
  "qunit-plugin"
11
11
  ],
12
12
  "engines": {
13
- "node": ">=20.1.0"
13
+ "node": ">=20.3.0"
14
14
  },
15
- "main": "index.js",
16
15
  "bin": {
17
16
  "qunitx": "cli.js"
18
17
  },
18
+ "imports": {
19
+ "qunitx": {
20
+ "node": "./shims/nodejs.js",
21
+ "deno": "./shims/deno.js",
22
+ "default": "./index.js"
23
+ }
24
+ },
25
+ "exports": {
26
+ "node": "./shims/nodejs.js",
27
+ "deno": "./shims/deno.js",
28
+ "default": "./index.js"
29
+ },
19
30
  "repository": {
20
31
  "type": "git",
21
32
  "url": "https://github.com/izelnakri/qunitx.git"
@@ -24,6 +35,9 @@
24
35
  "bin": "chmod +x cli.js && ./cli.js",
25
36
  "build": "npm run build:qunit",
26
37
  "build:qunit": "node scripts/hack-qunit.js",
38
+ "run": "npm run run:node",
39
+ "run:node": "node cli.js",
40
+ "run:deno": "deno run --allow-read deno/cli.js",
27
41
  "changelog:unreleased": "node_modules/.bin/auto-changelog --stdout --commit-limit false --package --unreleased-only --hide-credit --sort-commits date-desc",
28
42
  "changelog:preview": "node_modules/.bin/auto-changelog --stdout --commit-limit false --package -u --sort-commits date-desc",
29
43
  "changelog:update": "node_modules/.bin/auto-changelog --commit-limit false --package --sort-commits date-desc",
@@ -31,6 +45,7 @@
31
45
  "release:alpha": "node_modules/.bin/release-it --preRelease=alpha --no-git.requireUpstream",
32
46
  "release:beta": "node_modules/.bin/release-it --preRelease=beta --no-git.requireUpstream",
33
47
  "release": "node_modules/.bin/release-it",
48
+ "test:deno": "deno test --allow-read --allow-env --allow-run test/commands/index.js",
34
49
  "test": "node --test test/index.js | tee test-output.log",
35
50
  "test:old": "node_modules/.bin/mocha --require test/setup.js --bail --exit --check-leaks test/inputs test/commands test/flags/after-test.js test/flags/before-test.js -t=20000",
36
51
  "test:sanity-first": "./cli.js test/helpers/failing-tests.js test/helpers/failing-tests.ts",
@@ -60,7 +75,7 @@
60
75
  "release-it": "^15.10.3"
61
76
  },
62
77
  "volta": {
63
- "node": "20.1.0"
78
+ "node": "20.3.1"
64
79
  },
65
80
  "prettier": {
66
81
  "printWidth": 100,
@@ -0,0 +1,55 @@
1
+ import { assert, assertEquals, assertNotEquals, assertStrictEquals, assertNotStrictEquals, assertObjectMatch, assertRejects, assertThrows } from "https://deno.land/std@0.192.0/testing/asserts.ts";
2
+
3
+ class AssertionError extends Error {
4
+ override name = 'AssertionError';
5
+ constructor(message: string) {
6
+ super(message);
7
+ }
8
+ }
9
+
10
+ export default {
11
+ _steps: [],
12
+ async() {
13
+ return () => {}; // NOTE: noop, deno has sanitizeResources
14
+ },
15
+ deepEqual: assertEquals,
16
+ equal: assertEquals,
17
+ expect() {
18
+ return () => {}; // NOTE: NOT implemented
19
+ },
20
+ false(state, message) {
21
+ return assert(state === false, message);
22
+ },
23
+ notDeepEqual: assertNotEquals,
24
+ notEqual: assertNotEquals,
25
+ notOk(state, message) {
26
+ return assert(!state, message);
27
+ },
28
+ notPropContains() {
29
+ throw new AssertionError('assert.notPropContains is not implemented for deno on QUnit');
30
+ },
31
+ notPropEqual() {
32
+ throw new AssertionError('assert.notPropEqual is not implemented for deno on QUnit');
33
+ },
34
+ notStrictEqual: assertNotStrictEquals,
35
+ ok: assert,
36
+ propContains: assertObjectMatch,
37
+ pushResult() {
38
+ return () => {}; // NOTE: NOT implemented
39
+ },
40
+ rejects: assertRejects,
41
+ step(value = '') {
42
+ this._steps.push(value);
43
+ },
44
+ strictEqual: assertStrictEquals,
45
+ throws: assertThrows,
46
+ timeout() {
47
+ return true; // NOTE: NOT implemented
48
+ },
49
+ true(state, message) {
50
+ return assert(state === true, message);
51
+ },
52
+ verifySteps(steps, message = 'Verify steps failed!') {
53
+ return assertEquals(this._steps, steps, message);
54
+ }
55
+ };
package/shims/deno.js ADDED
@@ -0,0 +1,46 @@
1
+ import {
2
+ afterEach,
3
+ beforeEach,
4
+ beforeAll,
5
+ afterAll,
6
+ describe,
7
+ it,
8
+ } from "https://deno.land/std@0.192.0/testing/bdd.ts";
9
+ import assert from './deno-assert.js';
10
+
11
+ // TODO: TEST beforeEach, before, afterEach, after, currently not sure if they work!
12
+ export const module = async function(moduleName, runtimeOptions, moduleContent) {
13
+ let targetRuntimeOptions = moduleContent ? Object.assign(runtimeOptions, { name: moduleName }) : { name: moduleName };
14
+ let targetModuleContent = moduleContent ? moduleName : runtimeOptions;
15
+
16
+ return describe(assignDefaultValues(targetRuntimeOptions, { concurrency: true }), async function() {
17
+ return await targetModuleContent({ before: beforeAll, after: afterAll, beforeEach, afterEach }, {
18
+ moduleName,
19
+ options: runtimeOptions
20
+ });
21
+ });
22
+ }
23
+
24
+ export const test = async function(testName, runtimeOptions, testContent) {
25
+ let targetRuntimeOptions = testContent ? Object.assign(runtimeOptions, { name: testName }) : { name: testName };
26
+ let targetTestContent = testContent ? testContent : runtimeOptions;
27
+
28
+ return it(targetRuntimeOptions, async function() {
29
+ let metadata = { testName, options: targetRuntimeOptions, expectedTestCount: undefined };
30
+ return await targetTestContent(assert, metadata);
31
+
32
+ if (expectedTestCount) {
33
+
34
+ }
35
+ });
36
+ }
37
+
38
+ function assignDefaultValues(options, defaultValues) {
39
+ for (let key in defaultValues) {
40
+ if (options[key] === undefined) {
41
+ options[key] = defaultValues[key];
42
+ }
43
+ }
44
+
45
+ return options;
46
+ }
@@ -2,10 +2,13 @@ import assert from 'node:assert';
2
2
 
3
3
  // TODO: write test cases for these
4
4
  export default {
5
+ _steps: [],
5
6
  async: assert.async,
6
7
  deepEqual: assert.deepStrictEqual,
7
8
  equal: assert.strictEqual,
8
- expect: assert.expect,
9
+ expect() {
10
+ return () => {}; // NOTE: NOT implemented
11
+ },
9
12
  false: assert.false,
10
13
  notDeepEqual: assert.notDeepStrictEqual,
11
14
  notEqual: assert.notEqual,
@@ -19,10 +22,14 @@ export default {
19
22
  propContains: assert.propContains,
20
23
  pushResult: assert.pushResult,
21
24
  rejects: assert.rejects,
22
- step: assert.step,
25
+ step(value = '') {
26
+ this._steps.push(value);
27
+ },
23
28
  strictEqual: assert.strictEqual,
24
29
  throws: assert.throws,
25
30
  timeout: assert.timeout,
26
31
  true: assert.true,
27
- verifySteps: assert.verifySteps
32
+ verifySteps(steps, message = 'Verify steps failed!') {
33
+ return assert.deepEqual(this._steps, steps, message);
34
+ }
28
35
  };
package/shims/nodejs.js CHANGED
@@ -28,6 +28,8 @@ function assignDefaultValues(options, defaultValues) {
28
28
  options[key] = defaultValues[key];
29
29
  }
30
30
  }
31
+
32
+ return options;
31
33
  }
32
34
 
33
35
  // NOTE: later maybe expose these as well: