nigig-org/crates/apps/doc/doc-ui/COVERAGE.md
andodeki 1d8b3a6053
Some checks failed
makepad-table / model (push) Has been cancelled
makepad-table / widget (push) Has been cancelled
makepad-table / hygiene (push) Has been cancelled
PDF engine / engine (push) Has been cancelled
PDF engine / makepad-integration (push) Has been cancelled
PDF engine / fuzz (push) Has been cancelled
Payment domain, storage, platform and UI / isolated-payment-tests (push) Has been cancelled
Payment domain, storage, platform and UI / payment-ui-tests (push) Has been cancelled
repo hygiene / hygiene (push) Has been cancelled
doc-engine / engine (push) Has been cancelled
doc-engine / coverage (push) Has been cancelled
doc-engine / consumer (push) Has been cancelled
email / gates (push) Has been cancelled
email / email-domain (push) Has been cancelled
email / nigig-email (push) Has been cancelled
email / supply-chain (push) Has been cancelled
nigig-build (CAD) / supply-chain (push) Has been cancelled
nigig-build (CAD) / cad-module (push) Has been cancelled
nigig-build (CAD) / full-crate-check (push) Has been cancelled
nigig-build (CAD) / cad-engine-coverage (push) Has been cancelled
nigig-build (CAD) / doc-workspace-coverage (push) Has been cancelled
nigig-build (CAD) / cad-widget-coverage (push) Has been cancelled
nigig-map / test (push) Has been cancelled
sms / gates (push) Has been cancelled
sms / robius-sms (push) Has been cancelled
sms / android (push) Has been cancelled
sms / nigig-sms (push) Has been cancelled
sms / supply-chain (push) Has been cancelled
spreadsheet / engine-coverage (push) Has been cancelled
spreadsheet / ui-controller-coverage (push) Has been cancelled
merge(local): reapply local WIP onto merged main -- cad dashboard/explode/script_parts/xray merged with remote Phase-5 LOD, plus doc-ui extraction, spreadsheet xls-import, android ussd, camera and test work
2026-09-01 21:13:52 +03:00

99 lines
4.7 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Doc-workspace source coverage
`tools/test-doc-workspace-coverage.sh` measures line/region coverage for the
**pure** (widget-free) part of this module and enforces floors in CI
(`.forgejo/workflows/nigig-build.yml`, job `doc-workspace-coverage`). The same
suite also runs uninstrumented inside `cargo test -p nigig-build --lib`, so
every test executes twice: once in the real crate and once in the harness.
## How it works
The script copies the dependency-free sources — `advanced_json.rs`,
`crdt_bridge.rs`, `mobile_gesture.rs`, `persistence.rs`,
`projection_layout.rs`, `projection_session.rs`, and the `collaboration/`,
`editing/`, `layout/`, `model/`, `plugins/` trees — plus `tests_pure.rs`
byte-for-byte into a temporary host-only crate with the real module path. A 30
line `makepad-widgets` shim (re-exporting `makepad_math` plus the `log!` /
`error!` macros) satisfies the only Makepad symbols the pure layer uses
(`DVec2`, `Rect`, `Vec4f`, `dvec2`, `vec4`).
`doc-engine` is included as a path dependency because the pure projection code
sits on top of it.
The harness then installs its own pinned toolchain with
`llvm-tools-preview` into the same temp dir, runs the suite under
`-C instrument-coverage`, and enforces:
* a **total** line floor (`DOC_WS_COVERAGE_TOTAL_FLOOR`), and
* a **per-file** floor for every instrumented source
(`DOC_WS_COVERAGE_PER_FILE_FLOORS`).
The per-file floors are the point: deleting one file's whole test section
moves the total by a point or two and a lone number would wave that through.
Lowering a floor is a reviewable edit to the script, not something to do
quietly. Everything — toolchain, cargo home, target dir, fetched Makepad
tree, profraw data — is removed by a shell trap on every exit path; nothing
is written into the repository or `$HOME` unless `KEEP_COVERAGE=1` is set.
## Running it
```sh
./tools/test-doc-workspace-coverage.sh # gated run (CI)
DOC_WS_COVERAGE_REPORT_ONLY=1 ./tools/test-doc-workspace-coverage.sh # measure only
KEEP_COVERAGE=1 ./tools/test-doc-workspace-coverage.sh # keep uncovered-lines.txt + report
```
## Latest measurement (2026-08-17)
| File | Lines covered |
| --- | --- |
| TOTAL | **96.76%** (6170 lines) |
| advanced_json.rs | 98.02% |
| crdt_bridge.rs | 95.45% |
| mobile_gesture.rs | 100% |
| persistence.rs | 65.85% (see exclusions) |
| projection_layout.rs | 98.52% |
| projection_session.rs | 100% |
| collaboration/* | 100% |
| editing/commands.rs | 93.39% |
| editing/controller.rs | 93.39% |
| editing/history.rs | 95.65% |
| layout/* | 94100% |
| model/* | 91100% |
| plugins/mod.rs | 100% |
## What is intentionally not measured
* **The widget layer** — `mod.rs`, `crdt_widget.rs`, `widgets/`, `render/`,
`projection_renderer.rs`, `tests.rs`. These need `live_design!`, a `Cx`,
and an event loop; they are gated by the full `nigig-build` build/test CI
jobs instead. The split is deliberate: `tests_pure.rs` contains everything
that can run host-only, and both files are compiled into the crate's normal
test suite.
* **`persistence.rs` write paths** — `save_doc_state` / `save_doc_state_as` /
`load_saved_doc_state` resolve the host's real application-data directory
and unconditionally write into it. They are thin wrappers over
`save_doc_state_to` / `load_saved_doc_state_with`, which the tests drive
with explicit temp paths; the wrappers themselves are covered by the
widget-runtime tests on device. This is why `persistence.rs` keeps a lower
floor (55%) — do not lower it further without a genuine new exclusion.
* **Defensive guards** — cycle guards in RGA/block-order traversal
(`seen.insert` `continue` arms), unreachable block-id parse failures inside
`layout_projection` (engine ids always contain `actor:counter`), and the
`unreachable` canvas-text serialization arm's sibling rejections in
`advanced_json.rs`. They exist for invariant defense; there is no honest
public-API path that reaches them.
## Defects found by this coverage drive (fixed with tests)
1. `editing/commands.rs::ReplaceBlockRange` validated the explicit
`block_ids` length **after** draining blocks out of the document, so a
malformed command destroyed content before reporting failure. Validation
now happens before any mutation; a test pins that a rejected replace
leaves blocks and ids untouched.
2. `model/crdt.rs::visit_children` was dead code (a String-collecting
duplicate of `visit_atoms` with no callers). Removed.
3. Multi-peer atom-id collisions: two `CrdtMetadata::default()` peers mint
identical `AtomId`s, so a concurrent insert silently resurrects instead
of inserting. The sync test now assigns distinct
`document.crdt.local_actor`s — matching how real peers must be
provisioned — and pins the convergent `"hi!"` exchange.