rustdoc-html テストスイート
このページでは、rustdoc の HTML 出力をテストするために使用される rustdoc-html という名前のテストスイートについて説明します。
その他の rustdoc 固有のテストスイートについては、Rustdoc テストスイートを参照してください。
このテストスイートの各テストファイルは、通常の Rust コードコメント内に配置される、いわゆるディレクティブが散りばめられた Rust ソースファイル file.rs にすぎません。
これらには Compiletest と HtmlDocCk の 2 種類があります。
前者について詳しく知るには、Compiletest ディレクティブを読んでください。 後者については、このまま読み進めてください。
内部的には、compiletest が補助チェッカースクリプト htmldocck.py を呼び出します。
HtmlDocCk ディレクティブ
HtmlDocCk へのディレクティブは、生成された HTML に制約を課すアサーションです。
//@ コメントの形式を取るという点で compiletest に与えられるものと似ていますが、
最終的には完全に別物であり、異なるプログラムによって処理されます。
HTML ドキュメントツリーの一部をクエリするために XPath が使用されます。
導入例:
//@ has file/type.Alias.html
//@ has - '//*[@class="rust item-decl"]//code' 'type Alias = Option<i32>;'
pub type Alias = Option<i32>;
ここでは、クレート file のために生成されたドキュメントに、
先頭にあるコードブロックがそのアイテムの期待されるレンダリングを含んでいる
公開型エイリアス Alias のページが含まれていることを確認しています。
//*[@class="rust item-decl"]//code は XPath 式です。
慣習的には、これらのディレクティブは、テスト対象のものの直上に配置します。 ただし技術的に言えば、HtmlDocCk はディレクティブだけを探すため、そうする必要はありません。
すべてのディレクティブは PATH 引数を取ります。
繰り返しを避けるため、前回の PATH 引数を再利用する目的で - を渡せます。
パスにはクレート名が含まれるため、結果として得られるパスを短くするために、クレートルートに
#![crate_name = "foo"] 属性を追加するのが慣習です。
すべての引数はシェル形式の(一重または二重の)引用符付き文字列の形式を取ります。
ただし、COUNT と PATH の特殊な - 形式は例外です。
すべてのディレクティブ(files を除く)は、名前の前に ! を付けることで否定できます。
否定ディレクティブを追加する前に、その注意点を読んでください。
シェルコマンドと同様に、
ディレクティブは最後の文字が \ である場合、複数行にまたがることができます。
この場合、次の行の先頭は // である必要があり、@ は付けません。
compiletest ディレクティブと同様に、ディレクティブ名と引数を区切るには空白だけでなくコロン : も使用できますが、
HtmlDocCk ディレクティブでは空白が推奨されます。
現在のリリースチャネル(例: stable または nightly)を指す CHANNEL を含む URL https://doc.rust-lang.org/CHANNEL を参照したい場合は、
XPath、PATTERN 引数、およびスナップショットファイルで特殊文字列 {{channel}} を使用してください。
使用可能なすべてのディレクティブを以下に示します。
has
用法 1:
//@ has PATH
PATH で指定されたファイルが存在することを確認します。
用法 2:
//@ has PATH XPATH PATTERN
PATH で指定された空白正規化済み1ファイル内で、XPATH によって選択された各要素 / 属性 / テキストのテキストが、
(同じく空白正規化された)文字列 PATTERN と一致することを確認します。
ヒント: 空白正規化を避けたい場合、または正規表現で一致させたい場合は、
代わりに matches を使用してください。
hasraw
用法:
//@ hasraw PATH PATTERN
PATH で指定された空白正規化済み1ファイルの内容が、
(同じく空白正規化された)文字列 PATTERN と一致することを確認します。
ヒント: 空白正規化を避けたい場合、または正規表現で一致させたい場合は、
代わりに matchesraw を使用してください。
matches
用法:
//@ matches PATH XPATH PATTERN
PATH で指定されたファイル内で、XPATH によって選択された各要素 / 属性 / テキストのテキストが、
Python 風2の正規表現 PATTERN と一致することを確認します。
matchesraw
用法:
//@ matchesraw PATH PATTERN
PATH で指定されたファイルの内容が、
Python 風2の正規表現 PATTERN と一致することを確認します。
count
用法:
//@ count PATH XPATH COUNT
PATH で指定されたファイル内に、XPATH に一致するものがちょうど COUNT 個あることを確認します。
snapshot
用法:
//@ snapshot NAME PATH XPATH
PATH で指定されたファイル内で、XPATH によって選択された要素 / テキストが、
ファイル FILE_STEM.NAME.html 内に事前記録されたサブツリーまたはテキスト(「スナップショット」)と一致することを確認します。ここで FILE_STEM はテストファイルのファイルステムです。
現在のサブツリー/テキストを期待値として受け入れるには、compiletest に --bless オプションを渡します。
これにより、前述のファイルが上書きされます(存在しない場合は作成されます)。
チャネルに依存する URL https://doc.rust-lang.org/CHANNEL は、自動的に特殊文字列 {{channel}} に正規化されます。
has-dir
用法:
//@ has-dir PATH
PATH で指定されたディレクトリの存在を確認します。
files
用法:
//@ files PATH ENTRIES
PATH で指定されたディレクトリに、ちょうど ENTRIES が含まれていることを確認します。
ENTRIES は引用符付き文字列内の Python 風の文字列リストです。
例: //@ files "foo/bar" '["index.html", "sidebar-items.js"]'
Compiletest ディレクティブ(概要)
導入部で述べたように、compiletest ディレクティブにもアクセスできます。
最も重要なのは、補助クレートを登録し、
テスト対象の rustdoc バイナリにフラグを渡せることです。
それらについてまだ何も知らない場合は、その章を読むことを強く推奨します。
このテストスイートに特に関連する詳細をいくつか示します。
rustdocにフラグを渡すには//@ compile-flagsと//@ doc-flagsの両方を使用できますが、 意図を示すために後者を使用することを推奨します。 前者はrustc向けです。- 補助クレートを持つテストファイルには
//@ build-aux-docsを追加して、補助クレートをrustcでコンパイルするだけでなく、rustdocでそれらのドキュメントも生成するようにします。
注意点
要素またはテキスト片が存在しないことをテストするのはかなり壊れやすく、将来の変更に強いとは言えません。
生成される HTML ドキュメントツリーの形状は時々変わることがあります。 これには、たとえば CSS クラス名の変更が含まれます。
そのようなことが起こるたびに、肯定チェックは、(その XPath 式が十分に一般的 / 緩やかであれば)意図した要素 / 属性 / テキストに引き続き一致し、 したがって正しい対象をテストし続けるか、そうでなければ一致せず、その場合は失敗するため、 変更の作者にそれらを確認させることになります。
これを、XPath 式が「もはや」一致しなくなっても失敗しない否定チェック(例: //@ !has PATH XPATH PATTERN)と比較してください。
そのため、「形状」を変更した作者には通知されず、
結果として他の誰かが意図せず PATTERN を生成されたドキュメントに再導入しても、
元の否定チェックが失敗しない可能性があります。
注記: 否定チェックの使用は避けてください!
ヒント: どうしても避けられない場合は、「形状」を変更する人が気づいて否定チェックを更新できるように、 近接した場所で、必ず類似の肯定チェックと常に組み合わせてください!
制限事項
HtmlDocCk は Python 標準ライブラリの XPath 実装を使用します。 これにより、いくつかの制限があります。
- 実装上の欠陥により、すべての
XPATH引数は//で始まる必要があります。 - 多くの XPath 機能(関数、軸など)はサポートされていません。
- 整形式の HTML のみ解析できます(rustdoc がタグの不一致を出力しないことが期待されます)。
さらに、compiletest のリビジョンはサポートされていません。