mirror of
https://github.com/fluffos/fluffos
synced 2026-08-12 18:26:06 -04:00
The runner (command/tests.lpc) now speaks the gtest protocol: a [ RUN ]/[ OK ]/[ FAILED ] block per test file with per-file timing (perf_counter_ns), then a recap with total checks/files/elapsed. Failed checks are RECORDED (tests.h OUTPUT -> master::record_failure; clear_last_error doubles as the check counter) and the run CONTINUES -- one run reports every failure, then the recap lists each failed file and the driver exits nonzero; "Checks succeeded." + exit 0 is the pass signal. Interactive runs report without shutting the driver down. -ftest also accepts globs now (-ftest:efuns/dual*), and the fail-dir compile-log copy is skipped when a filtered run compiled nothing. The suite is a first-class ctest test: add_test(lpc-testsuite) with PASS/FAIL_REGULAR_EXPRESSION and LABELS lpc; CI's two test steps are now ctest -LE lpc (GTest) and ctest -L lpc (this suite). New coverage: - compiler/preprocessor.lpc: end-to-end pins for ## paste, # stringize, nested-comma arguments, backslash continuation, self-reference termination, redefinition-takes-effect, #warn survival, #undef, defined()/token-precedence #if, __FILE__/__DIR__/__LINE__ - compiler/fail/inherit_exact_ext.lpc (+ dedicated never-loaded fixture): an explicit ".c" inherit of an .lpc-only file must fail -- fixture is private to the test because the extension-blind registry would otherwise satisfy the inherit under randomized order - dual_extension.lpc: children() is extension-blind across spellings; a ".c"-spelled inherit of an already-loaded .lpc program compiles (registry identity, the positive twin of the fail pin) - save_object.lpc: ".lpc"/".c" are stripped before ".o" is appended Verified: full suite x3 (ASan Debug, randomized order) + ctest 297/297, and RelWithDebInfo ctest -L lpc / -LE lpc all green. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
31 lines
1.3 KiB
C
31 lines
1.3 KiB
C
#ifndef TESTS_H
|
|
#define TESTS_H
|
|
|
|
#define SAFE(x) do {x} while(0)
|
|
|
|
#define CLEAR_ERROR (("/single/master"->clear_last_error() || 1))
|
|
|
|
// A failed check is written immediately (with the caught error trace),
|
|
// RECORDED with the master, and the run continues -- gtest semantics.
|
|
// The runner (/command/tests.lpc) reports every recorded failure at the
|
|
// end and exits nonzero; a stray failure outside a runner still fails
|
|
// the run through master::flag()'s recap.
|
|
#define OUTPUT(x) SAFE(write(catch(error(x))); \
|
|
"/single/master"->record_failure(x);)
|
|
#define WHERE __FILE__ + ":" + __LINE__
|
|
|
|
#define ASSERT(x) if (CLEAR_ERROR && !(x)) { OUTPUT(WHERE + ", Check failed.\n"); }
|
|
#define ASSERT2(x, r) if (CLEAR_ERROR && !(x)) { OUTPUT(WHERE + ", Check failed: " + r + ".\n"); }
|
|
#define ASSERT_EQ(x, y) do { CLEAR_ERROR; __assert_eq((x), (y), WHERE); } while (0)
|
|
#define ASSERT_NE(x, y) do { CLEAR_ERROR; __assert_ne((x), (y), WHERE); } while (0)
|
|
|
|
#define SAVETP tp = this_player()
|
|
#define RESTORETP { if (tp) evaluate(bind( (: enable_commands :), tp)); else { object youd_never_use_this_as_a_var = new("/single/void"); evaluate(bind( (: enable_commands :), youd_never_use_this_as_a_var)); destruct(youd_never_use_this_as_a_var); } }
|
|
|
|
#ifdef __OLD_TYPE_BEHAVIOR__
|
|
#define TYPETEST scream and die
|
|
#else
|
|
#define TYPETEST
|
|
#endif
|
|
|
|
#endif
|