Skip to content

Commit a61c299

Browse files
committed
Revise jldoctest best practices
1 parent 2bd37fb commit a61c299

File tree

2 files changed

+77
-0
lines changed

2 files changed

+77
-0
lines changed

doc/make.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,7 @@ DevDocs = [
217217
"devdocs/functions.md",
218218
"devdocs/cartesian.md",
219219
"devdocs/meta.md",
220+
"devdocs/jldoctests.md",
220221
"devdocs/subarrays.md",
221222
"devdocs/isbitsunionarrays.md",
222223
"devdocs/sysimg.md",

doc/src/devdocs/jldoctests.md

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
# Best practices for jldoctests
2+
This page describes how to write and maintain `jldoctest` blocks in the documentation. Following these guidelines helps keep doctests reliable and easy to read.
3+
4+
5+
## Filters
6+
7+
Use `filter =` whenever output contains text that might vary across runs.
8+
The documentation relies on several recurring patterns:
9+
10+
- `r"int.jl:\\d+"` — remove line numbers from introspection macros.
11+
- `r"Stacktrace:(\\n \\[0-9]+\\].*)*"` — hide stack traces when illustrating
12+
errors.
13+
- `r"Closest candidates.*\\n .*"` — skip the method suggestions printed by
14+
`MethodError`.
15+
- `r"@ .*"` — strip file locations from the output of `methods` or
16+
`@which`.
17+
- `r"\\@world\\(MyStruct, \\d+:\\d+\\)"` — filter world age numbers.
18+
- `r"with \\d+ methods"` — ignore method counts when redefining functions.
19+
- `r"[0-9\\.]+ seconds \\(.*?\\)"` — remove timing output with memory
20+
information.
21+
- `r"[0-9\\.]+ seconds"` — remove simple timing results.
22+
- `r"[0-9\\.]+"` — filter digits from names such as anonymous functions.
23+
- `r"([A-B] [0-5])"` and `r"[A-B] [X-Z] [0-5]"` — account for non-deterministic
24+
process output.
25+
- `r"(world\\nhello|hello\\nworld)"` — allow either ordering of interleaved
26+
output.
27+
28+
If none of these match your situation, craft a regular expression that
29+
removes the varying text. Using filters keeps doctests stable across
30+
platforms and Julia versions.
31+
32+
## Setup code
33+
34+
Small setup expressions may be placed inline using the `setup =` option:
35+
36+
```jldoctest; setup = :(using InteractiveUtils)
37+
...
38+
```
39+
40+
For longer setup code or if multiple blocks require the same environment, use the
41+
`DocTestSetup` meta block:
42+
43+
```@meta
44+
DocTestSetup = :(import Random; Random.seed!(1234))
45+
```
46+
47+
and disable it afterwards with
48+
49+
```@meta
50+
DocTestSetup = nothing
51+
```
52+
53+
## Maintaining state between snippets
54+
55+
Related doctest blocks can share state by giving them the same label after the
56+
`jldoctest` keyword. The manual uses this pattern to demonstrate mutation:
57+
58+
```jldoctest mutation_vs_rebind
59+
julia> a = [1,2,3]
60+
...
61+
```
62+
63+
and later
64+
65+
```jldoctest mutation_vs_rebind
66+
julia> a[1] = 42
67+
...
68+
```
69+
70+
Blocks with the same name execute sequentially during doctesting, so variables
71+
created in the first block remain available in the following ones.
72+
73+
When a snippet needs to preserve its result for later examples, give it a label
74+
and reuse that label. This avoids repeating setup code and mirrors a REPL
75+
session more closely.
76+

0 commit comments

Comments
 (0)