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
|
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)))
|}]
;;
|