Skip to content

v0.5.0

Choose a tag to compare

@github-actions github-actions released this 03 Sep 17:52
· 28 commits to master since this release
5b09cbe

A minor rather than a patch: a closing scope() verifies less than it did, and
two Arg:: factories now refuse a configuration they used to accept. Both are
behaviour toward the consumer's own test code, which Composer's caret already
treats as breaking on 0.x.

  • bin/consumer-smoke now carries the analyser parity matrix: eleven
    idioms — our Arg unqualified, aliased and fully qualified, the static verb
    form, rest() short and leaked, a captor capture in a specification and in a
    real call, a namesake Arg under two spellings, and a plain leak — checked
    against one table of expectations by both understudy-psalm and
    understudy-phpstan. The two answer the same contract by opposite
    mechanisms, and nothing compared them before; the analyser packages' own CI
    runs these legs against their working tree. The phpunit leg gained the
    composition hazard the adapter cannot defend against: a consumer class that
    overrides assertPostConditions() without the documented alias loses
    verification silently, and the README's recipe keeps it — both now executed
    rather than described.
  • A closing scope() no longer answers for the enclosing context. It
    verified every live context of the test, so a self-contained nested scope
    failed on a claim the caller had simply not got round to satisfying yet —
    including the recommended use of scope() to drop doubles holding OS
    resources before the runner's teardown, which is exactly the position where
    the enclosing expectations are still open. A close now verifies the context
    it opened, and only that one; nothing is settled or forgiven, so
    verifyAll(), checkpoint() and the runner adapter's teardown still report
    the enclosing claims. A test that relied on a scope surfacing an outer
    failure earlier will now see it at the end of the test instead. (#84)
  • A matcher that could never match is refused where it is written.
    Arg::int(min: 5, max: 1) — and the same shape in Arg::float() and
    Arg::count() — describes an empty range, and Arg::string('/[unclosed') is
    not a pattern PCRE compiles. Both built a matcher that answered "no" to every
    argument, so a typo surfaced as an expectation never met with nothing
    pointing at its cause; the broken pattern also raised PHP's own warning on
    every call from inside the code under test, which is the one thing a matcher
    must not do. Both now raise InvalidCallSpecification, and the pattern's
    message carries PCRE's own reason. (#86)
  • Two decisions written down rather than changed. A predicate handed to
    Arg::satisfies() is the test's own code, so an exception in it travels
    instead of being read as a mismatch — unlike Arg::which(), which reaches
    into the argument. And verifySequence() with no calls asserts that nothing
    happened, where expectSequence() refuses an empty protocol; both are now
    stated in the docblocks and pinned by tests.
  • The mutation gate quoted in README.md, README.ru.md and AGENTS.md says
    92, which is what infection.json5 has required since #76.
  • Both READMEs and the failure-messages guide say what was only in the 0.1.0
    changelog: the wording of a failure message is not public contract, and
    anything acting on a failure reads FailureKind and the readonly fields of
    VerificationFailure, which are frozen.