helper.ml 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. open Base
  2. open OUnit2
  3. module type TESTABLE = sig
  4. type t
  5. val equal: t Equal.t
  6. val to_string: t -> string
  7. end
  8. module String_ = struct
  9. type t = string
  10. let equal = String.equal
  11. let to_string x = Printf.sprintf "%S" x
  12. end
  13. module Option_(X: TESTABLE) = struct
  14. type t = X.t option
  15. let equal = Option.equal X.equal
  16. let to_string = function
  17. | Some(x) -> "Some(" ^ X.to_string x ^ ")"
  18. | None -> "None"
  19. end
  20. module List_(X: TESTABLE) = struct
  21. type t = X.t list
  22. let equal = List.equal ~equal:X.equal
  23. let to_string l =
  24. Printf.sprintf "[%s]" @@
  25. String.concat ~sep:"; " @@
  26. List.map ~f:X.to_string l
  27. end
  28. module ListUnordered_(X: TESTABLE) = struct
  29. type t = X.t list
  30. let equal xs ys =
  31. List.for_all (xs @ ys)
  32. ~f:(fun e -> List.count xs ~f:(X.equal e) = List.count ys ~f:(X.equal e))
  33. let to_string l =
  34. Printf.sprintf "{%s}" @@
  35. String.concat ~sep:"; " @@
  36. List.map ~f:X.to_string l
  37. end
  38. module Pair_(A: TESTABLE)(B: TESTABLE) = struct
  39. type t = A.t * B.t
  40. let equal (a, x) (b, y) = A.equal a b && B.equal x y
  41. let to_string (x, y) =
  42. Printf.sprintf "(%s, %s)"
  43. (A.to_string x)
  44. (B.to_string y)
  45. end
  46. module Map_(K: sig
  47. type t
  48. type comparator_witness
  49. val to_string : t -> string
  50. end)
  51. (V: TESTABLE)
  52. =
  53. struct
  54. type t = (K.t, V.t, K.comparator_witness) Map.t
  55. let equal (a: t) (b: t) = Map.equal V.equal a b
  56. let to_string m =
  57. Printf.sprintf "{%s}" @@
  58. String.concat ~sep:"; " @@
  59. List.map (Map.to_alist m)
  60. ~f:(fun (k, v) -> Printf.sprintf "%s := %s"
  61. (K.to_string k)
  62. (V.to_string v))
  63. end
  64. module IntOption = Option_(Int)
  65. module StringOption = Option_(String_)
  66. module StringList = List_(String_)
  67. let asrt (type a) (module X: TESTABLE with type t = a) e a =
  68. assert_equal ~cmp:X.equal ~printer:X.to_string e a
  69. let t name m e a =
  70. name>::fun _ -> asrt m e a
  71. let ts m l =
  72. test_list
  73. (List.map l ~f:(fun (name, e, a) -> t name m e a))
  74. let log, t_log =
  75. let out = ref [] in
  76. let log x =
  77. out := x::!out
  78. in
  79. let t_log name expected func =
  80. out := [];
  81. func ();
  82. t name (module StringList) expected (List.rev !out)
  83. in
  84. log, t_log
  85. let logf fmt = Printf.ksprintf log fmt
  86. let tfail name e run =
  87. name>::fun _ -> match Result.try_with run with
  88. | Ok(_) -> assert_failure "no exception raised"
  89. | Error(a) ->
  90. assert_equal
  91. ~cmp:(fun e a -> match e, a with
  92. | Sexp.List [ Sexp.Atom(e_exn) ; Sexp.Atom(e_msg) ],
  93. Sexp.List [ Sexp.Atom(a_exn) ; Sexp.Atom(a_msg) ] ->
  94. String.(e_exn = a_exn && is_substring a_msg ~substring:e_msg)
  95. | Sexp.List [ Sexp.Atom(e_exn) ],
  96. Sexp.List [ Sexp.Atom(a_exn) ] ->
  97. String.(e_exn = a_exn)
  98. | _, _ -> false)
  99. ~printer:Sexp.to_string
  100. (Exn.sexp_of_t e)
  101. (Exn.sexp_of_t a)
  102. let tfails ts =
  103. test_list @@
  104. List.map ts ~f:(fun (name, exn, f) ->
  105. tfail name exn f)