Unit tests
test_state.py: StateStore with SQLite and in-memory backends. All methods. Persistence across instantiation.
test_cache.py: ObjectCache round-trips. Missing key behaviour. Content fidelity.
test_conflict.py: All four ChangeClass cases. resolver_fn call contract. ConflictError propagation.
No server needed. CI runs these on every push.
Integration tests
test_adapters/test_caldav.py: against Radicale (embedded). Full sync cycle: first sync, server change, local change, conflict.
test_adapters/test_jmap.py: against Cyrus (Docker). Same scenarios.
Docs
docs/usage/quickstart.rst: CalDAV adapter end-to-end example that actually runs, under 20 lines of code.
docs/usage/conflict-resolution.rst: the four conflict classes and how to write a resolver function.
docs/design/sync-state-machine.md: the design doc from #6, kept up to date.
docs/api/: autodoc for all public classes (StateStore, ObjectCache, ChangeClass, CalDAVAdapter, JMAPAdapter).
Unit tests
test_state.py: StateStore with SQLite and in-memory backends. All methods. Persistence across instantiation.test_cache.py: ObjectCache round-trips. Missing key behaviour. Content fidelity.test_conflict.py: All four ChangeClass cases. resolver_fn call contract. ConflictError propagation.No server needed. CI runs these on every push.
Integration tests
test_adapters/test_caldav.py: against Radicale (embedded). Full sync cycle: first sync, server change, local change, conflict.test_adapters/test_jmap.py: against Cyrus (Docker). Same scenarios.Docs
docs/usage/quickstart.rst: CalDAV adapter end-to-end example that actually runs, under 20 lines of code.docs/usage/conflict-resolution.rst: the four conflict classes and how to write a resolver function.docs/design/sync-state-machine.md: the design doc from #6, kept up to date.docs/api/: autodoc for all public classes (StateStore, ObjectCache, ChangeClass, CalDAVAdapter, JMAPAdapter).