Chapter 02.04 — Invariants#
Ocarina’s sub-DSL for typed, composable invariants. Used everywhere: CLI, POMs, the
custom_invariants/testing/that check suite consistency before any test runs.
Plan#
| # | File | Subject |
|---|---|---|
| 01 | 01-validate-flow.md | The full flow validate(value) → assert_that → execute → raise_if_invalid + the _ValidationChain class. |
| 02 | 02-assertions.md | Catalog of builtin assertions (is_str, is_email, is_positive, is_in, has_unique_elements, each, is_valid_filename, …). |
| 03 | 03-otherwise-any-of.md | .otherwise(...) and the OR combination via _any_of. |
| 04 | 04-then-chain-of-validations.md | .then(new_value) and chain_validations(...) for composition. |
| 05 | 05-business-vs-framework-validator.md | BusinessInvariantValidator vs FrameworkInvariantValidator |
| 06 | 06-invariant-errors.md | InvariantViolationError, DuplicatesError, AggregateInvariantViolationError. |
Why the invariants DSL#
- Pre-execution guard.
TestSuite.__init__checks — before launching anything — that test names / IDs are unique,max_workers >= 1, etc. - CLI validation. Every flag carries its
validate=lambda chain: chain.assert_that(...)inside theCliStore. Errors aggregate into one message. - POM-side validation. POM actions validate their parameters ("
retriesmust be positive") viavalidate(retries, name="retries").assert_that(is_positive).execute().raise_if_invalid().
The Holy Book sums it up: