150 lines
4.3 KiB
OCaml
150 lines
4.3 KiB
OCaml
open! Base
|
|
open Expect_test_helpers_base
|
|
|
|
type int_hashtbl = int Hashtbl.M(Int).t [@@deriving sexp]
|
|
|
|
let%test "Hashtbl.merge succeeds with first-class-module interface" =
|
|
let t1 = Hashtbl.create (module Int) in
|
|
let t2 = Hashtbl.create (module Int) in
|
|
let result =
|
|
Hashtbl.merge t1 t2 ~f:(fun ~key:_ -> function
|
|
| `Left x -> x
|
|
| `Right x -> x
|
|
| `Both _ -> assert false)
|
|
|> Hashtbl.to_alist
|
|
in
|
|
List.equal Poly.equal result []
|
|
;;
|
|
|
|
let%test_module _ =
|
|
(module Hashtbl_tests.Make (struct
|
|
include Hashtbl
|
|
|
|
let create_poly ?size () = Poly.create ?size ()
|
|
let of_alist_poly_exn l = Poly.of_alist_exn l
|
|
let of_alist_poly_or_error l = Poly.of_alist_or_error l
|
|
end))
|
|
;;
|
|
|
|
let%expect_test "Hashtbl.find_exn" =
|
|
let table = Hashtbl.of_alist_exn (module String) [ "one", 1; "two", 2; "three", 3 ] in
|
|
let test_success key =
|
|
require_does_not_raise [%here] (fun () ->
|
|
print_s [%sexp (Hashtbl.find_exn table key : int)])
|
|
in
|
|
test_success "one";
|
|
[%expect {| 1 |}];
|
|
test_success "two";
|
|
[%expect {| 2 |}];
|
|
test_success "three";
|
|
[%expect {| 3 |}];
|
|
let test_failure key =
|
|
require_does_raise [%here] (fun () -> Hashtbl.find_exn table key)
|
|
in
|
|
test_failure "zero";
|
|
[%expect {| (Not_found_s ("Hashtbl.find_exn: not found" zero)) |}];
|
|
test_failure "four";
|
|
[%expect {| (Not_found_s ("Hashtbl.find_exn: not found" four)) |}]
|
|
;;
|
|
|
|
let%expect_test "[t_of_sexp] error on duplicate" =
|
|
let sexp = Sexplib.Sexp.of_string "((0 a)(1 b)(2 c)(1 d))" in
|
|
(match [%of_sexp: string Hashtbl.M(String).t] sexp with
|
|
| t -> print_cr [%here] [%message "did not raise" (t : string Hashtbl.M(String).t)]
|
|
| exception (Sexp.Of_sexp_error _ as exn) -> print_s (sexp_of_exn exn)
|
|
| exception exn -> print_cr [%here] [%message "wrong kind of exception" (exn : exn)]);
|
|
[%expect {| (Of_sexp_error "Hashtbl.t_of_sexp: duplicate key" (invalid_sexp 1)) |}]
|
|
;;
|
|
|
|
let%expect_test "[choose], [choose_exn], [choose_randomly], [choose_randomly_exn]" =
|
|
let test ?size l =
|
|
let t = l |> List.map ~f:(fun i -> i, i) |> Hashtbl.of_alist_exn ?size (module Int) in
|
|
print_s
|
|
[%message
|
|
""
|
|
~input:(t : int_hashtbl)
|
|
~choose:(Hashtbl.choose t : (_ * _) option)
|
|
~choose_exn:
|
|
(Or_error.try_with (fun () -> Hashtbl.choose_exn t) : (_ * _) Or_error.t)
|
|
~choose_randomly:(Hashtbl.choose_randomly t : (_ * _) option)
|
|
~choose_randomly_exn:
|
|
(Or_error.try_with (fun () -> Hashtbl.choose_randomly_exn t)
|
|
: (_ * _) Or_error.t)]
|
|
in
|
|
test [];
|
|
[%expect
|
|
{|
|
|
((input ())
|
|
(choose ())
|
|
(choose_exn (Error ("[Hashtbl.choose_exn] of empty hashtbl")))
|
|
(choose_randomly ())
|
|
(choose_randomly_exn (
|
|
Error ("[Hashtbl.choose_randomly_exn] of empty hashtbl"))))
|
|
|}];
|
|
test [] ~size:100;
|
|
[%expect
|
|
{|
|
|
((input ())
|
|
(choose ())
|
|
(choose_exn (Error ("[Hashtbl.choose_exn] of empty hashtbl")))
|
|
(choose_randomly ())
|
|
(choose_randomly_exn (
|
|
Error ("[Hashtbl.choose_randomly_exn] of empty hashtbl"))))
|
|
|}];
|
|
test [ 1 ];
|
|
[%expect
|
|
{|
|
|
((input ((1 1)))
|
|
(choose ((_ _)))
|
|
(choose_exn (Ok (_ _)))
|
|
(choose_randomly ((_ _)))
|
|
(choose_randomly_exn (Ok (_ _))))
|
|
|}];
|
|
test [ 1 ] ~size:100;
|
|
[%expect
|
|
{|
|
|
((input ((1 1)))
|
|
(choose ((_ _)))
|
|
(choose_exn (Ok (_ _)))
|
|
(choose_randomly ((_ _)))
|
|
(choose_randomly_exn (Ok (_ _))))
|
|
|}];
|
|
test [ 1; 2 ];
|
|
[%expect
|
|
{|
|
|
((input (
|
|
(1 1)
|
|
(2 2)))
|
|
(choose ((_ _)))
|
|
(choose_exn (Ok (_ _)))
|
|
(choose_randomly ((_ _)))
|
|
(choose_randomly_exn (Ok (_ _))))
|
|
|}];
|
|
test [ 1; 2 ] ~size:100;
|
|
[%expect
|
|
{|
|
|
((input (
|
|
(1 1)
|
|
(2 2)))
|
|
(choose ((_ _)))
|
|
(choose_exn (Ok (_ _)))
|
|
(choose_randomly ((_ _)))
|
|
(choose_randomly_exn (Ok (_ _))))
|
|
|}]
|
|
;;
|
|
|
|
let%expect_test "update_and_return" =
|
|
let t = Hashtbl.create (module String) in
|
|
let update_and_return str ~f =
|
|
let x = Hashtbl.update_and_return t str ~f in
|
|
print_s [%message (t : (string, int) Hashtbl.t) (x : int)]
|
|
in
|
|
update_and_return "foo" ~f:(function
|
|
| None -> 1
|
|
| Some _ -> failwith "no");
|
|
[%expect {| ((t ((foo 1))) (x 1)) |}];
|
|
update_and_return "foo" ~f:(function
|
|
| Some 1 -> 2
|
|
| _ -> failwith "no");
|
|
[%expect {| ((t ((foo 2))) (x 2)) |}]
|
|
;;
|