コンパイルエラーとなるべきテスト項目の作成方法について。
コンパイルエラーとなるかの確認は、型により自明なため、殆どの場合は不要である。
しかし稀に、ポカヨケ確認、不用意な修正防止、などのために必要になる。
特に Rustでは、マクロにおける入力構文のエラー検証に使える。
以下の知識を組み合わせる。
#[doc(hidden)]
属性で文書化出力のみを抑制できる。
compile_fail
で文書化テストのコンパイルエラーを確認できる[1]。
以下では、for_loop
マクロが for-in 構文を模倣している。ここでループアイテムは元の構文と同じくパターンで、それは論駁不可能でなければならない。関数 _dummy_for_doc_test
の文書化テストでは、それについての確認が含まれている (もしマクロを while-let 構文で実装していれば、ここでエラーになっただろう)。
/// For-loop macro.
///
/// ```
/// # use rust_test::for_loop;
/// let values = vec![Some(1), Some(2), None];
/// let mut summary = 0;
/// for_loop!((&x in values.iter()) {
/// summary += x.unwrap_or(0);
/// });
///
/// assert_eq!(summary, 3);
/// ```
#[macro_export]
macro_rules! for_loop {
(($item:pat in $iter:expr) $block:block) => {{
let mut iter = IntoIterator::into_iter($iter);
loop {
match Iterator::next(&mut iter) {
None => break,
Some($item) => $block,
}
}
}};
}
/// Compilation error test.
///
/// Loop item should be irrefutable pattern.
///
/// ```compile_fail
/// # use rust_test::for_loop;
/// let values = vec![Some(1), Some(2), None];
/// let mut summary = 0;
/// for_loop!((&Some(x) in values.iter()) {
/// summary += x;
/// });
/// ```
#[doc(hidden)]
fn _dummy_for_doc_test() {
// nop.
}