Skip to content

Commit bc22f94

Browse files
committed
test(oracle): authenticate prepared fixture drivers
1 parent 6035f03 commit bc22f94

2 files changed

Lines changed: 84 additions & 71 deletions

File tree

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
1-
case_id fixture expected fixture_sha256 expected_sha256 mode transcript completion label
2-
r3g tests/fixtures/r3g_class_public_init.js tests/fixtures/r3g_class_public_init.quickjs-2026-06-04.txt de89a48a4363fd62d90cc17c7043a6958d5ae572bdc80b602a89a1b17e81a962 f97cf1523a3d8d7e7c818b260843544d20a741851844328337100f3e6ceea26b value r3gTranscript - class-public-init
3-
r3h tests/fixtures/r3h_class_private_fields.js tests/fixtures/r3h_class_private_fields.quickjs-2026-06-04.txt 94e030ba31b70b6688079042ef6c05251e15820c3d20774535e2f112909d5ced 39c783243c8e6abb2eb18f7b0905aeac6179d46b63d419e402a637ae788bafb0 value r3hTranscript - class-private-fields
4-
r3i tests/fixtures/r3i_class_private_methods.js tests/fixtures/r3i_class_private_methods.quickjs-2026-06-04.txt 23053aea3d41c9ee72a61007c713a17d7082dd418c9b06433a03800173b77567 7e87481d5b8a4202554d7c50264bb8063547512468f8c2df22bf05d06965e452 value r3iTranscript - class-private-methods
5-
r3j tests/fixtures/r3j_class_private_accessors.js tests/fixtures/r3j_class_private_accessors.quickjs-2026-06-04.txt 0ee124bbd77f45ae9cd81bc6203cedd03e03b5e78640460abc9670ca77ffca12 c2656658102e7bfd9ee8da51848e18519afccb9a9ec02cc094d27cb6646d834a value r3jTranscript - class-private-accessors
6-
r3l tests/fixtures/r3l_class_private_generators.js tests/fixtures/r3l_class_private_generators.quickjs-2026-06-04.txt 5af87d8181536da15ba5458ab97698e40d5df953955751bb74656a95a5dd382f ff79f3ed6798a77b04e1baec6a6e022a46538f0e463707298cee894487c1a2dc value r3lTranscript - class-private-generators
7-
r3m tests/fixtures/r3m_promise_jobs.js tests/fixtures/r3m_promise_jobs.quickjs-2026-06-04.txt 3a9bbd74e97aeae96883a47c801fb5256b8e0625879c0be74aa386642fa1c0b2 2251b9a554d3645bad15916617cf420ddd054e4117e9fcd7bf6ee692d5ac9e2d promise r3mTranscript r3mDone promise-jobs
8-
r3n tests/fixtures/r3n_promise_static.js tests/fixtures/r3n_promise_static.quickjs-2026-06-04.txt 2bc2a52869d42f314614905f4ac750b87064d6e44cbcfdcb20b3703522bdd0b2 0da636dbcf08f6d6ec112b439a54ec3d6b0816fff34f1381516a5cad3789f16d promise r3nTranscript r3nDone promise-static
9-
r3o tests/fixtures/r3o_promise_finally.js tests/fixtures/r3o_promise_finally.quickjs-2026-06-04.txt 720b53338045bd65c70337c3d43678b52e8c7d3e0ce0b0ef1210f512b7d7a53a 9b30fc689ebac8bb116d18a87460fb9bd987f5c7b40dfabe508f787c249c10fe promise r3oTranscript r3oDone promise-finally
10-
r3p tests/fixtures/r3p_promise_all.js tests/fixtures/r3p_promise_all.quickjs-2026-06-04.txt e43406b9de7de5a88034ec5321486d7b352f2c6f43986fddba1b36fe79074835 efb2fd9cfdd1db42291295e0b313dbf271b0007d30f3823e0377cb7196ab6b54 promise r3pTranscript r3pDone promise-all
11-
r3q tests/fixtures/r3q_promise_aggregates.js tests/fixtures/r3q_promise_aggregates.quickjs-2026-06-04.txt e053bb7944943607b9a29ef15fd34d44a58c44792afaf5193e6b757f4231d8c4 992d7e26fa681747b67c49a6cfd296c22ae54a558f1d8a86d70ce9eeea3a71e9 promise r3qTranscript r3qDone promise-aggregates
12-
r3r tests/fixtures/r3r_generator_destructuring_return.js tests/fixtures/r3r_generator_destructuring_return.quickjs-2026-06-04.txt 05d8e677e984df2a9accb0c56ddb6f2e06ba6d3b2d2d08a51d4ba48811463398 4e39206df0f8213845227839ad1986759f12566e570a4820265a40e239add715 value r3rTranscript - generator-destructuring-return
13-
r3s tests/fixtures/r3s_regexp_escape_control.js tests/fixtures/r3s_regexp_escape_control.quickjs-2026-06-04.txt babb9f0e94a7f4e3cf62ad25faf923dc86adb9248db36f081b4b2e7667c6f784 c6226637ca00cfcef2c436cb64442d8264ba18553aba31baffe70a34d48f480f value r3sTranscript - regexp-escape-control
14-
r3z tests/fixtures/r3z_async_function_core.js tests/fixtures/r3z_async_function_core.quickjs-2026-06-04.txt 8cf63d6278315bac4c02b47283c6cc603651d862350b07be88e353a15be52e4a f2f6240e23f9feedc9c1561959fb488755077e84ef623c0d715cccd8595fa14a direct - - async-function-core
1+
case_id fixture expected fixture_sha256 expected_sha256 mode transcript completion prepared_sha256 label
2+
r3g tests/fixtures/r3g_class_public_init.js tests/fixtures/r3g_class_public_init.quickjs-2026-06-04.txt de89a48a4363fd62d90cc17c7043a6958d5ae572bdc80b602a89a1b17e81a962 f97cf1523a3d8d7e7c818b260843544d20a741851844328337100f3e6ceea26b value r3gTranscript - c0f83745382ba2abd354ce4d94354b2d877c651e17df856d98952c2a4d02979c class-public-init
3+
r3h tests/fixtures/r3h_class_private_fields.js tests/fixtures/r3h_class_private_fields.quickjs-2026-06-04.txt 94e030ba31b70b6688079042ef6c05251e15820c3d20774535e2f112909d5ced 39c783243c8e6abb2eb18f7b0905aeac6179d46b63d419e402a637ae788bafb0 value r3hTranscript - eeb24046312cb29960bb2a3391dc1b7048dfea416501c4312de3794d430b5f8c class-private-fields
4+
r3i tests/fixtures/r3i_class_private_methods.js tests/fixtures/r3i_class_private_methods.quickjs-2026-06-04.txt 23053aea3d41c9ee72a61007c713a17d7082dd418c9b06433a03800173b77567 7e87481d5b8a4202554d7c50264bb8063547512468f8c2df22bf05d06965e452 value r3iTranscript - 2f3083eb9b80f99b2f31e0557f6aafb14be50d787bdbd2bb5fcb0c8f4c95ac70 class-private-methods
5+
r3j tests/fixtures/r3j_class_private_accessors.js tests/fixtures/r3j_class_private_accessors.quickjs-2026-06-04.txt 0ee124bbd77f45ae9cd81bc6203cedd03e03b5e78640460abc9670ca77ffca12 c2656658102e7bfd9ee8da51848e18519afccb9a9ec02cc094d27cb6646d834a value r3jTranscript - 5a8e38b9ae722b98a78f1762a8d679d989a4947131ca8548d9d4e8ef12f6b3b5 class-private-accessors
6+
r3l tests/fixtures/r3l_class_private_generators.js tests/fixtures/r3l_class_private_generators.quickjs-2026-06-04.txt 5af87d8181536da15ba5458ab97698e40d5df953955751bb74656a95a5dd382f ff79f3ed6798a77b04e1baec6a6e022a46538f0e463707298cee894487c1a2dc value r3lTranscript - ba2e764158730667ca14158ce35a8d4303228345c9536a84b89d335dcfa2ff9d class-private-generators
7+
r3m tests/fixtures/r3m_promise_jobs.js tests/fixtures/r3m_promise_jobs.quickjs-2026-06-04.txt 3a9bbd74e97aeae96883a47c801fb5256b8e0625879c0be74aa386642fa1c0b2 2251b9a554d3645bad15916617cf420ddd054e4117e9fcd7bf6ee692d5ac9e2d promise r3mTranscript r3mDone c8542f44162bd1b9576d796c9c3799ecffba7b82e5a1a31354e10ccc120bb89b promise-jobs
8+
r3n tests/fixtures/r3n_promise_static.js tests/fixtures/r3n_promise_static.quickjs-2026-06-04.txt 2bc2a52869d42f314614905f4ac750b87064d6e44cbcfdcb20b3703522bdd0b2 0da636dbcf08f6d6ec112b439a54ec3d6b0816fff34f1381516a5cad3789f16d promise r3nTranscript r3nDone a90871958e7eae4b1650e2d5765f985e21010f99f94eb9d6be5924b14c116aff promise-static
9+
r3o tests/fixtures/r3o_promise_finally.js tests/fixtures/r3o_promise_finally.quickjs-2026-06-04.txt 720b53338045bd65c70337c3d43678b52e8c7d3e0ce0b0ef1210f512b7d7a53a 9b30fc689ebac8bb116d18a87460fb9bd987f5c7b40dfabe508f787c249c10fe promise r3oTranscript r3oDone 9e0780374aaa172451b5b93c285c45ff3667bddb0fb620485e47b3a7d6f847e8 promise-finally
10+
r3p tests/fixtures/r3p_promise_all.js tests/fixtures/r3p_promise_all.quickjs-2026-06-04.txt e43406b9de7de5a88034ec5321486d7b352f2c6f43986fddba1b36fe79074835 efb2fd9cfdd1db42291295e0b313dbf271b0007d30f3823e0377cb7196ab6b54 promise r3pTranscript r3pDone e2d3158d0bcfedabc8363ed56a273569cbfc73c62fdf080f7fb42e251f4a1b80 promise-all
11+
r3q tests/fixtures/r3q_promise_aggregates.js tests/fixtures/r3q_promise_aggregates.quickjs-2026-06-04.txt e053bb7944943607b9a29ef15fd34d44a58c44792afaf5193e6b757f4231d8c4 992d7e26fa681747b67c49a6cfd296c22ae54a558f1d8a86d70ce9eeea3a71e9 promise r3qTranscript r3qDone ca05b5067e1c97df65fa3d428a3b0bff15aaeade7b5ccfd337a59db1ae878f7a promise-aggregates
12+
r3r tests/fixtures/r3r_generator_destructuring_return.js tests/fixtures/r3r_generator_destructuring_return.quickjs-2026-06-04.txt 05d8e677e984df2a9accb0c56ddb6f2e06ba6d3b2d2d08a51d4ba48811463398 4e39206df0f8213845227839ad1986759f12566e570a4820265a40e239add715 value r3rTranscript - 81cf8c1a45113d08d94773234e8ef7ac6b6b743346b02d0a0c89daa51de7b3e9 generator-destructuring-return
13+
r3s tests/fixtures/r3s_regexp_escape_control.js tests/fixtures/r3s_regexp_escape_control.quickjs-2026-06-04.txt babb9f0e94a7f4e3cf62ad25faf923dc86adb9248db36f081b4b2e7667c6f784 c6226637ca00cfcef2c436cb64442d8264ba18553aba31baffe70a34d48f480f value r3sTranscript - 079745fd23a22f593e651686d68f520427b4e2a331eb974c5d26482242ccbf83 regexp-escape-control
14+
r3z tests/fixtures/r3z_async_function_core.js tests/fixtures/r3z_async_function_core.quickjs-2026-06-04.txt 8cf63d6278315bac4c02b47283c6cc603651d862350b07be88e353a15be52e4a f2f6240e23f9feedc9c1561959fb488755077e84ef623c0d715cccd8595fa14a direct - - 8cf63d6278315bac4c02b47283c6cc603651d862350b07be88e353a15be52e4a async-function-core

