Skip to content

Commit

Permalink
Merge pull request #196 from NathanReb/refactor-test-further
Browse files Browse the repository at this point in the history
Improve test infrastructure
  • Loading branch information
NathanReb authored Nov 25, 2019
2 parents 7e912f1 + 66ca4b6 commit e65068a
Show file tree
Hide file tree
Showing 141 changed files with 1,008 additions and 745 deletions.
10 changes: 0 additions & 10 deletions Makefile

This file was deleted.

2 changes: 1 addition & 1 deletion mdx.opam
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ doc: "https://realworldocaml.github.io/mdx/"
build: [
["dune" "subst"] {pinned}
["dune" "build" "-p" name "-j" jobs]
[make "test"] {with-test}
["dune" "runtest" "-p" name] {with-test}
]

depends: [
Expand Down
4 changes: 0 additions & 4 deletions test/bin/dune

This file was deleted.

152 changes: 0 additions & 152 deletions test/bin/gen_dune_rules.ml

This file was deleted.

3 changes: 3 additions & 0 deletions test/bin/gen_rule_helpers/dune
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
(library
(name gen_rule_helpers)
(libraries cmdliner fmt))
151 changes: 151 additions & 0 deletions test/bin/gen_rule_helpers/gen_rule_helpers.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
(* Required for compat with OCaml < 4.04 *)
let extension filename =
let length = String.length filename in
let last_dot =
try String.rindex filename '.'
with Not_found -> (length - 1)
in
String.sub filename last_dot (length - last_dot)

let read_file filename =
let lines = ref [] in
let chan = open_in filename in
try
while true do
lines := input_line chan :: !lines
done;
assert false
with End_of_file ->
close_in chan;
List.rev !lines

let pp_string_list =
Fmt.(list ~sep:(const string " ") string)

let pp_options fmt = function
| [] -> ()
| options ->
pp_string_list fmt options;
Fmt.pf fmt " "

let read_dir dir =
Sys.readdir dir
|> Array.to_list
|> List.sort String.compare

let get_dirs dir =
let is_dir f = Filename.concat dir f |> Sys.is_directory in
read_dir dir |> List.filter is_dir

let get_files dir =
let is_file f = not (Filename.concat dir f |> Sys.is_directory) in
read_dir dir |> List.filter is_file

let cwd_options_file = "test-case.opts"
let cwd_test_file_md = "test-case.md"
let cwd_test_file_t = "test-case.t"

type dir =
{ test_file : string
; target_file : string
; expected_file : string
; options : string list
; dir_name : string
}

let test_file ~dir_name files =
let is_test_file f = f = cwd_test_file_md || f = cwd_test_file_t in
match List.filter is_test_file files with
| [test_file] -> test_file
| [] ->
Printf.eprintf "No test file for %s\n" dir_name;
Printf.eprintf "There should be one of %s or %s\n" cwd_test_file_md cwd_test_file_t;
exit 1
| _ ->
Printf.eprintf "More than one test file for %s\n" dir_name;
Printf.eprintf "There should be only one of %s or %s\n" cwd_test_file_md cwd_test_file_t;
exit 1

let expected_file ~dir_name ~test_file files =
let is_expected_file f = extension f = ".expected" in
match List.filter is_expected_file files with
| [] -> test_file
| [expected_file] -> expected_file
| _ ->
Printf.eprintf "More than one .expected file for %s\n" dir_name;
exit 1

let dir dir_name =
let files = get_files dir_name in
let test_file = test_file ~dir_name files in
let expected_file = expected_file ~dir_name ~test_file files in
let target_file = dir_name ^ ".actual" in
let options_file = Filename.concat dir_name cwd_options_file in
let options_file_exists = Sys.file_exists options_file in
let options = if options_file_exists then read_file options_file else [] in
{ test_file
; target_file
; expected_file
; options
; dir_name
}

let pr_runtest_alias dir =
Fmt.pr
{|
(alias
(name runtest)
(action (diff %s/%s %s)))
|}
dir.dir_name
dir.expected_file
dir.target_file

let pr_rule ~pp_action dir =
Fmt.pr
{|
(rule
(target %s)
(deps (package mdx) (source_tree %s))
(action%a))
|}
dir.target_file
dir.dir_name
pp_action dir

type generator =
{ pp_expect_action : Format.formatter -> dir -> unit
; pp_failure_action : Format.formatter -> dir -> unit
}

let pr_rule ~pp_action dir_name =
let dir = dir dir_name in
pr_rule ~pp_action dir;
pr_runtest_alias dir

let rule_gen generator rule_type () =
let pp_action =
match rule_type with
| `Test_expect -> generator.pp_expect_action
| `Test_failure -> generator.pp_failure_action
in
List.iter (pr_rule ~pp_action) (get_dirs ".")

let run generator =
let open Cmdliner in
let cmds =
Term.[
const (rule_gen generator `Test_expect) $ const (), info "test_expect";
const (rule_gen generator `Test_failure) $ const (), info "test_failure";
]
in
let default =
let doc = "Generate dune files for the binary tests." in
let exits = Term.default_exits in
let man = [] in
Term.(
ret (const (`Help (`Auto, None))),
info "gen_dune_rules" ~doc ~exits ~man
)
in
Term.exit (Term.eval_choice default cmds)
16 changes: 16 additions & 0 deletions test/bin/gen_rule_helpers/gen_rule_helpers.mli
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
val pp_options : string list Fmt.t

type dir =
{ test_file : string
; target_file : string
; expected_file : string
; options : string list
; dir_name : string
}

type generator =
{ pp_expect_action : Format.formatter -> dir -> unit
; pp_failure_action : Format.formatter -> dir -> unit
}

val run : generator -> unit
3 changes: 3 additions & 0 deletions test/bin/mdx-pp/dune
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
(executable
(name gen_dune_rules)
(libraries fmt gen_rule_helpers))
12 changes: 12 additions & 0 deletions test/bin/mdx-pp/expect/dune
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
(include dune.inc)

(rule
(target dune.gen)
(deps (source_tree .))
(action
(with-stdout-to %{target}
(run ../gen_dune_rules.exe test_expect))))

(alias
(name runtest)
(action (diff dune.inc dune.gen)))
Loading

0 comments on commit e65068a

Please sign in to comment.