@exodus/test 1.0.0-rc.108 → 1.0.0-rc.109
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 +4 -2
- package/bin/find-binary.js +4 -0
- package/bin/index.js +13 -5
- package/package.json +6 -5
- package/src/benchmark.js +3 -2
- package/src/engine.pure.snapshot.cjs +1 -1
package/README.md
CHANGED
|
@@ -12,7 +12,7 @@ It can run your existing tests on [all runtimes and also browsers](#engines), wi
|
|
|
12
12
|
and typestrip (via `--typescript`) modes
|
|
13
13
|
- Runs on Node.js [node:test](https://nodejs.org/api/test.html), Bun, Deno, Electron,
|
|
14
14
|
[v8 CLI](https://v8.dev/docs/d8), JSC, [Hermes](https://hermesengine.dev), [SpiderMonkey](https://spidermonkey.dev/),
|
|
15
|
-
Chrome, Firefox, WebKit, Brave, Microsoft Edge,
|
|
15
|
+
Chrome, Firefox, WebKit, Brave, Microsoft Edge, [Servo](https://servo.org/),
|
|
16
16
|
[QuickJS](https://github.com/quickjs-ng/quickjs), [XS](https://github.com/Moddable-OpenSource/moddable-xst),
|
|
17
17
|
[GraalJS](https://github.com/oracle/graaljs), [Escargot](https://github.com/Samsung/escargot),
|
|
18
18
|
[Boa](https://github.com/boa-dev/boa), and even [engine262](https://github.com/engine262/engine262).
|
|
@@ -66,6 +66,8 @@ Use `--engine` (or `EXODUS_TEST_ENGINE=`) to specify one of:
|
|
|
66
66
|
- `firefox:puppeteer` — Firefox
|
|
67
67
|
- `brave:puppeteer` — Brave
|
|
68
68
|
- `msedge:puppeteer` — Microsoft Edge
|
|
69
|
+
- Bundle
|
|
70
|
+
- `servo:bundle` — Servo (expects it to be installed in the system or in PATH)
|
|
69
71
|
- Barebone engines (system-provided or installed with `npx jsvu` / `npx esvu`):
|
|
70
72
|
- `v8:bundle` — [v8 CLI](https://v8.dev/docs/d8) (Chrome/Blink/Node.js JavaScript engine)
|
|
71
73
|
- `jsc:bundle` — [JavaScriptCore](https://docs.webkit.org/Deep%20Dive/JSC/JavaScriptCore.html) (Safari/WebKit JavaScript engine)
|
|
@@ -128,7 +130,7 @@ Use `--engine` (or `EXODUS_TEST_ENGINE=`) to specify one of:
|
|
|
128
130
|
</pre>
|
|
129
131
|
</details>
|
|
130
132
|
|
|
131
|
-
See live output in [CI](https://github.com/
|
|
133
|
+
See live output in [CI](https://github.com/ExodusOSS/test/actions/workflows/checks.yaml)
|
|
132
134
|
|
|
133
135
|
## Library
|
|
134
136
|
|
package/bin/find-binary.js
CHANGED
|
@@ -91,6 +91,10 @@ function findBinaryOnce(name) {
|
|
|
91
91
|
case 'safari':
|
|
92
92
|
addPaths('darwin', '/Applications/Safari.app/Contents/MacOS/Safari')
|
|
93
93
|
break
|
|
94
|
+
case 'servo':
|
|
95
|
+
addPaths('darwin', '/Applications/Servo.app/Contents/MacOS/servo')
|
|
96
|
+
addPaths('linux', '/usr/bin/servo')
|
|
97
|
+
break
|
|
94
98
|
default:
|
|
95
99
|
throw new Error('Trying to find an unexpected executable name')
|
|
96
100
|
}
|
package/bin/index.js
CHANGED
|
@@ -7,7 +7,7 @@ import { fileURLToPath } from 'node:url'
|
|
|
7
7
|
import { basename, join } from 'node:path'
|
|
8
8
|
import { randomUUID } from 'node:crypto'
|
|
9
9
|
import { existsSync, rmSync, realpathSync } from 'node:fs'
|
|
10
|
-
import { unlink } from 'node:fs/promises'
|
|
10
|
+
import { writeFile, unlink } from 'node:fs/promises'
|
|
11
11
|
import { tmpdir, availableParallelism, homedir } from 'node:os'
|
|
12
12
|
import assert from 'node:assert/strict'
|
|
13
13
|
// The following make sense only when we run the code in the same Node.js version, i.e. engineOptions.haveIsOk
|
|
@@ -52,6 +52,8 @@ const ENGINES = new Map(
|
|
|
52
52
|
'escargot:bundle': { binary: 'escargot', ...bareboneOpts },
|
|
53
53
|
'boa:bundle': { binary: 'boa', binaryArgs: ['-m'], ...bareboneOpts },
|
|
54
54
|
'jerryscript:bundle': { binary: 'jerryscript', ...bareboneOpts },
|
|
55
|
+
// Special case: running a browser from CLI like a bundle
|
|
56
|
+
'servo:bundle': { binary: 'servo', binaryArgs: ['--headless'], ...bundleOpts, html: true },
|
|
55
57
|
// Browser engines
|
|
56
58
|
'chrome:puppeteer': { binary: 'chrome', browsers: 'puppeteer', ...bundleOpts },
|
|
57
59
|
'firefox:puppeteer': { binary: 'firefox', browsers: 'puppeteer', ...bundleOpts },
|
|
@@ -65,7 +67,7 @@ const ENGINES = new Map(
|
|
|
65
67
|
})
|
|
66
68
|
)
|
|
67
69
|
const barebonesOk = ['v8', 'd8', 'spidermonkey', 'quickjs', 'xs', 'hermes', 'shermes']
|
|
68
|
-
const barebonesUnhandled = ['jsc', 'escargot', 'boa', 'graaljs', 'jerry', 'engine262']
|
|
70
|
+
const barebonesUnhandled = ['jsc', 'escargot', 'boa', 'graaljs', 'jerry', 'engine262', 'servo']
|
|
69
71
|
|
|
70
72
|
const getEnvFlag = (name) => {
|
|
71
73
|
if (!Object.hasOwn(process.env, name)) return
|
|
@@ -282,7 +284,7 @@ const engineOptions = ENGINES.get(options.engine)
|
|
|
282
284
|
assert(engineOptions, `Unknown engine: ${options.engine}`)
|
|
283
285
|
Object.assign(options, engineOptions)
|
|
284
286
|
options.platform = options.binary // binary can be overriden by c8 or electron
|
|
285
|
-
const isBrowserLike = options.browsers || options.electron
|
|
287
|
+
const isBrowserLike = options.browsers || options.electron || options.html
|
|
286
288
|
setEnv('EXODUS_TEST_ENGINE', options.engine) // e.g. 'hermes:bundle', 'node:bundle', 'node:test', 'node:pure'
|
|
287
289
|
setEnv('EXODUS_TEST_PLATFORM', options.binary === 'shermes' ? 'hermes' : options.binary) // e.g. 'hermes', 'node'
|
|
288
290
|
setEnv('EXODUS_TEST_TIMEOUT', options.testTimeout)
|
|
@@ -595,7 +597,7 @@ if (options.binary === 'electron') {
|
|
|
595
597
|
}
|
|
596
598
|
}
|
|
597
599
|
|
|
598
|
-
if (options.barebone || ['electron', 'workerd'].includes(options.binary)) {
|
|
600
|
+
if (options.barebone || ['electron', 'workerd', 'servo'].includes(options.binary)) {
|
|
599
601
|
options.binary = findBinary(options.binary)
|
|
600
602
|
options.binaryCanBeAbsolute = true
|
|
601
603
|
}
|
|
@@ -689,9 +691,14 @@ if (options.pure) {
|
|
|
689
691
|
const runOne = async (inputFile) => {
|
|
690
692
|
const bundled = buildFile ? await buildFile(inputFile) : undefined
|
|
691
693
|
if (buildFile) assert(bundled.file)
|
|
692
|
-
const file = buildFile ? bundled.file : inputFile
|
|
693
694
|
if (bundled?.errors.length > 0) return { ok: false, output: bundled.errors }
|
|
695
|
+
if (bundled && options.html) {
|
|
696
|
+
bundled.fileHtml = `${bundled.file}.html`
|
|
697
|
+
assert(/^[a-z0-9/_.-]+\.js$/iu.test(bundled.file), bundled.file)
|
|
698
|
+
await writeFile(bundled.fileHtml, `<script src="${bundled.file}"></script>`)
|
|
699
|
+
}
|
|
694
700
|
|
|
701
|
+
const file = buildFile ? bundled.fileHtml ?? bundled.file : inputFile
|
|
695
702
|
const failedBare = 'EXODUS_TEST_FAILED_EXIT_CODE_1'
|
|
696
703
|
const cleanOut = (out) => out.replaceAll(`\n${failedBare}\n`, '\n').replaceAll(failedBare, '')
|
|
697
704
|
// Timeout is fallback if timeout in script hangs, 50x as it can be adjusted per-script inside them
|
|
@@ -721,6 +728,7 @@ if (options.pure) {
|
|
|
721
728
|
throw err // Internal test runner error, e.g. launch() failed
|
|
722
729
|
} finally {
|
|
723
730
|
if (bundled) await unlink(bundled.file)
|
|
731
|
+
if (bundled?.fileHtml) await unlink(bundled.fileHtml)
|
|
724
732
|
}
|
|
725
733
|
}
|
|
726
734
|
|
package/package.json
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@exodus/test",
|
|
3
|
-
"version": "1.0.0-rc.
|
|
3
|
+
"version": "1.0.0-rc.109",
|
|
4
4
|
"author": "Exodus Movement, Inc.",
|
|
5
5
|
"description": "A test suite runner",
|
|
6
|
-
"homepage": "https://github.com/
|
|
6
|
+
"homepage": "https://github.com/ExodusOSS/test",
|
|
7
7
|
"repository": {
|
|
8
8
|
"type": "git",
|
|
9
|
-
"url": "https://github.com/
|
|
9
|
+
"url": "https://github.com/ExodusOSS/test.git"
|
|
10
10
|
},
|
|
11
11
|
"bugs": {
|
|
12
|
-
"url": "https://github.com/
|
|
12
|
+
"url": "https://github.com/ExodusOSS/tests/issues"
|
|
13
13
|
},
|
|
14
14
|
"keywords": [
|
|
15
15
|
"test",
|
|
@@ -124,6 +124,7 @@
|
|
|
124
124
|
"test:hermes": "EXODUS_TEST_ENGINE=hermes:bundle npm run test:_bundle --",
|
|
125
125
|
"test:shermes": "EXODUS_TEST_ENGINE=shermes:bundle npm run test:_bundle --",
|
|
126
126
|
"test:spidermonkey": "EXODUS_TEST_ENGINE=spidermonkey:bundle npm run test:_bundle --",
|
|
127
|
+
"test:servo": "EXODUS_TEST_ENGINE=servo:bundle npm run test:_bundle --",
|
|
127
128
|
"test:engine262": "EXODUS_TEST_ENGINE=engine262:bundle npm run test:_bundle --",
|
|
128
129
|
"test:quickjs": "EXODUS_TEST_ENGINE=quickjs:bundle npm run test:_bundle --",
|
|
129
130
|
"test:xs": "EXODUS_TEST_ENGINE=xs:bundle npm run test:_bundle --",
|
|
@@ -144,7 +145,7 @@
|
|
|
144
145
|
"optionalDependencies": {
|
|
145
146
|
"@chalker/queue": "^1.0.1",
|
|
146
147
|
"@exodus/replay": "^1.0.0-rc.9",
|
|
147
|
-
"@exodus/test-bundler": "1.0.0-rc.
|
|
148
|
+
"@exodus/test-bundler": "1.0.0-rc.10",
|
|
148
149
|
"c8": "^9.1.0",
|
|
149
150
|
"expect": "^30.2.0",
|
|
150
151
|
"fast-glob": "^3.2.11",
|
package/src/benchmark.js
CHANGED
|
@@ -37,6 +37,7 @@ export async function benchmark(name, options, fn) {
|
|
|
37
37
|
let min, max
|
|
38
38
|
let total = 0n
|
|
39
39
|
let count = 0
|
|
40
|
+
const endAt = getTime() + BigInt(timeout) * 10n ** 6n
|
|
40
41
|
while (true) {
|
|
41
42
|
const arg = args ? args[count % args.length] : count
|
|
42
43
|
count++
|
|
@@ -48,11 +49,11 @@ export async function benchmark(name, options, fn) {
|
|
|
48
49
|
total += diff
|
|
49
50
|
if (min === undefined || min > diff) min = diff
|
|
50
51
|
if (max === undefined || max < diff) max = diff
|
|
51
|
-
if (
|
|
52
|
+
if (stop >= endAt) break
|
|
52
53
|
}
|
|
53
54
|
|
|
54
55
|
const mean = total / BigInt(count)
|
|
55
|
-
const rps = 1e9 / Number(mean
|
|
56
|
+
const rps = (1e9 * count) / Number(total) // Loss in precision to doubles on very fast ops, but this is better than mean rounding
|
|
56
57
|
let res = `${name} x ${fRps(rps)} ops/sec @ ${fTime(mean)}/op`
|
|
57
58
|
if (fTime(min) !== fTime(max)) res += ` (${fTime(min)}..${fTime(max)})`
|
|
58
59
|
console.log(res)
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
const nameCounts = new Map()
|
|
2
2
|
let snapshotText, snapshotTextClean
|
|
3
3
|
|
|
4
|
-
const escapeSnapshot = (str) => str.replaceAll(/([\\`])/gu, '\\$1')
|
|
4
|
+
const escapeSnapshot = (str) => str.replaceAll(/([\\`]|\$\{)/gu, '\\$1')
|
|
5
5
|
|
|
6
6
|
function matchSnapshot(readSnapshot, assert, name, serialized) {
|
|
7
7
|
// We don't have native snapshots, polyfill reading
|