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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
use Cell;
/// A rejected assumption (`tc.assume(false)` / `tc.reject()`): discard this
/// test case as `Invalid` without counting it against the budget.
pub ;
/// The engine ran out of data for this test case: conclude it as `Overrun`.
pub ;
/// A recursive generation attempt drew more than its `max_leaves` budget
/// (`HEGEL_E_RETRY` from `hegel_recursion_leaf`): unwind back to the
/// `RecursiveGenerator` draw that opened the recursion scope, which
/// discards the attempt and retries with a lower branching probability.
pub ;
/// A completed recursive generation attempt turned out to be priced for
/// branches with more children than its branch function actually draws
/// (`HEGEL_E_RETRY` from `hegel_recursion_finish`): the engine has already
/// discarded it, so unwind back to the `RecursiveGenerator` draw that
/// opened the recursion scope, which drops the value and regenerates it at
/// the corrected branching probability.
pub ;
/// `TestCase::repeat`'s loop completed naturally. Because `repeat` returns
/// `!`, it has no normal-return path; this unwind is how it tells the
/// lifecycle "this test case finished successfully, record it as `Valid`".
pub ;
/// An invalid-argument (usage) error detected inside a running test body:
/// the caller configured the test in a way the framework can't honour (a
/// generator bound with `max < min`, an empty `sampled_from`, a non-finite
/// `tc.target()` score, ...). A mistake in how the test is *written*, not a
/// property that failed on some input — the lifecycle aborts the run with
/// the carried message instead of shrinking it as a counterexample.
pub String);
/// A violated internal invariant: a bug in Hegel itself, detected inside a
/// running test body. Aborts the run with a bug-report message — it must
/// never be classified as a counterexample and shrunk. Raised by the
/// [`hegel_internal_assert!`]-family macros.
pub String);
/// Raise a control-flow unwind carrying `payload`. See the module note
/// above for why this is `resume_unwind`, not `panic!`.
pub !
/// Raise an internal-error unwind (a bug in Hegel) carrying `message`,
/// with the caller's location and bug-report framing attached. Outside a
/// test context there is no lifecycle to catch a payload, so the message
/// is panicked directly.
pub !
/// Assert an internal invariant of Hegel itself. Use in place of `assert!`
/// everywhere under `src/` (enforced by `scripts/check-internal-asserts.py`):
/// a plain `assert!` that fires inside a running test body unwinds like a
/// test failure and gets shrunk as a counterexample, while a violated
/// internal invariant must abort the run with a bug-report message.
pub use hegel_internal_assert;
/// Raise an internal error (a bug in Hegel) directly, formatting like
/// [`format!`]. The non-assertion counterpart of
/// [`hegel_internal_assert!`], for invariant violations detected by
/// control flow rather than a boolean check.
pub use hegel_internal_error;
thread_local!
pub
/// Returns `true` if we are currently inside a Hegel test context.
///
/// This can be used to conditionally execute code that depends on a
/// live test case (e.g., generating values, recording notes).
///
/// # Example
///
/// ```no_run
/// if hegel::currently_in_test_context() {
/// // inside a test
/// }
/// ```