Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/j14159/ppx_test_match
PPX rewriter to test pattern matches.
https://github.com/j14159/ppx_test_match
ocaml ppx-rewriter testing
Last synced: 25 days ago
JSON representation
PPX rewriter to test pattern matches.
- Host: GitHub
- URL: https://github.com/j14159/ppx_test_match
- Owner: j14159
- License: mit
- Created: 2020-02-29T21:40:11.000Z (almost 5 years ago)
- Default Branch: master
- Last Pushed: 2020-03-02T02:56:16.000Z (almost 5 years ago)
- Last Synced: 2024-10-29T21:14:27.449Z (2 months ago)
- Topics: ocaml, ppx-rewriter, testing
- Language: OCaml
- Size: 27.3 KB
- Stars: 0
- Watchers: 3
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE.md
- Code of conduct: code_of_conduct.md
Awesome Lists containing this project
README
ppx\_test\_match
=====
A PPX rewriter to allow simpler testing of pattern matches rather than full equality. Roughly modelled on [EUnit's](http://erlang.org/doc/apps/eunit/chapter.html) `?assertMatch` macro.**Warning:** this is still very early and incomplete.
Please note that this project is released with a Contributor Code of Conduct, version 1.4. By participating in this project you agree to abide by its terms. Please see `code_of_conduct.md` in this repository for details.
# Usage
Add this preprocessing step to your `dune` file's library, executable, or test:```
(preprocess (pps ppx_test_match?))
```See `dune/test` for a more complete example or [the Dune documentation](https://dune.readthedocs.io/en/stable/concepts.html#preprocessing-spec).
This is still too early to be fully usable but the following are already possible:
```ocaml
let some_ounit_test _ =
let example_tuple = (2, 3) in
(* This will pass: *)
[%test_match? (x, y) when y > x] example_tuple;
(* This will fail: *)
[%test_match? (x, y) when x > y] example_tuple;
(* This will pass: *)
[%test_match? (2, _)] example_tupletype some_rec = { x : string; y : float }
let some_other_test_with_records =
let example_rec = { x = "hello"; y = 3.14159 } in
(* This will pass: *)
[%test_match? { x = "hello"; _ }] example_rectype a_variant = A of int
let test_with_variant _ =
(* Will pass: *)
[%test_match? (A a) when a > 4] (A 5)
```The PPX rewriter will also rewrite duplicated variables as an equality check, for example:
```ocaml
let some_other_ounit_test _ =
let t1 = (1.3, 1.3) in
let t2 = (1.0, 1.01) in
(* This will pass: *)
[%test_match? (x, x)] t1;
(* This will fail: *)
[%test_match? (x, x)] t2type some_other_rec = { a : int; b : string; c : int }
let another_test _ =
(* This will pass: *)
[%test_match? { a; c = a; _ }] { a = 1; b = "abc"; c = 1 }type a_variant = A of int
let test_eq_with_variant _ =
(* Will pass: *)
[%test_match? (a, A a)] (2, A 2)
(* Will fail: *)
[%test_match? (a, A a) when a < 5] (6, A 6)
```Only tuples, records, and variants support this rewriting at the moment.
## Printer Argument
You can optionally supply a `printer` argument to `test_match` that will be used to format a non-matching expression on failure. An example using [ppx_deriving](https://github.com/ocaml-ppx/ppx_deriving) to generate the printer:```ocaml
let test_with_printer _ =
(* This will fail with the following message in a `Failure` exception:Failed to match (x, x) with value (1, 2)
*)
[%test_match? (x, x)] (1, 2) ~printer:[derive.show: (int * int)]
```# Rewriting Details
When `test_match?` sees something like `(x, x)`, it will synthesize the following replacement:```ocaml
(x, _syn_0x) when x = _syn_0x
```A more complex example, e.g. `((x, y), x) when y > x)` will be rewritten as follows:
```ocaml
((x, y), _syn_0x) when y > x && x = _syn_0x
```More occurrences of the same variable are sequentially named, e.g. `(a, a, a, b)` will be rewritten to:
```ocaml
(a, _syn_0a, _syn_1a, b)
```# Licensing
ppx\_test\_match is released under the terms of the MIT license. Please see `LICENSE.md` for more details.