176 lines
5.3 KiB
OCaml
176 lines
5.3 KiB
OCaml
open! Base
|
|
open Expect_test_helpers_base
|
|
|
|
module type S = sig
|
|
type t [@@deriving sexp_of]
|
|
|
|
include Comparable.Comparisons with type t := t
|
|
end
|
|
|
|
(* Test the consistency of derived comparison operators with [compare] because many of
|
|
them are hand-optimized in [Base]. *)
|
|
let test (type a) here (module T : S with type t = a) list =
|
|
let op (type b) (module Result : S with type t = b) operator ~actual ~expect =
|
|
With_return.with_return (fun failed ->
|
|
List.iter list ~f:(fun arg1 ->
|
|
List.iter list ~f:(fun arg2 ->
|
|
let actual = actual arg1 arg2 in
|
|
let expect = expect arg1 arg2 in
|
|
if not (Result.compare actual expect = 0)
|
|
then (
|
|
print_cr
|
|
here
|
|
[%message
|
|
"comparison failed"
|
|
(operator : string)
|
|
(arg1 : T.t)
|
|
(arg2 : T.t)
|
|
(actual : Result.t)
|
|
(expect : Result.t)];
|
|
failed.return ()))))
|
|
in
|
|
let module C = Comparable.Make (T) in
|
|
op (module Bool) "equal" ~actual:T.equal ~expect:C.equal;
|
|
op (module T) "min" ~actual:T.min ~expect:C.min;
|
|
op (module T) "max" ~actual:T.max ~expect:C.max;
|
|
op (module Bool) "(=)" ~actual:T.( = ) ~expect:C.( = );
|
|
op (module Bool) "(<)" ~actual:T.( < ) ~expect:C.( < );
|
|
op (module Bool) "(>)" ~actual:T.( > ) ~expect:C.( > );
|
|
op (module Bool) "(<>)" ~actual:T.( <> ) ~expect:C.( <> );
|
|
op (module Bool) "(<=)" ~actual:T.( <= ) ~expect:C.( <= );
|
|
op (module Bool) "(>=)" ~actual:T.( >= ) ~expect:C.( >= );
|
|
op
|
|
(module Bool)
|
|
"Comparable.equal"
|
|
~actual:(fun a b -> Comparable.equal T.compare a b)
|
|
~expect:C.equal;
|
|
op
|
|
(module T)
|
|
"Comparable.min"
|
|
~actual:(fun a b -> Comparable.min T.compare a b)
|
|
~expect:C.min;
|
|
op
|
|
(module T)
|
|
"Comparable.max"
|
|
~actual:(fun a b -> Comparable.max T.compare a b)
|
|
~expect:C.max
|
|
;;
|
|
|
|
let%expect_test "Base" =
|
|
test
|
|
[%here]
|
|
(module struct
|
|
include Base
|
|
|
|
type t = int [@@deriving sexp_of]
|
|
end)
|
|
Int.[ min_value; minus_one; zero; one; max_value ];
|
|
[%expect {| |}]
|
|
;;
|
|
|
|
let%expect_test "Unit" =
|
|
test [%here] (module Unit) Unit.all;
|
|
[%expect {| |}]
|
|
;;
|
|
|
|
let%expect_test "Bool" =
|
|
test [%here] (module Bool) Bool.all;
|
|
[%expect {| |}]
|
|
;;
|
|
|
|
let%expect_test "Char" =
|
|
test [%here] (module Char) Char.all;
|
|
[%expect {| |}]
|
|
;;
|
|
|
|
let%expect_test "Float" =
|
|
test [%here] (module Float) Float.[ min_value; minus_one; zero; one; max_value ];
|
|
[%expect {| |}]
|
|
;;
|
|
|
|
let%expect_test "Int" =
|
|
test [%here] (module Int) Int.[ min_value; minus_one; zero; one; max_value ];
|
|
[%expect {| |}]
|
|
;;
|
|
|
|
let%expect_test "Int32" =
|
|
test [%here] (module Int32) Int32.[ min_value; minus_one; zero; one; max_value ];
|
|
[%expect {| |}]
|
|
;;
|
|
|
|
let%expect_test "Int64" =
|
|
test [%here] (module Int64) Int64.[ min_value; minus_one; zero; one; max_value ];
|
|
[%expect {| |}]
|
|
;;
|
|
|
|
let%expect_test "Nativeint" =
|
|
test [%here] (module Nativeint) Nativeint.[ min_value; minus_one; zero; one; max_value ];
|
|
[%expect {| |}]
|
|
;;
|
|
|
|
let%expect_test "Int63" =
|
|
test [%here] (module Int63) Int63.[ min_value; minus_one; zero; one; max_value ];
|
|
[%expect {| |}]
|
|
;;
|
|
|
|
let%test_module "lexicographic" =
|
|
(module struct
|
|
let%expect_test "single" =
|
|
Ref.set_temporarily sexp_style To_string_hum ~f:(fun () ->
|
|
List.iter
|
|
[ 1, 2; 1, 1; 2, 1 ]
|
|
~f:(fun (a, b) ->
|
|
let ordering = Ordering.of_int (compare a b) in
|
|
print_s [%message (a : int) (b : int) (ordering : Ordering.t)];
|
|
require_equal
|
|
[%here]
|
|
(module Ordering)
|
|
(Ordering.of_int (compare a b))
|
|
(Ordering.of_int (Comparable.lexicographic [ compare ] a b)));
|
|
[%expect
|
|
{|
|
|
((a 1) (b 2) (ordering Less))
|
|
((a 1) (b 1) (ordering Equal))
|
|
((a 2) (b 1) (ordering Greater))
|
|
|}])
|
|
;;
|
|
|
|
let%expect_test "three comparisons" =
|
|
Ref.set_temporarily sexp_style To_string_hum ~f:(fun () ->
|
|
let compare_first_three_elts a_1 b_1 =
|
|
Comparable.lexicographic
|
|
(List.init 3 ~f:(fun i a b -> compare a.(i) b.(i)))
|
|
a_1
|
|
b_1
|
|
in
|
|
let test a b =
|
|
let a = Array.of_list a in
|
|
let b = Array.of_list b in
|
|
let ordering = Ordering.of_int (compare_first_three_elts a b) in
|
|
print_s [%message (a : int array) (b : int array) (ordering : Ordering.t)]
|
|
in
|
|
test [ 1; 2; 3; 4 ] [ 1; 2; 4; 9 ];
|
|
[%expect {| ((a (1 2 3 4)) (b (1 2 4 9)) (ordering Less)) |}];
|
|
test [ 1; 2; 3; 4 ] [ 1; 2; 3; 9 ];
|
|
[%expect {| ((a (1 2 3 4)) (b (1 2 3 9)) (ordering Equal)) |}];
|
|
test [ 1; 2; 3; 4 ] [ 1; 1; 4; 9 ];
|
|
[%expect {| ((a (1 2 3 4)) (b (1 1 4 9)) (ordering Greater)) |}])
|
|
;;
|
|
end)
|
|
;;
|
|
|
|
let%expect_test "reversed" =
|
|
let list = [ 3; 1; 4; 1; 5; 9; 2; 6; 5; 3; 5; 9 ] in
|
|
let sort_asc1 = List.sort ~compare:[%compare: int] list in
|
|
let sort_desc = List.sort ~compare:[%compare: int Comparable.reversed] list in
|
|
let sort_asc2 =
|
|
List.sort ~compare:[%compare: int Comparable.reversed Comparable.reversed] list
|
|
in
|
|
print_s [%message (sort_asc1 : int list) (sort_desc : int list) (sort_asc2 : int list)];
|
|
[%expect
|
|
{|
|
|
((sort_asc1 (1 1 2 3 3 4 5 5 5 6 9 9))
|
|
(sort_desc (9 9 6 5 5 5 4 3 3 2 1 1))
|
|
(sort_asc2 (1 1 2 3 3 4 5 5 5 6 9 9)))
|
|
|}]
|
|
;;
|