Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## Next

- Add `2.16.0` as lower bound version of `atdgen`, [#54](https://github.com/ahrefs/melange-atdgen-codec-runtime/pull/54)

## 3.0.0 (2024-02-06)

- Expose `DecodeErrorPath`, [#51](https://github.com/ahrefs/melange-atdgen-codec-runtime/pull/51)
Expand Down
4 changes: 2 additions & 2 deletions example/src/cli.ml
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,12 @@ let read_events () =
(* parse the json *)
let json = Js.Json.parseExn file_content in
(* turn it into a proper record *)
let events: Meetup_t.events = Atdgen_codec_runtime.Decode.decode Meetup_bs.read_events json in
let events: Meetup_t.events = Atdgen_codec_runtime.Decode.decode Meetup_mel.read_events json in
events

let write_events events =
(* turn a list of records into json *)
let json = Atdgen_codec_runtime.Encode.encode Meetup_bs.write_events events in
let json = Atdgen_codec_runtime.Encode.encode Meetup_mel.write_events events in
(* convert the json to string *)
let file_content = Js.Json.stringifyWithSpace json 2 in
(* write the json in our file *)
Expand Down
4 changes: 2 additions & 2 deletions example/src/dune
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@
(promote (until-clean)))

(rule
(targets meetup_bs.ml meetup_bs.mli)
(targets meetup_mel.ml meetup_mel.mli)
(deps meetup.atd)
(action
(run atdgen -bs %{deps})))
(run atdgen -mel %{deps})))

(rule
(targets meetup_t.ml meetup_t.mli)
Expand Down
2 changes: 1 addition & 1 deletion melange-atdgen-codec-runtime.opam
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ depends: [
"ocaml"
"melange" {>= "3.0.0"}
"atd"
"atdgen"
"atdgen" {>= "2.16.0"}
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does it make sense to bump the version here?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. if we don't do this, the opam repo checks will fail.

"melange-json"
"melange-jest" {with-test}
"reason" {with-test}
Expand Down
4 changes: 2 additions & 2 deletions src/__tests__/decode_test.ml
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@ let run_decode_test ~name ~read ~data ~expected =
let () =
describe "JSON decoding tests" (fun () ->
run_decode_test ~name:"nullable field decoding a null"
~read:Test_bs.read_optional_field
~read:Test_mel.read_optional_field
~expected:
{ with_default = 9; no_default = None; no_default_nullable = None }
~data:[%raw {|{ no_default_nullable: null }|}];
run_decode_test ~name:"optional field decoding a null"
~read:Test_bs.read_optional_field
~read:Test_mel.read_optional_field
~expected:
{ with_default = 9; no_default = None; no_default_nullable = None }
~data:[%raw {|{ no_default: null}|}])
4 changes: 2 additions & 2 deletions src/__tests__/dune
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@
(pps melange.ppx)))

(rule
(targets test_bs.ml test_bs.mli)
(targets test_mel.ml test_mel.mli)
(deps test.atd)
(action
(run atdgen -bs %{deps})))
(run atdgen -mel %{deps})))

