Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@ are in [docs/plan.md](docs/plan.md) §12. Upgrading from v0.3: see the

## Unreleased

- **Spec fixtures vendored (Stage 1, PR 1).** `tests/spec_fixtures/` holds the
MorphoBricks-Spec conformance fixtures at a pinned commit, with a git tree-hash pin test,
a gate that makes a skipped `tests/test_spec_*.py` test a failure, and the "no fallback
rules" scan (conformance plan sections 1 and 2). Tests only: no change to the package,
the CLI, the notebook or any output.
- **Group statistics per channel (#104).** `group_summaries` and the notebook's step 4 no
longer pool distinct channels together: each group has one summary per channel, and the
intensity curves are drawn in one panel per channel. Single-channel tables give the same
Expand Down
17 changes: 17 additions & 0 deletions docs/development.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,23 @@ is pinned to the release in `RELEASE_TAG` (plan §12 question 58);
- Every acceptance check in the plan has a test.
- A bug fix comes with a test that fails without it.

## Spec conformance tests

The experiment-description reader is tested against the fixtures of
[MorphoBricks-Spec](https://github.com/CellMigrationLab/MorphoBricks-Spec)
(conformance plan, sections 1 and 2). They are vendored in `tests/spec_fixtures/` at the full
commit SHA in its `PIN.toml`, never a branch.

- **Pin integrity:** `tests/test_spec_pin.py` fails when one byte of the vendored `fixtures/`
differs, or a file is added or missing (git tree hash against the pin), so a local edit
of a fixture cannot make a reader pass. Never edit the vendored files; updating the pin
is a reviewed change (`tests/spec_fixtures/README.md`).
- **Skip is failure:** every test module named `tests/test_spec_*.py` is held by
`tests/spec_gate.py`: a skipped or xfailed test there fails the run.
- **No second copy of the rules:** `tests/test_spec_no_fallback.py` scans the reader's
modules (`description*.py`) for a second table of codes or names and for lenient, older or
default-version paths.

## Versioning

- Semantic versioning for the package.
Expand Down
3 changes: 2 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,8 @@ addopts = "-ra"
line-length = 100
target-version = "py311"
src = ["src", "tests", "tools"]
extend-exclude = ["tests/guard_fixtures"]
# The vendored Spec files are byte-exact copies (tests/spec_fixtures/README.md).
extend-exclude = ["tests/guard_fixtures", "tests/spec_fixtures"]

[tool.ruff.lint]
select = [
Expand Down
7 changes: 7 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,10 @@

# Lets tests import the shared simulation helpers.
sys.path.insert(0, str(Path(__file__).parent))

from spec_gate import SkipIsFailure # noqa: E402


def pytest_configure(config):
# A skipped Spec conformance test is a failure (conformance plan section 1).
config.pluginmanager.register(SkipIsFailure(), "spec-skip-is-failure")
3 changes: 3 additions & 0 deletions tests/spec_fixtures/.gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# The vendored Spec files are byte-exact copies. Git must not touch line endings
# (the pin is a hash of the bytes; a CRLF checkout would break it).
* -text
13 changes: 13 additions & 0 deletions tests/spec_fixtures/PIN.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# The MorphoBricks-Spec commit these files are copied from (conformance plan section 1).
# Updating the pin is a reviewed change: see README.md in this folder.
repository = "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/CellMigrationLab/MorphoBricks-Spec"
commit = "8922a359ec261148a23a4b6e740a1bdb69e9e318"

# `git rev-parse <commit>:fixtures`, the git tree-object ID of the fixtures/ folder. The
# vendored folder must hash to it, so one changed, added or missing byte fails a test.
fixtures_tree = "6d114d8028acc11cce1fba65b2f4f0d8314076d5"

# `git rev-parse <commit>:<path>`, the git blob ID of each other vendored file.
[files]
"docs/experiment-v1.md" = "3e5bd59edfa9e9b2deeb0b480d03da8ed57bb9f2"
"tools/audit/refval.py" = "bff88079732a63fe5ba11dd9df5a7887348d0587"
35 changes: 35 additions & 0 deletions tests/spec_fixtures/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Vendored MorphoBricks-Spec files

A partial copy of [MorphoBricks-Spec](https://github.com/CellMigrationLab/MorphoBricks-Spec)
at the commit named in `PIN.toml`, laid out as in the Spec repository:

| Here | In the Spec | Used for |
|---|---|---|
| `fixtures/` | `fixtures/` | The conformance fixtures: every test of the experiment-description reader runs on them |
| `docs/experiment-v1.md` | `docs/experiment-v1.md` | The normative text; tests compare the reader's tables of codes, names and fields with it |
| `tools/audit/refval.py` | `tools/audit/refval.py` | The reference validator, used **only as a test oracle**; nothing in `src/` imports it |

Rules (conformance plan, sections 1 and 2):

- **Never edit these files.** `tests/test_spec_pin.py` hashes `fixtures/` with git's tree
algorithm and each other file with git's blob algorithm, and fails when one byte differs
or a file is added or missing. A fixture that a reader fails is a finding for the Spec
repository, not something to change here.
- **The pin is a full commit SHA**, never a branch.
- **A skipped Spec test is a failure.** Every test module named `tests/test_spec_*.py` is
held to it by `tests/spec_gate.py`, so a missing package, file or weight cannot turn a
conformance test into a silent pass.
- The reader has no copy of the rules besides its one table module
(`tests/test_spec_no_fallback.py`).

## Updating the pin

1. In a checkout of the Spec, check out the new commit and read
`git rev-parse HEAD`, `git rev-parse HEAD:fixtures`,
`git rev-parse HEAD:docs/experiment-v1.md` and `git rev-parse HEAD:tools/audit/refval.py`.
2. Replace the vendored files from that commit, for example
`git archive HEAD fixtures | tar -x -C tests/spec_fixtures`, and `git show HEAD:<path>` for
the two single files.
3. Put the four values in `PIN.toml`.
4. Run the whole suite. The reader, its tables and its tests change in the same pull
request when the Spec changed text or fixtures (the Spec changes first).
Loading
Loading