-
Notifications
You must be signed in to change notification settings - Fork 15
/
test_pgx_value.ml
203 lines (198 loc) · 5.89 KB
/
test_pgx_value.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
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
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
open Printf
open Sexplib0
open Sexplib0.Sexp_conv
open Pgx.Value
let pp_value ppf x = Sexp.pp_hum ppf (sexp_of_t x)
let equal_value (x : t) (y : t) = x = y
let pp_hstore ppf x = Sexp.pp_hum ppf (sexp_of_hstore x)
let equal_hstore x y = Sexp.equal (sexp_of_hstore x) (sexp_of_hstore y)
let printer sexp value = sexp value |> Sexp.to_string_hum
let sort_hstore = List.sort (fun (k, _) (k', _) -> String.compare k k')
let to_hstore_sorted v = to_hstore v |> Option.map sort_hstore
let to_hstore_sorted_exn v = to_hstore_exn v |> sort_hstore
let pp_inet ppf (addr, port) = Format.fprintf ppf "%a:%d" Ipaddr.pp addr port
let equal_inet (a1, p1) (a2, p2) = Ipaddr.compare a1 a2 = 0 && p1 = p2
let epsilon = 0.00001
let equal_float x y =
match classify_float x, classify_float y with
| FP_infinite, FP_infinite -> x = y
| FP_nan, FP_nan -> true
| _, _ -> abs_float (x -. y) <= epsilon *. (abs_float x +. abs_float y)
;;
module Alcotest_ext = struct
let hstore = Alcotest.testable pp_hstore equal_hstore
let inet = Alcotest.testable pp_inet equal_inet
let value = Alcotest.testable pp_value equal_value
let uuid = Alcotest.testable Uuidm.pp Uuidm.equal
let our_float = Alcotest.testable Format.pp_print_float equal_float
end
let make_test name typ to_value of_value of_value_exn values fail_values =
let fail_tests =
Alcotest.test_case "null required input" `Quick (fun () ->
Alcotest.check_raises
"non-null conversion"
(Conversion_failure "Expected not-null but got null")
(fun () -> ignore (of_value_exn None)))
::
List.map
(fun str ->
let test_name = sprintf "bad conversion - %s" str in
let value = of_string str in
Alcotest.test_case test_name `Quick
@@ fun () ->
try
of_value value |> ignore;
Alcotest.fail "Expected Conversion_failure"
with
| Conversion_failure _ -> ())
fail_values
in
let success_opt_tests =
None :: List.map (fun v -> Some v) values
|> List.map (fun expect ->
let test_name =
Format.asprintf "good conversion - %a" Alcotest.(pp (option typ)) expect
in
Alcotest.test_case test_name `Quick
@@ fun () ->
let value = expect |> opt to_value |> of_value in
Alcotest.(check (option typ)) test_name expect value)
in
let success_tests =
List.map
(fun expect ->
let test_name = Format.asprintf "good conversion - %a" (Alcotest.pp typ) expect in
Alcotest.test_case test_name `Quick
@@ fun () ->
let value = expect |> to_value |> of_value_exn in
Alcotest.(check typ) test_name expect value)
values
in
name, success_tests @ success_opt_tests @ fail_tests
;;
let () =
let all_chars = String.init 255 char_of_int in
Alcotest.run
"Pgx.Value"
[ make_test
"binary"
Alcotest.string
of_binary
to_binary
to_binary_exn
[ ""; "normal string"; "string with null\x00 in the midddle"; all_chars ]
[]
; make_test
"bool"
Alcotest.bool
of_bool
to_bool
to_bool_exn
[ true; false ]
[ ""; "asd" ]
; make_test
"float"
Alcotest_ext.our_float
of_float
to_float
to_float_exn
[ 0.; 3.14; -5.; neg_infinity; infinity; nan; max_float; min_float ]
[ ""; "asd" ]
; make_test
"hstore"
Alcotest_ext.hstore
of_hstore
to_hstore_sorted
to_hstore_sorted_exn
[ []
; [ "a", Some "b" ]
; [ "key", None ]
; [ "1", Some "2"; "3;'", Some "'!"; "asdf=>", None ]
]
[ "asd"; "=>"; "a=>"; "=>v" ]
; make_test
"inet"
Alcotest_ext.inet
of_inet
to_inet
to_inet_exn
([ "127.0.0.1", 32; "192.168.5.9", 0; "fe80::0202:b3ff:fe1e:8329", 128 ]
|> List.map (fun (addr, mask) -> Ipaddr.of_string_exn addr, mask))
[ ""; "asd"; "192.168.1.a/32" ]
; make_test
"int"
Alcotest.int
of_int
to_int
to_int_exn
[ 0; 1; -1; max_int; min_int ]
[ ""; "asd"; "t"; "f" ]
; make_test
"int32"
Alcotest.int32
of_int32
to_int32
to_int32_exn
Int32.[ zero; of_int 1; of_int (-1); max_int; min_int ]
[ ""; "asd"; "t"; "f" ]
; make_test
"int64"
Alcotest.int64
of_int64
to_int64
to_int64_exn
Int64.[ zero; of_int 1; of_int (-1); max_int; min_int ]
[ ""; "asd"; "t"; "f" ]
; make_test
"list"
Alcotest.(list Alcotest_ext.value)
of_list
to_list
to_list_exn
[ []
; [ of_bool true
; of_bool false
; of_float 10.5
; of_hstore []
; of_hstore [ "key", Some "value" ]
; of_hstore [ "key2", None ]
; of_inet (Ipaddr.of_string_exn "8.8.8.8", 4)
; of_int 99
; of_int32 (Int32.of_int 101)
; of_int64 (Int64.of_int 1102931)
; of_list []
; null
; of_point (-5., 100.)
; unit
; of_uuid (Uuidm.create `V4)
; of_string all_chars
]
]
[ ""; "asd" ]
; make_test
"point"
Alcotest.(Alcotest_ext.(pair our_float our_float))
of_point
to_point
to_point_exn
[ 0., 0.; infinity, neg_infinity; nan, nan; max_float, 5.; -5., max_float ]
[ ""; "asd"; "5." ]
; make_test
"string"
Alcotest.string
of_string
to_string
to_string_exn
[ ""; "this is a test string"; all_chars ]
[]
; make_test "unit" Alcotest.unit (fun () -> unit) to_unit to_unit_exn [ () ] [ "asd" ]
; make_test
"uuid"
Alcotest_ext.uuid
of_uuid
to_uuid
to_uuid_exn
[ Uuidm.create `V4 ]
[ ""; "asd" ]
]
;;