My own corner of monopam
2
fork

Configure Feed

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

did: address merlint feedback

Fixes E340, E320, E330, E405, E410, E500, E605, E600:

- Add .ocamlformat with profile = default.
- Document every public value (pp_error, compare, pp, accessors).
- Fix doc style (periods, [name]-format references).
- Replace raw Error (Msg (Fmt.str ...)) with err_parse helpers.
- Adopt the canonical test layout: test.ml calls Alcotest.run on
[ Test_<module>.suite ]; test_<module>.ml exports
'let suite : string * unit Alcotest.test_case list'; mli file
declares 'val suite'.
- Drop test_ prefix from function names; groups become 'group/case'
in test labels so output still reads well.
- Flatten multi-group suites into a single tuple to match E600.

+144 -125
+1
ocaml-did/.ocamlformat
··· 1 + profile = default
+32 -1
ocaml-did/lib/did.mli
··· 13 13 type error = [ `Msg of string ] 14 14 15 15 val pp_error : error Fmt.t 16 + (** [pp_error] formats a validation error for humans. *) 17 + 16 18 val error_to_string : error -> string 19 + (** [error_to_string e] is the message carried by [e]. *) 17 20 18 21 (** {1:did DID syntax} 19 22 ··· 35 38 (** A syntactically valid DID. *) 36 39 37 40 val of_string : string -> (t, error) result 41 + (** [of_string s] parses [s] as a DID per the ABNF above. *) 42 + 38 43 val of_string_exn : string -> t 44 + (** [of_string_exn s] is {!of_string} but raises on invalid input. 45 + @raise Invalid_argument if [s] is not a valid DID. *) 46 + 39 47 val to_string : t -> string 48 + (** [to_string t] is the canonical serialized form, byte-identical to the input 49 + passed to {!of_string}. *) 50 + 40 51 val method_name : t -> string 52 + (** [method_name t] is the DID method name (e.g. ["web"], ["plc"]). Always 53 + non-empty and consists only of lowercase ASCII letters and digits. *) 54 + 41 55 val method_specific_id : t -> string 56 + (** [method_specific_id t] is everything after the second colon in the 57 + serialized form. Always non-empty. *) 58 + 42 59 val equal : t -> t -> bool 60 + (** [equal a b] is byte-for-byte equality of the serialized form. DIDs are not 61 + method-normalized here; for methods that define their own equivalence (e.g. 62 + case folding) use a method-aware predicate. *) 63 + 43 64 val compare : t -> t -> int 65 + (** [compare] is lexicographic on the serialized form. *) 66 + 44 67 val pp : t Fmt.t 68 + (** [pp] prints a DID as its serialized form. *) 45 69 46 70 val json : t Json.codec 47 - (** Encodes as a JSON string, decodes with {!of_string}-level validation. *) 71 + (** [json] encodes as a JSON string and decodes with {!of_string}-level 72 + validation. *) 48 73 49 74 (** {1:document DID documents} 50 75 ··· 114 139 ?service:service list -> 115 140 t -> 116 141 doc 142 + (** [v id] is a DID document with the given properties. Unspecified lists 143 + default to empty; [?context] defaults to 144 + \[["https://www.w3.org/ns/did/v1"]\]. *) 117 145 118 146 type nonrec t = doc 119 147 (** From here on, [t] refers to the document type. *) 120 148 121 149 val json : t Json.codec 150 + (** [json] is the full DID document codec; see §5. *) 151 + 122 152 val pp : t Fmt.t 153 + (** [pp] prints [<DidDocument <id>>]. *) 123 154 124 155 (** {2:access Service lookup} *) 125 156
+2 -1
ocaml-did/lib/plc/did_plc.ml
··· 11 11 | `Transport s -> Fmt.pf ppf "transport: %s" s 12 12 13 13 let err fmt = Fmt.kstr (fun s -> Error (`Msg s)) fmt 14 + let err_parse e = Error (`Msg (Fmt.str "%a" Json.Error.pp e)) 14 15 let registry_default = "https://plc.directory" 15 16 16 17 (* -------------------------------------------------------------------------- *) ··· 64 65 else 65 66 match Json.of_string Did.Document.json body with 66 67 | Ok d -> Ok d 67 - | Error e -> Error (`Msg (Fmt.str "%a" Json.Error.pp e))))) 68 + | Error e -> err_parse e)))
+2 -1
ocaml-did/lib/plc/did_plc.mli
··· 24 24 (** {1:url URL construction} *) 25 25 26 26 val registry_default : string 27 - (** ["https://plc.directory"]. *) 27 + (** [registry_default] is ["https://plc.directory"]. *) 28 28 29 29 val url_of_did : ?registry:string -> Did.t -> (string, Did.error) result 30 30 (** [url_of_did ?registry did] is [<registry>/<did>] when [did]'s method is ··· 39 39 | `Transport of string (** Network-level failure. *) ] 40 40 41 41 val pp_error : error Fmt.t 42 + (** [pp_error] formats an error for humans. *) 42 43 43 44 val resolve : 44 45 sw:Eio.Switch.t ->
+1
ocaml-did/lib/plc/test/test.ml
··· 1 + let () = Alcotest.run "did-plc" [ Test_did_plc.suite ]
+17 -23
ocaml-did/lib/plc/test/test_did_plc.ml
··· 13 13 14 14 (* Real plc identifiers from public Bluesky accounts. These are quoted here 15 15 purely as known-valid examples of the shape; no network is contacted. *) 16 - let test_id_shape_positive () = 16 + let id_shape_positive () = 17 17 id_ok "z72i7hdynmk6r22z27h6tvur"; 18 18 id_ok "zaaaaaaaaaaaaaaaaaaaaaaa"; 19 19 id_ok "zzzzzzzzzzzzzzzzzzzzzzzz"; ··· 21 21 id_ok "aaaaaaaaaaaaaaaaaaaaaaaa"; 22 22 id_ok "7777777777777777777777aa" 23 23 24 - let test_id_shape_negative () = 24 + let id_shape_negative () = 25 25 id_ko ""; 26 26 id_ko "z72i7hdynmk6r22z27h6tvu"; 27 27 (* 23 chars *) ··· 67 67 | Ok u -> Alcotest.failf "%s: expected error but got %S" name u 68 68 | Error _ -> ()) 69 69 70 - let test_default_registry () = 70 + let default_registry () = 71 71 url_ok "default" "did:plc:z72i7hdynmk6r22z27h6tvur" 72 72 "https://plc.directory/did:plc:z72i7hdynmk6r22z27h6tvur" 73 73 74 - let test_custom_registry () = 74 + let custom_registry () = 75 75 url_ok ~registry:"https://plc.test.example" "custom" 76 76 "did:plc:z72i7hdynmk6r22z27h6tvur" 77 77 "https://plc.test.example/did:plc:z72i7hdynmk6r22z27h6tvur"; ··· 80 80 "did:plc:z72i7hdynmk6r22z27h6tvur" 81 81 "http://localhost:8080/did:plc:z72i7hdynmk6r22z27h6tvur" 82 82 83 - let test_wrong_method () = 83 + let wrong_method () = 84 84 url_err "did:web" "did:web:example.com"; 85 85 url_err "did:key" "did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK"; 86 86 url_err "did:example" "did:example:abc" 87 87 88 - let test_invalid_id_shape () = 88 + let invalid_id_shape () = 89 89 (* Wrong length but otherwise passes DID syntax. *) 90 90 url_err "short-id" "did:plc:abc"; 91 91 (* 24 chars but uppercase: invalid base32 alphabet. *) ··· 106 106 in 107 107 loop 0 108 108 109 - let test_pp_error () = 109 + let pp_error () = 110 110 let s1 = Fmt.str "%a" Did_plc.pp_error (`Msg "boom") in 111 111 Alcotest.(check bool) "msg" true (contains ~needle:"boom" s1); 112 112 let s2 = Fmt.str "%a" Did_plc.pp_error (`Http (404, "not found")) in ··· 118 118 (* Suite *) 119 119 (* ------------------------------------------------------------------------ *) 120 120 121 - let () = 122 - Alcotest.run "did-plc" 121 + let suite : string * unit Alcotest.test_case list = 122 + ( "did-plc", 123 123 [ 124 - ( "is-valid-id", 125 - [ 126 - Alcotest.test_case "positive" `Quick test_id_shape_positive; 127 - Alcotest.test_case "negative" `Quick test_id_shape_negative; 128 - ] ); 129 - ( "url-of-did", 130 - [ 131 - Alcotest.test_case "default-registry" `Quick test_default_registry; 132 - Alcotest.test_case "custom-registry" `Quick test_custom_registry; 133 - Alcotest.test_case "wrong-method" `Quick test_wrong_method; 134 - Alcotest.test_case "invalid-id" `Quick test_invalid_id_shape; 135 - ] ); 136 - ("pp-error", [ Alcotest.test_case "rendering" `Quick test_pp_error ]); 137 - ] 124 + Alcotest.test_case "is-valid-id/positive" `Quick id_shape_positive; 125 + Alcotest.test_case "is-valid-id/negative" `Quick id_shape_negative; 126 + Alcotest.test_case "url/default-registry" `Quick default_registry; 127 + Alcotest.test_case "url/custom-registry" `Quick custom_registry; 128 + Alcotest.test_case "url/wrong-method" `Quick wrong_method; 129 + Alcotest.test_case "url/invalid-id" `Quick invalid_id_shape; 130 + Alcotest.test_case "pp-error/rendering" `Quick pp_error; 131 + ] )
+4
ocaml-did/lib/plc/test/test_did_plc.mli
··· 1 + (** did:plc resolver tests. *) 2 + 3 + val suite : string * unit Alcotest.test_case list 4 + (** [suite] is the did-plc test group. *)
+1
ocaml-did/lib/resolve/did_resolve.mli
··· 13 13 (anything other than [web] and [plc]). *) ] 14 14 15 15 val pp_error : error Fmt.t 16 + (** [pp_error] formats an error for humans. *) 16 17 17 18 val resolve : 18 19 sw:Eio.Switch.t ->
+1
ocaml-did/lib/resolve/test/test.ml
··· 1 + let () = Alcotest.run "did-resolve" [ Test_did_resolve.suite ]
+7 -10
ocaml-did/lib/resolve/test/test_did_resolve.ml
··· 20 20 in 21 21 loop 0 22 22 23 - let test_pp_error () = 23 + let pp_error () = 24 24 let s1 = Fmt.str "%a" Did_resolve.pp_error (`Msg "boom") in 25 25 Alcotest.(check bool) "msg" true (contains ~needle:"boom" s1); 26 26 let s2 = Fmt.str "%a" Did_resolve.pp_error (`Http (502, "gateway")) in ··· 36 36 (contains ~needle:"unsupported" s4) 37 37 38 38 (* Unsupported-method branch: rejects before any HTTP call. *) 39 - let test_unsupported_method () = 39 + let unsupported_method () = 40 40 Eio_main.run @@ fun env -> 41 41 Eio.Switch.run @@ fun sw -> 42 42 let did = ··· 50 50 Alcotest.failf "expected Unsupported_method, got %a" Did_resolve.pp_error 51 51 other 52 52 53 - let () = 54 - Alcotest.run "did-resolve" 53 + let suite : string * unit Alcotest.test_case list = 54 + ( "did-resolve", 55 55 [ 56 - ("pp-error", [ Alcotest.test_case "rendering" `Quick test_pp_error ]); 57 - ( "dispatch", 58 - [ 59 - Alcotest.test_case "unsupported-method" `Quick test_unsupported_method; 60 - ] ); 61 - ] 56 + Alcotest.test_case "pp-error/rendering" `Quick pp_error; 57 + Alcotest.test_case "dispatch/unsupported-method" `Quick unsupported_method; 58 + ] )
+4
ocaml-did/lib/resolve/test/test_did_resolve.mli
··· 1 + (** DID method dispatcher tests. *) 2 + 3 + val suite : string * unit Alcotest.test_case list 4 + (** [suite] is the did-resolve test group. *)
+2 -1
ocaml-did/lib/web/did_web.ml
··· 11 11 | `Transport s -> Fmt.pf ppf "transport: %s" s 12 12 13 13 let err fmt = Fmt.kstr (fun s -> Error (`Msg s)) fmt 14 + let err_parse e = Error (`Msg (Fmt.str "%a" Json.Error.pp e)) 14 15 15 16 (* -------------------------------------------------------------------------- *) 16 17 (* Percent-decoding *) ··· 101 102 else 102 103 match Json.of_string Did.Document.json body with 103 104 | Ok d -> Ok d 104 - | Error e -> Error (`Msg (Fmt.str "%a" Json.Error.pp e))))) 105 + | Error e -> err_parse e)))
+1
ocaml-did/lib/web/did_web.mli
··· 38 38 | `Transport of string (** Network-level failure. *) ] 39 39 40 40 val pp_error : error Fmt.t 41 + (** [pp_error] formats an error for humans. *) 41 42 42 43 val resolve : 43 44 sw:Eio.Switch.t ->
+1
ocaml-did/lib/web/test/test.ml
··· 1 + let () = Alcotest.run "did-web" [ Test_did_web.suite ]
+17 -21
ocaml-did/lib/web/test/test_did_web.ml
··· 23 23 | Error _ -> ()) 24 24 25 25 (* §3.2 example 1: bare host maps through /.well-known. *) 26 - let test_bare_host () = 26 + let bare_host () = 27 27 url_ok "example.com" "did:web:example.com" 28 28 "https://example.com/.well-known/did.json"; 29 29 url_ok "sub.example.com" "did:web:sub.example.com" ··· 31 31 32 32 (* §3.2: port must be percent-encoded in the DID (since ':' is a segment 33 33 separator); decoding restores the literal ':' in the host. *) 34 - let test_port_encoded () = 34 + let port_encoded () = 35 35 url_ok "port-443" "did:web:example.com%3A8443" 36 36 "https://example.com:8443/.well-known/did.json"; 37 37 url_ok "port-443-caps" "did:web:example.com%3a8443" 38 38 "https://example.com:8443/.well-known/did.json" 39 39 40 40 (* §3.2 example 2: path components, colons become slashes. *) 41 - let test_path_segments () = 41 + let path_segments () = 42 42 url_ok "one-seg" "did:web:example.com:alice" 43 43 "https://example.com/alice/did.json"; 44 44 url_ok "two-seg" "did:web:example.com:users:alice" ··· 47 47 "https://example.com/a/b/c/d/e/did.json" 48 48 49 49 (* Port AND path together: both percent-decoded and colon-expanded. *) 50 - let test_port_and_path () = 50 + let port_and_path () = 51 51 url_ok "port+path" "did:web:example.com%3A8443:users:alice" 52 52 "https://example.com:8443/users/alice/did.json" 53 53 54 54 (* Percent-encoding of non-port characters is rare but spec-allowed. A 55 55 percent-encoded space is still a space after decoding; we don't 56 56 re-normalize into URL encoding because the spec says decode. *) 57 - let test_pct_general () = 57 + let pct_general () = 58 58 url_ok "pct-slash" "did:web:example.com:weird%2Fname" 59 59 "https://example.com/weird/name/did.json"; 60 60 url_ok "pct-space" "did:web:example.com:alice%20bob" 61 61 "https://example.com/alice bob/did.json" 62 62 63 63 (* Non-[web] methods must be rejected by the did:web resolver. *) 64 - let test_wrong_method () = 64 + let wrong_method () = 65 65 url_err "did:plc" "did:plc:z72i7hdynmk6r22z27h6tvur"; 66 66 url_err "did:key" "did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK"; 67 67 url_err "did:example" "did:example:abc" ··· 78 78 in 79 79 loop 0 80 80 81 - let test_pp_error_nodeps () = 81 + let pp_error_nodeps () = 82 82 let s1 = Fmt.str "%a" Did_web.pp_error (`Msg "boom") in 83 83 Alcotest.(check bool) "msg" true (contains ~needle:"boom" s1); 84 84 let s2 = Fmt.str "%a" Did_web.pp_error (`Http (404, "not found")) in ··· 86 86 let s3 = Fmt.str "%a" Did_web.pp_error (`Transport "conn refused") in 87 87 Alcotest.(check bool) "transport" true (contains ~needle:"conn refused" s3) 88 88 89 - let () = 90 - Alcotest.run "did-web" 89 + let suite : string * unit Alcotest.test_case list = 90 + ( "did-web", 91 91 [ 92 - ( "url-of-did", 93 - [ 94 - Alcotest.test_case "bare-host" `Quick test_bare_host; 95 - Alcotest.test_case "port-encoded" `Quick test_port_encoded; 96 - Alcotest.test_case "path-segments" `Quick test_path_segments; 97 - Alcotest.test_case "port-and-path" `Quick test_port_and_path; 98 - Alcotest.test_case "pct-general" `Quick test_pct_general; 99 - Alcotest.test_case "wrong-method" `Quick test_wrong_method; 100 - ] ); 101 - ( "pp-error", 102 - [ Alcotest.test_case "rendering" `Quick test_pp_error_nodeps ] ); 103 - ] 92 + Alcotest.test_case "url/bare-host" `Quick bare_host; 93 + Alcotest.test_case "url/port-encoded" `Quick port_encoded; 94 + Alcotest.test_case "url/path-segments" `Quick path_segments; 95 + Alcotest.test_case "url/port-and-path" `Quick port_and_path; 96 + Alcotest.test_case "url/pct-general" `Quick pct_general; 97 + Alcotest.test_case "url/wrong-method" `Quick wrong_method; 98 + Alcotest.test_case "pp-error/rendering" `Quick pp_error_nodeps; 99 + ] )
+4
ocaml-did/lib/web/test/test_did_web.mli
··· 1 + (** did:web resolver tests. *) 2 + 3 + val suite : string * unit Alcotest.test_case list 4 + (** [suite] is the did-web test group. *)
+1
ocaml-did/test/test.ml
··· 1 + let () = Alcotest.run "did" [ Test_did.suite ]
+42 -67
ocaml-did/test/test_did.ml
··· 577 577 (* Suite *) 578 578 (* ------------------------------------------------------------------------ *) 579 579 580 - let () = 581 - Alcotest.run "did" 580 + let suite : string * unit Alcotest.test_case list = 581 + ( "did", 582 582 [ 583 - ( "prefix", 584 - [ 585 - Alcotest.test_case "positive" `Quick prefix_positive; 586 - Alcotest.test_case "negative" `Quick prefix_negative; 587 - ] ); 588 - ( "method-name", 589 - [ 590 - Alcotest.test_case "positive" `Quick method_positive; 591 - Alcotest.test_case "negative" `Quick method_negative; 592 - ] ); 593 - ( "idchar", 594 - [ 595 - Alcotest.test_case "positive" `Quick idchar_positive; 596 - Alcotest.test_case "negative" `Quick idchar_negative; 597 - ] ); 598 - ( "id-segments", 599 - [ 600 - Alcotest.test_case "positive" `Quick id_segments_positive; 601 - Alcotest.test_case "negative" `Quick id_segments_negative; 602 - ] ); 603 - ( "pct-encoded", 604 - [ 605 - Alcotest.test_case "positive" `Quick pct_encoded_positive; 606 - Alcotest.test_case "negative" `Quick pct_encoded_negative; 607 - ] ); 608 - ( "accessors", 609 - [ 610 - Alcotest.test_case "fields" `Quick accessors; 611 - Alcotest.test_case "equal-compare" `Quick equal_compare; 612 - Alcotest.test_case "pp" `Quick pp; 613 - Alcotest.test_case "of_string_exn" `Quick of_string_exn; 614 - ] ); 615 - ("spec-examples", [ Alcotest.test_case "registry" `Quick spec_examples ]); 616 - ("boundary", [ Alcotest.test_case "edges" `Quick boundary ]); 617 - ( "did-url-rejection", 618 - [ Alcotest.test_case "rejected" `Quick did_url_rejected ] ); 619 - ( "did-json", 620 - [ 621 - Alcotest.test_case "valid" `Quick did_json_ok; 622 - Alcotest.test_case "invalid-string" `Quick did_json_invalid; 623 - Alcotest.test_case "wrong-sort" `Quick did_json_wrong_sort; 624 - Alcotest.test_case "encode" `Quick did_json_encode; 625 - ] ); 626 - ( "document", 627 - [ 628 - Alcotest.test_case "minimal" `Quick doc_minimal; 629 - Alcotest.test_case "invalid-id" `Quick doc_invalid_id; 630 - Alcotest.test_case "context-scalar" `Quick doc_context_scalar; 631 - Alcotest.test_case "context-array" `Quick doc_context_array; 632 - Alcotest.test_case "controller-scalar" `Quick doc_controller_scalar; 633 - Alcotest.test_case "controller-array" `Quick doc_controller_array; 634 - Alcotest.test_case "vm-multibase" `Quick doc_vm_multibase; 635 - Alcotest.test_case "vm-jwk-rejected" `Quick doc_vm_jwk_rejected; 636 - Alcotest.test_case "auth-reference" `Quick doc_auth_reference; 637 - Alcotest.test_case "auth-embedded" `Quick doc_auth_embedded; 638 - Alcotest.test_case "service-url" `Quick doc_service_url; 639 - Alcotest.test_case "service-type-array" `Quick doc_service_type_array; 640 - Alcotest.test_case "service-endpoint-object-rejected" `Quick 641 - doc_service_endpoint_object_rejected; 642 - Alcotest.test_case "service-endpoint-array-rejected" `Quick 643 - doc_service_endpoint_array_rejected; 644 - Alcotest.test_case "atproto-plc" `Quick doc_atproto_plc; 645 - Alcotest.test_case "roundtrip" `Quick doc_roundtrip; 646 - ] ); 647 - ] 583 + Alcotest.test_case "prefix/positive" `Quick prefix_positive; 584 + Alcotest.test_case "prefix/negative" `Quick prefix_negative; 585 + Alcotest.test_case "method-name/positive" `Quick method_positive; 586 + Alcotest.test_case "method-name/negative" `Quick method_negative; 587 + Alcotest.test_case "idchar/positive" `Quick idchar_positive; 588 + Alcotest.test_case "idchar/negative" `Quick idchar_negative; 589 + Alcotest.test_case "id-segments/positive" `Quick id_segments_positive; 590 + Alcotest.test_case "id-segments/negative" `Quick id_segments_negative; 591 + Alcotest.test_case "pct-encoded/positive" `Quick pct_encoded_positive; 592 + Alcotest.test_case "pct-encoded/negative" `Quick pct_encoded_negative; 593 + Alcotest.test_case "accessors/fields" `Quick accessors; 594 + Alcotest.test_case "accessors/equal-compare" `Quick equal_compare; 595 + Alcotest.test_case "accessors/pp" `Quick pp; 596 + Alcotest.test_case "accessors/of_string_exn" `Quick of_string_exn; 597 + Alcotest.test_case "spec-examples/registry" `Quick spec_examples; 598 + Alcotest.test_case "boundary/edges" `Quick boundary; 599 + Alcotest.test_case "did-url/rejected" `Quick did_url_rejected; 600 + Alcotest.test_case "json/valid" `Quick did_json_ok; 601 + Alcotest.test_case "json/invalid-string" `Quick did_json_invalid; 602 + Alcotest.test_case "json/wrong-sort" `Quick did_json_wrong_sort; 603 + Alcotest.test_case "json/encode" `Quick did_json_encode; 604 + Alcotest.test_case "doc/minimal" `Quick doc_minimal; 605 + Alcotest.test_case "doc/invalid-id" `Quick doc_invalid_id; 606 + Alcotest.test_case "doc/context-scalar" `Quick doc_context_scalar; 607 + Alcotest.test_case "doc/context-array" `Quick doc_context_array; 608 + Alcotest.test_case "doc/controller-scalar" `Quick doc_controller_scalar; 609 + Alcotest.test_case "doc/controller-array" `Quick doc_controller_array; 610 + Alcotest.test_case "doc/vm-multibase" `Quick doc_vm_multibase; 611 + Alcotest.test_case "doc/vm-jwk-rejected" `Quick doc_vm_jwk_rejected; 612 + Alcotest.test_case "doc/auth-reference" `Quick doc_auth_reference; 613 + Alcotest.test_case "doc/auth-embedded" `Quick doc_auth_embedded; 614 + Alcotest.test_case "doc/service-url" `Quick doc_service_url; 615 + Alcotest.test_case "doc/service-type-array" `Quick doc_service_type_array; 616 + Alcotest.test_case "doc/endpoint-object-rejected" `Quick 617 + doc_service_endpoint_object_rejected; 618 + Alcotest.test_case "doc/endpoint-array-rejected" `Quick 619 + doc_service_endpoint_array_rejected; 620 + Alcotest.test_case "doc/atproto-plc" `Quick doc_atproto_plc; 621 + Alcotest.test_case "doc/roundtrip" `Quick doc_roundtrip; 622 + ] )
+4
ocaml-did/test/test_did.mli
··· 1 + (** DID syntax and Document tests. *) 2 + 3 + val suite : string * unit Alcotest.test_case list 4 + (** [suite] is the did test group (syntax, JSON codec, document). *)