1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315
|
open! Base
open Base_quickcheck
open Expect_test_helpers_base
open Functor
open Map
open struct
(** Instantiating key and data both as [int]. *)
module Instance_int = struct
module I = Instance (Int)
type t = int I.t [@@deriving equal, quickcheck, sexp_of]
end
end
(** module types *)
module type Accessors_generic = Accessors_generic
module type Creators_and_accessors_generic = Creators_and_accessors_generic
module type Creators_generic = Creators_generic
module type For_deriving = For_deriving
module type S_poly = S_poly
(** type-only modules for module type instantiation - untested *)
module With_comparator = With_comparator
module With_first_class_module = With_first_class_module
module Without_comparator = Without_comparator
(** supporting datatypes - untested *)
module Continue_or_stop = Continue_or_stop
module Finished_or_unfinished = Finished_or_unfinished
module Merge_element = Merge_element
module Or_duplicate = Or_duplicate
module Symmetric_diff_element = Symmetric_diff_element
(** types *)
type nonrec ('k, 'v, 'c) t = ('k, 'v, 'c) t
(** module types for ppx deriving *)
module type Compare_m = Compare_m
module type Equal_m = Equal_m
module type Hash_fold_m = Hash_fold_m
module type M_sexp_grammar = M_sexp_grammar
module type M_of_sexp = M_of_sexp
module type Sexp_of_m = Sexp_of_m
(** functor for ppx deriving - tested below *)
module M = M
(** sexp conversions and grammar *)
let sexp_of_m__t = sexp_of_m__t
let m__t_of_sexp = m__t_of_sexp
let%expect_test _ =
quickcheck_m
[%here]
(module Instance_int)
~f:(fun t ->
let sexp = [%sexp_of: int M(Int).t] t in
require_equal [%here] (module Sexp) sexp [%sexp (to_alist t : (int * int) list)];
let round_trip = [%of_sexp: int M(Int).t] sexp in
require_equal [%here] (module Instance_int) round_trip t);
[%expect {| |}]
;;
let m__t_sexp_grammar = m__t_sexp_grammar
let%expect_test _ =
print_s [%sexp ([%sexp_grammar: int M(Int).t] : _ Sexp_grammar.t)];
[%expect
{|
(Tagged (
(key sexp_grammar.assoc)
(value ())
(grammar (
List (
Many (
List (
Cons
(Tagged ((key sexp_grammar.assoc.key) (value ()) (grammar Integer)))
(Cons
(Tagged (
(key sexp_grammar.assoc.value) (value ()) (grammar Integer)))
Empty))))))))
|}]
;;
(** comparisons *)
let compare_m__t = compare_m__t
let equal_m__t = equal_m__t
let%expect_test _ =
quickcheck_m
[%here]
(module Pair (Instance_int))
~f:(fun (a, b) ->
require_equal
[%here]
(module Ordering)
(Ordering.of_int ([%compare: int M(Int).t] a b))
(Ordering.of_int ([%compare: (int * int) list] (to_alist a) (to_alist b)));
require_equal
[%here]
(module Bool)
([%equal: int M(Int).t] a b)
([%equal: (int * int) list] (to_alist a) (to_alist b)));
[%expect {| |}]
;;
(** hash functions *)
let hash_fold_m__t = hash_fold_m__t
let hash_fold_direct = hash_fold_direct
let%expect_test _ =
quickcheck_m
[%here]
(module Instance_int)
~f:(fun t ->
let actual_m = Hash.run [%hash_fold: int M(Int).t] t in
let actual_direct = Hash.run (hash_fold_direct Int.hash_fold_t Int.hash_fold_t) t in
let expect = Hash.run [%hash_fold: (int * int) list] (to_alist t) in
require_equal [%here] (module Int) actual_m expect;
require_equal [%here] (module Int) actual_direct expect);
[%expect {| |}]
;;
(** comparator accessors - untested *)
let comparator_s = comparator_s
let comparator = comparator
(** creators and accessors *)
include (Test_toplevel : Test_toplevel.S)
(** polymorphic comparison interface *)
module Poly = struct
open Poly
type nonrec ('k, 'v) t = ('k, 'v) t
type nonrec ('k, 'v) tree = ('k, 'v) tree
type nonrec comparator_witness = comparator_witness
include (Test_poly : Test_poly.S)
end
(** comparator interface *)
module Using_comparator = struct
open Using_comparator
(** type *)
type nonrec ('k, 'v, 'c) t = ('k, 'v, 'c) t
(** comparator accessor - untested *)
let comparator = comparator
(** sexp conversions *)
let sexp_of_t = sexp_of_t
let t_of_sexp_direct = t_of_sexp_direct
let%expect_test _ =
quickcheck_m
[%here]
(module Instance_int)
~f:(fun t ->
let sexp = sexp_of_t Int.sexp_of_t Int.sexp_of_t [%sexp_of: _] t in
require_equal [%here] (module Sexp) sexp ([%sexp_of: int Map.M(Int).t] t);
let round_trip =
t_of_sexp_direct ~comparator:Int.comparator Int.t_of_sexp Int.t_of_sexp sexp
in
require_equal [%here] (module Instance_int) round_trip t);
[%expect {| |}]
;;
(** hash function *)
let hash_fold_direct = hash_fold_direct
let%expect_test _ =
quickcheck_m
[%here]
(module Instance_int)
~f:(fun t ->
require_equal
[%here]
(module Int)
(Hash.run (hash_fold_direct Int.hash_fold_t Int.hash_fold_t) t)
(Hash.run [%hash_fold: int Map.M(Int).t] t));
[%expect {| |}]
;;
(** functor for polymorphic definition - untested *)
module Empty_without_value_restriction (Cmp : Comparator.S1) = struct
open Empty_without_value_restriction (Cmp)
let empty = empty
end
(** creators and accessors *)
include (Test_using_comparator : Test_using_comparator.S)
(** tree interface *)
module Tree = struct
open Tree
(** type *)
type nonrec ('k, 'v, 'c) t = ('k, 'v, 'c) t
(** sexp conversions *)
let sexp_of_t = sexp_of_t
let t_of_sexp_direct = t_of_sexp_direct
let%expect_test _ =
let module Tree_int = struct
module I = Instance_tree (Int)
type t = int I.t [@@deriving equal, quickcheck, sexp_of]
end
in
quickcheck_m
[%here]
(module Tree_int)
~f:(fun tree ->
let sexp = sexp_of_t Int.sexp_of_t Int.sexp_of_t [%sexp_of: _] tree in
require_equal
[%here]
(module Sexp)
sexp
([%sexp_of: int Map.M(Int).t]
(Using_comparator.of_tree tree ~comparator:Int.comparator));
let round_trip =
t_of_sexp_direct ~comparator:Int.comparator Int.t_of_sexp Int.t_of_sexp sexp
in
require_equal [%here] (module Tree_int) round_trip tree);
[%expect {| |}]
;;
(** polymorphic constructor - untested *)
let empty_without_value_restriction = empty_without_value_restriction
(** builders *)
module Build_increasing = struct
open Build_increasing
type nonrec ('k, 'v, 'c) t = ('k, 'v, 'c) t
(** tree builder functions *)
let empty = empty
let add_exn = add_exn
let to_tree = to_tree
let%expect_test _ =
let module Tree_int = struct
module I = Instance_tree (Int)
type t = int I.t [@@deriving equal, quickcheck, sexp_of]
end
in
quickcheck_m
[%here]
(module struct
type t =
((int[@generator Base_quickcheck.Generator.small_strictly_positive_int])
* int)
list
[@@deriving quickcheck, sexp_of]
end)
~f:(fun alist ->
let actual =
List.fold_result alist ~init:empty ~f:(fun builder (key, data) ->
Or_error.try_with (fun () ->
add_exn builder ~comparator:Int.comparator ~key ~data))
|> Or_error.map ~f:to_tree
in
Or_error.iter actual ~f:(fun map ->
require [%here] (Tree.invariants map ~comparator:Int.comparator));
let expect =
match List.is_sorted_strictly alist ~compare:[%compare: int * _] with
| false -> Error (Error.of_string "not sorted")
| true ->
Ok
(Map.Using_comparator.Tree.of_sequence_exn
~comparator:Int.comparator
(Sequence.of_list alist))
in
require_equal [%here] (module Ok (Tree_int)) actual expect);
[%expect {| |}]
;;
end
(** creators and accessors *)
include (Test_tree : Test_tree.S)
end
end
|