4.5 KiB
Tests and Validation
1. Principle
A feature is not complete without relevant validation.
The exchange validator is executable specification during the format gates.
2. Canonical exchange validation
Run:
python tools/validate_json.py
The command validates:
examples/session-v1.json;- all
tests/fixtures/valid/*.jsonas valid; - all
tests/fixtures/invalid/*.jsonas invalid.
A negative fixture passes only when Trainlog rejects it.
3. Validation layers
A v1 document must pass:
- JSON Schema validation;
- Trainlog semantic validation.
Schema handles shape, enumerations, and primitive ranges.
Semantic validation handles cross-object and normalized rules.
4. Gate 1 semantic coverage
The canonical validator checks:
- unique
exercise_id; - normalized exercise-name uniqueness;
- explicit timestamp offsets;
- end time later than start time;
- exact catalog/reference set equality;
- one workout entry per exercise;
- catalog tracking mode matching target;
- catalog tracking mode matching actual sets;
- load-mode/weight consistency;
- non-blank notes.
5. Positive fixture coverage
Gate 1 includes:
- mixed loaded repetition + timed session;
- active session without
ended_at; - planned exercise with zero actual sets;
- bodyweight exercise with zero-repetition failed attempt;
- assistance load;
- completely interrupted session with zero exercises.
6. Negative fixture coverage
Gate 1 includes rejection of:
- duplicate exercise IDs;
- duplicate normalized exercise names;
- duplicate workout exercise entries;
- end timestamp before start;
- missing timestamp offset;
- target/actual tracking mismatch;
- target containing both repetitions and duration;
- unknown exercise reference;
- unknown JSON field;
- catalog tracking-mode mismatch;
load_mode=nonecarrying weight;- loaded target missing weight;
- loaded actual set missing weight;
- unreferenced catalog entries;
- blank session notes;
- blank exercise notes;
- negative actual repetitions.
7. Gate 2 compiled validation
The normal Meson suite currently covers:
database
catalog
session_detail
duration
body_metrics
bodyviz
exercise_performance
session_type_schema
session_edit
body_observation_edit
The session-edit test verifies transactional child replacement without changing the parent session identity. The body-observation edit test verifies stable observation identity while metric values and notes are updated.
Schema validation includes the v1 -> v2 session_type migration.
8. C validation
Current pre-push validation includes:
- normal strict-warning build;
- the complete Meson test suite;
git diff --check;- frozen JSON v1 validators.
ASan/UBSan is run for meaningful implementation checkpoints before declaring a gate complete.
9. Pre-push checklist
Before every meaningful push:
- run
python tools/validate_json.py; - run
python tools/validate_import_contract.py; - run
meson compile -C build; - run
meson test -C build --print-errorlogs; - run sanitizers when relevant;
- run
git diff --check; - inspect
git status --short; - review documentation changes.
10. Catalog reconciliation contract
Before the C17 importer exists, Gate 1 defines local catalog merge behavior through an executable Python specification.
Run:
python tools/validate_import_contract.py
Canonical cases cover:
- exact existing exercise reuse;
- same identity with renamed display text;
- same identity with incompatible tracking mode;
- different identities with equivalent normalized names;
- new unique exercise creation.
The full Gate 1 validation command is:
python tools/validate_json.py
python tools/validate_import_contract.py
git diff --check
11. USB/MTP transport validation
The compiled suite now contains:
usb
mtp
The usb test covers API validation, physical-device enumeration invariants,
and rejection of duplicated USB interface children.
The mtp test covers bounded API argument validation for storage, folder,
upload, listing, and download entry points.
Hardware probes additionally validate the real device path:
trainlog-usb-probe
trainlog-mtp-probe
trainlog-mtp-exchange-probe
trainlog-mtp-roundtrip-probe
Physical checkpoint result:
MTP devices: 1
ROUNDTRIP=PASS Trainlog/trainlog-probe.txt
The hardware probe is intentionally separate from the normal automated test suite because CI is not expected to have a connected unlocked Android MTP device.