-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathrun_cli_tests.sh
More file actions
executable file
·505 lines (481 loc) · 18.3 KB
/
Copy pathrun_cli_tests.sh
File metadata and controls
executable file
·505 lines (481 loc) · 18.3 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
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
#!/usr/bin/env bash
set -euo pipefail
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
PS="${PS:-$ROOT_DIR/c/ps}"
export PS_MODULE_REGISTRY="${PS_MODULE_REGISTRY:-$ROOT_DIR/modules/registry.json}"
CLI_MODULES_TMP_DIR=""
if [[ -z "${PS_MODULE_PATH:-}" ]]; then
CLI_MODULES_TMP_DIR="$(mktemp -d "${TMPDIR:-/tmp}/ps_modules_cli_XXXXXX")"
export PS_MODULE_PATH="$CLI_MODULES_TMP_DIR"
fi
cleanup_cli_modules_tmp() {
if [[ -n "$CLI_MODULES_TMP_DIR" && -d "$CLI_MODULES_TMP_DIR" ]]; then
rm -rf "$CLI_MODULES_TMP_DIR"
fi
}
trap cleanup_cli_modules_tmp EXIT
if [[ -x "$ROOT_DIR/scripts/build_modules.sh" ]]; then
"$ROOT_DIR/scripts/build_modules.sh" >/tmp/ps_cli_modules_build.out 2>&1 || {
echo "ERROR: failed to build test modules" >&2
sed -n '1,80p' /tmp/ps_cli_modules_build.out >&2
exit 2
}
fi
pass=0
fail=0
json_status() {
local file="$1"
if command -v jq >/dev/null 2>&1; then
jq -r '.status // ""' "$file"
else
python3 - "$file" <<'PY'
import json, sys
with open(sys.argv[1], "r", encoding="utf-8") as f:
data = json.load(f)
print(data.get("status", ""))
PY
fi
}
json_stdout() {
local file="$1"
if command -v jq >/dev/null 2>&1; then
jq -r -j '.expected_stdout // ""' "$file"
else
python3 - "$file" <<'PY'
import json, sys
with open(sys.argv[1], "r", encoding="utf-8") as f:
data = json.load(f)
sys.stdout.write(data.get("expected_stdout", "") or "")
PY
fi
}
expect_exit() {
local desc="$1"
local expected="$2"
shift 2
set +e
"$@" >/tmp/ps_cli_test.out 2>&1
local rc=$?
set -e
if [[ "$rc" -eq "$expected" ]]; then
echo "PASS $desc"
pass=$((pass + 1))
else
echo "FAIL $desc"
echo " expected exit $expected, got $rc"
echo " cmd: $*"
echo " output:"
sed -n '1,80p' /tmp/ps_cli_test.out
fail=$((fail + 1))
fi
}
expect_output_contains() {
local desc="$1"
local needle="$2"
shift 2
set +e
"$@" >/tmp/ps_cli_test.out 2>&1
local rc=$?
set -e
if [[ "$rc" -ne 0 ]]; then
echo "FAIL $desc"
echo " expected exit 0, got $rc"
echo " cmd: $*"
echo " output:"
sed -n '1,80p' /tmp/ps_cli_test.out
fail=$((fail + 1))
return
fi
if grep -Fq "$needle" /tmp/ps_cli_test.out; then
echo "PASS $desc"
pass=$((pass + 1))
else
echo "FAIL $desc"
echo " missing output: $needle"
echo " cmd: $*"
echo " output:"
sed -n '1,80p' /tmp/ps_cli_test.out
fail=$((fail + 1))
fi
}
expect_error_contains() {
local desc="$1"
local needle="$2"
shift 2
set +e
"$@" >/tmp/ps_cli_test.out 2>&1
local rc=$?
set -e
if [[ "$rc" -eq 0 ]]; then
echo "FAIL $desc"
echo " expected non-zero exit, got 0"
echo " cmd: $*"
echo " output:"
sed -n '1,80p' /tmp/ps_cli_test.out
fail=$((fail + 1))
return
fi
if grep -Fq "$needle" /tmp/ps_cli_test.out; then
echo "PASS $desc"
pass=$((pass + 1))
else
echo "FAIL $desc"
echo " missing output: $needle"
echo " cmd: $*"
echo " output:"
sed -n '1,80p' /tmp/ps_cli_test.out
fail=$((fail + 1))
fi
}
expect_error_contains_not_contains() {
local desc="$1"
local must_have="$2"
local must_not_have="$3"
shift 3
set +e
"$@" >/tmp/ps_cli_test.out 2>&1
local rc=$?
set -e
if [[ "$rc" -eq 0 ]]; then
echo "FAIL $desc"
echo " expected non-zero exit, got 0"
echo " cmd: $*"
echo " output:"
sed -n '1,80p' /tmp/ps_cli_test.out
fail=$((fail + 1))
return
fi
if ! grep -Fq "$must_have" /tmp/ps_cli_test.out; then
echo "FAIL $desc"
echo " missing output: $must_have"
echo " cmd: $*"
echo " output:"
sed -n '1,80p' /tmp/ps_cli_test.out
fail=$((fail + 1))
return
fi
if grep -Fq "$must_not_have" /tmp/ps_cli_test.out; then
echo "FAIL $desc"
echo " unexpected output present: $must_not_have"
echo " cmd: $*"
echo " output:"
sed -n '1,80p' /tmp/ps_cli_test.out
fail=$((fail + 1))
return
fi
echo "PASS $desc"
pass=$((pass + 1))
}
expect_no_output() {
local desc="$1"
shift
set +e
"$@" >/tmp/ps_cli_test.out 2>&1
local rc=$?
set -e
if [[ "$rc" -ne 0 ]]; then
echo "FAIL $desc"
echo " expected exit 0, got $rc"
echo " cmd: $*"
echo " output:"
sed -n '1,80p' /tmp/ps_cli_test.out
fail=$((fail + 1))
return
fi
if [[ -s /tmp/ps_cli_test.out ]]; then
echo "FAIL $desc"
echo " expected no output"
echo " cmd: $*"
echo " output:"
sed -n '1,80p' /tmp/ps_cli_test.out
fail=$((fail + 1))
else
echo "PASS $desc"
pass=$((pass + 1))
fi
}
expect_same_static_diag_check_run() {
local desc="$1"
local src="$2"
set +e
"$PS" check "$src" >/tmp/ps_cli_check.out 2>&1
local rc_check=$?
"$PS" run "$src" >/tmp/ps_cli_run.out 2>&1
local rc_run=$?
set -e
if [[ "$rc_check" -eq 0 || "$rc_run" -eq 0 ]]; then
echo "FAIL $desc"
echo " expected non-zero for both check and run"
echo " check rc=$rc_check run rc=$rc_run"
fail=$((fail + 1))
return
fi
if cmp -s /tmp/ps_cli_check.out /tmp/ps_cli_run.out; then
echo "PASS $desc"
pass=$((pass + 1))
else
echo "FAIL $desc"
echo " check and run diagnostics differ"
echo " check output:"
sed -n '1,80p' /tmp/ps_cli_check.out
echo " run output:"
sed -n '1,80p' /tmp/ps_cli_run.out
fail=$((fail + 1))
fi
}
expect_node_c_run_parity() {
local desc="$1"
local src="$2"
local node_bin="$ROOT_DIR/bin/protoscriptc"
set +e
"$node_bin" --run "$src" >/tmp/ps_cli_node.out 2>&1
local rc_node=$?
"$PS" run "$src" >/tmp/ps_cli_c.out 2>&1
local rc_c=$?
set -e
if [[ "$rc_node" -eq 0 && "$rc_c" -ne 0 ]]; then
echo "FAIL $desc"
echo " node succeeded but c/ps failed"
sed -n '1,80p' /tmp/ps_cli_node.out
sed -n '1,80p' /tmp/ps_cli_c.out
fail=$((fail + 1))
return
fi
if [[ "$rc_node" -ne 0 && "$rc_c" -eq 0 ]]; then
echo "FAIL $desc"
echo " node failed but c/ps succeeded"
sed -n '1,80p' /tmp/ps_cli_node.out
sed -n '1,80p' /tmp/ps_cli_c.out
fail=$((fail + 1))
return
fi
if cmp -s /tmp/ps_cli_node.out /tmp/ps_cli_c.out; then
echo "PASS $desc"
pass=$((pass + 1))
else
echo "FAIL $desc"
echo " output differs between protoscriptc --run and c/ps run"
echo " node output:"
sed -n '1,80p' /tmp/ps_cli_node.out
echo " c/ps output:"
sed -n '1,80p' /tmp/ps_cli_c.out
fail=$((fail + 1))
fi
}
expect_token_dump_parity() {
local desc="$1"
local src="$2"
local node_bin="$ROOT_DIR/bin/protoscriptc"
local c_bin="$ROOT_DIR/c/pscc"
set +e
"$node_bin" --dump-tokens "$src" >/tmp/ps_cli_tokens_node.out 2>/tmp/ps_cli_tokens_node.err
local rc_node=$?
"$c_bin" --dump-tokens "$src" >/tmp/ps_cli_tokens_c.out 2>/tmp/ps_cli_tokens_c.err
local rc_c=$?
set -e
if [[ "$rc_node" -ne 0 || "$rc_c" -ne 0 ]]; then
echo "FAIL $desc"
echo " expected token dump success"
echo " node rc=$rc_node c rc=$rc_c"
echo " node stderr:"
sed -n '1,80p' /tmp/ps_cli_tokens_node.err
echo " c stderr:"
sed -n '1,80p' /tmp/ps_cli_tokens_c.err
fail=$((fail + 1))
return
fi
if cmp -s /tmp/ps_cli_tokens_node.out /tmp/ps_cli_tokens_c.out; then
echo "PASS $desc"
pass=$((pass + 1))
else
echo "FAIL $desc"
echo " token dump differs between Node and C"
echo " node dump:"
sed -n '1,80p' /tmp/ps_cli_tokens_node.out
echo " c dump:"
sed -n '1,80p' /tmp/ps_cli_tokens_c.out
fail=$((fail + 1))
fi
}
echo "== ProtoScript CLI Tests =="
echo "PS: $PS"
echo
expect_exit "help" 0 "$PS" --help
expect_exit "version" 0 "$PS" --version
expect_exit "inline -e" 0 "$PS" -e "int x = 1 + 2;"
expect_output_contains "repl prompt" "ps> " bash -c "printf 'exit\n' | \"$PS\" repl"
expect_output_contains "run outputs" "hello" "$PS" run "$ROOT_DIR/tests/cli/hello.pts"
expect_output_contains "run if basic" "yes" "$PS" run "$ROOT_DIR/tests/cli/if_basic.pts"
expect_output_contains "run list concat" "hello world" "$PS" run "$ROOT_DIR/tests/cli/list_concat.pts"
expect_output_contains "run io temp path" "ok" "$PS" run "$ROOT_DIR/tests/cli/io_temp_path.pts"
expect_output_contains "run proto bool field" "true" "$PS" run "$ROOT_DIR/tests/cli/proto_bool_field.pts"
expect_output_contains "run control flow continuation" "after_try" "$PS" run "$ROOT_DIR/tests/cli/control_flow_continuation.pts"
expect_output_contains "run generic compare shift" "true" "$PS" run "$ROOT_DIR/tests/edge/generic_compare_shift.pts"
expect_output_contains "run generic type then expr bool" "false" "$PS" run "$ROOT_DIR/tests/edge/generic_type_then_expr.pts"
expect_output_contains "run generic type then expr shift" "0" "$PS" run "$ROOT_DIR/tests/edge/generic_type_then_expr.pts"
expect_node_c_run_parity "run parity clone inherited throw" "$ROOT_DIR/tests/cli/clone_inherited_throw_parity.pts"
expect_output_contains "run manual ex008" "1" "$PS" run "$ROOT_DIR/tests/cli/manual_ex008.pts"
expect_output_contains "run manual ex010" "12" "$PS" run "$ROOT_DIR/tests/cli/manual_ex010.pts"
expect_output_contains "run manual ex011" "42" "$PS" run "$ROOT_DIR/tests/cli/manual_ex011.pts"
expect_output_contains "run manual ex012" "0.001" "$PS" run "$ROOT_DIR/tests/cli/manual_ex012.pts"
expect_output_contains "run manual ex013" "Bonjour" "$PS" run "$ROOT_DIR/tests/cli/manual_ex013.pts"
expect_output_contains "run manual ex014" "☺" "$PS" run "$ROOT_DIR/tests/cli/manual_ex014.pts"
expect_output_contains "run manual ex015" "a=1" "$PS" run "$ROOT_DIR/tests/cli/manual_ex015.pts"
expect_output_contains "run manual ex016" "0" "$PS" run "$ROOT_DIR/tests/cli/manual_ex016.pts"
expect_output_contains "run manual ex018" "10" "$PS" run "$ROOT_DIR/tests/cli/manual_ex018.pts"
expect_output_contains "run manual ex019" "ok" "$PS" run "$ROOT_DIR/tests/cli/manual_ex019.pts"
expect_output_contains "run manual ex021" "2" "$PS" run "$ROOT_DIR/tests/cli/manual_ex021.pts"
expect_output_contains "run manual ex024" "L0" "$PS" run "$ROOT_DIR/tests/cli/manual_ex024.pts"
expect_output_contains "run manual ex007" "json null" "$PS" run "$ROOT_DIR/tests/cli/manual_ex007.pts"
expect_exit "run exit code" 100 "$PS" run "$ROOT_DIR/tests/cli/exit_code.pts"
expect_exit "run static error exit" 1 "$PS" run "$ROOT_DIR/tests/invalid/type/type_mismatch_assignment.pts"
expect_error_contains_not_contains \
"run static redeclaration guard (no runtime)" \
"E3131 REDECLARATION" \
"R1011 UNHANDLED_EXCEPTION" \
"$PS" run "$ROOT_DIR/tests/invalid/type/redeclaration_same_scope.pts"
expect_same_static_diag_check_run \
"run/check static diag parity redeclaration" \
"$ROOT_DIR/tests/invalid/type/redeclaration_same_scope.pts"
expect_error_contains_not_contains \
"run multiple static errors guard (no runtime)" \
"E3131 REDECLARATION" \
"R1011 UNHANDLED_EXCEPTION" \
"$PS" run "$ROOT_DIR/tests/invalid/multiple_static_errors.pts"
expect_same_static_diag_check_run \
"run/check static diag parity multi-error-first" \
"$ROOT_DIR/tests/invalid/multiple_static_errors.pts"
expect_error_contains_not_contains \
"run --trace static error no runtime trace" \
"E3131 REDECLARATION" \
"[trace]" \
"$PS" --trace run "$ROOT_DIR/tests/invalid/multiple_static_errors.pts"
expect_error_contains_not_contains \
"run --trace --trace-ir static error no ir trace" \
"E3131 REDECLARATION" \
"[ir]" \
"$PS" --trace --trace-ir run "$ROOT_DIR/tests/invalid/multiple_static_errors.pts"
expect_exit "argv passthrough" 0 "$PS" run "$ROOT_DIR/tests/cli/args.pts"
expect_exit "runtime error exit" 1 "$PS" run "$ROOT_DIR/tests/cli/runtime_error.pts"
expect_error_contains "preprocess mapping" "mapped_file.pts:202:17 R1004 RUNTIME_DIVIDE_BY_ZERO:" "$PS" run "$ROOT_DIR/tests/cli/preprocess_runtime_error.pts"
abs_module_path="$ROOT_DIR/tests/fixtures/datastruct/Stack.pts"
tmp_abs_import="$(mktemp)"
cat >"$tmp_abs_import" <<EOF
import Io;
import "$abs_module_path";
function main() : void {
Stack s = Stack.clone();
int v = s.value();
Io.printLine(v.toString());
}
EOF
expect_output_contains "run import abs path" "444" "$PS" run "$tmp_abs_import"
rm -f "$tmp_abs_import"
expect_exit "static check success" 0 "$PS" check "$ROOT_DIR/tests/cli/hello.pts"
expect_exit "pscc check if basic" 0 "$ROOT_DIR/c/pscc" --check "$ROOT_DIR/tests/cli/if_basic.pts"
expect_exit "pscc check list concat" 0 "$ROOT_DIR/c/pscc" --check "$ROOT_DIR/tests/cli/list_concat.pts"
expect_exit "pscc check proto bool field" 0 "$ROOT_DIR/c/pscc" --check "$ROOT_DIR/tests/cli/proto_bool_field.pts"
expect_exit "pscc check control flow continuation" 0 "$ROOT_DIR/c/pscc" --check "$ROOT_DIR/tests/cli/control_flow_continuation.pts"
expect_exit "pscc check manual ex008" 0 "$ROOT_DIR/c/pscc" --check "$ROOT_DIR/tests/cli/manual_ex008.pts"
expect_exit "pscc check manual ex010" 0 "$ROOT_DIR/c/pscc" --check "$ROOT_DIR/tests/cli/manual_ex010.pts"
expect_exit "pscc check manual ex011" 0 "$ROOT_DIR/c/pscc" --check "$ROOT_DIR/tests/cli/manual_ex011.pts"
expect_exit "pscc check manual ex012" 0 "$ROOT_DIR/c/pscc" --check "$ROOT_DIR/tests/cli/manual_ex012.pts"
expect_exit "pscc check manual ex013" 0 "$ROOT_DIR/c/pscc" --check "$ROOT_DIR/tests/cli/manual_ex013.pts"
expect_exit "pscc check manual ex014" 0 "$ROOT_DIR/c/pscc" --check "$ROOT_DIR/tests/cli/manual_ex014.pts"
expect_exit "pscc check manual ex015" 0 "$ROOT_DIR/c/pscc" --check "$ROOT_DIR/tests/cli/manual_ex015.pts"
expect_exit "pscc check manual ex016" 0 "$ROOT_DIR/c/pscc" --check "$ROOT_DIR/tests/cli/manual_ex016.pts"
expect_exit "pscc check manual ex018" 0 "$ROOT_DIR/c/pscc" --check "$ROOT_DIR/tests/cli/manual_ex018.pts"
expect_exit "pscc check manual ex019" 0 "$ROOT_DIR/c/pscc" --check "$ROOT_DIR/tests/cli/manual_ex019.pts"
expect_exit "pscc check manual ex021" 0 "$ROOT_DIR/c/pscc" --check "$ROOT_DIR/tests/cli/manual_ex021.pts"
expect_exit "pscc check manual ex024" 0 "$ROOT_DIR/c/pscc" --check "$ROOT_DIR/tests/cli/manual_ex024.pts"
expect_exit "generic nested glyph check" 0 "$PS" check "$ROOT_DIR/tests/edge/generic_nested_types.pts"
expect_exit "generic deep nesting check" 0 "$PS" check "$ROOT_DIR/tests/edge/generic_deep_nesting.pts"
expect_exit "generic function param check" 0 "$PS" check "$ROOT_DIR/tests/edge/generic_function_param.pts"
expect_exit "generic deep then shift check" 0 "$PS" check "$ROOT_DIR/tests/edge/generic_deep_then_shift.pts"
expect_exit "pscc generic nested glyph check" 0 "$ROOT_DIR/c/pscc" --check "$ROOT_DIR/tests/edge/generic_nested_types.pts"
expect_exit "pscc generic deep nesting check" 0 "$ROOT_DIR/c/pscc" --check "$ROOT_DIR/tests/edge/generic_deep_nesting.pts"
expect_exit "pscc generic function param check" 0 "$ROOT_DIR/c/pscc" --check "$ROOT_DIR/tests/edge/generic_function_param.pts"
expect_exit "pscc generic deep then shift check" 0 "$ROOT_DIR/c/pscc" --check "$ROOT_DIR/tests/edge/generic_deep_then_shift.pts"
expect_exit "pscc check empty list no context" 1 "$ROOT_DIR/c/pscc" --check "$ROOT_DIR/tests/invalid/type/empty_list_no_context.pts"
expect_exit "pscc check empty map no context" 1 "$ROOT_DIR/c/pscc" --check "$ROOT_DIR/tests/invalid/type/empty_map_no_context.pts"
expect_exit "pscc check manual ex007" 0 "$ROOT_DIR/c/pscc" --check "$ROOT_DIR/tests/cli/manual_ex007.pts"
expect_exit "static check exit" 2 "$PS" check "$ROOT_DIR/tests/invalid/type/type_mismatch_assignment.pts"
expect_exit "static check uninitialized call arg" 2 "$PS" check "$ROOT_DIR/tests/invalid/type/uninitialized_read_call_arg.pts"
expect_exit "static check empty list no context" 2 "$PS" check "$ROOT_DIR/tests/invalid/type/empty_list_no_context.pts"
expect_exit "static check empty map no context" 2 "$PS" check "$ROOT_DIR/tests/invalid/type/empty_map_no_context.pts"
expect_exit "static check null literal" 2 "$PS" check "$ROOT_DIR/tests/invalid/type/null_literal.pts"
expect_output_contains "ast outputs" "\"kind\"" "$PS" ast "$ROOT_DIR/tests/cli/exit_code.pts"
expect_output_contains "ir outputs" "\"functions\"" "$PS" ir "$ROOT_DIR/tests/cli/exit_code.pts"
expect_exit "trace enabled" 0 "$PS" run "$ROOT_DIR/tests/cli/hello.pts" --trace
expect_output_contains "trace-ir enabled" "[ir]" "$PS" run "$ROOT_DIR/tests/cli/hello.pts" --trace-ir
expect_output_contains "time enabled" "time:" "$PS" run "$ROOT_DIR/tests/cli/hello.pts" --time
expect_output_contains "pscc emit-c outputs C" "int main" "$ROOT_DIR/c/pscc" --emit-c "$ROOT_DIR/tests/cli/exit_code.pts"
expect_token_dump_parity "token dump parity generic context" "$ROOT_DIR/tests/edge/generic_token_parity.pts"
expect_output_exact() {
local desc="$1"
local expected_file="$2"
shift 2
set +e
"$@" >/tmp/ps_cli_test.out 2>&1
local rc=$?
set -e
if [[ "$rc" -ne 0 ]]; then
echo "FAIL $desc"
echo " expected exit 0, got $rc"
echo " cmd: $*"
echo " output:"
sed -n '1,80p' /tmp/ps_cli_test.out
fail=$((fail + 1))
return
fi
if cmp -s /tmp/ps_cli_test.out "$expected_file"; then
echo "PASS $desc"
pass=$((pass + 1))
else
echo "FAIL $desc"
echo " output differs from expected"
echo " cmd: $*"
echo " expected:"
sed -n '1,80p' "$expected_file"
echo " actual:"
sed -n '1,80p' /tmp/ps_cli_test.out
fail=$((fail + 1))
fi
}
# Manual examples (runtime, exact stdout)
for exp in "$ROOT_DIR/tests/edge/manual_ex"*.expect.json; do
[[ -f "$exp" ]] || continue
status="$(json_status "$exp")"
if [[ "$status" != "accept-runtime" ]]; then
continue
fi
case_id="$(basename "$exp" .expect.json)"
expected_file="/tmp/ps_cli_expected.out"
json_stdout "$exp" >"$expected_file"
expect_output_exact "run $case_id" "$expected_file" "$PS" run "$ROOT_DIR/tests/edge/$case_id.pts"
done
# Manual examples (static errors)
for exp in "$ROOT_DIR/tests/invalid/parse/manual_ex"*.expect.json "$ROOT_DIR/tests/invalid/type/manual_ex"*.expect.json; do
[[ -f "$exp" ]] || continue
case_id="$(basename "$exp" .expect.json)"
suite_dir="$(dirname "$exp")"
expect_exit "check $case_id" 2 "$PS" check "$suite_dir/$case_id.pts"
done
# Manual examples (runtime errors)
for exp in "$ROOT_DIR/tests/invalid/runtime/manual_ex"*.expect.json; do
[[ -f "$exp" ]] || continue
case_id="$(basename "$exp" .expect.json)"
suite_dir="$(dirname "$exp")"
expect_exit "run $case_id runtime" 1 "$PS" run "$suite_dir/$case_id.pts"
done
# pscc checks for manual examples
for src in "$ROOT_DIR/tests/edge/manual_ex"*.pts; do
[[ -f "$src" ]] || continue
case_id="$(basename "$src" .pts)"
expect_exit "pscc check $case_id" 0 "$ROOT_DIR/c/pscc" --check "$src"
done
echo
echo "Summary: PASS=$pass FAIL=$fail TOTAL=$((pass + fail))"
if [[ "$fail" -ne 0 ]]; then
exit 1
fi