|
2 | 2 | # -*- coding: utf-8 -*- |
3 | 3 |
|
4 | 4 | r""" |
5 | | -htmldocck.py is a custom checker script for Rustdoc HTML outputs. |
6 | | -
|
7 | | -# How and why? |
8 | | -
|
9 | | -The principle is simple: This script receives a path to generated HTML |
10 | | -documentation and a "template" script, which has a series of check |
11 | | -commands like `@has` or `@matches`. Each command is used to check if |
12 | | -some pattern is present or not present in the particular file or in |
13 | | -a particular node of the HTML tree. In many cases, the template script |
14 | | -happens to be the source code given to rustdoc. |
15 | | -
|
16 | | -While it indeed is possible to test in smaller portions, it has been |
17 | | -hard to construct tests in this fashion and major rendering errors were |
18 | | -discovered much later. This script is designed to make black-box and |
19 | | -regression testing of Rustdoc easy. This does not preclude the needs for |
20 | | -unit testing, but can be used to complement related tests by quickly |
21 | | -showing the expected renderings. |
22 | | -
|
23 | | -In order to avoid one-off dependencies for this task, this script uses |
24 | | -a reasonably working HTML parser and the existing XPath implementation |
25 | | -from Python's standard library. Hopefully, we won't render |
26 | | -non-well-formed HTML. |
27 | | -
|
28 | | -# Commands |
29 | | -
|
30 | | -Commands start with an `@` followed by a command name (letters and |
31 | | -hyphens), and zero or more arguments separated by one or more whitespace |
32 | | -characters and optionally delimited with single or double quotes. The `@` |
33 | | -mark cannot be preceded by a non-whitespace character. Other lines |
34 | | -(including every text up to the first `@`) are ignored, but it is |
35 | | -recommended to avoid the use of `@` in the template file. |
36 | | -
|
37 | | -There are a number of supported commands: |
38 | | -
|
39 | | -* `@has PATH` checks for the existence of the given file. |
40 | | -
|
41 | | - `PATH` is relative to the output directory. It can be given as `-` |
42 | | - which repeats the most recently used `PATH`. |
43 | | -
|
44 | | -* `@hasraw PATH PATTERN` and `@matchesraw PATH PATTERN` checks |
45 | | - for the occurrence of the given pattern `PATTERN` in the specified file. |
46 | | - Only one occurrence of the pattern is enough. |
47 | | -
|
48 | | - For `@hasraw`, `PATTERN` is a whitespace-normalized (every consecutive |
49 | | - whitespace being replaced by one single space character) string. |
50 | | - The entire file is also whitespace-normalized including newlines. |
51 | | -
|
52 | | - For `@matchesraw`, `PATTERN` is a Python-supported regular expression. |
53 | | - The file remains intact but the regexp is matched without the `MULTILINE` |
54 | | - and `IGNORECASE` options. You can still use a prefix `(?m)` or `(?i)` |
55 | | - to override them, and `\A` and `\Z` for definitely matching |
56 | | - the beginning and end of the file. |
57 | | -
|
58 | | - (The same distinction goes to other variants of these commands.) |
59 | | -
|
60 | | -* `@has PATH XPATH PATTERN` and `@matches PATH XPATH PATTERN` checks for |
61 | | - the presence of the given XPath `XPATH` in the specified HTML file, |
62 | | - and also the occurrence of the given pattern `PATTERN` in the matching |
63 | | - node or attribute. Only one occurrence of the pattern in the match |
64 | | - is enough. |
65 | | -
|
66 | | - `PATH` should be a valid and well-formed HTML file. It does *not* |
67 | | - accept arbitrary HTML5; it should have matching open and close tags |
68 | | - and correct entity references at least. |
69 | | -
|
70 | | - `XPATH` is an XPath expression to match. The XPath is fairly limited: |
71 | | - `tag`, `*`, `.`, `//`, `..`, `[@attr]`, `[@attr='value']`, `[tag]`, |
72 | | - `[POS]` (element located in given `POS`), `[last()-POS]`, `text()` |
73 | | - and `@attr` (both as the last segment) are supported. Some examples: |
74 | | -
|
75 | | - - `//pre` or `.//pre` matches any element with a name `pre`. |
76 | | - - `//a[@href]` matches any element with an `href` attribute. |
77 | | - - `//*[@class="impl"]//code` matches any element with a name `code`, |
78 | | - which is an ancestor of some element which `class` attr is `impl`. |
79 | | - - `//h1[@class="fqn"]/span[1]/a[last()]/@class` matches a value of |
80 | | - `class` attribute in the last `a` element (can be followed by more |
81 | | - elements that are not `a`) inside the first `span` in the `h1` with |
82 | | - a class of `fqn`. Note that there cannot be any additional elements |
83 | | - between them due to the use of `/` instead of `//`. |
84 | | -
|
85 | | - Do not try to use non-absolute paths, it won't work due to the flawed |
86 | | - ElementTree implementation. The script rejects them. |
87 | | -
|
88 | | - For the text matches (i.e. paths not ending with `@attr`), any |
89 | | - subelements are flattened into one string; this is handy for ignoring |
90 | | - highlights for example. If you want to simply check for the presence of |
91 | | - a given node or attribute, use an empty string (`""`) as a `PATTERN`. |
92 | | -
|
93 | | -* `@count PATH XPATH COUNT` checks for the occurrence of the given XPath |
94 | | - in the specified file. The number of occurrences must match the given |
95 | | - count. |
96 | | -
|
97 | | -* `@count PATH XPATH TEXT COUNT` checks for the occurrence of the given XPath |
98 | | - with the given text in the specified file. The number of occurrences must |
99 | | - match the given count. |
100 | | -
|
101 | | -* `@snapshot NAME PATH XPATH` creates a snapshot test named NAME. |
102 | | - A snapshot test captures a subtree of the DOM, at the location |
103 | | - determined by the XPath, and compares it to a pre-recorded value |
104 | | - in a file. The file's name is the test's name with the `.rs` extension |
105 | | - replaced with `.NAME.html`, where NAME is the snapshot's name. |
106 | | -
|
107 | | - htmldocck supports the `--bless` option to accept the current subtree |
108 | | - as expected, saving it to the file determined by the snapshot's name. |
109 | | - compiletest's `--bless` flag is forwarded to htmldocck. |
110 | | -
|
111 | | -* `@has-dir PATH` checks for the existence of the given directory. |
112 | | -
|
113 | | -* `@files FOLDER_PATH [ENTRIES]`, checks that `FOLDER_PATH` contains exactly |
114 | | - `[ENTRIES]`. |
115 | | -
|
116 | | -All conditions can be negated with `!`. `@!has foo/type.NoSuch.html` |
117 | | -checks if the given file does not exist, for example. |
118 | | -
|
| 5 | +For documentation and usage instructions, please see |
| 6 | +https://rustc-dev-guide.rust-lang.org/rustdoc-internals/rustdoc-test-suite.html |
119 | 7 | """ |
120 | 8 |
|
121 | 9 | from __future__ import absolute_import, print_function, unicode_literals |
|
0 commit comments