scripts/test-quickjs-fixtures.sh

Lines changed: 70 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -107,17 +107,19 @@ tmp_dir=$(mktemp -d "${TMPDIR:-/tmp}/quickjs-oxide-fixture-gates.XXXXXX")
107107
trap 'rm -rf -- "$tmp_dir"' EXIT HUP INT TERM
108108
rows=$tmp_dir/rows.tsv
109109

110-
expected_header=$'case_id\tfixture\texpected\tfixture_sha256\texpected_sha256\tmode\ttranscript\tcompletion\tlabel'
110+
expected_header=$'case_id\tfixture\texpected\tfixture_sha256\texpected_sha256\tmode\ttranscript\tcompletion\tprepared_sha256\tlabel'
111111
header=$(sed -n '1p' "$registry")
112112
[[ "$header" == "$expected_header" ]] || die "unsupported fixture registry schema"
113+
[[ "$(tail -c 1 "$registry" | wc -l | tr -d '[:space:]')" == 1 ]] \
114+
|| die "fixture registry must end with a newline"
113115

114116
tail -n +2 "$registry" | while IFS= read -r line; do
115117
[[ -n "$line" ]] || die "fixture registry contains a blank row"
116118
[[ "$line" != *$'\r'* && "$line" != *$'\t' ]] \
117119
|| die "fixture registry contains non-canonical whitespace"
118120
field_count=$(awk -F '\t' '{ print NF }' <<<"$line")
119-
[[ "$field_count" == 9 ]] || die "fixture registry row must have 9 columns"
120-
IFS=$'\t' read -r id fixture expected fixture_sha expected_sha mode transcript completion label <<<"$line"
121+
[[ "$field_count" == 10 ]] || die "fixture registry row must have 10 columns"
122+
IFS=$'\t' read -r id fixture expected fixture_sha expected_sha mode transcript completion prepared_sha label <<<"$line"
121123
[[ "$id" =~ ^r3[a-z0-9]+$ ]] || die "invalid fixture case id: $id"
122124
[[ "$fixture" =~ ^tests/fixtures/[a-z0-9_]+\.js$ ]] \
123125
|| die "invalid fixture path for $id: $fixture"
@@ -130,6 +132,7 @@ tail -n +2 "$registry" | while IFS= read -r line; do
130132
|| die "expected transcript does not match fixture: $id"
131133
[[ "$fixture_sha" =~ ^[0-9a-f]{64}$ ]] || die "invalid fixture hash for $id"
132134
[[ "$expected_sha" =~ ^[0-9a-f]{64}$ ]] || die "invalid expected hash for $id"
135+
[[ "$prepared_sha" =~ ^[0-9a-f]{64}$ ]] || die "invalid prepared hash for $id"
133136
[[ "$label" =~ ^[a-z0-9]+(-[a-z0-9]+)*$ ]] || die "invalid label for $id"
134137
case $mode in
135138
value)
@@ -145,6 +148,8 @@ tail -n +2 "$registry" | while IFS= read -r line; do
145148
direct)
146149
[[ "$transcript" == - && "$completion" == - ]] \
147150
|| die "invalid direct-mode fields for $id"
151+
[[ "$prepared_sha" == "$fixture_sha" ]] \
152+
|| die "direct fixture prepared hash must equal its source hash: $id"
148153
;;
149154
*) die "invalid fixture mode for $id: $mode" ;;
150155
esac
@@ -155,9 +160,9 @@ tail -n +2 "$registry" | while IFS= read -r line; do
155160
[[ "$last_line" == "$completion;" ]] \
156161
|| die "promise fixture does not end with $completion;: $id"
157162
fi
158-
printf '%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n' \
163+
printf '%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n' \
159164
"$id" "$fixture" "$expected" "$fixture_sha" "$expected_sha" \
160-
"$mode" "$transcript" "$completion" "$label"
165+
"$mode" "$transcript" "$completion" "$prepared_sha" "$label"
161166
done >"$rows"
162167

