Skip to content

Release v2.0.0 → v2.1.0: beehave rewrite + scoped generated tests#27

Open
nullhack wants to merge 9 commits into
mainfrom
release/beehave-v2
Open

Release v2.0.0 → v2.1.0: beehave rewrite + scoped generated tests#27
nullhack wants to merge 9 commits into
mainfrom
release/beehave-v2

Conversation

@nullhack

@nullhack nullhack commented Jul 18, 2026

Copy link
Copy Markdown
Owner

Release v2.0.0 → v2.1.0

Publishes the `beehave-v2` rewrite plus the `beehave-v3` scoping follow-up from `dev` → `main`. The head carries both the seven-cycle v2.0.0 rewrite (squash-merged to `dev`) and the v2.1.0 minor bump that scopes generated tests to `tests/features/`.

v2.1.0 — scoped generated tests

Generated `*_test.{pyi,py}` now land in `tests/features/` (parallel to `docs/features/`), making the subdirectory the ownership marker: anything inside `tests/features/` is beehave-owned (wiped/regenerated), anything outside is consumer-owned (untouched).

  • `generate` emits into `tests/features/`, creates the dir on demand, and wipes stale `*_test.pyi` in that subdir before each run so deleted scenarios/features stop orphaning files.
  • `check` scans `tests/features/` for `*_test.py` without a `.pyi` sibling (orphans) and fails with one stderr line per orphan before the AST binding loop. Hand-written tests outside `tests/features/` are never inspected.
  • `status` counts `*_test.pyi` under `tests/features/` (was `tests/`).
  • `.pyi` signatures unchanged — behavior + path scope only.
  • Migration: `mkdir -p tests/features && git mv tests/*_test.py{i,} tests/features/` before re-running `beehave generate`.

v2.0.0 — breaking rewrite

The 1.x source modules are removed: `beehave/{clean,config,discover,models}.py`, the 1.x test surface (`test_{check,clean,cli,config,discover,generate,gherkin}.py`, `tests/conftest.py`, and the legacy `tests/features/{case_insensitive_matching,comb_construction,hive_activity,status_command,title_validation}/` suites).

Rewritten as a thin layer over Hypothesis with a Gherkin-style BDD pipeline. Seven source modules built across five TDD cycles (red → green → refactor → ship):

Module Responsibility
`beehave/step.py` the `with step(...)` BDD pipeline primitive
`beehave/gherkin.py` Gherkin parsing into the step model
`beehave/generate.py` Hypothesis strategy inference + example generation
`beehave/check.py` example checking against invariants
`beehave/status.py` run status / outcome reporting
`beehave/cli.py` command-line entry point
`beehave/init.py` public surface re-exports

Type-safety surface: `.pyi` stubs for every source module (the binding contract), `py.typed` marker (PEP 561), `with step(...)` BDD pipeline as the public API entry, Hypothesis strategy inference from annotations.

Gate (verified green on PR head `efa3d51`)

  • `mypy --strict` clean across the package.
  • Whole-package `stubtest` — 21 modules clean (source + tests), no drift.
  • `ruff check`, `ruff format --check`, `lint-merge` clean.
  • Whole suite: 59 tests green; no pending markers remain.

Version

`pyproject.toml` → `2.1.0` (single source of truth; minor bump for the scoped-tests behavior change — no external consumers yet, so no breaking-class semver impact). No git tag and no PyPI publish are part of this PR — both deferred pending separate approval.

Commits on the PR head ahead of `main`

```
efa3d51 feat(beehave-v3): scope generated tests to tests/features/
6454329 fix(beehave-v2): move pytest_plugins to root conftest
47f629f chore: strip docstrings for next dev cycle
dbc770e docs: regenerate living spec for 2.0.0
9bd497e feat(beehave-v2)!: rewrite as thin Hypothesis layer with Gherkin BDD pipeline
90b66ef docs(beehave-v2): regenerate docstrings + format
d614250 chore(beehave-v2): sync uv.lock to 2.0.0
2b55974 plan(beehave-v2): author contract surface
```

Reviewer notes

  • Opened for review — not auto-merged. Stakeholder review is the gate to `main`.
  • No PyPI publish. No git tag. Those await separate approval.

nullhack added 8 commits July 18, 2026 05:28
Source .pyi stubs (7): __init__, step, gherkin (8 parse-model shapes +
parse_feature, Q2 collapse — no models.pyi), generate, check, status, cli.

