Skip to content

Commit c9f6903

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

File tree

2 files changed

+86
-0
lines changed

2 files changed

+86
-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: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
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+
````
37+
```jldoctest; setup = :(using InteractiveUtils)
38+
...
39+
```
40+
````
41+
42+
For longer setup code or if multiple blocks require the same environment, use the
43+
`DocTestSetup` meta block:
44+
45+
````
46+
```@meta
47+
DocTestSetup = :(import Random; Random.seed!(1234))
48+
```
49+
````
50+
51+
and disable it afterwards with
52+
53+
````
54+
```@meta
55+
DocTestSetup = nothing
56+
```
57+
````
58+
59+
## Maintaining state between snippets
60+
61+
Related doctest blocks can share state by giving them the same label after the
62+
`jldoctest` keyword. The manual uses this pattern to demonstrate mutation:
63+
64+
````
65+
```jldoctest mutation_vs_rebind
66+
julia> a = [1,2,3]
67+
...
68+
```
69+
````
70+
71+
and later
72+
73+
````
74+
```jldoctest mutation_vs_rebind
75+
julia> a[1] = 42
76+
...
77+
```
78+
````
79+
80+
Blocks with the same name execute sequentially during doctesting, so variables
81+
created in the first block remain available in the following ones.
82+
83+
When a snippet needs to preserve its result for later examples, give it a label
84+
and reuse that label. This avoids repeating setup code and mirrors a REPL
85+
session more closely.

0 commit comments

Comments
 (0)