objective categorical abstract machine language personal data server
65
fork

Configure Feed

Select the types of activity you want to include in your feed.

TID tests

futurGH fa456b0c 30843f2b

+134 -33
+1 -1
dune-project
··· 21 21 (name mist) 22 22 (synopsis "Atproto repo functionality") 23 23 (allow_empty) 24 - (depends ocaml dune (cborl (>= 0.1.0)) (cid (>= 0.1.0)) (hacl-star (>= 0.7.2)) lwt (mtime (>= 2.1.0)) (multihash (>= 0.1.0)) (yojson (>= 3.0.0)) (alcotest :with-test))) 24 + (depends ocaml dune (cborl (>= 0.1.0)) (cid (>= 0.1.0)) (hacl-star (>= 0.7.2)) lwt (mtime (>= 2.1.0)) (multihash (>= 0.1.0)) (re (>= 1.13.2)) (yojson (>= 3.0.0)) (alcotest :with-test))) 25 25 26 26 (package 27 27 (name ipld)
+1
mist.opam
··· 15 15 "lwt" 16 16 "mtime" {>= "2.1.0"} 17 17 "multihash" {>= "0.1.0"} 18 + "re" {>= "1.13.2"} 18 19 "yojson" {>= "3.0.0"} 19 20 "alcotest" {with-test} 20 21 "odoc" {with-doc}
+1
mist/lib/dune
··· 7 7 lwt 8 8 mtime.clock 9 9 multihash 10 + re 10 11 str 11 12 yojson 12 13 ppx_deriving_yojson.runtime)
+54 -19
mist/lib/tid.ml
··· 2 2 3 3 let charset = "234567abcdefghijklmnopqrstuvwxyz" 4 4 5 - let encode (n : int64) : t = 6 - let rec encode ~tid n = 5 + let tid_regexp = 6 + Re.Pcre.regexp "[234567abcdefghij][234567abcdefghijklmnopqrstuvwxyz]{12}" 7 + 8 + let is_valid (s : string) : bool = 9 + match String.length s with 10 + | 13 when Re.execp tid_regexp s -> 11 + true 12 + | _ -> 13 + false 14 + 15 + let ensure_valid (tid : t) : unit = 16 + if String.length tid <> 13 then 17 + raise 18 + (Invalid_argument 19 + (Format.sprintf "invalid tid length %d: %s" (String.length tid) tid) ) 20 + else if not (Re.execp tid_regexp tid) then 21 + raise (Invalid_argument (Format.sprintf "invalid tid format: %s" tid)) 22 + 23 + let _encode (n : int64) : t = 24 + let rec _encode ~tid n = 7 25 match n with 8 26 | 0L -> 9 27 tid 10 28 | n -> 11 - encode 29 + _encode 12 30 ~tid:(String.make 1 charset.[Int64.to_int (Int64.rem n 32L)] ^ tid) 13 31 (Int64.unsigned_div n 32L) 14 32 in 15 - encode ~tid:"" n 33 + _encode ~tid:"" n 16 34 17 - let decode (s : t) : int64 = 18 - let rec decode ~(n : int64) (s : string) = 35 + let _decode (s : t) : int64 = 36 + let rec _decode ~(n : int64) (s : string) = 19 37 match s with 20 38 | s when String.length s > 0 -> 21 39 let c = s.[0] in 22 40 let cs = String.sub s 1 (String.length s - 1) in 23 - decode 41 + _decode 24 42 ~n: 25 43 (Int64.add (Int64.mul n 32L) 26 44 (Int64.of_int (String.index charset c)) ) ··· 28 46 | _ -> 29 47 n 30 48 in 31 - decode ~n:0L s 49 + _decode ~n:0L s 50 + 51 + let of_timestamp_us (timestamp : int64) ~(clockid : int) : t = 52 + if timestamp < 0L || timestamp >= Int64.shift_left 1L 53 then 53 + raise (Invalid_argument "timestamp must be within range [0, 2^53)") ; 54 + if clockid < 0 || clockid > 1023 then 55 + raise (Invalid_argument "clockid must be within range [0, 1023]") ; 56 + let rec pad str len = 57 + if String.length str >= len then str else pad ("2" ^ str) len 58 + in 59 + pad (_encode timestamp) 11 ^ pad (_encode @@ Int64.of_int clockid) 2 60 + 61 + let of_timestamp_ms (timestamp : int64) ~(clockid : int) : t = 62 + of_timestamp_us (Int64.mul timestamp 1000L) ~clockid 63 + 64 + let to_timestamp_us (tid : t) : int64 * int = 65 + ensure_valid tid ; 66 + let timestamp = _decode (String.sub tid 0 11) in 67 + let clockid = Int64.to_int @@ _decode (String.sub tid 11 2) in 68 + (timestamp, clockid) 69 + 70 + let to_timestamp_ms (tid : t) : int64 * int = 71 + ensure_valid tid ; 72 + let timestamp = _decode (String.sub tid 0 11) in 73 + let clockid = Int64.to_int @@ _decode (String.sub tid 11 2) in 74 + (Int64.div timestamp 1000L, clockid) 32 75 33 76 let now () : t = 34 - Mtime_clock.now_ns () |> Int64.unsigned_div 1_000_000L |> encode 77 + Mtime_clock.now_ns () |> Int64.unsigned_div 1_000L 78 + |> of_timestamp_us ~clockid:(Random.int_in_range ~min:0 ~max:1023) 35 79 36 - let of_string (s : string) : t = 37 - match String.length s with 38 - | 13 39 - when Str.string_match 40 - (Str.regexp 41 - "/^[234567abcdefghij][234567abcdefghijklmnopqrstuvwxyz]{12}$/" ) 42 - s 0 -> 43 - s 44 - | _ -> 45 - raise (Invalid_argument (Format.sprintf "invalid tid: %s" s)) 80 + let of_string (s : string) : t = ensure_valid s ; s 46 81 47 82 let to_string (s : t) : string = s 48 83
+13 -9
mist/lib/util.ml
··· 8 8 let zeros' = 9 9 zeros 10 10 + 11 - if byte = 0x0 then 4 12 - else if byte < 0x04 then 3 13 - else if byte < 0x10 then 2 14 - else if byte < 0x40 then 1 11 + if byte = 0 then 4 12 + else if byte < 4 then 3 13 + else if byte < 16 then 2 14 + else if byte < 64 then 1 15 15 else 0 16 16 in 17 - if byte = 0x0 then loop (idx + 1) zeros' else zeros' 17 + if byte = 0 then loop (idx + 1) zeros' else zeros' 18 18 in 19 19 loop 0 0 20 20 ··· 26 26 in 27 27 loop 0 28 28 29 - let valid_key_char_regex = Str.regexp "^[a-zA-Z0-9_~\\-:.]*$" 29 + let shared_prefix (a : string) (b : string) : string = 30 + let len = shared_prefix_length a b in 31 + String.sub a 0 len 32 + 33 + let valid_key_char_regex = Re.Pcre.regexp "^[a-zA-Z0-9_~\\-:.]*$" 30 34 31 35 let is_valid_mst_key (key : string) : bool = 32 36 match String.split_on_char '/' key with 33 37 | [coll; rkey] 34 38 when String.length key <= 1024 35 39 && coll <> "" && rkey <> "" 36 - && Str.string_match valid_key_char_regex coll 0 37 - && Str.string_match valid_key_char_regex rkey 0 -> 40 + && Re.execp valid_key_char_regex coll 41 + && Re.execp valid_key_char_regex rkey -> 38 42 true 39 43 | _ -> 40 44 false 41 45 42 46 let ensure_valid_key (key : string) : unit = 43 - if not (is_valid_mst_key key) then raise (Invalid_argument "Invalid MST key") 47 + if not (is_valid_mst_key key) then raise (Invalid_argument "invalid mst key")
+2 -2
mist/test/dune
··· 1 - (test 2 - (name test_mist) 1 + (tests 2 + (names test_tid test_util) 3 3 (package mist) 4 4 (libraries mist alcotest))
+2 -2
mist/test/test_mist.ml mist/test/test_util.ml
··· 27 27 value (shared_prefix_length a b) ) 28 28 29 29 let () = 30 - Alcotest.run "mist" 31 - [ ( "mst utils" 30 + Alcotest.run "util" 31 + [ ( "repo utils" 32 32 , [ ("leading_zeros", `Quick, test_leading_zeros) 33 33 ; ("shared_prefix_length", `Quick, test_shared_prefix_length) ] ) ]
+60
mist/test/test_tid.ml
··· 1 + module Tid = Mist.Tid 2 + 3 + let test_create () = 4 + Alcotest.(check string) 5 + "tid" "3kztsgrxhzsje" 6 + (Tid.of_timestamp_ms 1723819911723L ~clockid:490) 7 + 8 + let test_invalid_create () = 9 + Alcotest.check_raises "non-negative" 10 + (Invalid_argument "timestamp must be within range [0, 2^53)") (fun () -> 11 + ignore (Tid.of_timestamp_us (-1L) ~clockid:490) ) ; 12 + Alcotest.check_raises "too large" 13 + (Invalid_argument "timestamp must be within range [0, 2^53)") (fun () -> 14 + ignore (Tid.of_timestamp_us (Int64.shift_left 1L 53) ~clockid:490) ) 15 + 16 + let test_clockid () = 17 + Alcotest.check_raises "clockid too large" 18 + (Invalid_argument "clockid must be within range [0, 1023]") (fun () -> 19 + ignore (Tid.of_timestamp_ms 1723819911723L ~clockid:1024) ) ; 20 + Alcotest.check_raises "clockid too small" 21 + (Invalid_argument "clockid must be within range [0, 1023]") (fun () -> 22 + ignore (Tid.of_timestamp_ms 1723819911723L ~clockid:(-1)) ) ; 23 + (* shouldn't throw *) 24 + ignore (Tid.of_timestamp_ms 1723819911723L ~clockid:0) ; 25 + (* shouldn't throw *) 26 + ignore (Tid.of_timestamp_ms 1723819911723L ~clockid:1023) 27 + 28 + let test_parse () = 29 + let timestamp, clockid = Tid.to_timestamp_ms "3kztrqxakokct" in 30 + Alcotest.(check int64) "timestamp" timestamp 1723819179066L ; 31 + Alcotest.(check int) "clockid" clockid 281 32 + 33 + let test_validate () = 34 + let valid_tids = ["3jzfcijpj2z2a"; "7777777777777"; "3zzzzzzzzzzzz"] in 35 + let invalid_tids = 36 + [ "3jzfcijpj2z21" 37 + ; "0000000000000" 38 + ; "3jzfcijpj2z2aa" 39 + ; "3jzfcijpj2z2" 40 + ; "3jzf-cij-pj2z-2a" 41 + ; "zzzzzzzzzzzzz" 42 + ; "kjzfcijpj2z2a" 43 + ; "kjzfcijpj2z2a" ] 44 + in 45 + List.iter 46 + (fun tid -> Alcotest.(check bool) ("valid " ^ tid) true (Tid.is_valid tid)) 47 + valid_tids ; 48 + List.iter 49 + (fun tid -> 50 + Alcotest.(check bool) ("invalid " ^ tid) false (Tid.is_valid tid) ) 51 + invalid_tids 52 + 53 + let () = 54 + Alcotest.run "tid" 55 + [ ( "create" 56 + , [ ("create", `Quick, test_create) 57 + ; ("invalid timestamp", `Quick, test_invalid_create) 58 + ; ("invalid clockid", `Quick, test_clockid) ] ) 59 + ; ("parse", [("parse", `Quick, test_parse)]) 60 + ; ("validate", [("validate", `Quick, test_validate)]) ]