@hivecommons/promptargs 0.7.0 → 0.8.0
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 +100 -15
- package/dist/autodetect.js +24 -9
- package/dist/autodetect.js.map +1 -1
- package/dist/cli.js +51 -147
- package/dist/cli.js.map +1 -1
- package/dist/commands.d.ts +4 -0
- package/dist/commands.js +130 -0
- package/dist/commands.js.map +1 -0
- package/dist/flags.d.ts +14 -0
- package/dist/flags.js +57 -0
- package/dist/flags.js.map +1 -0
- package/dist/loader.d.ts +2 -0
- package/dist/loader.js +64 -11
- package/dist/loader.js.map +1 -1
- package/dist/log.d.ts +19 -0
- package/dist/log.js +41 -0
- package/dist/log.js.map +1 -0
- package/dist/parser.js +33 -7
- package/dist/parser.js.map +1 -1
- package/dist/resolver.d.ts +2 -0
- package/dist/resolver.js +60 -30
- package/dist/resolver.js.map +1 -1
- package/dist/status.d.ts +1 -1
- package/dist/status.js +5 -4
- package/dist/status.js.map +1 -1
- package/dist/ui.html +18 -5
- package/dist/ui.js +36 -11
- package/dist/ui.js.map +1 -1
- package/package.json +13 -4
- package/dist/autodetect.test.d.ts +0 -1
- package/dist/autodetect.test.js +0 -207
- package/dist/autodetect.test.js.map +0 -1
- package/dist/cli.test.d.ts +0 -1
- package/dist/cli.test.js +0 -310
- package/dist/cli.test.js.map +0 -1
- package/dist/index.test.d.ts +0 -1
- package/dist/index.test.js +0 -59
- package/dist/index.test.js.map +0 -1
- package/dist/iterate.test.d.ts +0 -1
- package/dist/iterate.test.js +0 -20
- package/dist/iterate.test.js.map +0 -1
- package/dist/loader.test.d.ts +0 -1
- package/dist/loader.test.js +0 -65
- package/dist/loader.test.js.map +0 -1
- package/dist/parser.test.d.ts +0 -1
- package/dist/parser.test.js +0 -93
- package/dist/parser.test.js.map +0 -1
- package/dist/resolver.test.d.ts +0 -1
- package/dist/resolver.test.js +0 -184
- package/dist/resolver.test.js.map +0 -1
- package/dist/sanitize.test.d.ts +0 -1
- package/dist/sanitize.test.js +0 -38
- package/dist/sanitize.test.js.map +0 -1
- package/dist/status.test.d.ts +0 -1
- package/dist/status.test.js +0 -33
- package/dist/status.test.js.map +0 -1
- package/dist/ui-bootstrap.test.d.ts +0 -1
- package/dist/ui-bootstrap.test.js +0 -479
- package/dist/ui-bootstrap.test.js.map +0 -1
- package/dist/ui-builder.test.d.ts +0 -1
- package/dist/ui-builder.test.js +0 -272
- package/dist/ui-builder.test.js.map +0 -1
- package/dist/ui-command-quoting.test.d.ts +0 -1
- package/dist/ui-command-quoting.test.js +0 -95
- package/dist/ui-command-quoting.test.js.map +0 -1
- package/dist/ui-harness.d.ts +0 -20
- package/dist/ui-harness.js +0 -40
- package/dist/ui-harness.js.map +0 -1
- package/dist/ui-harness.test.d.ts +0 -1
- package/dist/ui-harness.test.js +0 -30
- package/dist/ui-harness.test.js.map +0 -1
- package/dist/ui-inline.test.d.ts +0 -1
- package/dist/ui-inline.test.js +0 -90
- package/dist/ui-inline.test.js.map +0 -1
- package/dist/ui-interactions.test.d.ts +0 -1
- package/dist/ui-interactions.test.js +0 -489
- package/dist/ui-interactions.test.js.map +0 -1
- package/dist/ui.test.d.ts +0 -1
- package/dist/ui.test.js +0 -283
- package/dist/ui.test.js.map +0 -1
package/dist/ui-builder.test.js
DELETED
|
@@ -1,272 +0,0 @@
|
|
|
1
|
-
import test from 'node:test';
|
|
2
|
-
import assert from 'node:assert';
|
|
3
|
-
import { readFileSync } from 'node:fs';
|
|
4
|
-
import { join, dirname } from 'node:path';
|
|
5
|
-
import { fileURLToPath } from 'node:url';
|
|
6
|
-
import { expand, parseVars, VAR_PATTERN } from './parser.js';
|
|
7
|
-
import { cartesian, zip } from './iterate.js';
|
|
8
|
-
import { compileInlineScript } from './ui-harness.js';
|
|
9
|
-
/**
|
|
10
|
-
* Behavior tests for ui.html's builder logic: `update()` (preview rendering
|
|
11
|
-
* and the copyable CLI command) plus the PRESETS catalogue.
|
|
12
|
-
*
|
|
13
|
-
* ui.html runs an IIFE against the live DOM, so `update()` cannot be
|
|
14
|
-
* imported. Instead the function bodies are extracted verbatim from the
|
|
15
|
-
* page (same approach as ui-inline.test.ts) and instantiated with a tiny
|
|
16
|
-
* stub DOM: `tmpl` exposes `.value`, `varBody.querySelectorAll('tr')`
|
|
17
|
-
* yields rows whose `.querySelector(sel).value` returns the cell values, and
|
|
18
|
-
* the three output nodes record `innerHTML` / `textContent` / `className`.
|
|
19
|
-
* The grammar and iteration helpers are the real compiled modules, exactly
|
|
20
|
-
* as the browser imports them.
|
|
21
|
-
*/
|
|
22
|
-
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
23
|
-
const uiHtml = readFileSync(join(__dirname, 'ui.html'), 'utf-8');
|
|
24
|
-
function extractFunction(name) {
|
|
25
|
-
const start = uiHtml.indexOf(`function ${name}(`);
|
|
26
|
-
assert.notEqual(start, -1, `function ${name} not found in ui.html`);
|
|
27
|
-
const bodyStart = uiHtml.indexOf('{', start);
|
|
28
|
-
let depth = 0;
|
|
29
|
-
for (let i = bodyStart; i < uiHtml.length; i++) {
|
|
30
|
-
if (uiHtml[i] === '{')
|
|
31
|
-
depth++;
|
|
32
|
-
else if (uiHtml[i] === '}') {
|
|
33
|
-
depth--;
|
|
34
|
-
if (depth === 0)
|
|
35
|
-
return uiHtml.slice(start, i + 1);
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
assert.fail(`unbalanced braces extracting ${name} from ui.html`);
|
|
39
|
-
}
|
|
40
|
-
function makeHarness(mode = 'zip') {
|
|
41
|
-
const node = () => ({ innerHTML: '', textContent: '', className: '' });
|
|
42
|
-
const tmpl = { value: '' };
|
|
43
|
-
const rows = [];
|
|
44
|
-
const previewBody = node();
|
|
45
|
-
const previewCount = node();
|
|
46
|
-
const cliText = node();
|
|
47
|
-
const varBody = {
|
|
48
|
-
querySelectorAll(selector) {
|
|
49
|
-
assert.equal(selector, 'tr');
|
|
50
|
-
return rows.map(row => ({
|
|
51
|
-
querySelector(sel) {
|
|
52
|
-
if (sel === '.var-name')
|
|
53
|
-
return { value: row.name };
|
|
54
|
-
if (sel === '.var-values')
|
|
55
|
-
return { value: row.values };
|
|
56
|
-
if (sel === '.var-source')
|
|
57
|
-
return { value: row.source ?? 'manual' };
|
|
58
|
-
assert.fail(`unexpected cell selector ${sel}`);
|
|
59
|
-
},
|
|
60
|
-
}));
|
|
61
|
-
},
|
|
62
|
-
};
|
|
63
|
-
const src = ['getRowData', 'splitValues', 'escHtml', 'highlightUnfilled', 'update']
|
|
64
|
-
.map(extractFunction)
|
|
65
|
-
.join('\n');
|
|
66
|
-
const factory = compileInlineScript('ui-update', [
|
|
67
|
-
'tmpl', 'varBody', 'previewBody', 'previewCount', 'cliText', 'mode',
|
|
68
|
-
'sharedCartesian', 'sharedZip', 'sharedExpand', 'VAR_PATTERN',
|
|
69
|
-
], `${src}\nreturn update;`);
|
|
70
|
-
const update = factory(tmpl, varBody, previewBody, previewCount, cliText, mode, cartesian, zip, expand, VAR_PATTERN);
|
|
71
|
-
return {
|
|
72
|
-
update,
|
|
73
|
-
tmpl,
|
|
74
|
-
rows,
|
|
75
|
-
previewBody,
|
|
76
|
-
previewCount,
|
|
77
|
-
cliText,
|
|
78
|
-
cli: () => cliText.innerHTML.replace(/^<span class="dollar">\$<\/span>/, ''),
|
|
79
|
-
iterations: () => (previewBody.innerHTML.match(/<div class="iteration">/g) ?? []).length,
|
|
80
|
-
};
|
|
81
|
-
}
|
|
82
|
-
function expandedTexts(h) {
|
|
83
|
-
return [...h.previewBody.innerHTML.matchAll(/<div class="expanded-text">(.*?)<\/div>/gs)].map(m => m[1]);
|
|
84
|
-
}
|
|
85
|
-
test('update renders the empty state and a bare command when the template is blank', () => {
|
|
86
|
-
const h = makeHarness();
|
|
87
|
-
h.tmpl.value = ' \n';
|
|
88
|
-
h.rows.push({ name: 'file', values: 'a.go' });
|
|
89
|
-
h.update();
|
|
90
|
-
assert.match(h.previewBody.innerHTML, /preview-empty/);
|
|
91
|
-
assert.equal(h.previewCount.textContent, '0 results');
|
|
92
|
-
assert.equal(h.previewCount.className, 'preview-count empty');
|
|
93
|
-
assert.equal(h.cli(), 'promptargs');
|
|
94
|
-
});
|
|
95
|
-
test('update expands scalar values into a single unlabeled result', () => {
|
|
96
|
-
const h = makeHarness();
|
|
97
|
-
h.tmpl.value = 'Review {{file}} for {{focus=correctness}}';
|
|
98
|
-
h.rows.push({ name: 'file', values: 'api.go' }, { name: 'focus', values: 'security' });
|
|
99
|
-
h.update();
|
|
100
|
-
assert.equal(h.previewCount.textContent, '1 result');
|
|
101
|
-
assert.equal(h.previewCount.className, 'preview-count has-results');
|
|
102
|
-
assert.equal(h.iterations(), 1);
|
|
103
|
-
assert.ok(!h.previewBody.innerHTML.includes('iter-label'), 'single results carry no [i/n] label');
|
|
104
|
-
assert.deepEqual(expandedTexts(h), ['Review api.go for security']);
|
|
105
|
-
assert.equal(h.cli(), 'promptargs "Review {{file}} for {{focus=correctness}}" --file=api.go --focus=security');
|
|
106
|
-
});
|
|
107
|
-
test('update zips arrays 1:1 and labels each iteration', () => {
|
|
108
|
-
const h = makeHarness('zip');
|
|
109
|
-
h.tmpl.value = '{{file}}:{{focus}}';
|
|
110
|
-
h.rows.push({ name: 'file', values: 'a.go,b.go' }, { name: 'focus', values: 'x,y' });
|
|
111
|
-
h.update();
|
|
112
|
-
assert.equal(h.previewCount.textContent, '2 results');
|
|
113
|
-
assert.deepEqual(expandedTexts(h), ['a.go:x', 'b.go:y']);
|
|
114
|
-
assert.match(h.previewBody.innerHTML, /<div class="iter-label">\[1\/2\] file=a\.go {2}focus=x<\/div>/);
|
|
115
|
-
assert.match(h.previewBody.innerHTML, /<div class="iter-label">\[2\/2\] file=b\.go {2}focus=y<\/div>/);
|
|
116
|
-
assert.equal(h.cli(), 'promptargs "{{file}}:{{focus}}" --file=a.go,b.go --focus=x,y');
|
|
117
|
-
});
|
|
118
|
-
test('update in cross mode renders every combination and appends --cross', () => {
|
|
119
|
-
const h = makeHarness('cross');
|
|
120
|
-
h.tmpl.value = '{{file}}:{{focus}}';
|
|
121
|
-
h.rows.push({ name: 'file', values: 'a.go,b.go' }, { name: 'focus', values: 'x,y' });
|
|
122
|
-
h.update();
|
|
123
|
-
assert.equal(h.previewCount.textContent, '4 results');
|
|
124
|
-
assert.deepEqual(expandedTexts(h), ['a.go:x', 'a.go:y', 'b.go:x', 'b.go:y']);
|
|
125
|
-
assert.equal(h.cli(), 'promptargs "{{file}}:{{focus}}" --file=a.go,b.go --focus=x,y --cross');
|
|
126
|
-
});
|
|
127
|
-
test('update omits --cross when fewer than two arrays exist, matching CLI semantics', () => {
|
|
128
|
-
const h = makeHarness('cross');
|
|
129
|
-
h.tmpl.value = '{{file}} {{tone}}';
|
|
130
|
-
h.rows.push({ name: 'file', values: 'a.go,b.go' }, { name: 'tone', values: 'terse' });
|
|
131
|
-
h.update();
|
|
132
|
-
assert.equal(h.previewCount.textContent, '2 results');
|
|
133
|
-
assert.deepEqual(expandedTexts(h), ['a.go terse', 'b.go terse']);
|
|
134
|
-
assert.ok(!h.cli().endsWith('--cross'), `--cross is redundant for one array: ${h.cli()}`);
|
|
135
|
-
});
|
|
136
|
-
test('update mixes scalar and array values and carries scalars into every iteration', () => {
|
|
137
|
-
const h = makeHarness('zip');
|
|
138
|
-
h.tmpl.value = '{{file}} ({{tone}})';
|
|
139
|
-
h.rows.push({ name: 'tone', values: 'concise' }, { name: 'file', values: 'a.go,b.go,c.go' });
|
|
140
|
-
h.update();
|
|
141
|
-
assert.deepEqual(expandedTexts(h), ['a.go (concise)', 'b.go (concise)', 'c.go (concise)']);
|
|
142
|
-
assert.match(h.previewBody.innerHTML, /\[3\/3\] tone=concise {2}file=c\.go/);
|
|
143
|
-
});
|
|
144
|
-
test('update treats @file sources as one opaque value and quotes glob sources', () => {
|
|
145
|
-
const h = makeHarness();
|
|
146
|
-
h.tmpl.value = 'Check {{file}} and {{src}}';
|
|
147
|
-
h.rows.push({ name: 'file', values: 'list.txt', source: 'file' }, { name: 'src', values: 'src/*.go', source: 'glob' });
|
|
148
|
-
h.update();
|
|
149
|
-
// The browser cannot read list.txt or expand the glob, so the preview
|
|
150
|
-
// shows one iteration with the raw markers...
|
|
151
|
-
assert.equal(h.previewCount.textContent, '1 result');
|
|
152
|
-
assert.deepEqual(expandedTexts(h), ['Check list.txt and src/*.go']);
|
|
153
|
-
// ...while the command hands them to the CLI in the syntax `promptargs help` documents.
|
|
154
|
-
assert.equal(h.cli(), 'promptargs "Check {{file}} and {{src}}" --file=@list.txt --src="src/*.go"');
|
|
155
|
-
});
|
|
156
|
-
test('update does not split a comma-containing @file value into an array', () => {
|
|
157
|
-
const h = makeHarness('cross');
|
|
158
|
-
h.tmpl.value = '{{file}}/{{focus}}';
|
|
159
|
-
h.rows.push({ name: 'file', values: 'one,two', source: 'file' }, { name: 'focus', values: 'x,y' });
|
|
160
|
-
h.update();
|
|
161
|
-
assert.equal(h.previewCount.textContent, '2 results');
|
|
162
|
-
assert.deepEqual(expandedTexts(h), ['one,two/x', 'one,two/y']);
|
|
163
|
-
assert.ok(!h.cli().includes('--cross'), 'only one real array, so no --cross');
|
|
164
|
-
});
|
|
165
|
-
test('update skips rows with empty values in the command but still previews defaults', () => {
|
|
166
|
-
const h = makeHarness();
|
|
167
|
-
h.tmpl.value = 'Be {{tone=concise}} about {{file}}';
|
|
168
|
-
h.rows.push({ name: 'tone', values: '' }, { name: 'file', values: 'a.go' });
|
|
169
|
-
h.update();
|
|
170
|
-
assert.deepEqual(expandedTexts(h), ['Be concise about a.go']);
|
|
171
|
-
assert.equal(h.cli(), 'promptargs "Be {{tone=concise}} about {{file}}" --file=a.go');
|
|
172
|
-
});
|
|
173
|
-
test('update highlights variables that remain unfilled after expansion', () => {
|
|
174
|
-
const h = makeHarness();
|
|
175
|
-
h.tmpl.value = 'Fix {{issue}} in {{file}}';
|
|
176
|
-
h.rows.push({ name: 'file', values: 'main.go' });
|
|
177
|
-
h.update();
|
|
178
|
-
assert.deepEqual(expandedTexts(h), ['Fix <span class="unfilled">{{issue}}</span> in main.go']);
|
|
179
|
-
});
|
|
180
|
-
test('update HTML-escapes template text, values, and labels before rendering', () => {
|
|
181
|
-
const h = makeHarness('zip');
|
|
182
|
-
h.tmpl.value = '<b>{{x}}</b> & {{y}}';
|
|
183
|
-
h.rows.push({ name: 'x', values: '<img src=x onerror=alert(1)>,ok' }, { name: 'y', values: 'a,b' });
|
|
184
|
-
h.update();
|
|
185
|
-
const html = h.previewBody.innerHTML;
|
|
186
|
-
assert.ok(!html.includes('<img'), 'raw value markup must not reach the preview');
|
|
187
|
-
assert.ok(!html.includes('<b>'), 'raw template markup must not reach the preview');
|
|
188
|
-
assert.match(html, /<b><img src=x onerror=alert\(1\)><\/b> & a/);
|
|
189
|
-
assert.match(html, /iter-label">\[1\/2\] x=<img src=x onerror=alert\(1\)> {2}y=a</);
|
|
190
|
-
assert.match(h.cliText.innerHTML, /--x='<img src=x onerror=alert\(1\)>,ok'/);
|
|
191
|
-
});
|
|
192
|
-
test('update inlines the template in the command only when it is short and single-line', () => {
|
|
193
|
-
const inline = makeHarness();
|
|
194
|
-
inline.tmpl.value = 'Say "hi" to {{name}}';
|
|
195
|
-
inline.rows.push({ name: 'name', values: 'World' });
|
|
196
|
-
inline.update();
|
|
197
|
-
assert.equal(inline.cli(), 'promptargs "Say \\"hi\\" to {{name}}" --name=World');
|
|
198
|
-
const multiline = makeHarness();
|
|
199
|
-
multiline.tmpl.value = 'Line one {{name}}\nLine two';
|
|
200
|
-
multiline.rows.push({ name: 'name', values: 'World' });
|
|
201
|
-
multiline.update();
|
|
202
|
-
assert.equal(multiline.cli(), 'promptargs --name=World');
|
|
203
|
-
assert.deepEqual(expandedTexts(multiline), ['Line one World\nLine two']);
|
|
204
|
-
const long = makeHarness();
|
|
205
|
-
long.tmpl.value = `${'x'.repeat(200)} {{name}}`;
|
|
206
|
-
long.rows.push({ name: 'name', values: 'World' });
|
|
207
|
-
long.update();
|
|
208
|
-
assert.equal(long.cli(), 'promptargs --name=World');
|
|
209
|
-
});
|
|
210
|
-
test('update ignores rows without a name', () => {
|
|
211
|
-
const h = makeHarness();
|
|
212
|
-
h.tmpl.value = 'Hello {{name}}';
|
|
213
|
-
h.rows.push({ name: ' ', values: 'orphan' }, { name: 'name', values: 'World' });
|
|
214
|
-
h.update();
|
|
215
|
-
assert.deepEqual(expandedTexts(h), ['Hello World']);
|
|
216
|
-
assert.equal(h.cli(), 'promptargs "Hello {{name}}" --name=World');
|
|
217
|
-
});
|
|
218
|
-
function extractPresets() {
|
|
219
|
-
const start = uiHtml.indexOf('const PRESETS = [');
|
|
220
|
-
assert.notEqual(start, -1, 'PRESETS not found in ui.html');
|
|
221
|
-
const end = uiHtml.indexOf('\n ];', start);
|
|
222
|
-
assert.notEqual(end, -1, 'PRESETS array is not terminated');
|
|
223
|
-
const literal = uiHtml.slice(start + 'const PRESETS = '.length, end + '\n ];'.length);
|
|
224
|
-
// eslint-disable-next-line no-new-func
|
|
225
|
-
return new Function(`return ${literal}`)();
|
|
226
|
-
}
|
|
227
|
-
const presets = extractPresets();
|
|
228
|
-
test('every preset fills each template variable and uses a known iteration mode', () => {
|
|
229
|
-
assert.ok(presets.length >= 8, `expected the shipped preset catalogue, got ${presets.length}`);
|
|
230
|
-
const names = new Set();
|
|
231
|
-
for (const p of presets) {
|
|
232
|
-
assert.ok(!names.has(p.name), `duplicate preset name ${p.name}`);
|
|
233
|
-
names.add(p.name);
|
|
234
|
-
assert.ok(['zip', 'cross'].includes(p.mode), `${p.name}: unknown mode ${p.mode}`);
|
|
235
|
-
const templateVars = parseVars(p.template).map(v => v.name);
|
|
236
|
-
assert.ok(templateVars.length > 0, `${p.name}: template declares no variables`);
|
|
237
|
-
for (const v of templateVars) {
|
|
238
|
-
assert.ok(v in p.vars, `${p.name}: template uses {{${v}}} but vars has no entry for it`);
|
|
239
|
-
assert.ok(p.vars[v].length > 0, `${p.name}: vars.${v} is empty`);
|
|
240
|
-
}
|
|
241
|
-
for (const v of Object.keys(p.vars)) {
|
|
242
|
-
assert.ok(templateVars.includes(v), `${p.name}: vars.${v} is not used by the template`);
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
|
-
});
|
|
246
|
-
test('every preset renders through update() with no unfilled variables', () => {
|
|
247
|
-
for (const p of presets) {
|
|
248
|
-
const h = makeHarness(p.mode);
|
|
249
|
-
h.tmpl.value = p.template;
|
|
250
|
-
for (const [name, values] of Object.entries(p.vars))
|
|
251
|
-
h.rows.push({ name, values });
|
|
252
|
-
h.update();
|
|
253
|
-
assert.ok(!h.previewBody.innerHTML.includes('class="unfilled"'), `${p.name}: preview left a variable unfilled`);
|
|
254
|
-
const arrays = Object.values(p.vars).filter(v => v.includes(',')).map(v => v.split(',').length);
|
|
255
|
-
const expected = arrays.length === 0
|
|
256
|
-
? 1
|
|
257
|
-
: p.mode === 'cross'
|
|
258
|
-
? arrays.reduce((a, b) => a * b, 1)
|
|
259
|
-
: Math.max(...arrays);
|
|
260
|
-
assert.equal(h.iterations(), expected, `${p.name}: iteration count`);
|
|
261
|
-
assert.ok(h.cli().startsWith('promptargs '), `${p.name}: command is built`);
|
|
262
|
-
}
|
|
263
|
-
});
|
|
264
|
-
test('preset templates use only the documented {{var}} / {{var=default}} grammar', () => {
|
|
265
|
-
for (const p of presets) {
|
|
266
|
-
const braces = p.template.match(/\{\{[^}]*\}\}/g) ?? [];
|
|
267
|
-
VAR_PATTERN.lastIndex = 0;
|
|
268
|
-
const parsed = p.template.match(VAR_PATTERN) ?? [];
|
|
269
|
-
assert.deepEqual(parsed, braces, `${p.name}: a {{...}} token does not match VAR_PATTERN`);
|
|
270
|
-
}
|
|
271
|
-
});
|
|
272
|
-
//# sourceMappingURL=ui-builder.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ui-builder.test.js","sourceRoot":"","sources":["../src/ui-builder.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,95 +0,0 @@
|
|
|
1
|
-
import { test } from 'node:test';
|
|
2
|
-
import assert from 'node:assert';
|
|
3
|
-
import { readFileSync } from 'node:fs';
|
|
4
|
-
import { dirname, join } from 'node:path';
|
|
5
|
-
import { fileURLToPath } from 'node:url';
|
|
6
|
-
import { spawnSync } from 'node:child_process';
|
|
7
|
-
import { VAR_PATTERN, expand } from './parser.js';
|
|
8
|
-
import { cartesian, zip } from './iterate.js';
|
|
9
|
-
import { compileInlineScript } from './ui-harness.js';
|
|
10
|
-
/**
|
|
11
|
-
* Regression tests for the shell safety of the command `update()` in
|
|
12
|
-
* ui.html generates (#86): a value with whitespace or shell metacharacters
|
|
13
|
-
* used to be emitted bare, so the `explain` and `fix` presets produced a
|
|
14
|
-
* command whose prompt was silently truncated by the shell.
|
|
15
|
-
*
|
|
16
|
-
* `update()` lives inside ui.html's IIFE, so it is extracted verbatim and
|
|
17
|
-
* evaluated against a stub DOM holding only what the command builder reads.
|
|
18
|
-
*/
|
|
19
|
-
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
20
|
-
const uiHtml = readFileSync(join(__dirname, 'ui.html'), 'utf-8');
|
|
21
|
-
function extractFunction(name) {
|
|
22
|
-
const start = uiHtml.indexOf(`function ${name}(`);
|
|
23
|
-
assert.notEqual(start, -1, `function ${name} not found in ui.html`);
|
|
24
|
-
let depth = 0;
|
|
25
|
-
for (let i = uiHtml.indexOf('{', start); i < uiHtml.length; i++) {
|
|
26
|
-
if (uiHtml[i] === '{')
|
|
27
|
-
depth++;
|
|
28
|
-
else if (uiHtml[i] === '}' && --depth === 0)
|
|
29
|
-
return uiHtml.slice(start, i + 1);
|
|
30
|
-
}
|
|
31
|
-
assert.fail(`unbalanced braces extracting ${name} from ui.html`);
|
|
32
|
-
}
|
|
33
|
-
/** Runs update() for one template + rows and returns the generated command. */
|
|
34
|
-
function commandFor(template, rows) {
|
|
35
|
-
const node = () => ({ innerHTML: '', textContent: '', className: '' });
|
|
36
|
-
const cliText = node();
|
|
37
|
-
const varBody = {
|
|
38
|
-
querySelectorAll: () => rows.map(row => ({
|
|
39
|
-
querySelector: (sel) => sel === '.var-name' ? { value: row.name }
|
|
40
|
-
: sel === '.var-values' ? { value: row.values }
|
|
41
|
-
: { value: row.source ?? 'manual' },
|
|
42
|
-
})),
|
|
43
|
-
};
|
|
44
|
-
const src = ['getRowData', 'splitValues', 'escHtml', 'highlightUnfilled', 'update']
|
|
45
|
-
.map(extractFunction).join('\n');
|
|
46
|
-
const factory = compileInlineScript('ui-update', [
|
|
47
|
-
'tmpl', 'varBody', 'previewBody', 'previewCount', 'cliText', 'mode',
|
|
48
|
-
'sharedCartesian', 'sharedZip', 'sharedExpand', 'VAR_PATTERN',
|
|
49
|
-
], `${src}\nreturn update;`);
|
|
50
|
-
const update = factory({ value: template }, varBody, node(), node(), cliText, 'zip', cartesian, zip, expand, VAR_PATTERN);
|
|
51
|
-
update();
|
|
52
|
-
return cliText.innerHTML
|
|
53
|
-
.replace(/^<span class="dollar">\$<\/span>/, '')
|
|
54
|
-
.replace(/"/g, '"').replace(/'/g, "'").replace(/</g, '<').replace(/>/g, '>').replace(/&/g, '&');
|
|
55
|
-
}
|
|
56
|
-
/** What a POSIX shell would hand to the CLI for the generated command. */
|
|
57
|
-
function shellWords(command) {
|
|
58
|
-
const args = command.replace(/^promptargs /, '');
|
|
59
|
-
const r = spawnSync('sh', ['-c', `printf '%s\\n' ${args}`], { encoding: 'utf-8' });
|
|
60
|
-
assert.equal(r.status, 0, r.stderr);
|
|
61
|
-
return r.stdout.replace(/\n$/, '').split('\n');
|
|
62
|
-
}
|
|
63
|
-
test('bare values stay unquoted, so the common command is unchanged', () => {
|
|
64
|
-
assert.equal(commandFor('Review {{file}} for {{focus=correctness}}', [{ name: 'file', values: 'api.go' }, { name: 'focus', values: 'security' }]), 'promptargs "Review {{file}} for {{focus=correctness}}" --file=api.go --focus=security');
|
|
65
|
-
assert.equal(commandFor('{{file}} {{src}}', [{ name: 'file', values: 'list.txt', source: 'file' }, { name: 'src', values: 'src/*.go', source: 'glob' }]), 'promptargs "{{file}} {{src}}" --file=@list.txt --src="src/*.go"');
|
|
66
|
-
});
|
|
67
|
-
test('explain preset: a multi-word audience reaches the CLI as one argument', () => {
|
|
68
|
-
const cmd = commandFor('Explain {{file}} to a {{audience=junior developer}}', [{ name: 'file', values: 'a.ts' }, { name: 'audience', values: 'junior developer' }]);
|
|
69
|
-
assert.equal(cmd, `promptargs "Explain {{file}} to a {{audience=junior developer}}" --file=a.ts --audience='junior developer'`);
|
|
70
|
-
assert.deepEqual(shellWords(cmd), ['Explain {{file}} to a {{audience=junior developer}}', '--file=a.ts', '--audience=junior developer']);
|
|
71
|
-
});
|
|
72
|
-
test('fix preset: expected/actual sentences are not split into stray positionals', () => {
|
|
73
|
-
const cmd = commandFor('Fix {{file}}: expected {{expected}} but {{actual}}', [
|
|
74
|
-
{ name: 'file', values: 'x.go' },
|
|
75
|
-
{ name: 'expected', values: 'returns user object' },
|
|
76
|
-
{ name: 'actual', values: 'crashes on line 42' },
|
|
77
|
-
]);
|
|
78
|
-
assert.deepEqual(shellWords(cmd), [
|
|
79
|
-
'Fix {{file}}: expected {{expected}} but {{actual}}', '--file=x.go',
|
|
80
|
-
'--expected=returns user object', '--actual=crashes on line 42',
|
|
81
|
-
]);
|
|
82
|
-
});
|
|
83
|
-
test('shell metacharacters in values and the template are literal', () => {
|
|
84
|
-
const cmd = commandFor('Cost is $HOME `whoami` \\ "quoted" {{v}}', [{ name: 'v', values: `it's $x; rm -rf *` }]);
|
|
85
|
-
assert.deepEqual(shellWords(cmd), ['Cost is $HOME `whoami` \\ "quoted" {{v}}', `--v=it's $x; rm -rf *`]);
|
|
86
|
-
});
|
|
87
|
-
test('a comma-separated array value stays a bare word so arrays still parse', () => {
|
|
88
|
-
assert.equal(commandFor('{{f}}', [{ name: 'f', values: 'a.go,b.go' }]), 'promptargs "{{f}}" --f=a.go,b.go');
|
|
89
|
-
});
|
|
90
|
-
test('a glob value keeps its double quotes but shell-expandable characters inside are escaped', () => {
|
|
91
|
-
const cmd = commandFor('{{src}}', [{ name: 'src', values: 'src/$HOME/`x`/"q"/*.go', source: 'glob' }]);
|
|
92
|
-
assert.equal(cmd, 'promptargs "{{src}}" --src="src/\\$HOME/\\`x\\`/\\"q\\"/*.go"');
|
|
93
|
-
assert.deepEqual(shellWords(cmd), ['{{src}}', '--src=src/$HOME/`x`/"q"/*.go']);
|
|
94
|
-
});
|
|
95
|
-
//# sourceMappingURL=ui-command-quoting.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ui-command-quoting.test.js","sourceRoot":"","sources":["../src/ui-command-quoting.test.ts"],"names":[],"mappings":"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"}
|
package/dist/ui-harness.d.ts
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Test helper: compile a fragment of ui.html's inline script so the test
|
|
3
|
-
* runner's coverage reporter can see it.
|
|
4
|
-
*
|
|
5
|
-
* The ui-*.test.ts suites extract functions out of ui.html and run them
|
|
6
|
-
* against a stub DOM. Doing that with `new Function` hides the code from
|
|
7
|
-
* `--experimental-test-coverage`: V8 reports such scripts with an empty URL
|
|
8
|
-
* and the reporter drops them, so the thresholds in scripts/run-tests.mjs
|
|
9
|
-
* could never gate ui.html. Writing the assembled source to a scratch file
|
|
10
|
-
* and compiling it with `vm.Script` under that file's URL makes it show up
|
|
11
|
-
* in the report like any other source file.
|
|
12
|
-
*
|
|
13
|
-
* Scratch files live in `.test-scratch/ui-inline/` at the repository root —
|
|
14
|
-
* gitignored, and outside `dist/` so `npm publish` never ships them. The
|
|
15
|
-
* file name is `<label>-<content hash>.js`: suites that assemble identical
|
|
16
|
-
* source share one entry in the report, and editing ui.html simply produces
|
|
17
|
-
* a new file instead of clashing with a stale one.
|
|
18
|
-
*/
|
|
19
|
-
export declare const SCRATCH_DIR: string;
|
|
20
|
-
export declare function compileInlineScript<T>(label: string, params: readonly string[], body: string): (...args: unknown[]) => T;
|
package/dist/ui-harness.js
DELETED
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
import { createHash } from 'node:crypto';
|
|
2
|
-
import { existsSync, mkdirSync, renameSync, writeFileSync } from 'node:fs';
|
|
3
|
-
import { dirname, join } from 'node:path';
|
|
4
|
-
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
5
|
-
import { Script } from 'node:vm';
|
|
6
|
-
/**
|
|
7
|
-
* Test helper: compile a fragment of ui.html's inline script so the test
|
|
8
|
-
* runner's coverage reporter can see it.
|
|
9
|
-
*
|
|
10
|
-
* The ui-*.test.ts suites extract functions out of ui.html and run them
|
|
11
|
-
* against a stub DOM. Doing that with `new Function` hides the code from
|
|
12
|
-
* `--experimental-test-coverage`: V8 reports such scripts with an empty URL
|
|
13
|
-
* and the reporter drops them, so the thresholds in scripts/run-tests.mjs
|
|
14
|
-
* could never gate ui.html. Writing the assembled source to a scratch file
|
|
15
|
-
* and compiling it with `vm.Script` under that file's URL makes it show up
|
|
16
|
-
* in the report like any other source file.
|
|
17
|
-
*
|
|
18
|
-
* Scratch files live in `.test-scratch/ui-inline/` at the repository root —
|
|
19
|
-
* gitignored, and outside `dist/` so `npm publish` never ships them. The
|
|
20
|
-
* file name is `<label>-<content hash>.js`: suites that assemble identical
|
|
21
|
-
* source share one entry in the report, and editing ui.html simply produces
|
|
22
|
-
* a new file instead of clashing with a stale one.
|
|
23
|
-
*/
|
|
24
|
-
export const SCRATCH_DIR = join(dirname(fileURLToPath(import.meta.url)), '..', '.test-scratch', 'ui-inline');
|
|
25
|
-
export function compileInlineScript(label, params, body) {
|
|
26
|
-
const source = `(function (${params.join(', ')}) {\n${body}\n})`;
|
|
27
|
-
const hash = createHash('sha256').update(source).digest('hex').slice(0, 8);
|
|
28
|
-
const file = join(SCRATCH_DIR, `${label}-${hash}.js`);
|
|
29
|
-
if (!existsSync(file)) {
|
|
30
|
-
mkdirSync(SCRATCH_DIR, { recursive: true });
|
|
31
|
-
// Suites run in parallel processes; write-then-rename keeps a reader
|
|
32
|
-
// in another process from seeing a half-written file.
|
|
33
|
-
const tmp = `${file}.${process.pid}.tmp`;
|
|
34
|
-
writeFileSync(tmp, source);
|
|
35
|
-
renameSync(tmp, file);
|
|
36
|
-
}
|
|
37
|
-
const script = new Script(source, { filename: pathToFileURL(file).href });
|
|
38
|
-
return script.runInThisContext();
|
|
39
|
-
}
|
|
40
|
-
//# sourceMappingURL=ui-harness.js.map
|
package/dist/ui-harness.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ui-harness.js","sourceRoot":"","sources":["../src/ui-harness.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC3E,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACxD,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAEjC;;;;;;;;;;;;;;;;;GAiBG;AAEH,MAAM,CAAC,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,eAAe,EAAE,WAAW,CAAC,CAAC;AAE7G,MAAM,UAAU,mBAAmB,CACjC,KAAa,EACb,MAAyB,EACzB,IAAY;IAEZ,MAAM,MAAM,GAAG,cAAc,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,IAAI,MAAM,CAAC;IACjE,MAAM,IAAI,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAC3E,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,EAAE,GAAG,KAAK,IAAI,IAAI,KAAK,CAAC,CAAC;IAEtD,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QACtB,SAAS,CAAC,WAAW,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC5C,qEAAqE;QACrE,sDAAsD;QACtD,MAAM,GAAG,GAAG,GAAG,IAAI,IAAI,OAAO,CAAC,GAAG,MAAM,CAAC;QACzC,aAAa,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;QAC3B,UAAU,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IACxB,CAAC;IAED,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC,MAAM,EAAE,EAAE,QAAQ,EAAE,aAAa,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;IAC1E,OAAO,MAAM,CAAC,gBAAgB,EAA+B,CAAC;AAChE,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
package/dist/ui-harness.test.js
DELETED
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
import test from 'node:test';
|
|
2
|
-
import assert from 'node:assert';
|
|
3
|
-
import { existsSync, readFileSync } from 'node:fs';
|
|
4
|
-
import { SCRATCH_DIR, compileInlineScript } from './ui-harness.js';
|
|
5
|
-
test('compileInlineScript returns a callable bound to the given parameters', () => {
|
|
6
|
-
const add = compileInlineScript('harness-self-test', ['a', 'b'], 'return a + b;');
|
|
7
|
-
assert.equal(add(2, 3), 5);
|
|
8
|
-
assert.equal(compileInlineScript('harness-self-test', [], 'return "none";')(), 'none');
|
|
9
|
-
});
|
|
10
|
-
test('compileInlineScript compiles under a content-hashed scratch file URL', () => {
|
|
11
|
-
const body = 'throw new Error(msg);';
|
|
12
|
-
const thrower = compileInlineScript('harness-self-test', ['msg'], body);
|
|
13
|
-
// Compiling the same source again must reuse the file, not fail on it.
|
|
14
|
-
compileInlineScript('harness-self-test', ['msg'], body);
|
|
15
|
-
let stack = '';
|
|
16
|
-
try {
|
|
17
|
-
thrower('where');
|
|
18
|
-
}
|
|
19
|
-
catch (e) {
|
|
20
|
-
stack = e.stack ?? '';
|
|
21
|
-
}
|
|
22
|
-
// The frame inside the script names the file the reporter will key on.
|
|
23
|
-
const match = /file:\/\/[^\s)]+harness-self-test-[0-9a-f]{8}\.js/.exec(stack);
|
|
24
|
-
assert.ok(match, `expected scratch file URL in stack, got:\n${stack}`);
|
|
25
|
-
const path = decodeURIComponent(match[0].replace(/^file:\/\//, ''));
|
|
26
|
-
assert.ok(path.startsWith(SCRATCH_DIR), `${path} should live under ${SCRATCH_DIR}`);
|
|
27
|
-
assert.ok(existsSync(path));
|
|
28
|
-
assert.equal(readFileSync(path, 'utf-8'), `(function (msg) {\n${body}\n})`);
|
|
29
|
-
});
|
|
30
|
-
//# sourceMappingURL=ui-harness.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ui-harness.test.js","sourceRoot":"","sources":["../src/ui-harness.test.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,MAAM,MAAM,aAAa,CAAC;AACjC,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,WAAW,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAEnE,IAAI,CAAC,sEAAsE,EAAE,GAAG,EAAE;IAChF,MAAM,GAAG,GAAG,mBAAmB,CAAS,mBAAmB,EAAE,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,eAAe,CAAC,CAAC;IAC1F,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAC3B,MAAM,CAAC,KAAK,CAAC,mBAAmB,CAAS,mBAAmB,EAAE,EAAE,EAAE,gBAAgB,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;AACjG,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,sEAAsE,EAAE,GAAG,EAAE;IAChF,MAAM,IAAI,GAAG,uBAAuB,CAAC;IACrC,MAAM,OAAO,GAAG,mBAAmB,CAAQ,mBAAmB,EAAE,CAAC,KAAK,CAAC,EAAE,IAAI,CAAC,CAAC;IAC/E,uEAAuE;IACvE,mBAAmB,CAAQ,mBAAmB,EAAE,CAAC,KAAK,CAAC,EAAE,IAAI,CAAC,CAAC;IAE/D,IAAI,KAAK,GAAG,EAAE,CAAC;IACf,IAAI,CAAC;QAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IAAC,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QAAC,KAAK,GAAI,CAAW,CAAC,KAAK,IAAI,EAAE,CAAC;IAAC,CAAC;IAEzE,uEAAuE;IACvE,MAAM,KAAK,GAAG,mDAAmD,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC9E,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,6CAA6C,KAAK,EAAE,CAAC,CAAC;IACvE,MAAM,IAAI,GAAG,kBAAkB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC,CAAC;IACpE,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,GAAG,IAAI,sBAAsB,WAAW,EAAE,CAAC,CAAC;IACpF,MAAM,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC;IAC5B,MAAM,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,EAAE,sBAAsB,IAAI,MAAM,CAAC,CAAC;AAC9E,CAAC,CAAC,CAAC"}
|
package/dist/ui-inline.test.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
package/dist/ui-inline.test.js
DELETED
|
@@ -1,90 +0,0 @@
|
|
|
1
|
-
import test from 'node:test';
|
|
2
|
-
import assert from 'node:assert';
|
|
3
|
-
import { readFileSync } from 'node:fs';
|
|
4
|
-
import { join, dirname } from 'node:path';
|
|
5
|
-
import { fileURLToPath } from 'node:url';
|
|
6
|
-
import { resolve } from './resolver.js';
|
|
7
|
-
import { compileInlineScript } from './ui-harness.js';
|
|
8
|
-
/**
|
|
9
|
-
* Regression tests for ui.html's browser <script>.
|
|
10
|
-
*
|
|
11
|
-
* ui.html previously hand-reimplemented the {{var}} grammar, expansion, and
|
|
12
|
-
* array-iteration logic from parser.ts/resolver.ts as plain functions, with
|
|
13
|
-
* nothing type-checking that copy — it could silently drift from the CLI
|
|
14
|
-
* (see issue #62). ui.html now imports parseVars/expand from './parser.js'
|
|
15
|
-
* and cartesian/zip from './iterate.js' directly (the exact compiled modules
|
|
16
|
-
* the CLI runs), served by ui.ts alongside the page. These tests assert that
|
|
17
|
-
* wiring stays in place and only the browser-only helpers (splitValues,
|
|
18
|
-
* esc, escHtml — which have no CLI counterpart) remain hand-written.
|
|
19
|
-
*/
|
|
20
|
-
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
21
|
-
const uiHtml = readFileSync(join(__dirname, 'ui.html'), 'utf-8');
|
|
22
|
-
/** Extract a `function name(...) { ... }` declaration via brace matching. */
|
|
23
|
-
function extractFunction(name) {
|
|
24
|
-
const start = uiHtml.indexOf(`function ${name}(`);
|
|
25
|
-
assert.notEqual(start, -1, `function ${name} not found in ui.html`);
|
|
26
|
-
const bodyStart = uiHtml.indexOf('{', start);
|
|
27
|
-
let depth = 0;
|
|
28
|
-
for (let i = bodyStart; i < uiHtml.length; i++) {
|
|
29
|
-
if (uiHtml[i] === '{')
|
|
30
|
-
depth++;
|
|
31
|
-
else if (uiHtml[i] === '}') {
|
|
32
|
-
depth--;
|
|
33
|
-
if (depth === 0)
|
|
34
|
-
return uiHtml.slice(start, i + 1);
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
assert.fail(`unbalanced braces extracting ${name} from ui.html`);
|
|
38
|
-
}
|
|
39
|
-
function instantiate(name) {
|
|
40
|
-
const src = extractFunction(name);
|
|
41
|
-
return compileInlineScript(`ui-fn-${name}`, [], `return ${src};`)();
|
|
42
|
-
}
|
|
43
|
-
const uiSplitValues = instantiate('splitValues');
|
|
44
|
-
const uiEsc = instantiate('esc');
|
|
45
|
-
const uiEscHtml = instantiate('escHtml');
|
|
46
|
-
test('ui.html imports the canonical grammar/iteration modules instead of reimplementing them', () => {
|
|
47
|
-
assert.match(uiHtml, /import \{ parseVars, expand as \w+, VAR_PATTERN \} from '\.\/parser\.js';/);
|
|
48
|
-
assert.match(uiHtml, /import \{ cartesian as \w+, zip as \w+ \} from '\.\/iterate\.js';/);
|
|
49
|
-
// The functions that used to hand-duplicate parser/resolver logic must be
|
|
50
|
-
// gone — their behavior now comes solely from the imported modules.
|
|
51
|
-
for (const removed of ['parseVarsFromTemplate', 'function expand(', 'function cartesian(', 'function zip(']) {
|
|
52
|
-
assert.ok(!uiHtml.includes(removed), `${removed} should no longer be defined in ui.html`);
|
|
53
|
-
}
|
|
54
|
-
});
|
|
55
|
-
test('ui.html declares an import map resolving "mustache" for the browser', () => {
|
|
56
|
-
assert.match(uiHtml, /<script type="importmap">/);
|
|
57
|
-
assert.match(uiHtml, /"mustache":\s*"\.\/mustache\.mjs"/);
|
|
58
|
-
});
|
|
59
|
-
test('ui splitValues mirrors CLI comma-separated handling', () => {
|
|
60
|
-
assert.deepEqual(uiSplitValues('a.go, b.go ,c.go', 'manual'), ['a.go', 'b.go', 'c.go']);
|
|
61
|
-
assert.deepEqual(uiSplitValues('a,,b,', 'manual'), ['a', 'b']);
|
|
62
|
-
assert.deepEqual(uiSplitValues('', 'manual'), []);
|
|
63
|
-
// @file values are opaque single entries in the UI (server has no file access)
|
|
64
|
-
assert.deepEqual(uiSplitValues('one,two', 'file'), ['one,two']);
|
|
65
|
-
});
|
|
66
|
-
test('ui esc/escHtml escape injection-relevant characters', () => {
|
|
67
|
-
// esc feeds attribute values built with innerHTML
|
|
68
|
-
assert.equal(uiEsc('a&b "c" <d>'), 'a&b "c" <d>');
|
|
69
|
-
// escHtml feeds text content
|
|
70
|
-
assert.equal(uiEscHtml('a&b <script>'), 'a&b <script>');
|
|
71
|
-
});
|
|
72
|
-
// Sanity check that resolver's cartesian/zip iteration order (which the
|
|
73
|
-
// browser now imports verbatim via iterate.js) still matches what
|
|
74
|
-
// resolve() produces, keeping this parity documented even though the logic
|
|
75
|
-
// itself is no longer duplicated.
|
|
76
|
-
test('resolver cartesian/zip iteration order used by resolve()', async () => {
|
|
77
|
-
const vars = [
|
|
78
|
-
{ name: 'file', raw: '{{file}}' },
|
|
79
|
-
{ name: 'focus', raw: '{{focus}}' },
|
|
80
|
-
];
|
|
81
|
-
const cross = await resolve(vars, { file: 'a.go,b.go,c.go', focus: 'security,perf' }, false, true);
|
|
82
|
-
assert.deepEqual(cross.iterations.map(it => [it['file'], it['focus']]), [
|
|
83
|
-
['a.go', 'security'], ['a.go', 'perf'],
|
|
84
|
-
['b.go', 'security'], ['b.go', 'perf'],
|
|
85
|
-
['c.go', 'security'], ['c.go', 'perf'],
|
|
86
|
-
]);
|
|
87
|
-
const zipped = await resolve(vars, { file: 'a.go,b.go,c.go', focus: 'security,perf' }, false, false);
|
|
88
|
-
assert.deepEqual(zipped.iterations.map(it => [it['file'], it['focus']]), [['a.go', 'security'], ['b.go', 'perf'], ['c.go', 'security']]);
|
|
89
|
-
});
|
|
90
|
-
//# sourceMappingURL=ui-inline.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ui-inline.test.js","sourceRoot":"","sources":["../src/ui-inline.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|