Files
libakstdlib/tests/test_tree.c

114 lines
3.1 KiB
C
Raw Normal View History

Build a real test harness (TODO.md section 1.0) The suite could not fail and did not run. test_linkedlist.c asserted nothing at all -- it printed node names and returned 0 -- so every confirmed list defect passed it. test_tree.c was red on every run because parms.steps was never reset between its three searches, and four libakerror tests registered but never built, reporting Not Run. CI, meanwhile, was not fetching the submodule, so configure failed before reaching any of it. - tests/aksl_capture.h: AKSL_CHECK (NDEBUG-proof), AKSL_CHECK_STATUS/_OK to run an akerror-returning call, assert its status and release the context, a capturing akerr_log_method, aksl_slots_in_use(), and an AKSL_RUN driver that fails any test leaking an error-pool slot. - test_linkedlist.c: rewritten as 15 assertion cases over the append, iterate and pop behaviour that is correct today. - test_tree.c: each search builds its own tree and params. - Registration driven by AKSL_TESTS, plus AKSL_WILL_FAIL_TESTS (aborts by design) and AKSL_KNOWN_FAILING_TESTS, which marks WILL_FAIL the three new tests asserting correct behaviour for the confirmed defects in TODO.md 2.1.1-2.1.3. Fixing a defect flips its test to "unexpectedly passed", which is the cue to promote it into AKSL_TESTS. - add_test/set_tests_properties are shadowed across the libakerror add_subdirectory call: CMake cannot un-register a test and set_tests_properties cannot cross directory scopes. The dependency has its own CI. - AKSL_SANITIZE=ON builds library, tests and dependency with ASan+UBSan. - scripts/mutation_test.py ported and retargeted at src/stdlib.c; wired to a manual `mutation` target, not a CI gate until 1.1-1.9 exist. - CI: checkout with submodules: recursive, and ctest --output-on-failure. ctest is now 5/5 green in both the default and sanitizer builds. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-28 12:39:54 -04:00
/*
* Depth-first tree search.
*
* Previously this test shared one TreeSearchParams across all three searches
* without resetting it, so `steps` accumulated (7, then 14, then 21) and the
* second assertion failed -- `tree` was a red test on every run. Each search
* now gets its own params.
*
* Caveat worth knowing when reading the step counts below: the value is hidden
* in tree[6], which is the last node visited in pre-, in- and post-order alike,
* so "7 steps" holds for all three orders and does not actually distinguish
* them -- nor does it prove that AKERR_ITERATOR_BREAK stopped anything (it does
* not; see tests/test_tree_iterate_break.c and TODO.md 2.1.3). Visit-order
* assertions that tell the three traversals apart are TODO.md section 1.8.
*/
2026-06-27 13:13:17 -04:00
Build a real test harness (TODO.md section 1.0) The suite could not fail and did not run. test_linkedlist.c asserted nothing at all -- it printed node names and returned 0 -- so every confirmed list defect passed it. test_tree.c was red on every run because parms.steps was never reset between its three searches, and four libakerror tests registered but never built, reporting Not Run. CI, meanwhile, was not fetching the submodule, so configure failed before reaching any of it. - tests/aksl_capture.h: AKSL_CHECK (NDEBUG-proof), AKSL_CHECK_STATUS/_OK to run an akerror-returning call, assert its status and release the context, a capturing akerr_log_method, aksl_slots_in_use(), and an AKSL_RUN driver that fails any test leaking an error-pool slot. - test_linkedlist.c: rewritten as 15 assertion cases over the append, iterate and pop behaviour that is correct today. - test_tree.c: each search builds its own tree and params. - Registration driven by AKSL_TESTS, plus AKSL_WILL_FAIL_TESTS (aborts by design) and AKSL_KNOWN_FAILING_TESTS, which marks WILL_FAIL the three new tests asserting correct behaviour for the confirmed defects in TODO.md 2.1.1-2.1.3. Fixing a defect flips its test to "unexpectedly passed", which is the cue to promote it into AKSL_TESTS. - add_test/set_tests_properties are shadowed across the libakerror add_subdirectory call: CMake cannot un-register a test and set_tests_properties cannot cross directory scopes. The dependency has its own CI. - AKSL_SANITIZE=ON builds library, tests and dependency with ASan+UBSan. - scripts/mutation_test.py ported and retargeted at src/stdlib.c; wired to a manual `mutation` target, not a CI gate until 1.1-1.9 exist. - CI: checkout with submodules: recursive, and ctest --output-on-failure. ctest is now 5/5 green in both the default and sanitizer builds. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-28 12:39:54 -04:00
#include "aksl_capture.h"
#define MAX_LEAVES 7
#define HIDDEN_VALUE ((void *)17336)
2026-06-27 13:13:17 -04:00
typedef struct TreeSearchParams
{
void *value;
int steps;
aksl_TreeNode *node;
} TreeSearchParams;
Build a real test harness (TODO.md section 1.0) The suite could not fail and did not run. test_linkedlist.c asserted nothing at all -- it printed node names and returned 0 -- so every confirmed list defect passed it. test_tree.c was red on every run because parms.steps was never reset between its three searches, and four libakerror tests registered but never built, reporting Not Run. CI, meanwhile, was not fetching the submodule, so configure failed before reaching any of it. - tests/aksl_capture.h: AKSL_CHECK (NDEBUG-proof), AKSL_CHECK_STATUS/_OK to run an akerror-returning call, assert its status and release the context, a capturing akerr_log_method, aksl_slots_in_use(), and an AKSL_RUN driver that fails any test leaking an error-pool slot. - test_linkedlist.c: rewritten as 15 assertion cases over the append, iterate and pop behaviour that is correct today. - test_tree.c: each search builds its own tree and params. - Registration driven by AKSL_TESTS, plus AKSL_WILL_FAIL_TESTS (aborts by design) and AKSL_KNOWN_FAILING_TESTS, which marks WILL_FAIL the three new tests asserting correct behaviour for the confirmed defects in TODO.md 2.1.1-2.1.3. Fixing a defect flips its test to "unexpectedly passed", which is the cue to promote it into AKSL_TESTS. - add_test/set_tests_properties are shadowed across the libakerror add_subdirectory call: CMake cannot un-register a test and set_tests_properties cannot cross directory scopes. The dependency has its own CI. - AKSL_SANITIZE=ON builds library, tests and dependency with ASan+UBSan. - scripts/mutation_test.py ported and retargeted at src/stdlib.c; wired to a manual `mutation` target, not a CI gate until 1.1-1.9 exist. - CI: checkout with submodules: recursive, and ctest --output-on-failure. ctest is now 5/5 green in both the default and sanitizer builds. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-28 12:39:54 -04:00
static akerr_ErrorContext AKERR_NOIGNORE *find_value(aksl_TreeNode *node, void *data)
2026-06-27 13:13:17 -04:00
{
TreeSearchParams *parms = NULL;
Build a real test harness (TODO.md section 1.0) The suite could not fail and did not run. test_linkedlist.c asserted nothing at all -- it printed node names and returned 0 -- so every confirmed list defect passed it. test_tree.c was red on every run because parms.steps was never reset between its three searches, and four libakerror tests registered but never built, reporting Not Run. CI, meanwhile, was not fetching the submodule, so configure failed before reaching any of it. - tests/aksl_capture.h: AKSL_CHECK (NDEBUG-proof), AKSL_CHECK_STATUS/_OK to run an akerror-returning call, assert its status and release the context, a capturing akerr_log_method, aksl_slots_in_use(), and an AKSL_RUN driver that fails any test leaking an error-pool slot. - test_linkedlist.c: rewritten as 15 assertion cases over the append, iterate and pop behaviour that is correct today. - test_tree.c: each search builds its own tree and params. - Registration driven by AKSL_TESTS, plus AKSL_WILL_FAIL_TESTS (aborts by design) and AKSL_KNOWN_FAILING_TESTS, which marks WILL_FAIL the three new tests asserting correct behaviour for the confirmed defects in TODO.md 2.1.1-2.1.3. Fixing a defect flips its test to "unexpectedly passed", which is the cue to promote it into AKSL_TESTS. - add_test/set_tests_properties are shadowed across the libakerror add_subdirectory call: CMake cannot un-register a test and set_tests_properties cannot cross directory scopes. The dependency has its own CI. - AKSL_SANITIZE=ON builds library, tests and dependency with ASan+UBSan. - scripts/mutation_test.py ported and retargeted at src/stdlib.c; wired to a manual `mutation` target, not a CI gate until 1.1-1.9 exist. - CI: checkout with submodules: recursive, and ctest --output-on-failure. ctest is now 5/5 green in both the default and sanitizer builds. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-28 12:39:54 -04:00
2026-06-27 13:13:17 -04:00
PREPARE_ERROR(e);
FAIL_ZERO_RETURN(e, node, AKERR_NULLPOINTER, "node");
FAIL_ZERO_RETURN(e, data, AKERR_NULLPOINTER, "data");
parms = (TreeSearchParams *)data;
parms->steps += 1;
if ( node->leaf == parms->value ) {
parms->node = node;
FAIL_RETURN(e, AKERR_ITERATOR_BREAK, "stop");
}
SUCCEED_RETURN(e);
}
Build a real test harness (TODO.md section 1.0) The suite could not fail and did not run. test_linkedlist.c asserted nothing at all -- it printed node names and returned 0 -- so every confirmed list defect passed it. test_tree.c was red on every run because parms.steps was never reset between its three searches, and four libakerror tests registered but never built, reporting Not Run. CI, meanwhile, was not fetching the submodule, so configure failed before reaching any of it. - tests/aksl_capture.h: AKSL_CHECK (NDEBUG-proof), AKSL_CHECK_STATUS/_OK to run an akerror-returning call, assert its status and release the context, a capturing akerr_log_method, aksl_slots_in_use(), and an AKSL_RUN driver that fails any test leaking an error-pool slot. - test_linkedlist.c: rewritten as 15 assertion cases over the append, iterate and pop behaviour that is correct today. - test_tree.c: each search builds its own tree and params. - Registration driven by AKSL_TESTS, plus AKSL_WILL_FAIL_TESTS (aborts by design) and AKSL_KNOWN_FAILING_TESTS, which marks WILL_FAIL the three new tests asserting correct behaviour for the confirmed defects in TODO.md 2.1.1-2.1.3. Fixing a defect flips its test to "unexpectedly passed", which is the cue to promote it into AKSL_TESTS. - add_test/set_tests_properties are shadowed across the libakerror add_subdirectory call: CMake cannot un-register a test and set_tests_properties cannot cross directory scopes. The dependency has its own CI. - AKSL_SANITIZE=ON builds library, tests and dependency with ASan+UBSan. - scripts/mutation_test.py ported and retargeted at src/stdlib.c; wired to a manual `mutation` target, not a CI gate until 1.1-1.9 exist. - CI: checkout with submodules: recursive, and ctest --output-on-failure. ctest is now 5/5 green in both the default and sanitizer builds. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-28 12:39:54 -04:00
/*
* Build the 3-level tree used by every case here, with the search value hidden
* in the bottom-right leaf.
*
* LEFT RIGHT
* TREE[0]
* +--------^^---------+
* | |
* TREE[1] TREE[2]
* +---^^---+ +---^^---+
* | | | |
*TREE[3] TREE[4] TREE[5] TREE[6]
*/
static void build_tree(aksl_TreeNode *tree, TreeSearchParams *parms)
{
memset((void *)tree, 0x00, sizeof(aksl_TreeNode) * MAX_LEAVES);
tree[0].left = &tree[1];
tree[0].right = &tree[2];
tree[1].left = &tree[3];
tree[1].right = &tree[4];
tree[2].left = &tree[5];
tree[2].right = &tree[6];
tree[6].leaf = HIDDEN_VALUE;
memset((void *)parms, 0x00, sizeof(TreeSearchParams));
parms->value = HIDDEN_VALUE;
}
static int search_finds_hidden_value(uint8_t searchmode)
{
aksl_TreeNode tree[MAX_LEAVES];
TreeSearchParams parms;
build_tree(tree, &parms);
AKSL_CHECK_OK(aksl_tree_iterate(&tree[0], &find_value, NULL, NULL,
searchmode, &parms, NULL));
AKSL_CHECK(parms.node == &tree[6]);
AKSL_CHECK(parms.steps == MAX_LEAVES);
return 0;
}
static int test_dfs_preorder(void)
{
return search_finds_hidden_value(AKSL_TREE_SEARCH_DFS_PREORDER);
}
static int test_dfs_inorder(void)
{
return search_finds_hidden_value(AKSL_TREE_SEARCH_DFS_INORDER);
}
static int test_dfs_postorder(void)
{
return search_finds_hidden_value(AKSL_TREE_SEARCH_DFS_POSTORDER);
}
2026-06-27 13:13:17 -04:00
int main(void)
{
Build a real test harness (TODO.md section 1.0) The suite could not fail and did not run. test_linkedlist.c asserted nothing at all -- it printed node names and returned 0 -- so every confirmed list defect passed it. test_tree.c was red on every run because parms.steps was never reset between its three searches, and four libakerror tests registered but never built, reporting Not Run. CI, meanwhile, was not fetching the submodule, so configure failed before reaching any of it. - tests/aksl_capture.h: AKSL_CHECK (NDEBUG-proof), AKSL_CHECK_STATUS/_OK to run an akerror-returning call, assert its status and release the context, a capturing akerr_log_method, aksl_slots_in_use(), and an AKSL_RUN driver that fails any test leaking an error-pool slot. - test_linkedlist.c: rewritten as 15 assertion cases over the append, iterate and pop behaviour that is correct today. - test_tree.c: each search builds its own tree and params. - Registration driven by AKSL_TESTS, plus AKSL_WILL_FAIL_TESTS (aborts by design) and AKSL_KNOWN_FAILING_TESTS, which marks WILL_FAIL the three new tests asserting correct behaviour for the confirmed defects in TODO.md 2.1.1-2.1.3. Fixing a defect flips its test to "unexpectedly passed", which is the cue to promote it into AKSL_TESTS. - add_test/set_tests_properties are shadowed across the libakerror add_subdirectory call: CMake cannot un-register a test and set_tests_properties cannot cross directory scopes. The dependency has its own CI. - AKSL_SANITIZE=ON builds library, tests and dependency with ASan+UBSan. - scripts/mutation_test.py ported and retargeted at src/stdlib.c; wired to a manual `mutation` target, not a CI gate until 1.1-1.9 exist. - CI: checkout with submodules: recursive, and ctest --output-on-failure. ctest is now 5/5 green in both the default and sanitizer builds. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-28 12:39:54 -04:00
int failures = 0;
akerr_init();
AKSL_RUN(failures, test_dfs_preorder);
AKSL_RUN(failures, test_dfs_inorder);
AKSL_RUN(failures, test_dfs_postorder);
AKSL_REPORT(failures);
2026-06-27 13:13:17 -04:00
}