Skip to content

feat: add expect.* factories + consolidate arch/ module#34

Merged
othercodes merged 1 commit into
masterfrom
feat/expect-bridge
May 18, 2026
Merged

feat: add expect.* factories + consolidate arch/ module#34
othercodes merged 1 commit into
masterfrom
feat/expect-bridge

Conversation

@othercodes
Copy link
Copy Markdown
Owner

Summary

Two related improvements:

  1. expect.* as unified entry point — thin factory methods on expect that wrap the existing constructors. Same fluent style for any subject, lazy imports keep expect light.
  2. arch/ module consolidation — collapses 4 internal files into a single assertable.py, removing the entrypoint.py indirection that broke convention with the rest of the library.

What's new

Bridge

expect(value)                # → AssertableValue (generic, existing)
expect.json(data)            # → AssertableJson
expect.html(markup)          # → AssertableHtml
expect.mcp(payload)          # → AssertableMCP
expect.arch("myapp.domain")  # → AssertableArch | AssertableMultiArch
  • Direct constructors (AssertableJson(...), etc.) remain available — zero breaking changes.
  • Each factory does lazy import so from pyssertive import expect stays light.
  • expect.arch has explicit signature (name, optional callback) for proper mypy/IDE support.

_MultiAssertableArchAssertableMultiArch

The class was already exposed in public type signatures (return type of assert_arch, callback type) but prefixed with _ indicating internal. Renamed to match the Assertable* convention and added to __all__ so it's a first-class public type.

arch/ module consolidation

Before:
```
arch/
├── init.py
├── _chains.py
├── assertable.py (AssertableArch, AssertableMultiArch)
├── entrypoint.py (_AssertArch, assert_arch singleton)
├── graph.py (build_graph)
├── layers.py (AssertableLayers)
└── modules.py (AssertableModules)
```

After:
```
arch/
├── init.py (public re-exports)
├── _chains.py (graph traversal helpers — kept separate)
└── assertable.py (everything Assertable + _AssertArch + assert_arch + build_graph)
```

Why: the rest of the library follows "the Assertable class is the entry point" (cf. formats/json.py, formats/html.py, protocols/mcp/assertable.py). arch/ was the outlier with a separate entrypoint.py. Consolidating restores convention. The _chains.py graph traversal helpers stay separate (different responsibility — _ prefix correctly signals internal).

Test plan

  • 5 thin bridge tests in tests/test_assertions.py — one per expect.* entry point, type-check only (behavior covered by the underlying suites).
  • All existing tests pass after the rename and the arch consolidation.
  • mypy strict clean (now 35 source files, down from 39).
  • Coverage 100% maintained.
  • ruff lint + format clean.
  • README: new #### Unified entry point section in ### Expectations.

Backward compatibility

100%. No public APIs changed:

  • AssertableJson(...), AssertableHtml(...), AssertableMCP(...), assert_arch(...) all continue to work.
  • from pyssertive.arch import AssertableArch, assert_arch (the public path) unchanged.
  • Internal from pyssertive.arch.entrypoint import ... / from pyssertive.arch.layers import ... / etc. would break, but nothing inside or outside the library used those paths.

@sonarqubecloud
Copy link
Copy Markdown

sonarqubecloud Bot commented May 18, 2026

@othercodes othercodes merged commit 747aa80 into master May 18, 2026
33 checks passed
@othercodes othercodes deleted the feat/expect-bridge branch May 18, 2026 01:05
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