docs: split context into layered, agent-oriented files
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.
This commit is contained in:
113
testing/stubs.md
Normal file
113
testing/stubs.md
Normal file
@@ -0,0 +1,113 @@
|
||||
# Stubs
|
||||
|
||||
Unit tests link against the unit-under-test plus a parallel set of "stub"
|
||||
implementations of every dependency. Stubs are organised by module under
|
||||
`tests/unittests/<module>/`.
|
||||
|
||||
## Layout
|
||||
|
||||
| Stub directory | Replaces |
|
||||
|---|---|
|
||||
| `tests/unittests/chatlog/` | `src/chatlog.c` |
|
||||
| `tests/unittests/command/` | parts of `src/command/` |
|
||||
| `tests/unittests/config/` | `src/config/` (accounts, cafile, ...) |
|
||||
| `tests/unittests/database/` | `src/database.c` |
|
||||
| `tests/unittests/event/` | `src/event/` |
|
||||
| `tests/unittests/log/` | `src/log.c` |
|
||||
| `tests/unittests/omemo/` | `src/omemo/` |
|
||||
| `tests/unittests/otr/` | `src/otr/` |
|
||||
| `tests/unittests/pgp/` | `src/pgp/` |
|
||||
| `tests/unittests/plugins/` | `src/plugins/` |
|
||||
| `tests/unittests/tools/` | `src/tools/` |
|
||||
| `tests/unittests/ui/` | `src/ui/` |
|
||||
| `tests/unittests/xmpp/` | `src/xmpp/` |
|
||||
| `tests/unittests/unittests/` | top-level utility stubs |
|
||||
|
||||
Files are named `stub_<module>.c` (sometimes split, e.g.
|
||||
`tests/unittests/config/stub_accounts.c`, `stub_cafile.c`).
|
||||
|
||||
## Two stub flavours
|
||||
|
||||
### Pass-through default
|
||||
|
||||
Returns a benign default (NULL, FALSE, 0). Used when the test does not care
|
||||
about the call.
|
||||
|
||||
```c
|
||||
void
|
||||
chatlog_msg_in(...)
|
||||
{
|
||||
// no-op
|
||||
}
|
||||
```
|
||||
|
||||
### `will_return`-driven
|
||||
|
||||
The stub pops a value queued by the test:
|
||||
|
||||
```c
|
||||
jabber_conn_status_t
|
||||
connection_get_status(void)
|
||||
{
|
||||
return (jabber_conn_status_t)mock();
|
||||
}
|
||||
```
|
||||
|
||||
Test side:
|
||||
|
||||
```c
|
||||
will_return(connection_get_status, JABBER_CONNECTED);
|
||||
```
|
||||
|
||||
If the stub is `will_return`-driven, **every test** that exercises a code
|
||||
path through it must queue a value, or cmocka aborts.
|
||||
|
||||
### `expect_*`-driven
|
||||
|
||||
The stub asserts argument values against expectations:
|
||||
|
||||
```c
|
||||
void
|
||||
cons_bad_cmd_usage(const char* const cmd)
|
||||
{
|
||||
check_expected(cmd);
|
||||
}
|
||||
```
|
||||
|
||||
Test side:
|
||||
|
||||
```c
|
||||
expect_string(cons_bad_cmd_usage, cmd, CMD_ACCOUNT);
|
||||
```
|
||||
|
||||
## When to add a stub
|
||||
|
||||
1. You call a new function from production code, and the call site is
|
||||
reachable from a unit test.
|
||||
2. `make check` link fails with an undefined-symbol error.
|
||||
|
||||
Procedure:
|
||||
|
||||
- Locate the matching stub module by callee path: `src/foo/bar.c` →
|
||||
`tests/unittests/foo/stub_bar.c`. Create the stub file if absent.
|
||||
- Stub the new function with the right flavour:
|
||||
- Pass-through if tests don't need to observe / drive it.
|
||||
- `mock()` if a test needs to inject a return value.
|
||||
- `check_expected()` if a test needs to assert an argument.
|
||||
- Wire the new stub `.c` into the build. See `tests/unittests/Makefile.am`
|
||||
(or whatever wires the stubs into the `unittests` target).
|
||||
|
||||
## When to extend an existing stub
|
||||
|
||||
If a stub already pass-through and a test now needs to drive it, **change the
|
||||
stub to `mock()`**. Then every test (existing and new) reaching that stub
|
||||
must `will_return` — be ready to update unrelated tests.
|
||||
|
||||
## Convention notes
|
||||
|
||||
- Stubs do **not** include real headers from `src/<module>/` if doing so
|
||||
would pull in the very symbol they replace. Forward-declare instead.
|
||||
- `tests/unittests/ui/stub_ai.c` is a UI-side stub for the AI client surface
|
||||
consumed by `src/ui/`.
|
||||
- The `tests/unittests/unittests/` directory holds top-level catch-alls that
|
||||
do not fit a single module.
|
||||
Reference in New Issue
Block a user