trustfall_core 0.7.1

The trustfall query engine, empowering you to query everything.
Documentation
# Testing `trustfall_core`

In addition to small unit tests for specific functionality, `trustfall_core`
includes snapshot-style tests across the different layers of the compiler
toolchain. They ensure that running a query, or parsing a schema, continues to
produce the same outcomes at all levels of the compiler even as it continues to
evolve.

Contents:
- [Testing query behavior]#testing-query-behavior
- [Testing schema parsing]#testing-schema-parsing

## Testing query behavior

Query processing in `trustfall_core` includes these stages:
- syntax parsing
- conversion to IR ("frontend")
- execution via the Trustfall interpreter

Each of the stages may succeed in producing output (i.e. the input of the next
stage, if any), or fail with an error. We test both successes and failures: we
compare the result of the stage to the expected result (successful output or
error).

The subdirectories in [`tests`](./tests/) contain files named like `X.Y.ron`:
- The `X` is the test case name, describing what is being tested.
- The `Y` specifies which stage's input or output we're looking at.
- `.ron` is the [Rusty Object Notation]https://github.com/ron-rs/ron extension.

Different subdirectories here will have different options for `Y`. For example,
in the [`valid_queries`](./tests/valid_queries/) subdirectory:
- `Y = graphql` files contain a query to be used as input to the syntax parsing
  stage.
- `Y = graphql-parsed` files contain the parse tree: output from syntax parsing,
  input to the frontend.
- `Y = ir` files contain the [intermediate
  representation](https://en.wikipedia.org/wiki/Intermediate_representation) for
  the query: output from the frontend, input to the interpreter
- `Y = trace` files contain an execution trace showing the exact series of steps
  the interpreter took in order to produce its results, as well as the final
  results of running the query.

Other subdirectories test error conditions at various stages, and will have a
subset of these `Y` options as well as some new ones for stage errors: `Y =
parse-error`, `Y = frontend-error`, or `Y = exec-error`.

### Composition of tests ➡ End-to-end tests

Trustfall is a deterministic compiler; any non-determinism is considered a bug
and will be caught by tests. Therefore, per-stage tests are composable: if each
individual stage continues to produce the same output as before, we are
guaranteed that the compiler (as a mere composition of stages) continues to
produce the same output as well.

As a result, we get the benefit of end-to-end tests at the cost of per-stage
tests. This is convenient! `cargo test` can run our per-stage tests in parallel,
while getting the correctness benefits of running the equivalent sequential
end-to-end tests.

## Testing schema parsing

Schema parsing is simpler to test since there's only one stage: parsing the
schema. We adopt a similar approach: we have test schemas that are expected to
either parse successfully ([`valid_schemas`](./tests/valid_schemas/) directory)
or produce a specified error ([`schema_errors`](./tests/schema_errors/) directory).

The naming scheme for schema files and their corresponding expected errors is
similar to the one for queries: schemas are named like `X.graphql` while their
errors are named `X.schema-error.ron`.

## Recreating the test files

Under [`scripts`](../../scripts) there are bash scripts to create the `ron` files.
In general, the scripts named `recreate_*` work as a "pipeline" where they take the
output of a previous script and generate a `ron` file. For example
`recreate_all_parsed_graphql.sh` takes all `*.graphql.ron` files under
`trustfall_core/test_data/tests/valid_queries`, `trustfall_core/test_data/tests/execution_errors`,
and `trustfall_core/test_data/tests/frontend_errors` and generates `*.graphql-parsed.ron` on
those folders. While `recreate_all_ir.sh` takes all `*.graphql-parsed.ron`and generates
the `*.ir.ron`.

They are useful when you slightly modified a `*.graphql.ron` and want to update the other
files based on that.

The scripts named `create_*` receive as input a list of `graphql.ron` files and generate 
all needed files for a given test case. For example, `create_frontend_error_data.sh` will
create `*.graphql-parsed.ron` and `*.frontend-error.ron` files.

If you want to create a new valid query test, you can run:
`./create_valid_query_data.sh ../trustfall_core/test_data/tests/valid_queries/my_test.graphql.ron`.