Skip to content

Commit 9f10dbd

Browse files
committed
ci,test: move more tests into the tap suite
1 parent 20557fc commit 9f10dbd

39 files changed

+296
-1499
lines changed

.github/workflows/test.yml

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -78,22 +78,13 @@ jobs:
7878
uses: actions/github-script@v6
7979
with:
8080
script: core.setFailed('dist cache hit failed')
81+
- name: Test (TAP)
82+
run: npm run tap:node
83+
if: ${{ !startsWith(steps.node.outputs.node-version, 'v12') }}
8184
- run: find test -type f -name '*.mjs' -print0 | xargs -0 sed -i -e "s/await import(/require(/g"
8285
if: ${{ startsWith(steps.node.outputs.node-version, 'v12') }}
83-
- name: Test with Node.js crypto module
86+
- name: Test (AVA)
8487
run: npm run test
85-
- name: Test with Node.js crypto module w/ CryptoKey
86-
run: npm run test-cryptokey
87-
if: ${{ !startsWith(steps.node.outputs.node-version, 'v14') && !startsWith(steps.node.outputs.node-version, 'v12') }}
88-
- name: Test with Node.js Web Cryptography API
89-
run: npm run test-webcrypto
90-
if: ${{ !startsWith(steps.node.outputs.node-version, 'v14') && !startsWith(steps.node.outputs.node-version, 'v12') }}
91-
- name: Test with Node.js Web API
92-
run: npm run test-webapi
93-
if: ${{ !startsWith(steps.node.outputs.node-version, 'v14') && !startsWith(steps.node.outputs.node-version, 'v12') }}
94-
- name: TAP Suite with both Node.js runtimes
95-
run: npm run tap:node
96-
if: ${{ !startsWith(steps.node.outputs.node-version, 'v14') && !startsWith(steps.node.outputs.node-version, 'v12') }}
9788

9889
deno:
9990
needs:

.node_flags.sh

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1-
NODE_VERSION=$(node -v)
1+
node -e 'process.exit(parseInt(process.versions.node, 10))' &> /dev/null
2+
NODE_VERSION=$?
23
export NODE_OPTIONS='--no-warnings'
34

4-
if [[ $NODE_VERSION == "v16."* ]]; then
5-
export NODE_OPTIONS+=' --experimental-global-webcrypto --experimental-fetch'
6-
elif [[ "$NODE_VERSION" == "v18."* ]]; then
5+
if [[ "$NODE_VERSION" -ge 18 ]]; then
76
export NODE_OPTIONS+=' --experimental-global-webcrypto'
7+
elif [[ $NODE_VERSION -ge 16 ]]; then
8+
export NODE_OPTIONS+=' --experimental-global-webcrypto --experimental-fetch'
89
fi

ava.cryptokey.config.cjs

Lines changed: 0 additions & 5 deletions
This file was deleted.

ava.webapi.config.cjs

Lines changed: 0 additions & 11 deletions
This file was deleted.

ava.webcrypto.config.cjs

Lines changed: 0 additions & 5 deletions
This file was deleted.

