Source file test_result.ml

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
open! Base
open! Import

module%test [@name "Result.Error"] _ = struct
  open Result.Error.Let_syntax

  module Int_or_string = struct
    type t = (int, string) Result.t [@@deriving equal, sexp_of]
  end

  let%expect_test "return" =
    require_equal (module Int_or_string) (return "error") (Error "error");
    [%expect {| |}]
  ;;

  let%expect_test "bind Error" =
    let result =
      let%bind e1 = Error "e1" in
      let%bind e2 = Error "e2" in
      let%bind e3 = Error "e3" in
      return (String.concat ~sep:"," [ e1; e2; e3 ])
    in
    require_equal (module Int_or_string) result (Error "e1,e2,e3");
    [%expect {| |}]
  ;;

  let%expect_test "bind Ok" =
    let result =
      let%bind e1 = Error "e1" in
      let%bind e2 = Ok 1 in
      let%bind e3 = Error "e3" in
      return (String.concat ~sep:"," [ e1; e2; e3 ])
    in
    require_equal (module Int_or_string) result (Ok 1);
    [%expect {| |}]
  ;;

  let%expect_test "map Error" =
    let result =
      let%map e1 = Error "e1" in
      e1 ^ "!"
    in
    require_equal (module Int_or_string) result (Error "e1!");
    [%expect {| |}]
  ;;

  let%expect_test "map Ok" =
    let result =
      let%map e1 = Ok 1 in
      e1 ^ "!"
    in
    require_equal (module Int_or_string) result (Ok 1);
    [%expect {| |}]
  ;;

  (* The rest of the Monad functions are derived using the Monad.Make functor, which is
     well-tested. *)
end

module%test [@name "can contain nulls"] _ = struct
  (* no annotation *)
  let _ = Ok Null
  let _ = Error Null

  (* toplevel alias in [base.ml] *)
  let _ : _ result = Ok Null
  let _ : _ result = Error Null
  let _ : _ Result.t = Ok Null
  let _ : _ Result.t = Error Null

  (* This isn't directly exposed anywhere by Base, but it gets re-exported by Core. *)
  let _ : _ Result.Export._result = Ok Null
  let _ : _ Result.Export._result = Error Null

  (* check that [open]ing [Result] doesn't ruin the visible constructors *)
  open! Result

  let _ = Ok Null
  let _ = Error Null
  let _ : _ t = Ok Null
  let _ : _ t = Error Null
end

module%test [@name "Option.transpose_result and Result.transpose_opt are inverses"] _ =
struct
  module Result_option = struct
    type t = (string option, string) Result.t [@@deriving equal, sexp_of]
  end

  module Option_result = struct
    type t = (string, string) Result.t option [@@deriving equal, sexp_of]
  end

  let%expect_test "inverses" =
    let test_inverse ~(here : [%call_pos]) test_m f g examples =
      List.iter examples ~f:(fun original ->
        let double_transposed = f (g original) in
        require_equal ~here test_m original double_transposed)
    in
    test_inverse
      (module Result_option)
      Option.transpose_result
      Result.transpose_opt
      [ Ok (Some "ok"); Ok None; Error "error" ];
    [%expect {| |}];
    test_inverse
      (module Option_result)
      Result.transpose_opt
      Option.transpose_result
      [ Some (Ok "ok"); None; Some (Error "error") ];
    [%expect {| |}]
  ;;
end