163168
[[ -s "$rows" ]] || die "fixture registry has no cases"
@@ -169,11 +174,6 @@ sort -c -t $'\t' -k1,1 "$rows" \
169174
|| die "fixture registry cases must be sorted by id"
170175
case_count=$(wc -l <"$rows" | tr -d '[:space:]')
171176

172-
if $validate_only; then
173-
echo "QuickJS fixture registry passed: $case_count authenticated cases."
174-
exit 0
175-
fi
176-
177177
if [[ "$selection" == case ]] && ! awk -F '\t' -v id="$case_id" '$1 == id { found=1 } END { exit !found }' "$rows"; then
178178
die "unknown fixture case: $case_id"
179179
fi
@@ -182,6 +182,54 @@ if [[ "$selection" == case ]]; then
182182
selected_count=1
183183
fi
184184

185+
prepare_case() {
186+
local row=$1
187+
local fixture_sha expected_sha
188+
IFS=$'\t' read -r fixture_case_id fixture_relative expected_relative \
189+
fixture_sha expected_sha fixture_mode fixture_transcript \
190+
fixture_completion fixture_prepared_sha fixture_label <<<"$row"
191+
fixture_path=$root/$fixture_relative
192+
expected_path=$root/$expected_relative
193+
engine_fixture=$fixture_path
194+
195+
case $fixture_mode in
196+
value)
197+
engine_fixture=$tmp_dir/$fixture_case_id.js
198+
{
199+
cat "$fixture_path"
200+
printf '\nprint(%s.join("\\n"));\n' "$fixture_transcript"
201+
} >"$engine_fixture"
202+
quickjs_args=(--script "$engine_fixture")
203+
oxide_args=(--print-result "$fixture_path")
204+
;;
205+
promise)
206+
engine_fixture=$tmp_dir/$fixture_case_id.js
207+
{
208+
sed '$d' "$fixture_path"
209+
printf '\n%s.then(\n' "$fixture_completion"
210+
printf ' function () { print(%s.join("\\n")); },\n' "$fixture_transcript"
211+
printf ' function (error) { throw error; }\n'
212+
printf ');\n'
213+
} >"$engine_fixture"
214+
quickjs_args=(--std --script "$engine_fixture")
215+
oxide_args=("$engine_fixture")
216+
;;
217+
direct)
218+
quickjs_args=(--std --script "$fixture_path")
219+
oxide_args=("$fixture_path")
220+
;;
221+
esac
222+
verify_hash "$engine_fixture" "$fixture_prepared_sha"
223+
}
224+
225+
if $validate_only; then
226+
while IFS= read -r row; do
227+
prepare_case "$row"
228+
done <"$rows"
229+
echo "QuickJS fixture registry passed: $case_count authenticated cases and drivers."
230+
exit 0
231+
fi
232+
185233
oracle=$("$script_dir/build-quickjs-oracle.sh")
186234
[[ -x "$oracle" ]] || die "pinned QuickJS oracle is not executable: $oracle"
187235
if [[ -n "$oxide" && ! -x "$oxide" ]]; then
@@ -220,63 +268,28 @@ compare_transcript() {
220268

221269
run_case() {
222270
local row=$1
223-
local id fixture expected fixture_sha expected_sha mode transcript completion label
224-
local fixture_path expected_path engine_fixture
225271
local quickjs_out quickjs_err oxide_out oxide_err
226-
local -a quickjs_args oxide_args
227-
IFS=$'\t' read -r id fixture expected fixture_sha expected_sha mode transcript completion label <<<"$row"
228-
fixture_path=$root/$fixture
229-
expected_path=$root/$expected
230-
engine_fixture=$fixture_path
231-
232-
case $mode in
233-
value)
234-
engine_fixture=$tmp_dir/$id.js
235-
{
236-
cat "$fixture_path"
237-
printf '\nprint(%s.join("\\n"));\n' "$transcript"
238-
} >"$engine_fixture"
239-
quickjs_args=(--script "$engine_fixture")
240-
oxide_args=(--print-result "$fixture_path")
241-
;;
242-
promise)
243-
engine_fixture=$tmp_dir/$id.js
244-
{
245-
sed '$d' "$fixture_path"
246-
printf '\n%s.then(\n' "$completion"
247-
printf ' function () { print(%s.join("\\n")); },\n' "$transcript"
248-
printf ' function (error) { throw error; }\n'
249-
printf ');\n'
250-
} >"$engine_fixture"
251-
quickjs_args=(--std --script "$engine_fixture")
252-
oxide_args=("$engine_fixture")
253-
;;
254-
direct)
255-
quickjs_args=(--std --script "$fixture_path")
256-
oxide_args=("$fixture_path")
257-
;;
258-
esac
259-
260-
quickjs_out=$tmp_dir/$id.quickjs.out
261-
quickjs_err=$tmp_dir/$id.quickjs.err
262-
run_engine "pinned QuickJS 2026-06-04 ($id)" "$oracle" \
272+
prepare_case "$row"
273+
quickjs_out=$tmp_dir/$fixture_case_id.quickjs.out
274+
quickjs_err=$tmp_dir/$fixture_case_id.quickjs.err
275+
run_engine "pinned QuickJS 2026-06-04 ($fixture_case_id)" "$oracle" \
263276
"$quickjs_out" "$quickjs_err" "${quickjs_args[@]}"
264-
compare_transcript "pinned QuickJS 2026-06-04 ($id)" "$expected_path" "$quickjs_out"
277+
compare_transcript "pinned QuickJS 2026-06-04 ($fixture_case_id)" "$expected_path" "$quickjs_out"
265278

