|  | 
| 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