Repository navigation
Releases: rasuvaeff/property-testing-testo
Releases · rasuvaeff/property-testing-testo
Release list
v1.2.0
- Changed: Testo assertion and test-double expectations now run for every generated property input, so an unmet expectation identifies and shrinks the failing input.
#[ExpectException]is evaluated per run. (#66) - Added:
#[Property(failOn: ...)]converts selected PHP warnings, notices and deprecations intoErrorExceptionfailures for the generated input; the failure shrinks with that input, while@suppression remains effective. (#67)
v1.1.0
- Added: generators written on the property's parameters with core's
#[Generate](#68). Withoutauto, the attributes alone are enough
when they cover every parameter — no generators method needed — and they may
share the parameters with a provider; underauto: truethey sit between
the provider and the@paramtype. Requiresrasuvaeff/property-testing-core
^1.2. - Changed: without
auto, a parameter neither the provider nor
#[Generate]covers is refused naming the method and the parameter, instead
of the engine'sNo generator for parameter "x".
v1.0.0
The stability release, in step with rasuvaeff/property-testing-core 1.0.0.
The adapter's surface is that of 0.12.0, unchanged: #[Property] with its
knobs, PropertyInterceptor, TestoTrialExecutor, VerboseListener, the
environment table and the drop-in contract with the frozen
rasuvaeff/property-testing 2.8. A project on ^0.12 upgrades by widening
the constraint to ^1.0.
- Requires
rasuvaeff/property-testing-core^1.0(compatibility policy
§8: a caret on the engine's current major). - Docs: the footnotes that dated a behaviour to a core 0.x release
(since core 0.9,under core 0.9 …) are gone from the READMEs and
llms.txt— every 1.0 install has the current behaviour.
v0.12.0
- Added: the core 0.12 knobs on
#[Property]—exhaustive/
exhaustiveBudget(walk the parameter domain instead of sampling it),
flakyReplays(re-execute the minimised counterexample; a passing replay
is reported as flaky) andsearchRuns(targeted search after the random
phase for a body that callsTarget::maximize()/minimize()); the
interceptor refuses an out-of-range value by name like the other knobs. - Added:
PROPERTY_EXHAUSTIVE(a flag) andPROPERTY_SEARCH_RUNS(a
non-negative integer,0switches the search off) dial the suite, the way
PROPERTY_DERANDOMIZEandPROPERTY_RUNSdo. - Added: the interceptor reports every
Classify::tabulate()table with
its pairwise intersections, whether exhaustive mode walked the domain (or
why it sampled, as a warning), and the search report, beside the
distribution line;PROPERTY_VERBOSElogs everyTargetImprovedevent. - Requires
rasuvaeff/property-testing-core^0.12; the
tests/Support/CoreCompatshim that spanned the 0.9–0.11 lines is gone.
v0.11.2
- Fixed. A wide
throws:swallowed a failed assertion: Testo's
AssertionExceptionandExpectationFailedextend\LogicException, so
throws: \LogicException::class— or\Exception,\Throwable—
matched a failingAssertin the body and the property passed on a
falsified body, the T-1 of 0.11.0 on the new knob. The interceptor
refuses such a class when the property is set up, naming why; the
executor never takes an assertion failure for the expected throw,
whatever class was named (#61).testo/assertis a direct requirement,
as the executor now reads its types.
v0.11.1
- Changed. Accepts
rasuvaeff/property-testing-core^0.11alongside^0.9/^0.10. Nothing in 0.11.0 reaches this package: the release is additive (thePropertyTestingExceptionmarker,AssumptionSkippedpromoted to@api,Gen::stringOf()defaults, docblock reading inGen::forClass()), and the suite is green against it unchanged.
v0.11.0
#[Property]combined with Testo's#[ExpectException]is refused as an
error of the test (cannot be combined with #[ExpectException]; use throws: instead), the way a data provider already was. The expectation interceptor
runs outside the property and sees only the aggregate
PropertyViolationException— aRuntimeException— so
#[ExpectException(\RuntimeException::class)]was satisfied by any
falsification, a failed assertion included, and the test came back green
(#56).#[Property(throws: SomeException::class)], appended as the last
parameter: the exception class every run must throw, with the PHPUnit
adapter'sPropertyCheck::throws()semantics — throwing it (or a subclass)
passes the run, returning normally fails it withExpected <class> to be thrown, but it was notand shrinks the input, another class is that run's
failure; a skip and anAssume::that()discard keep their meaning. The
matching throw is recorded as an assertion, so a body that only throws is
not reported as risky (#57).- A generators key that is not a parameter of the property is refused with or
withoutauto: true; it used to be ignored silently withoutauto. A
provider shared by two properties of different arity is therefore refused —
give each property its own (#58). - The attribute is a data holder and the interceptor validates it. Testo
instantiates#[Property]before the interceptor runs, soruns: 0, a
negative cap,pathwithoutseedorgenerators: [Cls::class, 'missing']
used to abort the pipeline (Error during test execution pipeline., reason
inprevious); they are now the test's own error,#[Property] on "<method>" cannot be set up: ….Property::$generators/$examples
accordingly accept — and keep as written — a non-callable array, which
widens their type from\Closure|string|nullto
\Closure|array|string|null; the attribute constructor no longer throws. PropertyInterceptor::__construct(listeners:)is documented (README ×2,
llms.txt) with thetesto.phpplugin recipe for attaching a
PropertyListener, which the suite now executes end to end.- The environment table says what core 0.10 does:
PROPERTY_VERBOSEand
PROPERTY_DERANDOMIZEare off forfalse/off/noas well as''/0
(README ×2,llms.txt); the packageAGENTS.mdhad it since 0.10.0. examples/are a Testo suite of their own:vendor/bin/testo --suite=Examplesruns them (no documented command did before), the
stateful example carries#[ExpectNoAssertions]instead of coming back
risky, andproperty_test.phpdemonstratesthrows:.testo/testois required as^0.10.39; the|| ^1.0half promised
compatibility with a major that has not been released.
v0.10.0
- Accepts
rasuvaeff/property-testing-core^0.10alongside^0.9. - Documentation catches up with core 0.9 and 0.10, from the family's 1.0
review: a partly skipped property spends a separate budget rather than
counting againstmaxDiscards(README ×2),maxDiscardscaps both budgets
when set and leaves them different when unset (attribute table ×2), and the
two flag variables are off forfalse/off/noas well as0
(AGENTS.md). AGENTS.mdno longer routes the corpus throughCorpusFromEnv::resolve(),
a class this package removed in 0.7.0; it is core'sCorpusFactory::fromDsn().psalm.xmlno longer enablesext-redisandcomposer-require-checker.json
no longer whitelistsPredis\ClientandRedis. Both were left over from
0.6, when this package parsed the DSN itself; neithersrc/file has
mentioned Redis since.composer rectoris green again: the anonymousCaseInstancestub in the
interceptor's suite is areadonlyclass, asReadOnlyAnonymousClassRector
asks. It had been red since the stub was introduced, which iscomposer release-checkred —composer builddoes not run rector.- Three characterizations resolve the engine's own spelling instead of pinning
the one core 0.9 uses, so they stay exact while this package's constraint
spans two core lines: the exception a bounded-attempt generator gives up with
(GenerationExhaustedin 0.9,GenerationExhaustedExceptionfrom 0.10) and
the counterexample field countingAssume::that()discards (skipsin 0.9,
discardsfrom 0.10, whereskipsbecomes the environmental count). The new
Tests\Support\CoreCompatprovokes the exception rather than naming it — a
literal for either spelling is a reference to a class the other engine does
not have — and reads the field throughCounterExample::toArray(). It is
temporary by construction and goes away when the constraint narrows again.
v0.9.0
- The
Classifydistribution line is written toMessenger::CHANNEL_STDERR
instead ofCHANNEL_STDOUT, so it survives a run that contains a failure.
Testo's terminal renderer writes the stderr channel through as-is and streams
every other channel only at-v, rescuing a stdout message at normal
verbosity solely when the whole run holds one passing test — so in a real
suite the distribution was never shown, and specifically not on the red run,
which is whenClassify::when()andClassify::label()are read at all. The
level staysInfo; only the channel decides visibility. The PHPUnit adapter
already printed both lines unconditionally. - Requires
rasuvaeff/property-testing-core^0.9, where an environmental skip
no longer spends the discard budget: a machine missing a dependency is no
longer told to narrow generators that were never at fault. The excessive-
discard warning printed here reads the engine's discard counter, so it stops
firing on such a machine without a change of its own.
v0.8.0
- A skipped run — from the body or from a lifecycle hook — is reported to the
engine asTrialOutcome::skipped()rather than as a plain discard, so a
recorded regression whose replay only skipped is kept instead of pruned. A
machine without the dependency the body guards against used to delete the
counterexample for every machine that has it. Requires
rasuvaeff/property-testing-core^0.8. - A
SkipTestorCancelTestraised from a lifecycle hook now skips the
property, the wayREADME.mdhas always described it. The lifecycle
interceptor is innermost, so a hook's throw never reached the handler that
turns a skip from the body into a status: the engine took it as a
falsification and shrank around the skip, re-running the hook on every trial. PROPERTY_PATHwithout a pinned seed is refused instead of doing nothing.
The adapter draws a random seed for an unseeded property, so the engine's own
"a path needs a seed" check never fired and the path silently described a
descent of a run that never happened.- An attribute argument PHP rejects with a
TypeErrororValueError—
generators: [Provider::class, 'missingMethod']is not a callable — is
reported as this test's error with the reason in the message, instead of
escaping the pipeline and coming back asStatus::Abortedwith the reason
buried inprevious. A generators or examples provider that is not static
and has no test-case instance to run on says so by name.