266279
if [[ -n "$oxide" ]]; then
267-
oxide_out=$tmp_dir/$id.oxide.out
268-
oxide_err=$tmp_dir/$id.oxide.err
269-
run_engine "quickjs-oxide ($id)" "$oxide" \
280+
oxide_out=$tmp_dir/$fixture_case_id.oxide.out
281+
oxide_err=$tmp_dir/$fixture_case_id.oxide.err
282+
run_engine "quickjs-oxide ($fixture_case_id)" "$oxide" \
270283
"$oxide_out" "$oxide_err" "${oxide_args[@]}"
271-
compare_transcript "quickjs-oxide ($id)" "$expected_path" "$oxide_out"
284+
compare_transcript "quickjs-oxide ($fixture_case_id)" "$expected_path" "$oxide_out"
272285
if ! cmp -s -- "$quickjs_out" "$oxide_out"; then
273-
echo "error: quickjs-oxide differs from pinned QuickJS 2026-06-04 ($id)" >&2
286+
echo "error: quickjs-oxide differs from pinned QuickJS 2026-06-04 ($fixture_case_id)" >&2
274287
diff -u -- "$quickjs_out" "$oxide_out" >&2 || true
275288
exit 1
276289
fi
277-
echo "$id $label differential passed"
290+
echo "$fixture_case_id $fixture_label differential passed"
278291
else
279-
echo "$id $label oracle passed"
292+
echo "$fixture_case_id $fixture_label oracle passed"
280293
fi
281294
}
282295

0 commit comments

Comments
 (0)