oden/fine/tests
John Doty 85ffc0c7dd [fine] All error sentinels carry diagnostics
The system has an invariant that if you ever return an error
sentinel (error environment, error type) then that sentinel is caused
by an error that was reported to the user. We have had too many bugs
over the last little while where that was not the case!

(An example is if we mis-interpret the tree by calling `nth_tree` with
the wrong index or something, and get `None`, and think "oh must be a
syntax error", but it was really just the wrong index. Then there's an
error sentinel with no error diagnostic and we don't discover the
mistake until much farther along.)

Now we enforce this by requiring that whoever constructs the error
sentinel *prove* that they can do so by providing a diagnostic. It's
less efficient but prevents the problem.

This actually uncovered a couple of latent bugs where we were
generating error sentinels instead of a more appropriate type! Whoops!
2024-03-25 08:07:18 -07:00
..
errors [fine] Parse alternate types 2024-02-01 07:56:30 -08:00
expression [fine] All error sentinels carry diagnostics 2024-03-25 08:07:18 -07:00
modules [fine] Imports maybe 2024-03-07 20:07:41 -08:00
example_tests.rs [fine] All error sentinels carry diagnostics 2024-03-25 08:07:18 -07:00
README.md [fine] OK 2024-01-13 15:07:38 -08:00

Snapshot Tests

The .fine files in this directory and its descendants are processed by build.rs into a series of snapshot-tests. The various test assertions are specified by @ directives in comments in the file.

e.g., a test might look like this:

// @concrete:
// | File
// |   ExpressionStatement
// |     BinaryExpression
// |       BinaryExpression
// |         LiteralExpression
// |           Number:'"1"'
// |         Star:'"*"'
// |         LiteralExpression
// |           Number:'"2"'
// |       Plus:'"+"'
// |       BinaryExpression
// |         UnaryExpression
// |           Minus:'"-"'
// |           LiteralExpression
// |             Number:'"3"'
// |         Star:'"*"'
// |         LiteralExpression
// |           Number:'"4"'
// |     Semicolon:'";"'
//
1 * 2 + -3 * 4;

// @type: 532 f64

Assertions

The various assertions are as follows:

  • The // @ignore directive marks the test as ignored.

  • The // @concrete: assertion says that the following lines (prefixed with // | , as above) describe the concrete syntax tree of the file after parsing.

    e.g.:

    // @concrete:
    // | File
    // |   ExpressionStatement
    // |     LiteralExpression
    // |       String:'"\"Hello world\""'
    // |     Semicolon:'";"'
    //
    "Hello world";
    
  • The // @type: assertion says that the type of the tree at the given point will match the given type. @type assertions usually go after the contents of the file to make the probe points more stable in the face of new assertions and whatnot.

    e.g.:

    "Hello world!"
    // @type: 2 string
    
  • The // @type-error: assertion says that the type of the tree at the given point should be an error, and that the error message provided should be among the generated errors. (Like @type, these usually go after the code, for stability.)

    e.g.:

    - "twenty five";
    // @type-error: 0 cannot apply unary operator '-' to value of type string