(rule
(targets test_t.ml test_t.mli)
Expand Down
14 changes: 7 additions & 7 deletions src/__tests__/errors_test.ml
Original file line number Diff line number Diff line change
Expand Up @@ -31,37 +31,37 @@ let () =

test "missing field in record" (fun () ->
let j = Json.parseOrRaise {|{"o": 44}|} in
expect (wrap_exn (fun () -> Atdgen_codec_runtime.Decode.decode Test_bs.read_ro j))
expect (wrap_exn (fun () -> Atdgen_codec_runtime.Decode.decode Test_mel.read_ro j))
|> toBe("Expected field 'c'"));

test "optional field with default: wrong type throws exception" (fun () ->
let j = Json.parseOrRaise {|{"with_default": "not right"}|} in
expect (wrap_exn (fun () -> Atdgen_codec_runtime.Decode.decode Test_bs.read_optional_field j))
expect (wrap_exn (fun () -> Atdgen_codec_runtime.Decode.decode Test_mel.read_optional_field j))
|> toBe({|with_default: Expected number, got "not right"|}));

test "optional field: wrong type throws exception" (fun () ->
let j = Json.parseOrRaise {|{"no_default": "not right"}|} in
expect (wrap_exn (fun () -> Atdgen_codec_runtime.Decode.decode Test_bs.read_optional_field j))
expect (wrap_exn (fun () -> Atdgen_codec_runtime.Decode.decode Test_mel.read_optional_field j))
|> toBe({|no_default: Expected number, got "not right"|}));

test "error in variant" (fun () ->
let j = Json.parseOrRaise {|["A", "not right"]|} in
expect (wrap_exn (fun () -> Atdgen_codec_runtime.Decode.decode Test_bs.read_v j))
expect (wrap_exn (fun () -> Atdgen_codec_runtime.Decode.decode Test_mel.read_v j))
|> toBe({|A: Expected number, got "not right"|}));

test "deeply nested error (array element fails)" (fun () ->
let j = Json.parseOrRaise {|["A", [[1, "not right"], "Bool"]]|} in
expect (wrap_exn (fun () -> Atdgen_codec_runtime.Decode.decode Test_bs.read_deeply_nested j))
expect (wrap_exn (fun () -> Atdgen_codec_runtime.Decode.decode Test_mel.read_deeply_nested j))
|> toBe({|A.0.1: Expected number, got "not right"|}));

test "deeply nested error (tuple element fails)" (fun () ->
let j = Json.parseOrRaise {|["A", [[1, 2], "Boolean"]]|} in
expect (wrap_exn (fun () -> Atdgen_codec_runtime.Decode.decode Test_bs.read_deeply_nested j))
expect (wrap_exn (fun () -> Atdgen_codec_runtime.Decode.decode Test_mel.read_deeply_nested j))
|> toBe({|A.1.Boolean: unknown constructor "Boolean"|}));

test "deeply nested error (rec_list element fails deep enough)" (fun () ->
let j = Json.parseOrRaise {|["A", [[1, 2], ["List", ["Bool", "Fail"]]]]|} in
expect (wrap_exn (fun () -> Atdgen_codec_runtime.Decode.decode Test_bs.read_deeply_nested j))
expect (wrap_exn (fun () -> Atdgen_codec_runtime.Decode.decode Test_mel.read_deeply_nested j))
|> toBe({|A.1.List.1.Fail: unknown constructor "Fail"|}));


Expand Down
84 changes: 42 additions & 42 deletions src/__tests__/roundtrip_test.ml
Original file line number Diff line number Diff line change
Expand Up @@ -17,111 +17,111 @@ let () =
describe "roundtrip tests" (fun () ->
run_test
~name:"record"
~write:Test_bs.write_r
~read:Test_bs.read_r
~write:Test_mel.write_r
~read:Test_mel.read_r
~data:{Test_t.a = 1; b = "string";};
run_test
~name:"record optional absent"
~write:Test_bs.write_ro
~read:Test_bs.read_ro
~write:Test_mel.write_ro
~read:Test_mel.read_ro
~data:{Test_t.c = "s"; o = None;};
run_test
~name:"record optional present"
~write:Test_bs.write_ro
~read:Test_bs.read_ro
~write:Test_mel.write_ro
~read:Test_mel.read_ro
~data:{Test_t.c = "s"; o = Some 3L;};
run_test
~name:"variant list"
~write:Test_bs.write_vl
~read:Test_bs.read_vl
~write:Test_mel.write_vl
~read:Test_mel.read_vl
~data:[Test_t.A 1; B "s"];
run_test
~name:"variant poly list"
~write:Test_bs.write_vpl
~read:Test_bs.read_vpl
~write:Test_mel.write_vpl
~read:Test_mel.read_vpl
~data:[`A 1; `B "s"];
run_test
~name:"tuple"
~write:Test_bs.write_t
~read:Test_bs.read_t
~write:Test_mel.write_t
~read:Test_mel.read_t
~data:(1, "s", 1.1);
run_test
~name:"int nullable absent"
~write:Test_bs.write_n
~read:Test_bs.read_n
~write:Test_mel.write_n
~read:Test_mel.read_n
~data:None;
run_test
~name:"int nullable present"
~write:Test_bs.write_n
~read:Test_bs.read_n
~write:Test_mel.write_n
~read:Test_mel.read_n
~data:(Some 1);
run_test
~name:"int64"
~write:Test_bs.write_myInt
~read:Test_bs.read_myInt
~write:Test_mel.write_myInt
~read:Test_mel.read_myInt
~data:3L;
run_test
~name:"recurse"
~write:Test_bs.write_recurse
~read:Test_bs.read_recurse
~write:Test_mel.write_recurse
~read:Test_mel.read_recurse
~data:{Test_t.recurse_items = [{ recurse_items = []}]};
run_test
~name:"mutual recurse"
~write:Test_bs.write_mutual_recurse1
~read:Test_bs.read_mutual_recurse1
~write:Test_mel.write_mutual_recurse1
~read:Test_mel.read_mutual_recurse1
~data:(
let rec mutual_recurse1 = { Test_t.mutual_recurse2; }
and mutual_recurse2 = [{ Test_t.mutual_recurse1 = [] }]
in mutual_recurse1
);
run_test
~name:"rec list"
~write:Test_bs.write_rec_list
~read:Test_bs.read_rec_list
~write:Test_mel.write_rec_list
~read:Test_mel.read_rec_list
~data:(`List [`Bool;`Bool;`List [`Bool]; `List []]);
run_test
~name:"adapter variant 1"
~write:Test_bs.write_adapted
~read:Test_bs.read_adapted
~write:Test_mel.write_adapted
~read:Test_mel.read_adapted
~data:Test_t.(`A {thing = "thing"; other_thing = false;});
run_test
~name:"adapter variant 2"
~write:Test_bs.write_adapted
~read:Test_bs.read_adapted
~write:Test_mel.write_adapted
~read:Test_mel.read_adapted
~data:Test_t.(`B {thing = 1;});
run_test
~name:"adapter kind field - variant 1"
~write:Test_bs.write_adapted_kind
~read:Test_bs.read_adapted_kind
~write:Test_mel.write_adapted_kind
~read:Test_mel.read_adapted_kind
~data:Test_t.(`A {thing = "thing"; other_thing = false;});
run_test
~name:"adapter kind field - variant 2"
~write:Test_bs.write_adapted_kind
~read:Test_bs.read_adapted_kind
~write:Test_mel.write_adapted_kind
~read:Test_mel.read_adapted_kind
~data:Test_t.(`B {thing = 1;});
run_test
~name:"int array"
~write:Test_bs.write_an_array
~read:Test_bs.read_an_array
~write:Test_mel.write_an_array
~read:Test_mel.read_an_array
~data:[| 1;2;3;4;5 |];
run_test
~name:"record with optional fields"
~write:Test_bs.write_optional_field
~read:Test_bs.read_optional_field
~write:Test_mel.write_optional_field
~read:Test_mel.read_optional_field
~data:{with_default = 1; no_default = None; no_default_nullable = Some 11};
run_test
~name:"adapter scalar"
~write:Test_bs.write_adapted_scalar
~read:Test_bs.read_adapted_scalar
~write:Test_mel.write_adapted_scalar
~read:Test_mel.read_adapted_scalar
~data:(`A 1);
run_test
~name:"adapter scalar - variant 2"
~write:Test_bs.write_adapted_scalar
~read:Test_bs.read_adapted_scalar
~write:Test_mel.write_adapted_scalar
~read:Test_mel.read_adapted_scalar
~data:(`B "thing");
run_test
~name:"adapter list"
~write:Test_bs.write_adapted_list
~read:Test_bs.read_adapted_list
~write:Test_mel.write_adapted_list
~read:Test_mel.read_adapted_list
~data:(`A [1]);
)