@@ -25,6 +25,51 @@ let uuid_arrays =
25
25
let non_uuid_arrays =
26
26
[[|0 |]; [|0 ; 1 ; 2 ; 3 ; 4 ; 5 ; 6 ; 7 ; 8 ; 9 ; 10 ; 11 ; 12 ; 13 ; 14 |]]
27
27
28
+ let uuid_v4_cases =
29
+ [
30
+ ((0L , 0L ), " 00000000-0000-4000-8000-000000000000" )
31
+ ; ((- 1L , - 1L ), " ffffffff-ffff-4fff-bfff-ffffffffffff" )
32
+ ; ((0x89ab_cdefL , 0x0123_4567L ), " 00000000-89ab-4def-8000-000001234567" )
33
+ ]
34
+
35
+ let uuid_v7_times =
36
+ let of_ms ms = Ptime.Span. of_float_s (ms /. 1000.0 ) |> Option. get in
37
+ let power_of_2_ms n =
38
+ Float. pow 2.0 (Float. of_int n) |> of_ms |> Ptime.Span. truncate ~frac_s: 3
39
+ in
40
+ let zero = of_ms 0.0 in
41
+ let ms = of_ms 1.0 in
42
+ let ps = Ptime.Span. of_d_ps (0 , 1L ) |> Option. get in
43
+ (* Using RFC9562 "method 3" for representiong sub-millisecond fractions,
44
+ that smallest amount of time a v7 UUID can represent is 1 / 4096 ms,
45
+ which is (just less than) 244141 picoseconds *)
46
+ let tick = Ptime.Span. of_d_ps (0 , 244141L ) |> Option. get in
47
+ let ( - ) = Ptime.Span. sub in
48
+ let to_d_ps = Ptime.Span. to_d_ps in
49
+ [
50
+ (zero |> to_d_ps, " 00000000-0000-7000-8000-000000000000" )
51
+ ; (tick |> to_d_ps, " 00000000-0000-7001-8000-000000000000" )
52
+ ; (ms |> to_d_ps, " 00000000-0001-7000-8000-000000000000" )
53
+ ; (ms - ps |> to_d_ps, " 00000000-0000-7fff-8000-000000000000" )
54
+ (* Test a wide range of dates - but we can't get much bigger than
55
+ epoch + 2^47 milliseconds, and that puts us in the year 6429 and Ptime
56
+ only allows dates up to the year 9999 *)
57
+ ; (power_of_2_ms 05 |> to_d_ps, " 00000000-0020-7000-8000-000000000000" )
58
+ ; (power_of_2_ms 15 |> to_d_ps, " 00000000-8000-7000-8000-000000000000" )
59
+ ; (power_of_2_ms 25 |> to_d_ps, " 00000200-0000-7000-8000-000000000000" )
60
+ ; (power_of_2_ms 35 |> to_d_ps, " 00080000-0000-7000-8000-000000000000" )
61
+ ; (power_of_2_ms 45 |> to_d_ps, " 20000000-0000-7000-8000-000000000000" )
62
+ ; (power_of_2_ms 47 |> to_d_ps, " 80000000-0000-7000-8000-000000000000" )
63
+ ; (power_of_2_ms 47 - ps |> to_d_ps, " 7fffffff-ffff-7fff-8000-000000000000" )
64
+ ]
65
+
66
+ let uuid_v7_bytes =
67
+ [
68
+ (1L , " 00000000-0000-7000-8000-000000000001" )
69
+ ; (- 1L , " 00000000-0000-7000-bfff-ffffffffffff" )
70
+ ; (0x1234_5678_9abc_def0L , " 00000000-0000-7000-9234-56789abcdef0" )
71
+ ]
72
+
28
73
type resource
29
74
30
75
let uuid_testable : (module Alcotest.TESTABLE with type t = resource Uuidx. t) =
@@ -51,6 +96,51 @@ let roundtrip_tests testing_uuid =
51
96
; (" Roundtrip array conversion" , `Quick , test_array)
52
97
]
53
98
99
+ let uuid_v4_tests ((upper , lower ), expected_as_string ) =
100
+ let expected =
101
+ match Uuidx. of_string expected_as_string with
102
+ | Some uuid ->
103
+ uuid
104
+ | None ->
105
+ Alcotest. fail
106
+ (Printf. sprintf " Couldn't convert to UUID: %s" expected_as_string)
107
+ in
108
+ let test () =
109
+ let result = Uuidx. make_v4_uuid upper lower in
110
+ Alcotest. (check @@ uuid_testable) " make UUIDv4" expected result
111
+ in
112
+ (expected_as_string, [(" Make UUIDv4 from bytes" , `Quick , test)])
113
+
114
+ let uuid_v7_time_tests (t , expected_as_string ) =
115
+ let expected =
116
+ match Uuidx. of_string expected_as_string with
117
+ | Some uuid ->
118
+ uuid
119
+ | None ->
120
+ Alcotest. fail
121
+ (Printf. sprintf " Couldn't convert to UUID: %s" expected_as_string)
122
+ in
123
+ let test () =
124
+ let result = Uuidx. make_v7_uuid_from_time_and_bytes t 0L in
125
+ Alcotest. (check @@ uuid_testable) " make UUIDv7" expected result
126
+ in
127
+ (expected_as_string, [(" Make UUIDv7 from time" , `Quick , test)])
128
+
129
+ let uuid_v7_bytes_tests (bs , expected_as_string ) =
130
+ let expected =
131
+ match Uuidx. of_string expected_as_string with
132
+ | Some uuid ->
133
+ uuid
134
+ | None ->
135
+ Alcotest. fail
136
+ (Printf. sprintf " Couldn't convert to UUID: %s" expected_as_string)
137
+ in
138
+ let test () =
139
+ let result = Uuidx. make_v7_uuid_from_time_and_bytes (0 , 0L ) bs in
140
+ Alcotest. (check @@ uuid_testable) " make UUIDv7" expected result
141
+ in
142
+ (expected_as_string, [(" Make UUIDv7 from bytes" , `Quick , test)])
143
+
54
144
let string_roundtrip_tests testing_string =
55
145
let testing_uuid =
56
146
match Uuidx. of_string testing_string with
@@ -111,6 +201,9 @@ let regression_tests =
111
201
; List. map array_roundtrip_tests uuid_arrays
112
202
; List. map invalid_string_tests non_uuid_strings
113
203
; List. map invalid_array_tests non_uuid_arrays
204
+ ; List. map uuid_v4_tests uuid_v4_cases
205
+ ; List. map uuid_v7_time_tests uuid_v7_times
206
+ ; List. map uuid_v7_bytes_tests uuid_v7_bytes
114
207
]
115
208
116
209
let () = Alcotest. run " Uuid" regression_tests
0 commit comments