Three audit findings around polish + a release-readiness commit:
* #UX1 LIST/DISPLAY output: dropped \r\n (unix terminals showed a
stray ^M), moved the newline to AFTER each row (no more leading
blank line), and added the `*` deleted-record marker after the
record number — matches xBase LIST/DISPLAY convention. With
SET DELETED ON the marker is unreachable since the row would
have been skipped at Area.Skip level; with SET DELETED OFF the
user now sees which rows are tombstoned.
* #26 temp aliases: `__copytmp` / `__sorttmp` / `__totaltmp` /
`__jointmp` were process-global string constants. A nested
invocation (e.g., COPY inside a FOR clause whose expression
runs another COPY) collided on the alias and the inner Open
failed with "alias already in use" — surfacing as `.F.` with
no clear cause. Each Open now goes through a new helper
`nextTmpAlias(prefix)` backed by an atomic counter, so every
call gets `__copytmp_1`, `__copytmp_2`, etc. — no collisions.
* #J test coverage gap: the 13 std.ch regression tests were all
sitting in `/tmp` — lost on tmpfs reboot, never in git, never
in CI. Move them into `tests/std_ch/` and add a simple
`run.sh` runner that builds + executes each one in a temp
scratch directory and grep-asserts on FAIL / NOT REJECTED /
expectation-mismatch markers. 13/13 pass against the current
head:
PASS test_pp_stdch PASS test_count
PASS test_sum_avg PASS test_sum_multi
PASS test_copy PASS test_sort
PASS test_list PASS test_total
PASS test_join PASS test_update
PASS test_set_deleted PASS test_unsupported
PASS test_block_comma
test_block_comma in particular guards the gengo SeqExpr fix
from Wave 1 — without it the comma-in-block miscompile would
silently come back.
Gates green:
go test ./... : PASS
FiveSql2 SQL:1999 : 43/43
Harbour compat : 56/56
std.ch suite : 13/13
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
40 lines
1.2 KiB
Plaintext
40 lines
1.2 KiB
Plaintext
/* Test that std.ch #command rules expand correctly. */
|
|
|
|
PROCEDURE Main()
|
|
LOCAL cName := "/tmp/__pp_test_std_ch.tmp"
|
|
|
|
/* Create a junk file so ERASE/RENAME have something to work with. */
|
|
hb_MemoWrit( cName, "x" )
|
|
? "1. file created exists?", File( cName ), "(expect .T.)"
|
|
|
|
/* ERASE <(f)> → FErase(<(f)>) */
|
|
ERASE ( cName )
|
|
? "2. after ERASE exists?", File( cName ), "(expect .F.)"
|
|
|
|
/* RENAME — recreate, rename, check both. */
|
|
hb_MemoWrit( cName, "y" )
|
|
RENAME ( cName ) TO ( cName + ".moved" )
|
|
? "3. after RENAME orig exists?", File( cName ), "(expect .F.)"
|
|
? " moved exists?", File( cName + ".moved" ), "(expect .T.)"
|
|
FErase( cName + ".moved" )
|
|
|
|
/* DELETE FILE <(f)> alias for ERASE */
|
|
hb_MemoWrit( cName, "z" )
|
|
DELETE FILE ( cName )
|
|
? "4. after DELETE FILE exists?", File( cName ), "(expect .F.)"
|
|
|
|
/* CLOSE / CLOSE ALL / CLOSE DATABASES — should compile without
|
|
hardcoded parser support. They each call DbCloseArea or
|
|
DbCloseAll. With no open workareas, both are no-ops. */
|
|
CLOSE
|
|
CLOSE ALL
|
|
CLOSE DATABASES
|
|
? "5. CLOSE / CLOSE ALL / CLOSE DATABASES compiled OK"
|
|
|
|
/* COMMIT — DbCommit() with no open area is a no-op too. */
|
|
COMMIT
|
|
? "6. COMMIT compiled OK"
|
|
|
|
? "DONE"
|
|
RETURN
|