File: hash_queue_test.ml

package info (click to toggle)
janest-core 107.01-5
  • links: PTS, VCS
  • area: main
  • in suites: wheezy
  • size: 2,440 kB
  • sloc: ml: 26,624; ansic: 2,498; sh: 49; makefile: 29
file content (142 lines) | stat: -rw-r--r-- 5,961 bytes parent folder | download
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
(******************************************************************************
 *                             Core                                           *
 *                                                                            *
 * Copyright (C) 2008- Jane Street Holding, LLC                               *
 *    Contact: opensource@janestreet.com                                      *
 *    WWW: http://www.janestreet.com/ocaml                                    *
 *                                                                            *
 *                                                                            *
 * This library is free software; you can redistribute it and/or              *
 * modify it under the terms of the GNU Lesser General Public                 *
 * License as published by the Free Software Foundation; either               *
 * version 2 of the License, or (at your option) any later version.           *
 *                                                                            *
 * This library is distributed in the hope that it will be useful,            *
 * but WITHOUT ANY WARRANTY; without even the implied warranty of             *
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU          *
 * Lesser General Public License for more details.                            *
 *                                                                            *
 * You should have received a copy of the GNU Lesser General Public           *
 * License along with this library; if not, write to the Free Software        *
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA  *
 *                                                                            *
 ******************************************************************************)

open OUnit;;
open Core.Std

let test =
  "hash_queue" >:::
    [
      "basic" >:: (fun () ->
        let module Hq_arg = struct
          include String
          let hash (x : t) = Hashtbl.hash x
          let equal (x : t) (y : t) = x = y
          let sexp_of_t = Sexplib.Conv.sexp_of_string
          let t_of_sexp = Sexplib.Conv.string_of_sexp
        end in
        let module Hq = Hash_queue.Make (Hq_arg) in
        let hq = Hq.create () in
        let inv () = Hq.invariant hq in

        (* tests over empty queue *)
        inv ();
        assert (Hq.is_empty hq);
        assert (Hq.dequeue hq = None);
        assert (try ignore (Hq.dequeue_exn hq); false with _ -> true);
        assert (Hq.dequeue_with_key hq = None);
        assert (try ignore (Hq.dequeue_with_key_exn hq); false with _ -> true);
        Hq.dequeue_all hq ~f:(fun _ -> assert false);
        assert (Hq.remove hq "foobar" = `No_such_key);
        assert (try ignore (Hq.remove_exn hq "foobar"); false with | _ -> true);
        assert (Hq.replace hq "foobar" 0 = `No_such_key);
        assert (try ignore (Hq.replace_exn hq "foobar" 0); false with
          | _ -> true);
        assert
          ([] = Hq.foldi hq ~init:[] ~f:(fun ac ~key:_ ~data:_ -> () :: ac));
        assert ([] = Hq.fold hq ~init:[] ~f:(fun ac _ -> () :: ac));
        Hq.iteri hq ~f:(fun ~key:_ ~data:_ -> assert false);

        (* test with 10 elems *)
        let n = 10 in
        for i = 1 to n do
          assert (Hq.enqueue hq (string_of_int i) i = `Ok);
          inv ();
        done;
        assert (Hq.length hq = n);
        assert
          (List.rev
              (Hq.foldi hq ~init:[] ~f:(fun ac ~key ~data -> (key, data) :: ac))
              = List.init n ~f:(fun i -> let i = i + 1 in (string_of_int i, i)));
        assert
          (List.rev (Hq.fold hq ~init:[] ~f:(fun ac data -> data :: ac))
              = List.init n ~f:(fun i -> i + 1));
        Hq.iteri hq ~f:(fun ~key ~data -> assert (key = string_of_int data));

        (* test removing the first element from the queue *)
        let sum = ref 0 in
        Hq.iter hq ~f:(fun x -> sum := !sum + x);
        assert (!sum = (n * (n + 1) / 2));
        assert (Hq.mem hq "1");
        ignore (Hq.dequeue hq);
        inv ();
        assert (not (Hq.mem hq "1"));
        assert (Hq.length hq = n - 1);

        (* remove the last *)
        assert (Hq.remove hq (string_of_int n) = `Ok);
        (* double remove *)
        assert (Hq.remove hq (string_of_int n) = `No_such_key);
        inv ();
        assert (Hq.length hq = n - 2);

        (* remove everything *)
        let num = ref 0 in
        Hq.dequeue_all hq ~f:(fun _ -> num := !num + 1);
        inv ();
        assert (!num = n - 2);
        assert (Hq.is_empty hq);
        inv ();
        Hq.clear hq;
        assert (Hq.is_empty hq);

        (* add 100 *)
        for i = 1 to 100 do
          assert (Hq.enqueue hq (string_of_int i) i = `Ok);
        done;
        (* double booking *)
        assert (Hq.enqueue hq "42" 42 = `Key_already_present);
        assert (try
            Hq.enqueue_exn hq "42" 42; false
          with
          | _ -> true);
        assert (Hq.replace hq "1" 42 = `Ok);
        assert (Hq.lookup hq "1" = Some 42);
        assert (Hq.lookup_exn hq "1" = 42);
        assert (Hq.dequeue_with_key hq = Some ("1", 42));
        assert (Hq.replace hq "1" 42 = `No_such_key);
        assert (try
            Hq.replace_exn hq "1" 42; false
          with
          | _ -> true);
        assert (Hq.lookup hq "1" = None);
        assert (try ignore (Hq.lookup_exn hq "1"); false with
          | Not_found -> true | _ -> false);

        Hq.clear hq;
        assert (Hq.is_empty hq);

        let add i = Hq.enqueue_exn hq (Int.to_string i) i in
        List.iter [1; 2; 3] ~f:add;
        assert (["1"; "2"; "3" ] = Hq.keys hq);
        begin
          try Hq.iter hq ~f:(fun _ -> add 13); assert false
          with _ -> ();
        end;
        begin
          try Hq.iter hq ~f:(fun _ -> ignore (Hq.remove hq "foo")); assert false
          with _ -> ();
        end;
      )
    ]