hegel 0.3.0
hegel: ^0.3.0 copied to clipboard
Property-based testing for Dart, powered by the Hegel engine. Generators, shrinking, stateful and concurrent testing, and replay of failures.
Changelog #
0.3.0 #
- The build hook no longer fails a Flutter build. A hook is run once for
every kind of asset the embedder is collecting, and
flutter runruns one pass that asks for none at all; the hook read the code-asset configuration before checking whether code assets had been asked for, which throws, and took the whole build down with it before the app started. It now answers that pass with nothing.dart testanddart runnever made the call, so this was only ever reachable from Flutter. example/flutterpoints the same generators, shrinking and stateful testing at a user interface, in three shapes: a configuration sweep whose oracle is Flutter's own error reporting, a model the screen is held against, and a monkey that reads the semantics tree and insists only that the app go on working. It is a package of its own rather than part of the published archive — Flutter cannot be a dependency of a pure Dart package — and it is wherehegel_flutteris being worked out.
0.2.0 #
oneOftakes optionalweights, pairing one to one with its options: an option is drawn in proportion to its share, and a counterexample still shrinks toward the first option — weight shapes the distribution, never the shrink. Each weight is at least one and their total has to fit a draw; anything else is refused where it was written. The first consumer's document generators are what pulled this out of the deferred list.TestCase.collect(value, label: ...)tallies observations per label across the valid cases of a run, and the distribution prints at the end fromVerbosity.verboseup — the answer to "did the generators actually produce the shapes this property is supposed to exercise?". Observations made by a caseassumerejected, or inside a stateful rule that declined, are discarded with their case.
0.1.0 #
First release.
Writing properties #
property()registers an ordinarypackage:testtest, so groups,-N, tags, skips and the IDE's run button all work on it.runProperty()is the same runner for harnesses that are notpackage:test.- Draw with
tc.draw(generator, name: ...), narrow a case withtc.assume, explain one withtc.note, and steer generation withtc.target. - Failures are reported as the error your own
expectraised, with its own stack, under the counterexample the engine shrank to. A run that finds several distinct bugs reports all of them. - Counterexamples are kept in an example database and replayed ahead of
anything new, so a property keeps failing until the bug is fixed;
reproduce:replays one from a blob, which is how a CI failure comes back to a machine with a debugger. HEGEL_TEST_CASESandHEGEL_DATABASEoverride a run without editing it.
Generators #
- Numbers, text, and time:
integers,bigIntegers,doubles,booleans,durations,text,characters,fromRegex,emails,urls,domains,bytes,dates,times,dateTimes,uuids,ipAddresses. - Collections:
listswith optional uniqueness,sets,maps, all with length bounds. - Composition:
map,where,flatMapon every generator, plusjust,sampledFrom,oneOf,optional,tuple2–tuple4,composite, anddeferredfor recursive shapes. package:hegel/generators.dartis the catalog on its own, for prefixing.
Stateful testing #
StateMachine,Rule,InvariantandrunStateful: the engine picks the rules, and shrinks the sequence to the shortest script that still breaks an invariant.Rule.preconditionkeeps a rule off the table until it can run;Pool<T>holds what one step made for a later step to act on, and the engine chooses and shrinks over which.maxConcurrency:above one runs the rules several at a time, interleaving at everyawaitin a rule body, with each worker's steps tagged in the report.Rule.groupsays what may overlap with what.
The engine #
- Distributed through a build hook: the pinned release is downloaded, verified against a checked-in SHA-256, and published as a code asset, with a local-engine override via pub user-defines. Nothing to install.
- Linux x64 and arm64, macOS arm64, Windows x64 and arm64 — the targets hegel-rust publishes.
- Use
dart build clirather thandart compile exeto bundle an application that depends on this package;dart runanddart testneed nothing.
Notes #
- Pure-Dart properties run under
flutter testtoday. Widget-level property testing is planned as a separatehegel_flutterpackage, becauseflutter_testpinstest_apiexactly. - Requires Dart 3.13 or later, for build hooks and code assets.