rslint_core/
testing.rs

1//! Macros for easily making rule tests which also generate documentation examples.
2
3/// A macro for generating linter rule tests.
4///
5/// The tests are also used to generate "more examples" sections
6/// in user facing docs. You can use a `/// ignore` doc
7/// on a code expr to make docgen ignore it for user facing docs.
8///
9/// test code is run as modules, not scripts.
10#[macro_export]
11macro_rules! rule_tests {
12    ($rule:expr,
13    err: {
14        $(
15            // An optional tag to give to docgen
16            $(#[$err_meta:meta])*
17            $code:literal
18        ),* $(,)?
19    },
20
21    // Optional doc used in the user facing docs for the
22    // more valid code examples section.
23    $(#[_:meta])*
24    ok: {
25        $(
26            // An optional tag to give to docgen
27            $(#[$ok_meta:meta])*
28            $ok_code:literal
29        ),* $(,)?
30    } $(,)?) => {
31        rule_tests!(valid, invalid, $rule, err: { $($code),* }, ok: { $($ok_code),* });
32    };
33    (
34    $ok_name:ident,
35    $err_name:ident,
36    $rule:expr,
37    err: {
38        $(
39            // An optional tag to give to docgen
40            $(#[$err_meta:meta])*
41            $code:literal
42        ),* $(,)?
43    },
44    ok: {
45        $(
46            // An optional tag to give to docgen
47            $(#[$ok_meta:meta])*
48            $ok_code:literal
49        ),* $(,)?
50    } $(,)?) => {
51        #[test]
52        fn $err_name() {
53            $(
54                let res = rslint_parser::parse_module($code, 0);
55                let errs = $crate::run_rule(&$rule, 0, res.syntax(), true, &[], std::sync::Arc::from($code.to_string()));
56                if errs.diagnostics.is_empty() {
57                    panic!("\nExpected:\n```\n{}\n```\nto fail linting, but instead it passed (with {} parsing errors)", $code, res.errors().len());
58                }
59            )*
60        }
61
62        #[test]
63        fn $ok_name() {
64            $(
65                let res = rslint_parser::parse_module($ok_code, 0);
66                let errs = $crate::run_rule(&$rule, 0, res.syntax(), true, &[], std::sync::Arc::from($ok_code.to_string()));
67
68                if !errs.diagnostics.is_empty() {
69                    panic!("\nExpected:\n```\n{}\n```\nto pass linting, but instead it threw errors (along with {} parsing errors):\n\n", $ok_code, res.errors().len());
70                }
71            )*
72        }
73    };
74}