Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix the processing of test filter ranges to match the documentation #312

Merged
merged 3 commits into from
Jun 1, 2021
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@
- Avoid exporting `list_tests` in the main test APIs (`Alcotest{,_lwt,_async}`).
Use `Alcotest_engine` directly if you want this function. (#310, @CraigFe)

- Fix parsing of test filter ranges to allow '-' separators (e.g. `test alpha
1-4`), as advertised in the manpage. The previously-used '..' separator is
also supported. (#312, @CraigFe)

### 1.4.0 (2021-04-15)

- Add `?here` and `?pos` arguments to the test assertion functions. These can be
Expand Down
8 changes: 6 additions & 2 deletions src/alcotest-engine/config.ml
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,10 @@ module Key = struct
if lower > upper then acc else range (succ lower) upper (lower :: acc)
in
let process_range acc s =
String.cuts ~sep:".." s |> List.map String.to_int |> function
String.cuts ~sep:".." s
|> List.concat_map (String.cuts ~sep:"-")
|> List.map String.to_int
|> function
| [ Some i ] -> i :: acc
| [ Some lower; Some upper ] when lower <= upper ->
range lower upper acc
Expand All @@ -172,7 +175,8 @@ module Key = struct
and+ index_cases =
let doc =
"A comma-separated list of test case numbers (and ranges of numbers) \
to run, e.g: '4,6-10,19'"
to run, e.g: '4,6-10,19'. When specifying ranges, both '-' and '..' \
are accepted as valid separators."
in
Arg.(
value
Expand Down
9 changes: 9 additions & 0 deletions src/alcotest-stdlib-ext/alcotest_stdlib_ext.ml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,15 @@ module List = struct
in
aux [] n l

let concat_map f l =
let rec aux f acc = function
| [] -> rev acc
| x :: l ->
let xs = f x in
(aux [@tailcall]) f (rev_append xs acc) l
in
aux f [] l
Comment on lines +49 to +55

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any reason you are passing f to aux?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is just me over-optimising out of habit. ocamlopt w/o flambda doesn't do lambda lifting, so if you don't string f through the calls to aux then you need to allocate a closure to store it (which is slower).

https://godbolt.org/z/4zxvszW7c

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks :)


let filter_map f l =
let rec inner acc = function
| [] -> rev acc
Expand Down
1 change: 1 addition & 0 deletions src/alcotest-stdlib-ext/alcotest_stdlib_ext.mli
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ module List : sig
val rev_head : int -> 'a list -> 'a list
(** Reverse a list, taking at most the first n elements of the original list. *)

val concat_map : ('a -> 'b list) -> 'a list -> 'b list
val filter_map : ('a -> 'b option) -> 'a list -> 'b list
val lift_result : ('a, 'b) result t -> ('a t, 'b t) result
val init : int -> (int -> 'a) -> 'a list
Expand Down
21 changes: 21 additions & 0 deletions test/e2e/alcotest/passing/dune.inc
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
empty_test_name
filter_name
filter_name_regex
filter_range
isatty
json_output
list_tests
Expand All @@ -34,6 +35,7 @@
empty_test_name
filter_name
filter_name_regex
filter_range
isatty
json_output
list_tests
Expand Down Expand Up @@ -255,6 +257,25 @@
(action
(diff filter_name_regex.expected filter_name_regex.processed)))

(rule
(target filter_range.actual)
(action
(with-outputs-to %{target}
(with-accepted-exit-codes (or 0 125)
(run %{dep:filter_range.exe} test main 0..1,1-3,5)))))

(rule
(target filter_range.processed)
(action
(with-outputs-to %{target}
(run ../../strip_randomness.exe %{dep:filter_range.actual}))))

(rule
(alias runtest)
(package alcotest)
(action
(diff filter_range.expected filter_range.processed)))

(rule
(target isatty.actual)
(action
Expand Down
12 changes: 12 additions & 0 deletions test/e2e/alcotest/passing/filter_range.expected
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
Testing `test/e2e/alcotest/passing/filter_range.ml'.
This run has ID `<uuid>'.

[OK] main 0 test-0.
[OK] main 1 test-1.
[OK] main 2 test-2.
[OK] main 3 test-3.
[SKIP] main 4 test-4.
[OK] main 5 test-5.

Full test results in `<build-context>/_build/_tests/<test-dir>'.
Test Successful in <test-duration>s. 5 tests run.
11 changes: 11 additions & 0 deletions test/e2e/alcotest/passing/filter_range.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
let () =
let should_run i =
(* Corresponds to ranges specified in [filter_range.opts]. *)
List.mem i [ 0; 1; 2; 3; 5 ]
in
let tests =
List.init 6 (fun i ->
Alcotest.test_case (Printf.sprintf "test-%d" i) `Quick (fun () ->
if not (should_run i) then failwith "Test should have been skipped"))
in
Alcotest.run __FILE__ [ ("main", tests) ]
1 change: 1 addition & 0 deletions test/e2e/alcotest/passing/filter_range.opts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
test main 0..1,1-3,5