expect¶
expect builds an expectation about an actual value. The current matcher is be, which uses Raku's smartmatch operator (~~).
Basic form¶
1 | |
expect returns a builder, .to is a no-op for readability, and .be(expected) performs the comparison.
1 2 3 4 5 | |
Smartmatch semantics¶
Because be uses ~~ (via the built-in BeMatcher), you can match against types, regexes, ranges, junctions, and anything else Raku smartmatches:
1 2 3 4 | |
Plain values are wrapped in BeMatcher automatically. To plug in your own logic, pass any object that does the Matcher role — or use define-matcher for the lighter, callback-based form. Combine matchers with .and / .or; see Composable Matchers. For Raku-native any / all / one / none junctions, see Junctions.
Negation¶
.not flips the comparison:
1 | |
Reading from let¶
expect recognises a single named-pair argument as a let lookup:
1 2 3 4 5 | |
You can also pass a Pair as the expected value to read from a let:
1 2 3 4 5 | |
For more flexible let access, prefer the binding syntax shown in let.
Failure output¶
When an expectation fails, the runner records the file and line of the expect call and prints them in the failure summary so you can jump straight to the offending line.
For diffable shapes (strings, arrays, hashes, sets, bags, mixes), the failure block also includes a colorized Diff: section that highlights only the changed regions. See Diff Output for the full conventions.
Built-in matchers beyond be¶
expect(...).to.<matcher>(...) is the general form. The current built-ins:
| Matcher | Purpose |
|---|---|
be |
Smartmatch (~~) against the expected value. |
eq |
Order-dependent structural equality via eqv. See Matchers › EqMatcher. |
contain-exactly |
Order-independent multiset equality on arrays / lists. See Matchers › ContainExactlyMatcher. |
match-array |
Single-array alias for contain-exactly. |
include |
Membership check across arrays, hashes, sets/bags, strings, and ranges. See Matchers › IncludeMatcher. |
start-with |
Sequence prefix check for arrays / lists; per-arg prefix check for strings. See Matchers › StartWithMatcher. |
end-with |
Sequence suffix check for arrays / lists; per-arg suffix check for strings. See Matchers › EndWithMatcher. |
all |
Every element of a collection must match an inner matcher. See Matchers › AllMatcher. |
be-a / be-an |
Type check including subclasses, roles, and subsets ($actual ~~ $type). See Matchers › BeAMatcher. |
be-an-instance-of |
Strict runtime-type check ($actual.WHAT === $type, requires defined). See Matchers › BeAnInstanceOfMatcher. |
respond-to |
Method-presence check via $actual.^can(...). Accepts one or more method names. See Matchers › RespondToMatcher. |
have-attributes |
Multi-attribute check: each named pair calls the accessor on $actual and compares (eqv, or an inner Matcher). See Matchers › HaveAttributesMatcher. |
be-greater-than / be-gt |
Numeric > comparison; fails (not dies) on undefined or non-Real actuals. See Matchers › Comparison matchers. |
be-greater-than-or-equal-to / be-gte |
Numeric >= comparison. |
be-less-than / be-lt |
Numeric < comparison. |
be-less-than-or-equal-to / be-lte |
Numeric <= comparison. |
be-between |
Range check between two Real bounds. Inclusive by default; chain .exclusive or .inclusive to flip the mode. See Matchers › BeBetweenMatcher. |
be-within |
Tolerance check: be-within($delta).of($expected) passes when abs(actual - expected) <= delta. See Matchers › BeWithinMatcher. |
be-truthy |
Boolean coercion check (?$actual); empty Array/Hash, Nil, and undefined type objects are not truthy. See Matchers › BeTruthyMatcher. |
be-falsy |
Inverse of be-truthy (!$actual). See Matchers › BeFalsyMatcher. |
be-nil |
Undefined-value check (!$actual.defined); passes for Nil, Any, and undefined type objects. See Matchers › BeNilMatcher. |
match |
Regex match against a Str ($actual ~~ /pattern/); fails (not dies) on undefined or non-Str actuals. See Matchers › MatchMatcher. |
raise-error |
Passes when a Callable actual raises an exception when invoked. Wrap the code under test in { ... }. Forms: raise-error, raise-error(Type), raise-error(Type, /pattern/), raise-error(/pattern/). Chain .with-message($str-or-regex) to filter by exception message (Str compares with eq, Regex with ~~). See Matchers › RaiseErrorMatcher. |
change |
Passes when a Callable action changes the value returned by an observable block (compared with eqv). Wrap the action and the observable in { ... }. Chain .from(value) / .to(value) to constrain the start and / or end value, or .by(delta) / .by-at-least(delta) / .by-at-most(delta) for numeric deltas. See Matchers › ChangeMatcher. |
be-kept |
Passes when a Promise actual settles in the Kept state. Blocks up to a default 5-second timeout; pass be-kept($seconds) for a custom timeout. Surfaces the broken cause in failure messages. See Matchers › BeKeptMatcher. |
be-broken |
Passes when a Promise actual settles in the Broken state. Same timeout shape as be-kept. Surfaces the kept value or the broken cause in failure messages. See Matchers › BeBrokenMatcher. |
complete-within |
Passes when a Promise actual settles (kept or broken) within the given duration (Real seconds). See Matchers › CompleteWithinMatcher. |
emit |
Passes when a Supply or Channel actual emits exactly the given values (compared via eqv) within the collection window. Pass :within($seconds) to change the default 1-second window. See Matchers › EmitMatcher. |
emit-at-least |
Passes when a Supply or Channel actual emits at least the given count of values within the collection window. Pass :within($seconds) to change the default 1-second window. See Matchers › EmitAtLeastMatcher. |
complete |
Passes when a Supply (sending done) or Channel (closed) completes within the collection window. Pass :within($seconds) to change the default 1-second window. See Matchers › CompleteMatcher. |
eventually |
Re-runs a Callable actual on a polling loop until the chained inner matcher passes or the timeout elapses. Chain any matcher method (be, eq, match, include, be-truthy, be-greater-than, ...) or pass a Matcher instance via .matches-with. Configure with eventually(:timeout(s), :interval(s)) (defaults: 2s / 0.05s). Useful for eventually-consistent state. See Matchers › EventuallyMatcher. |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | |
Custom matchers¶
be accepts any object that does the Matcher role. The matcher's matches, failure-message, and failure-message-negated methods drive the result and the failure summary, so user-defined matchers plug in the same way as the built-in ones.
Failure behavior¶
When an expect(...) matcher fails, the failure is recorded on Failures.list and the example body stops executing — anything after the failing line is skipped. The example is reported once in the run summary regardless of how many expect statements its body contained.
This matches RSpec's default. Ideally each it block contains exactly one expect so the first miss is also the last. When you do need multiple expectations in a single example, wrap them in aggregate-failures { ... }; the throw is suppressed inside the block, every expectation runs, and the inner failures are rolled up into a single labeled Failures row at the aggregate-failures line. See aggregate-failures.
If you're writing meta-tests that deliberately trigger a failure and then inspect the recorded Failure records, use capture-failures { ... } instead — it suppresses the throw and returns the captured failures without polluting the surrounding example. See aggregate-failures § capture-failures for meta-tests.