Test contract (9 pairs .pyi/.py + 2 conftests):
- tests/integration/: step_cm, title_derivation, idempotency, roundtrip,
  strategy_inference, parsing (55 falsifiable claims, @pytest.mark.pending)
- tests/e2e/: check, generate, status (pytester-driven CLI surface)

docs/glossary.md: 3 contexts, 23 terms.

Build-entry setup (v1 deletion, mypy/stubtest/taskipy wiring, py.typed)
follows on feature/beehave-v2.
…pipeline

Squash-merges the seven-contract v2 build cycle into dev.

Modules:

- beehave/step.py: step context manager wiring Gherkin steps to Hypothesis

- beehave/gherkin.py: Gherkin parse model

- beehave/generate.py: test-file generator

- beehave/check.py: contract verifier

- beehave/status.py: status command

- beehave/cli.py: CLI surface

- beehave/__init__.py: __version__ = 2.0.0

Removes clean.py, config.py, discover.py, models.py (consolidation to thin layer).

Adds .stubtest_allowlist, beehave/py.typed; activates integration + e2e test bodies.

BREAKING CHANGE: beehave 2.0.0 is a rewrite; 1.x modules removed.
Authored by refresh-cycle from the 55-test green suite (33 integration + 22
e2e) plus the source stubs, glossary, and absence of cassettes/migrations.
Derived view per the simplicity-discipline rule; never hand-edited.
Module/class/function docstrings stripped from the 7 source .py modules
(21 docstrings total) via AST line-range removal. Tests already docstring-
free. ruff format applied; lint-merge + 55-test suite + whole-package
stubtest all clean.
pytest 9.0.3 forbids `pytest_plugins` in non-top-level conftests; the
declaration in tests/e2e/conftest.py broke bare `task test` / `uv run
pytest` collection (ERROR: Defining 'pytest_plugins' in a non-top-level
conftest is no longer supported). Move it to a top-level conftest.py at
the repo rootdir as pytest's deprecation notice recommends. The e2e
conftest keeps its pending-marker hooks (nested hooks remain allowed).

Verified: `task test`, `task lint`, `task lint-merge`, `task stubtest`
all green; 55 passed.
Emit beehave-generated *_test.{pyi,py} into tests/features/ (parallel
to docs/features/) so the subdirectory is the ownership marker:
anything inside is beehave-owned (wiped/regenerated), anything outside
is consumer-owned (untouched).

generate: emit into tests/features/, mkdir on demand, and wipe stale
*_test.pyi in that subdir before each run so deleted scenarios/features
stop orphaning files.

check: _check_all now scans tests/features/ for *_test.py without a
.pyi sibling (orphans) and fails with one stderr line per orphan before
the AST binding loop. Hand-written tests outside tests/features/ are
never inspected.

status: counts *_test.pyi under tests/features/ (was tests/).

Bumps version to 2.1.0. Signatures in the .pyi files are unchanged;
the change is behavior + path scope only.

Migration: move existing generated files from tests/ to tests/features/
(e.g. `mkdir -p tests/features && git mv tests/*_test.py{i,} tests/features/`)
before re-running `beehave generate`.
@nullhack nullhack changed the title Release v2.0.0: beehave-v2 rewrite as thin Hypothesis layer with Gherkin BDD pipeline Release v2.0.0 → v2.1.0: beehave rewrite + scoped generated tests Jul 18, 2026
Replace v2's Hypothesis-strategy-inference path with
@pytest.mark.parametrize for Scenario Outlines. The generator emits a
parametrize decorator over each Outline's test function whose arg-names
are the Examples headers and whose rows are the Examples cells (string
tuples). All parameters are now typed `str`; the strategy-inference
helpers (_is_int/_is_float/_is_bool/_infer_param_type) are removed.
Plain scenarios (no Examples) emit no parametrize and no `import pytest`.

Extend check.py to parse @pytest.mark.parametrize from each test
function's decorator list and verify the arg-names and rows round-trip
the feature's Examples table. Examples present without a matching
parametrize now fails check (closing the Examples-row binding gap).
Step-template binding (count/keyword/text/placeholder-names) is checked
first; parametrize verification runs only for scenarios that have
Examples.

Bumps version to 2.2.0. .pyi signatures unchanged in shape (still flat
typed signatures); comment prose updated to describe parametrize.

Drops tests/integration/strategy_inference_test (the concept is gone)
and replaces it with tests/integration/parametrize_test covering
emission + check roundtrip. Adds one e2e test each in generate_test
(parametrize emission via the CLI) and check_test (check catches edited
parametrize rows via the CLI).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant