1// SPDX-License-Identifier: MIT
2//
3// Writes testdata/fromjson_errors.json: for the inputs of testdata/fromjson_cases.json
4// that the runner's fromJSON rejects, plus a few hand-picked ones (blank input, a
5// bad character on a later line or deep in a document), the message of the
6// JsonReaderException. TestFromJSONErrorsMatchRunner replays it.
7//
8// node expr/gen/runner/fromjson_errors.mjs > expr/testdata/fromjson_errors.json
9//
10// Needs the built driver, see README.md.
11
12import { readFileSync, writeFileSync, mkdtempSync, rmSync } from "node:fs";
13import { tmpdir } from "node:os";
14import { join } from "node:path";
15import { runDriver, here, checkEnvironment } from "./env.mjs";
16
17checkEnvironment();
18const cases = JSON.parse(readFileSync(join(here, "../../testdata/fromjson_cases.json"), "utf8"));
19const extra = [
20 "", " ", "\n", "not json", " not json", "\nnot json", "[x]", "[1,x]", '{"a":x}', "[\n x]", '{"a b":x}', '{"a.b":[1,x]}',
21 "{\"it's\":x}", '{"a":{"b":[1,2,x]}}', "[[x]]", "{", "[", "[1,2", '{"a":1', '"abc', "{'a'}", "[1 2]", '{"a":1 "b":2}',
22 "tru", '{"k":tru}', '"\\q"', "[1,\n2,\n x]", " \n x", '{"a":\n\n [1,\n x]}',
23];
24const inputs = [...new Set([...cases.filter(c => !c.ok).map(c => c.in), ...extra])];
25const lit = s => "'" + s.replaceAll("'", "''") + "'";
26const tmp = mkdtempSync(join(tmpdir(), "fje-"));
27writeFileSync(join(tmp, "in.json"), JSON.stringify({ contexts: {}, cases: inputs.map(s => ({ e: `fromJSON(${lit(s)})` })) }));
28const out = runDriver([join(tmp, "in.json")]).split("\n").filter(Boolean);
29rmSync(tmp, { recursive: true });
30if (out.length !== inputs.length) throw new Error("answer count");
31const res = [];
32inputs.forEach((s, i) => {
33 const r = JSON.parse(out[i]);
34 if (r.err && r.err.t === "eval") res.push({ in: s, msg: r.err.m });
35});
36process.stdout.write(JSON.stringify(res));