Replace the single file-structure.md with a stratified layout designed
for AI/agent skill consumption: tables and concrete identifiers over
prose, files loaded on demand, content separated by churn rate.
Layers:
- architecture/ stable structural reference (overview, source-map,
test-map, data-flow)
- patterns/ memory, commands, autocomplete, events, xmpp,
encryption, ui, plugins
- testing/ unit-tests, stubs, functional-tests, bench
- build/ local, docker, ci
- playbooks/ add-command, add-test, add-autocomplete,
add-event-handler, add-encryption
- gotchas.md append-only dated entries (seven seed entries)
- wip/ branch-specific notes; deleted on merge to master
Stable layers describe cproof on master only. In-flight feature
branches (currently feat/ai) get a single file under wip/.
INDEX.md is the entry map with churn labels; SKILL.md is the
always-loaded skill hint pointing to it.
2.4 KiB
Playbook: add a unit test file
Recipe for a new tests/unittests/test_<topic>.c + .h pair.
1. Create the header
tests/unittests/test_<topic>.h:
#ifndef TEST_<TOPIC>_H
#define TEST_<TOPIC>_H
void test_<topic>_<scenario_1>(void** state);
void test_<topic>_<scenario_2>(void** state);
#endif
One declaration per test function. Headers exist solely so unittests.c can
include them and reference each function symbol.
2. Create the source
tests/unittests/test_<topic>.c:
#include "config.h"
#include "prof_cmocka.h"
#include <stdarg.h>
#include <stddef.h>
#include <setjmp.h>
#include <cmocka.h>
#include "test_<topic>.h"
// ... includes for the unit under test and any types it needs ...
void
test_<topic>_<scenario_1>(void** state)
{
// Arrange — `will_return`, `expect_string`, etc.
// Act — call the unit
// Assert — `assert_*`
}
3. Register in unittests.c
#include "test_<topic>.h"
// inside the tests[] array passed to cmocka_run_group_tests:
cmocka_unit_test(test_<topic>_<scenario_1>),
cmocka_unit_test(test_<topic>_<scenario_2>),
If multiple tests share fixture, add a setup / teardown pair and use
cmocka_unit_test_setup_teardown (or define a per-topic macro near the top
of unittests.c, like muc_unit_test).
4. Stubs
For each external function the unit calls, ensure a stub exists in the
matching tests/unittests/<module>/stub_*.c. Three flavours:
- Pass-through — no observation needed.
mock()/will_return— test injects return values.check_expected()/expect_*— test asserts arguments.
See testing/stubs.md.
5. Wire into Make
tests/unittests/Makefile.am (or the active wiring file): add
test_<topic>.c to the unittests_SOURCES (or equivalent) list. Same for
any new stub file.
6. Build & run
Inside Docker:
./autogen.sh && ./configure && make -j$(nproc) check
Diagnose failures via tests/unittests/unittests.log and the cmocka stderr
output.
7. Conventions
- Test functions:
test_<topic>_<scenario>— nevertest_topic1,test_topic2. Names should describe the scenario. - One assertion focus per test (multiple
assert_*calls are fine; multiple unrelated assertions are not). - Don't reuse stubs across topic suites unless the call truly is uniform — diverging behaviour is a strong sign you want a dedicated stub.
- No I/O in unit tests. Filesystem, network, ncurses are all stubbed.