File: test_compare.ml

package info (click to toggle)
janest-base 0.17.3-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 3,632 kB
  • sloc: ml: 48,653; ansic: 281; javascript: 126; makefile: 14
file content (176 lines) | stat: -rw-r--r-- 5,441 bytes parent folder | download | duplicates (2)
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)))
    |}]
;;