Skip to content

Commit 047ccc0

Browse files
authored
Merge pull request #2295 from lolbinarycat/rustdoc-htmldocck
add new section on the `rustdoc` test suite
2 parents 2165464 + 59f11cd commit 047ccc0

File tree

3 files changed

+119
-8
lines changed

3 files changed

+119
-8
lines changed

Diff for: src/SUMMARY.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@
9595
- [Parallel Compilation](./parallel-rustc.md)
9696
- [Rustdoc internals](./rustdoc-internals.md)
9797
- [Search](./rustdoc-internals/search.md)
98-
98+
- [The `rustdoc` test suite](./rustdoc-internals/rustdoc-test-suite.md)
9999
# Source Code Representation
100100

101101
- [Prologue](./part-3-intro.md)

Diff for: src/rustdoc-internals/rustdoc-test-suite.md

+111
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
# The `rustdoc` test suite
2+
3+
This page is specifically about the test suite named `rustdoc`, for other test suites used for testing rustdoc, see [Rustdoc tests](../rustdoc.md#tests).
4+
5+
The `rustdoc` test suite is specifically used to test the HTML output of rustdoc.
6+
7+
This is achived by means of `htmldocck.py`, a custom checker script that leverages [XPath].
8+
9+
[XPath]: https://en.wikipedia.org/wiki/XPath
10+
11+
## Directives
12+
Directives to htmldocck are similar to those given to `compiletest` in that they take the form of `//@` comments.
13+
14+
In addition to the directives listed here,
15+
`rustdoc` tests also support most
16+
[compiletest directives](../tests/directives.html).
17+
18+
All `PATH`s in directives are relative to the the rustdoc output directory (`build/TARGET/test/rustdoc/TESTNAME`),
19+
so it is conventional to use a `#![crate_name = "foo"]` attribute to avoid
20+
having to write a long crate name multiple times.
21+
To avoid repetion, `-` can be used in any `PATH` argument to re-use the previous `PATH` argument.
22+
23+
All arguments take the form of quoted strings
24+
(both single and double quotes are supported),
25+
with the exception of `COUNT` and the special `-` form of `PATH`.
26+
27+
Directives are assertions that place constraints on the generated HTML.
28+
29+
All directives (except `files`) can be negated by putting a `!` in front of their name.
30+
31+
Similar to shell commands,
32+
directives can extend across multiple lines if their last char is `\`.
33+
In this case, the start of the next line should be `//`, with no `@`.
34+
35+
For example, `//@ !has 'foo/struct.Bar.html'` checks that crate `foo` does not have a page for a struct named `Bar` in the crate root.
36+
37+
### `has`
38+
39+
Usage 1: `//@ has PATH`
40+
Usage 2: `//@ has PATH XPATH PATTERN`
41+
42+
In the first form, `has` checks that a given file exists.
43+
44+
In the second form, `has` is an alias for `matches`,
45+
except `PATTERN` is a whitespace-normalized[^1] string instead of a regex.
46+
47+
### `matches`
48+
49+
Usage: `//@ matches PATH XPATH PATTERN`
50+
51+
Checks that the text of each element selected by `XPATH` in `PATH` matches the python-flavored regex `PATTERN`.
52+
53+
### `matchesraw`
54+
55+
Usage: `//@ matchesraw PATH PATTERN`
56+
57+
Checks that the contents of the file `PATH` matches the regex `PATTERN`.
58+
59+
### `hasraw`
60+
61+
Usage: `//@ hasraw PATH PATTERN`
62+
63+
Same as `matchesraw`, except `PATTERN` is a whitespace-normalized[^1] string instead of a regex.
64+
65+
### `count`
66+
67+
Usage: `//@ count PATH XPATH COUNT`
68+
69+
Checks that there are exactly `COUNT` matches for `XPATH` within the file `PATH`.
70+
71+
### `snapshot`
72+
73+
Usage: `//@ snapshot NAME PATH XPATH`
74+
75+
Creates a snapshot test named NAME.
76+
A snapshot test captures a subtree of the DOM, at the location
77+
determined by the XPath, and compares it to a pre-recorded value
78+
in a file. The file's name is the test's name with the `.rs` extension
79+
replaced with `.NAME.html`, where NAME is the snapshot's name.
80+
81+
htmldocck supports the `--bless` option to accept the current subtree
82+
as expected, saving it to the file determined by the snapshot's name.
83+
compiletest's `--bless` flag is forwarded to htmldocck.
84+
85+
### `has-dir`
86+
87+
Usage: `//@ has-dir PATH`
88+
89+
Checks for the existance of directory `PATH`.
90+
91+
### `files`
92+
93+
Usage: `//@ files PATH ENTRIES`
94+
95+
Checks that the directory `PATH` contains exactly `ENTRIES`.
96+
`ENTRIES` is a python list of strings inside a quoted string,
97+
as if it were to be parsed by `eval`.
98+
(note that the list is actually parsed by `shlex.split`,
99+
so it cannot contain arbitrary python expressions).
100+
101+
Example: `//@ files "foo/bar" '["index.html", "sidebar-items.js"]'`
102+
103+
[^1]: Whitespace normalization means that all spans of consecutive whitespace are replaced with a single space. The files themselves are also whitespace-normalized.
104+
105+
## Limitations
106+
`htmldocck.py` uses the xpath implementation from the standard library.
107+
This leads to several limitations:
108+
* All `XPATH` arguments must start with `//` due to a flaw in the implemention.
109+
* Many XPath features (functions, axies, etc.) are not supported.
110+
* Only well-formed HTML can be parsed (hopefully rustdoc doesn't output mismatched tags).
111+

Diff for: src/rustdoc.md

+7-7
Original file line numberDiff line numberDiff line change
@@ -77,27 +77,27 @@ does is call the `main()` that's in this crate's `lib.rs`, though.)
7777
`doctest.rs`.
7878
* The Markdown renderer is loaded up in `html/markdown.rs`, including functions
7979
for extracting doctests from a given block of Markdown.
80-
* The tests on the structure of rustdoc HTML output are located in `tests/rustdoc`, where
81-
they're handled by the test runner of bootstrap and the supplementary script
82-
`src/etc/htmldocck.py`.
8380
* Frontend CSS and JavaScript are stored in `html/static/`.
8481

8582
## Tests
8683

87-
* All paths in this section are relative to `tests` in the rust-lang/rust repository.
88-
* Tests on search engine and index are located in `rustdoc-js` and `rustdoc-js-std`.
84+
* Tests on search engine and index are located in `tests/rustdoc-js` and `tests/rustdoc-js-std`.
8985
The format is specified
9086
[in the search guide](rustdoc-internals/search.md#testing-the-search-engine).
9187
* Tests on the "UI" of rustdoc (the terminal output it produces when run) are in
92-
`rustdoc-ui`
88+
`tests/rustdoc-ui`
9389
* Tests on the "GUI" of rustdoc (the HTML, JS, and CSS as rendered in a browser)
94-
are in `rustdoc-gui`. These use a [NodeJS tool called
90+
are in `tests/rustdoc-gui`. These use a [NodeJS tool called
9591
browser-UI-test](https://github.com/GuillaumeGomez/browser-UI-test/) that uses
9692
puppeteer to run tests in a headless browser and check rendering and
9793
interactivity.
9894
* Additionally, JavaScript type annotations are written using [TypeScript-flavored JSDoc]
9995
comments and an external d.ts file. The code itself is plain, valid JavaScript; we only
10096
use tsc as a linter.
97+
* The tests on the structure of rustdoc HTML output are located in `tests/rustdoc`,
98+
where they're handled by the test runner of bootstrap and
99+
the supplementary script `src/etc/htmldocck.py`.
100+
[These tests have several extra directives available to them](./rustdoc-internals/rustdoc-test-suite.md).
101101

102102
[TypeScript-flavored JSDoc]: https://www.typescriptlang.org/docs/handbook/jsdoc-supported-types.html
103103

0 commit comments

Comments
 (0)