-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtest-ops-parser.ts
More file actions
90 lines (85 loc) · 3.11 KB
/
test-ops-parser.ts
File metadata and controls
90 lines (85 loc) · 3.11 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
import './test-env.js';
// Smoke for batch_design's operations parser. Targets the recently-fixed bug
// where embedded single quotes inside double-quoted strings were clobbered
// (e.g. `fontFamily: "system-ui, 'Segoe UI', sans-serif"`), plus regression
// coverage for the existing single-quoted-string / bare-word-value / unquoted-
// key idioms the parser already supports.
//
// Usage: npx tsx test-ops-parser.ts
import { parseAndExecute } from './src/operations.js';
import type { SceneNode } from './src/types.js';
interface Case {
name: string;
ops: string;
expect: (node: SceneNode) => boolean | string; // true | error message
}
const cases: Case[] = [
{
name: "fontFamily with embedded 'Segoe UI' (the bug)",
ops: `I("document", { type: "text", content: "x", fontFamily: "system-ui, 'Segoe UI', sans-serif" })`,
expect: (root) => {
const child = root.children?.[0];
const want = "system-ui, 'Segoe UI', sans-serif";
return child?.fontFamily === want || `got fontFamily=${JSON.stringify(child?.fontFamily)} expected ${JSON.stringify(want)}`;
},
},
{
name: 'single-quoted string value',
ops: `I("document", { type: 'frame', fill: '#FF0000' })`,
expect: (root) => {
const child = root.children?.[0];
return (child?.type === 'frame' && child?.fill === '#FF0000') || `got ${JSON.stringify(child)}`;
},
},
{
name: 'escaped single quote inside single-quoted string',
ops: `I("document", { type: "text", content: 'it\\'s working' })`,
expect: (root) => {
const child = root.children?.[0];
return child?.content === "it's working" || `got content=${JSON.stringify(child?.content)}`;
},
},
{
name: 'bare-word value still becomes string',
ops: `I("document", { type: "frame", layout: horizontal })`,
expect: (root) => {
const child = root.children?.[0];
return child?.layout === 'horizontal' || `got layout=${JSON.stringify(child?.layout)}`;
},
},
{
name: 'unquoted keys still work',
ops: `I("document", { type: "frame", width: 200, fill: "#00FF00" })`,
expect: (root) => {
const child = root.children?.[0];
return (child?.width === 200 && child?.fill === '#00FF00') || `got ${JSON.stringify(child)}`;
},
},
{
name: "double-quoted value with apostrophe (e.g. content: \"it's fine\")",
ops: `I("document", { type: "text", content: "it's fine" })`,
expect: (root) => {
const child = root.children?.[0];
return child?.content === "it's fine" || `got content=${JSON.stringify(child?.content)}`;
},
},
];
let allPass = true;
for (const c of cases) {
const root: SceneNode = { id: 'document', type: 'document', children: [] };
const results = parseAndExecute(root, c.ops);
const opOk = results.every((r) => r.ok);
if (!opOk) {
allPass = false;
console.log(`FAIL ${c.name}\n op error: ${results.find((r) => !r.ok)?.error}`);
continue;
}
const verdict = c.expect(root);
if (verdict === true) {
console.log(`PASS ${c.name}`);
} else {
allPass = false;
console.log(`FAIL ${c.name}\n ${verdict}`);
}
}
process.exit(allPass ? 0 : 1);