package.json

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -67,12 +67,6 @@
6767
"import": "./dist/node/esm/*.js",
6868
"require": "./dist/node/cjs/*.js"
6969
},
70-
"#dist/webcrypto/*": {
71-
"import": "./dist/node/webcrypto/*.js"
72-
},
73-
"#dist/webcrypto": {
74-
"import": "./dist/node/webcrypto/index.js"
75-
},
7670
"#dist/webapi/*": {
7771
"import": "./dist/browser/*.js"
7872
},
@@ -108,15 +102,6 @@
108102
"scripts": {
109103
"build": "tsc",
110104
"build-all": "run-s clear build:*",
111-
"build-fast-all": "run-s clear build-fast:*",
112-
"build-fast:browser": "npm run-script runtime-browser && npm run-script -s esbuild-find | xargs -0 esbuild --log-level=warning --target=es2018 --outdir=dist/browser --format=esm && echo '{\"type\": \"module\"}'> dist/browser/package.json",
113-
"build-fast:browser-bundle": "npm run-script build:browser-bundle",
114-
"build-fast:browser-bundle-min": "npm run-script build:browser-bundle-min",
115-
"build-fast:build:browser-umd": "npm run-script build:build:browser-umd",
116-
"build-fast:deno": "npm run-script build:deno",
117-
"build-fast:node-cjs": "npm run-script runtime-node && npm run-script -s esbuild-find | xargs -0 esbuild --log-level=warning --platform=node --target=node12 --outdir=dist/node/cjs --format=cjs",
118-
"build-fast:node-esm": "npm run-script runtime-node && npm run-script -s esbuild-find | xargs -0 esbuild --log-level=warning --platform=node --target=node12 --outdir=dist/node/esm --format=esm && echo '{\"type\": \"module\"}'> dist/node/esm/package.json",
119-
"build-fast:node-webcrypto": "npm run-script runtime-node-webcrypto && npm run-script -s esbuild-find | xargs -0 esbuild --log-level=warning --platform=node --target=esnext --outdir=dist/node/webcrypto --format=esm && echo '{\"type\": \"module\"}'> dist/node/webcrypto/package.json",
120105
"build:browser": "run-s runtime-browser 'build -- -p ./tsconfig/browser.json' && echo '{\"type\": \"module\"}'> dist/browser/package.json",
121106
"build:browser-bundle": "esbuild --bundle dist/browser/index.js --format=esm --target=es2018 --outfile=dist/browser/index.bundle.js",
122107
"build:browser-bundle-min": "esbuild --minify --bundle dist/browser/index.js --format=esm --target=es2018 --outfile=dist/browser/index.bundle.min.js",
@@ -125,25 +110,19 @@
125110
"build:types": "npm run-script build -- -p ./tsconfig/types.json && cd src && find . -name '*.d.ts' -maxdepth 2 -type f -exec rsync -R \"{}\" ../dist/types \\; && cd .. && run-s -s types:find | xargs -0 sed -i.bak -e \"s/\\.js'/'/g\" -e \"s/\\.d'/'/g\" && npm run-script sedcleanup",
126111
"build:node-cjs": "run-s runtime-node 'build -- -p ./tsconfig/node-cjs.json'",
127112
"build:node-esm": "run-s runtime-node 'build -- -p ./tsconfig/node-esm.json' && echo '{\"type\": \"module\"}'> dist/node/esm/package.json",
128-
"build:node-webcrypto": "run-s runtime-node-webcrypto 'build -- -p ./tsconfig/node-webcrypto.json' && echo '{\"type\": \"module\"}'> dist/node/webcrypto/package.json",
129113
"clear": "rm -Rf dist",
130114
"sedcleanup": "find . -name '*.bak' -type f -print0 | xargs -0 rm -f",
131115
"docs:generate": "typedoc",
132-
"esbuild-find": "find src -type f -name '*.ts' -not -path '*/runtime/*/*' -not -name '*.d.ts' -print0",
133116
"runtime-browser": "run-s runtime:clear runtime:browser:* runtime:refs",
134117
"runtime-deno": "npm run-script runtime-browser && mkdir -p dist/deno && cp -R src/. dist/deno && rm -R dist/deno/runtime/browser dist/deno/runtime/node",
135118
"runtime-node": "run-s runtime:clear runtime:node:* runtime:refs",
136-
"runtime-node-webcrypto": "run-s runtime:clear runtime:browser:* && cp ./src/runtime/node/webcrypto.ts ./src/runtime/ && cp ./src/runtime/node/fetch_jwks.ts ./src/runtime/ && cp ./src/runtime/node/base64url.ts ./src/runtime/ && cp ./src/runtime/node/zlib.ts ./src/runtime/ && run-s runtime:refs",
137119
"runtime:browser:copy": "cp ./src/runtime/browser/*.ts ./src/runtime",
138120
"runtime:clear": "run-s -s runtime:find | xargs -0 rm -f",
139121
"runtime:find": "find src/runtime -not -name '*.d.ts' -maxdepth 1 -type f -print0",
140122
"types:find": "find dist/types -name '*.d.ts' -type f -print0",
141123
"runtime:node:copy": "cp ./src/runtime/node/*.ts ./src/runtime",
142124
"runtime:refs": "run-s -s runtime:find | xargs -0 sed -i.bak -e \"s/'\\.\\.\\//'\\.\\//g\" -e \"s/'\\.\\/\\.\\./'../g\" && npm run-script sedcleanup",
143125
"test": "ava",
144-
"test-cryptokey": "npm test -- --config ava.cryptokey.config.cjs",
145-
"test-webapi": "npm test -- --config ava.webapi.config.cjs",
146-
"test-webcrypto": "npm test -- --config ava.webcrypto.config.cjs",
147126
"format": "prettier --loglevel silent --write ./test ./tap ./src ./tools ./cookbook",
148127
"tap:browsers": "./tap/.browsers.sh",
149128
"tap:deno": "./tap/.deno.sh",

tap/.browsers.sh

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
--log-level=warning \
44
--format=esm \
55
--bundle \
6-
--minify-syntax \
76
--target=esnext \
87
--outfile=tap/run-browser.js \
98
tap/run-browser.ts

tap/.edge-runtime.sh

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
--log-level=warning \
44
--format=esm \
55
--bundle \
6-
--minify-syntax \
76
--target=esnext \
87
--outfile=tap/run-edge-runtime.js \
98
tap/run-edge-runtime.ts

tap/.electron.sh

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,9 @@
33
--log-level=warning \
44
--format=esm \
55
--bundle \
6+
--platform=node \
67
--external:electron \
78
--external:#dist \
8-
--platform=node \
9-
--minify-syntax \
109
--target=esnext \
1110
--outfile=tap/run-electron.js \
1211
tap/run-electron.ts

tap/.node.sh

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,9 @@
33
--log-level=warning \
44
--format=esm \
55
--bundle \
6+
--platform=node \
67
--external:#dist \
78
--external:#dist/webapi \
8-
--platform=node \
9-
--minify-syntax \
109
--target=esnext \
1110
--outfile=tap/run-node.mjs \
1211
tap/run-node.ts
@@ -16,7 +15,29 @@ source .node_flags.sh
1615
node tap/run-node.mjs '#dist'
1716
NODE_CRYPTO_API=$?
1817

18+
node -e 'process.exit(parseInt(process.versions.node, 10))' &> /dev/null
19+
NODE_VERSION=$?
20+
21+
if [[ "$NODE_VERSION" -le 14 ]]; then
22+
exit $NODE_CRYPTO_API
23+
fi
24+
1925
node tap/run-node.mjs '#dist/webapi'
2026
WEB_CRYPTO_API=$?
2127

22-
test $WEB_CRYPTO_API -eq 0 && test $NODE_CRYPTO_API -eq 0
28+
node tap/run-node.mjs '#dist/hybrid'
29+
HYBRID=$?
30+
31+
echo ""
32+
echo "node:crypto"
33+
test $WEB_CRYPTO_API -eq 0 && echo " passed" || echo " failed"
34+
35+
echo ""
36+
echo "WebCryptoAPI"
37+
test $NODE_CRYPTO_API -eq 0 && echo " passed" || echo " failed"
38+
39+
echo ""
40+
echo "node:crypto with CryptoKey"
41+
test $HYBRID -eq 0 && echo " passed" || echo " failed"
42+
43+
test $WEB_CRYPTO_API -eq 0 && test $NODE_CRYPTO_API -eq 0 && test $HYBRID -eq 0

tap/.workers.sh

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
--log-level=warning \
44
--format=esm \
55
--bundle \
6-
--minify-syntax \
76
--target=esnext \
87
--outfile=tap/run-workers.js \
98
tap/run-workers.ts

tap/aes.ts

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import type QUnit from 'qunit'
22
import * as env from './env.js'
33
import type * as jose from '../src/index.js'
4+
import random from './random.js'
5+
import roundtrip from './encrypt.js'
46

57
export default (QUnit: QUnit, lib: typeof jose) => {
68
const { module, test } = QUnit
@@ -16,37 +18,51 @@ export default (QUnit: QUnit, lib: typeof jose) => {
1618
['A256CBC-HS512', true],
1719
]
1820

19-
function title(vector: Vector) {
21+
function title(vector: Vector, label = '') {
2022
const [enc, works] = vector
2123
let result = ''
2224
if (!works) {
2325
result = '[not supported] '
2426
}
2527
result += `${enc}`
28+
if (label) {
29+
result += ` ${label}`
30+
}
2631
return result
2732
}
2833

34+
function secretsFor(enc: string) {
35+
return [
36+
lib.generateSecret(enc),
37+
random(parseInt(enc.endsWith('GCM') ? enc.slice(1, 4) : enc.slice(-3)) >> 3),
38+
]
39+
}
40+
2941
for (const vector of algorithms) {
3042
const [enc, works] = vector
3143

3244
const execute = async (t: typeof QUnit.assert) => {
33-
const secret = await lib.generateSecret(enc)
34-
35-
const jwe = await new lib.FlattenedEncrypt(crypto.getRandomValues(new Uint8Array(32)))
36-
.setProtectedHeader({ alg: 'dir', enc })
37-
.setAdditionalAuthenticatedData(crypto.getRandomValues(new Uint8Array(32)))
38-
.encrypt(secret)
45+
for await (const secret of secretsFor(enc)) {
46+
await roundtrip(t, lib, 'dir', enc, secret)
47+
}
48+
}
3949

40-
await lib.flattenedDecrypt(jwe, secret)
41-
t.ok(1)
50+
const emptyClearText = async (t: typeof QUnit.assert) => {
51+
for await (const secret of secretsFor(enc)) {
52+
await roundtrip(t, lib, 'dir', enc, secret, new Uint8Array())
53+
}
4254
}
4355

4456
if (works) {
4557
test(title(vector), execute)
58+
test(title(vector, 'empty cleartext'), emptyClearText)
4659
} else {
4760
test(title(vector), async (t) => {
4861
await t.rejects(execute(t))
4962
})
63+
test(title(vector, 'empty cleartext'), async (t) => {
64+
await t.rejects(emptyClearText(t))
65+
})
5066
}
5167
}
5268
}

tap/aeskw.ts

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import type QUnit from 'qunit'
22
import * as env from './env.js'
33
import type * as jose from '../src/index.js'
4+
import random from './random.js'
5+
import roundtrip from './encrypt.js'
46

57
export default (QUnit: QUnit, lib: typeof jose) => {
68
const { module, test } = QUnit
@@ -26,19 +28,17 @@ export default (QUnit: QUnit, lib: typeof jose) => {
2628
return result
2729
}
2830

31+
function secretsFor(alg: string) {
32+
return [lib.generateSecret(alg), random(parseInt(alg.slice(1, 4), 10) >> 3)]
33+
}
34+
2935
for (const vector of algorithms) {
3036
const [alg, works] = vector
3137

3238
const execute = async (t: typeof QUnit.assert) => {
33-
const secret = await lib.generateSecret(alg)
34-
35-
const jwe = await new lib.FlattenedEncrypt(crypto.getRandomValues(new Uint8Array(32)))
36-
.setProtectedHeader({ alg, enc: 'A256GCM' })
37-
.setAdditionalAuthenticatedData(crypto.getRandomValues(new Uint8Array(32)))
38-
.encrypt(secret)
39-
40-
await lib.flattenedDecrypt(jwe, secret)
41-
t.ok(1)
39+
for await (const secret of secretsFor(alg)) {
40+
await roundtrip(t, lib, alg, 'A128GCM', secret)
41+
}
4242
}
4343

4444
if (works) {

tap/cookbook.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ export default (QUnit: QUnit, lib: typeof jose) => {
144144
if (env.isElectron && vector.electron === false) {
145145
return false
146146
}
147-
if (vector.input.zip && !env.isNodeCrypto) {
147+
if (vector.input.zip && !env.hasZlib) {
148148
return false
149149
}
150150
return true

tap/ecdh.ts

Lines changed: 13 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,38 @@
11
import type QUnit from 'qunit'
22
import * as env from './env.js'
33
import type * as jose from '../src/index.js'
4+
import roundtrip from './encrypt.js'
45

56
export default (QUnit: QUnit, lib: typeof jose) => {
67
const { module, test } = QUnit
78
module('ecdh.ts')
89

9-
type Vector = [string, jose.GenerateKeyPairOptions, boolean]
10+
type Vector = [string, boolean] | [string, boolean, jose.GenerateKeyPairOptions]
1011
const algorithms: Vector[] = [
11-
['ECDH-ES', { crv: 'P-256' }, true],
12-
['ECDH-ES', { crv: 'P-384' }, true],
13-
['ECDH-ES', { crv: 'P-521' }, !env.isDeno],
14-
['ECDH-ES', { crv: 'secp256k1' }, false],
15-
['ECDH-ES', { crv: 'X25519' }, env.isNode || env.isElectron],
16-
['ECDH-ES', { crv: 'X448' }, env.isNode],
12+
['ECDH-ES', true],
13+
['ECDH-ES', true, { crv: 'P-384' }],
14+
['ECDH-ES', !env.isDeno, { crv: 'P-521' }],
15+
['ECDH-ES', false, { crv: 'secp256k1' }],
16+
['ECDH-ES', env.isNode || env.isElectron, { crv: 'X25519' }],
17+
['ECDH-ES', env.isNode, { crv: 'X448' }],
1718
]
1819

1920
function title(vector: Vector) {
20-
const [alg, options, works] = vector
21+
const [alg, works, options] = vector
2122
let result = ''
2223
if (!works) {
2324
result = '[not supported] '
2425
}
25-
result += `${alg}`
26-
if (alg === 'ECDH-ES') {
27-
result += ` ${options.crv}`
28-
}
26+
result += `${alg} ${options?.crv || 'P-256'}`
2927
return result
3028
}
3129

3230
for (const vector of algorithms) {
33-
const [alg, options, works] = vector
31+
const [alg, works, options] = vector
3432

3533
const execute = async (t: typeof QUnit.assert) => {
36-
const { privateKey, publicKey } = await lib.generateKeyPair(alg, options)
37-
38-
const jwe = await new lib.FlattenedEncrypt(crypto.getRandomValues(new Uint8Array(32)))
39-
.setProtectedHeader({ alg, enc: 'A256GCM' })
40-
.setAdditionalAuthenticatedData(crypto.getRandomValues(new Uint8Array(32)))
41-
.encrypt(publicKey)
42-
43-
await lib.flattenedDecrypt(jwe, privateKey)
44-
t.ok(1)
34+
const kp = await lib.generateKeyPair(alg, options)
35+
await roundtrip(t, lib, alg, 'A128GCM', kp)
4536
}
4637

4738
if (works) {

0 commit comments

Comments
 (0)