Skip to content

Commit 4bc92f5

Browse files
committed
Make guide link to API items
1 parent 42cec27 commit 4bc92f5

File tree

1 file changed

+135
-50
lines changed

1 file changed

+135
-50
lines changed

chaos_theory/docs/guide.md

Lines changed: 135 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
# Guide
22

33
This is a short guide to chaos_theory basics. It covers how to write properties with
4-
`Source`, with a focus on the two core building blocks after `any`: `repeat` and `select`,
5-
and includes an overview of generators.
4+
[`Source`][source], with a focus on the two core building blocks after [`any`][source_any]:
5+
[`repeat`][source_repeat] and [`select`][source_select], and includes an overview of generators.
66

7-
*This is an AI-generated document that was manually reviewed and edited.*
7+
*Note: original version of this document was AI-generated.*
88

99
## The Shape Of A Property
1010

@@ -20,17 +20,18 @@ check(|src| {
2020
});
2121
```
2222

23-
`Source` gives you structured randomness. Your job is to explore the system using it.
23+
[`Source`][source] gives you structured randomness. Your job is to explore the system using it.
2424

2525
## Working With `Source`
2626

2727
The basic operations:
2828

29-
- `any` / `any_of` generate values from `Arbitrary` or from a generator.
30-
- `choose` selects an element from a slice.
31-
- `select` chooses a labeled variant and runs a branch.
32-
- `repeat` repeats a step, using `Effect` to report what happened.
33-
- `maybe` and `find` are for optional steps and recoverable failures.
29+
- [`any`][source_any] / [`any_of`][source_any_of] generate values from [`Arbitrary`][arbitrary]
30+
or from a generator.
31+
- [`choose`][source_choose] selects an element from a slice.
32+
- [`select`][source_select] chooses a labeled variant and runs a branch.
33+
- [`repeat`][source_repeat] repeats a step, using [`Effect`][effect] to report what happened.
34+
- [`maybe`][source_maybe] and [`find`][source_find] are for optional steps and recoverable failures.
3435

3536
Labels matter. Use short, stable labels (like `"action"` or `"key"`). They are
3637
not required for chaos_theory to work, but they make replay output and
@@ -39,7 +40,7 @@ often enough to spot the issue immediately.
3940

4041
## `select`: Variants With Meaning
4142

42-
`select` is how you define structured choices:
43+
[`select`][source_select] is how you define structured choices:
4344

4445
```rust
4546
# fn prop(src: &mut chaos_theory::Source) {
@@ -55,11 +56,12 @@ src.select("action", &["insert", "remove", "get"], |src, action, _ix| {
5556
```
5657

5758
You should not encode a variant choice as `any::<u8>()` or a random number. Use
58-
`select` so replay and minimization can preserve the variant choice when necessary.
59+
[`select`][source_select] so replay and minimization can preserve the variant choice
60+
when necessary.
5961

6062
## `repeat`: Exploration Over Time
6163

62-
`repeat` is the right way to explore sequences:
64+
[`repeat`][source_repeat] is the right way to explore sequences:
6365

6466
```rust
6567
use chaos_theory::Effect;
@@ -72,13 +74,13 @@ src.repeat("step", |src| {
7274
# }
7375
```
7476

75-
`Effect` matters:
77+
[`Effect`][effect] matters:
7678

77-
- `Success`: useful work was done.
78-
- `Change`: state may have changed, but no clear progress.
79-
- `Noop`: nothing happened to the system (example: action was non-applicable).
79+
- [`Success`][effect_success]: useful work was done.
80+
- [`Change`][effect_change]: state may have changed, but no clear progress.
81+
- [`Noop`][effect_noop]: nothing happened to the system (example: action was non-applicable).
8082

81-
Honest `Effect` values make exploration and minimization much more efficient.
83+
Honest [`Effect`][effect] values make exploration and minimization much more efficient.
8284

8385
### Common Anti-Pattern: Manual Random Loops
8486

@@ -93,8 +95,8 @@ for _ in 0..n {
9395
# }
9496
```
9597

96-
Use `repeat` instead. `repeat` is structured and minimizes well, while manual
97-
random loops are opaque and minimize poorly.
98+
Use [`repeat`][source_repeat] instead. `repeat` is structured and minimizes
99+
well, while manual random loops are opaque and minimize poorly.
98100

99101
Another version of the same issue is:
100102

@@ -105,7 +107,8 @@ if do_it { /* use src here */ }
105107
# }
106108
```
107109

108-
Prefer `maybe` or `select` so the execution shape is tracked structurally.
110+
Prefer [`maybe`][source_maybe] or [`select`][source_select] so the execution shape is tracked
111+
structurally.
109112

110113
## Stateful Testing (State Machines)
111114

@@ -115,7 +118,7 @@ already the "advanced" mode.
115118
The most common pattern is:
116119

117120
1. Build the system under test and a reference model.
118-
2. `repeat` a step that selects and applies an action.
121+
2. [`repeat`][source_repeat] a step that selects and applies an action.
119122
3. Assert invariants or compare against the model.
120123

121124
Example shape:
@@ -134,29 +137,33 @@ src.repeat("step", |src| {
134137
# }
135138
```
136139

137-
Nested `repeat` and `select` are normal and encouraged for complex stateful systems.
140+
Nested [`repeat`][source_repeat] and [`select`][source_select] are normal and encouraged
141+
for complex stateful systems.
138142

139143
## Filtering And Validity
140144

141145
If you need to reject invalid values, prefer recoverable filtering:
142146

143-
- `Generator::filter` returns `Option` so you can handle failure without panicking.
144-
- `filter_assume` and `assume!` mark the whole test case as invalid when the condition fails.
147+
- [`Generator::filter`][generator_filter] returns `Option` so you can handle failure
148+
without panicking.
149+
- [`filter_assume`][generator_filter_assume] and [`assume!`][assume] mark the whole test case as
150+
invalid when the condition fails.
145151

146-
Too many invalid cases will make `check` fail early because it cannot generate enough valid tests.
152+
Too many invalid cases will make [`check`][check] fail early because it cannot generate enough
153+
valid tests.
147154

148155
## Debugging Output
149156

150-
Use `should_log`, `vdbg!`, and `vprintln!` so output appears only for the
151-
failing case. It keeps tests fast and logs focused.
157+
Use [`should_log`][source_should_log], [`vdbg!`][vdbg], and [`vprintln!`][vprintln] so output
158+
appears only for the failing case. It keeps tests fast and logs focused.
152159

153160
## Generators
154161

155162
Most users never write custom generators. You can get far with:
156163

157-
- built-in generators in `make::*`,
158-
- composing with `select`, `repeat`, and `any`,
159-
- occasional use of `from_fn` if needed.
164+
- built-in generators in [`make::*`][make],
165+
- composing with [`select`][source_select], [`repeat`][source_repeat], and [`any`][source_any],
166+
- occasional use of [`from_fn`][make_from_fn] if needed.
160167

161168
Custom generators are useful for domain types or complex invariants, but they
162169
are not required for everyday property tests.
@@ -175,14 +182,22 @@ let v: Vec<String> = src.any("v");
175182

176183
Common categories:
177184

178-
- Core: `just`, `one_of`, `mix_of`, `option`, `result`
179-
- Numbers: `int_in_range`, `float_in_range`
180-
- Strings and chars: `string`, `string_with_size`, `char_ascii`, `byte_ascii`
181-
- Collections: `vec`, `vec_with_size`, `btree_map`, `hash_map`, `btree_set`, `hash_set`
182-
- Time: `duration_in_range`, `system_time_in_range`
183-
- Sync and cells: `mutex`, `rw_lock`, `once_lock`, `cell`, `ref_cell`
184-
- Regex (feature-gated): `string_matching`, `bytes_matching`
185-
- Extra crates (feature-gated): `hashbrown`, `indexmap`, `ordered_float`, `tinyvec`, `ecow`
185+
- Core: [`just`][make_just], [`one_of`][make_one_of], [`mix_of`][make_mix_of],
186+
[`option`][make_option], [`result`][make_result]
187+
- Numbers: [`int_in_range`][make_int_in_range], [`float_in_range`][make_float_in_range]
188+
- Strings and chars: [`string`][make_string], [`string_with_size`][make_string_with_size],
189+
[`char_ascii`][make_char_ascii], [`byte_ascii`][make_byte_ascii]
190+
- Collections: [`vec`][make_vec], [`vec_with_size`][make_vec_with_size],
191+
[`btree_map`][make_btree_map], [`hash_map`][make_hash_map],
192+
[`btree_set`][make_btree_set], [`hash_set`][make_hash_set]
193+
- Time: [`duration_in_range`][make_duration_in_range],
194+
[`system_time_in_range`][make_system_time_in_range]
195+
- Sync and cells: [`mutex`][make_mutex], [`rw_lock`][make_rw_lock],
196+
[`once_lock`][make_once_lock], [`cell`][make_cell], [`ref_cell`][make_ref_cell]
197+
- Regex (feature-gated): [`string_matching`][make_string_matching],
198+
[`bytes_matching`][make_bytes_matching]
199+
- Extra crates (feature-gated): [`hashbrown`][make_hashbrown], [`indexmap`][make_indexmap],
200+
[`ordered_float`][make_ordered_float], [`tinyvec`][make_tinyvec], [`ecow`][make_ecow]
186201

187202
If a generator exists, prefer using it instead of re-implementing the logic.
188203

@@ -198,10 +213,10 @@ without you having to tune distributions by hand.
198213

199214
Useful combinators:
200215

201-
- `map` and `map_reversible` for transforms
202-
- `or` and `mix_of` for alternatives
203-
- `collect` and `collect_n` for collections
204-
- `and_then` for flat-map style composition
216+
- [`map`][generator_map] and [`map_reversible`][generator_map_reversible] for transforms
217+
- [`or`][generator_or] and [`mix_of`][make_mix_of] for alternatives
218+
- [`collect`][generator_collect] and [`collect_n`][generator_collect_n] for collections
219+
- [`and_then`][generator_and_then] for flat-map style composition
205220

206221
### Seeded Generation
207222

@@ -216,17 +231,17 @@ let city = make::string_matching("[A-Za-z '-]+", true).seeded(&cities, true);
216231
# }
217232
```
218233

219-
Built-in generators already have seeds pre-configured internally,
220-
so use `seeded` only to provide seeds that are specific to your domain.
234+
Built-in generators already have seeds pre-configured internally, so use [`seeded`][generator_seeded]
235+
only to provide seeds that are specific to your domain.
221236

222237
### Writing Custom Generators
223238

224239
There are two main approaches:
225240

226-
- Use `make::from_fn` for small generators
227-
- Implement `Generator` directly for full control
241+
- Use [`make::from_fn`][make_from_fn] for small generators
242+
- Implement [`Generator`][generator] directly for full control
228243

229-
Most of this becomes unnecessary once a derive macro for `Arbitrary` exists, but
244+
Most of this becomes unnecessary once a derive macro for [`Arbitrary`][arbitrary] exists, but
230245
it is still useful for domain-specific logic.
231246

232247
#### Struct-Like Types
@@ -258,7 +273,7 @@ impl Generator for PointGen {
258273

259274
#### Enum-Like Types
260275

261-
Use `select` to choose a variant with a stable label:
276+
Use [`select`][sourceraw_select] to choose a variant with a stable label:
262277

263278
```rust
264279
use core::num::NonZero;
@@ -305,7 +320,7 @@ impl Generator for OpGen {
305320

306321
#### Collection-Like Types
307322

308-
Use `repeat` to build the collection:
323+
Use [`repeat`][sourceraw_repeat] to build the collection:
309324

310325
```rust
311326
use chaos_theory::{Arbitrary, Effect, Generator, SourceRaw};
@@ -344,4 +359,74 @@ The rule is simple: if you generate sub-values, pass the corresponding `example`
344359
sub-values into their generators. This is how chaos_theory reconstructs known
345360
values and minimizes effectively.
346361

347-
Avoid calling `Generator::next` directly. Use `Source::any` or `Source::any_of` instead.
362+
Avoid calling [`Generator::next`][generator_next] directly. Use [`Source::any`][source_any] or
363+
[`Source::any_of`][source_any_of] instead.
364+
365+
[source]: crate::Source
366+
[source_any]: crate::Source::any
367+
[source_any_of]: crate::Source::any_of
368+
[source_choose]: crate::Source::choose
369+
[source_select]: crate::Source::select
370+
[source_repeat]: crate::Source::repeat
371+
[source_maybe]: crate::Source::maybe
372+
[source_find]: crate::Source::find
373+
[source_should_log]: crate::Source::should_log
374+
[sourceraw_select]: crate::SourceRaw::select
375+
[sourceraw_repeat]: crate::SourceRaw::repeat
376+
377+
[effect]: crate::Effect
378+
[effect_success]: crate::Effect::Success
379+
[effect_change]: crate::Effect::Change
380+
[effect_noop]: crate::Effect::Noop
381+
382+
[arbitrary]: crate::Arbitrary
383+
[generator]: crate::Generator
384+
[generator_filter]: crate::Generator::filter
385+
[generator_filter_assume]: crate::Generator::filter_assume
386+
[generator_map]: crate::Generator::map
387+
[generator_map_reversible]: crate::Generator::map_reversible
388+
[generator_or]: crate::Generator::or
389+
[generator_collect]: crate::Generator::collect
390+
[generator_collect_n]: crate::Generator::collect_n
391+
[generator_and_then]: crate::Generator::and_then
392+
[generator_seeded]: crate::Generator::seeded
393+
[generator_next]: crate::Generator::next
394+
395+
[check]: crate::check
396+
[assume]: crate::assume
397+
[vdbg]: crate::vdbg
398+
[vprintln]: crate::vprintln
399+
400+
[make]: crate::make
401+
[make_from_fn]: crate::make::from_fn
402+
[make_mix_of]: crate::make::mix_of
403+
[make_just]: crate::make::just
404+
[make_one_of]: crate::make::one_of
405+
[make_option]: crate::make::option
406+
[make_result]: crate::make::result
407+
[make_int_in_range]: crate::make::int_in_range
408+
[make_float_in_range]: crate::make::float_in_range
409+
[make_string]: crate::make::string
410+
[make_string_with_size]: crate::make::string_with_size
411+
[make_char_ascii]: crate::make::char_ascii
412+
[make_byte_ascii]: crate::make::byte_ascii
413+
[make_vec]: crate::make::vec
414+
[make_vec_with_size]: crate::make::vec_with_size
415+
[make_btree_map]: crate::make::btree_map
416+
[make_hash_map]: crate::make::hash_map
417+
[make_btree_set]: crate::make::btree_set
418+
[make_hash_set]: crate::make::hash_set
419+
[make_duration_in_range]: crate::make::duration_in_range
420+
[make_system_time_in_range]: crate::make::system_time_in_range
421+
[make_mutex]: crate::make::mutex
422+
[make_rw_lock]: crate::make::rw_lock
423+
[make_once_lock]: crate::make::once_lock
424+
[make_cell]: crate::make::cell
425+
[make_ref_cell]: crate::make::ref_cell
426+
[make_string_matching]: crate::make::string_matching
427+
[make_bytes_matching]: crate::make::bytes_matching
428+
[make_hashbrown]: crate::make::hashbrown
429+
[make_indexmap]: crate::make::indexmap
430+
[make_ordered_float]: crate::make::ordered_float
431+
[make_tinyvec]: crate::make::tinyvec
432+
[make_ecow]: crate::make::ecow

0 commit comments

Comments
 (0)