pest-test

Testing framework for pest parser (similar to tree-sitter test).

Test cases

A test case is a text file with three sections:

Here is an example test. Note that the code block delimiter is exactly 7 '=' characters.

``` My Test

=======

fn x() int { return 1; }

=======

(sourcefile (functiondefinition (identifier: "x") (parameterlist) (primitivetype: "int") (block (return_statement (number: "1") ) ) ) )

```

Attributes

Nodes in the expected output S-expression may be annotated with attributes of the form #[name(args)]. The currently recognized attributes are:

Usage

The main interface to the test framework is pest_test::PestTester. By default, tests are assumed to be in the tests/pest directory of your crate and have a .txt file extension. The example below shows using the lazy_static macro to create a single PestTester instance and then using it to evaluate any number of tests.

```rust

[cfg(test)]

mod tests { use mycrate::parser::{MyParser, Rule}; use lazystatic::lazystatic; use pest_test::{Error, PestTester};

lazystatic! { static ref TESTER: PestTester = PestTester::fromdefaults(Rule::root_rule); }

// Loads test from tests/pest/mytest.txt and evaluates it. Returns an Err<pest_test::Error> // if there was an error evaluating the test, or if the expected and actual values do not match. fn testmyparser -> Result<(), Error> { (*TESTER).evaluate_strict("mytest") } } ```

If you add pest-test-gen as a dev dependency, then you can use the pest_tests attribute macro to generate tests for all your test cases:

``rust // Generate tests for all test cases in tests/pest/foo/ and all subdirectories. Since //lazy_static = true, a singlePestTesteris created and used by all tests; otherwise a new //PestTester` would be created for each test.

[pest_tests(

mycrate::parser::MyParser, mycrate::parser::Rule, "rootrule", subdir = "foo", recursive = true, lazystatic = true, )]

[cfg(test)]

mod foo_tests {} ```

To disable colorization of the diff output, run cargo with CARGO_TERM_COLOR=never.

Note that a test module is only recompiled when its code changes. Thus, if you add or rename a test case in tests/pest without changing the test module, the test module might not get updated to include the new/renamed tests, so you may need to delete the target folder to force your tests to be recompiled.

Details

Test files are parsed using pest. The source code is parsed using your pest grammar, and the resulting tree is iterated exhaustively to build up a nested data structure, which is then matched to the same structure built from the expected output. If they don't match, the tree is printed with the differences in-line.