forked from
anil.recoil.org/ocaml-claudeio
OCaml Claude SDK using Eio and Jsont
1(*---------------------------------------------------------------------------
2 Copyright (c) 2025 Anil Madhavapeddy <anil@recoil.org>. All rights reserved.
3 SPDX-License-Identifier: ISC
4 ---------------------------------------------------------------------------*)
5
6(** Tests for Handler module: default handler, dispatch. *)
7
8module R = Claude.Response
9module M = Claude.Message
10module CB = Claude.Content_block
11module H = Claude.Handler
12
13(* Helpers to create response events *)
14let mk_text_response s =
15 let proto_text = Claude.Proto.Content_block.Text.create s in
16 R.Text (R.Text.of_block (CB.Text.of_proto proto_text))
17
18let mk_init_response () =
19 let proto = Claude.Proto.Message.System.init ~session_id:"s1" () in
20 let sys = M.System.of_proto proto in
21 match R.Init.of_system sys with
22 | Some init -> R.Init init
23 | None -> failwith "failed to create init response"
24
25let mk_error_response () =
26 let proto = Claude.Proto.Message.System.error ~error:"test error" in
27 let sys = M.System.of_proto proto in
28 match R.Error.of_system sys with
29 | Some err -> R.Error err
30 | None -> failwith "failed to create error response"
31
32let mk_complete_response () =
33 let proto =
34 Claude.Proto.Message.Result.create ~subtype:"success" ~duration_ms:100
35 ~duration_api_ms:50 ~is_error:false ~num_turns:1 ~session_id:"s1" ()
36 in
37 R.Complete (R.Complete.of_result (M.Result.of_proto proto))
38
39(* Default handler tests - verify all methods are callable without error *)
40let test_default_handler_text () =
41 let handler = new H.default in
42 let text = mk_text_response "hello" in
43 H.dispatch handler text
44
45let test_default_handler_init () =
46 let handler = new H.default in
47 let init = mk_init_response () in
48 H.dispatch handler init
49
50let test_default_handler_error () =
51 let handler = new H.default in
52 let err = mk_error_response () in
53 H.dispatch handler err
54
55let test_default_handler_complete () =
56 let handler = new H.default in
57 let complete = mk_complete_response () in
58 H.dispatch handler complete
59
60(* Custom handler that records calls *)
61let test_custom_handler_dispatch () =
62 let calls = ref [] in
63 let handler =
64 object
65 inherit H.default
66 method! on_text _t = calls := "text" :: !calls
67 method! on_complete _c = calls := "complete" :: !calls
68 end
69 in
70 H.dispatch handler (mk_text_response "t");
71 H.dispatch handler (mk_complete_response ());
72 Alcotest.(check (list string)) "calls" [ "complete"; "text" ] !calls
73
74(* dispatch_all *)
75let test_dispatch_all () =
76 let count = ref 0 in
77 let handler =
78 object
79 inherit H.default
80 method! on_text _t = incr count
81 method! on_complete _c = incr count
82 end
83 in
84 H.dispatch_all handler [ mk_text_response "a"; mk_complete_response () ];
85 Alcotest.(check int) "dispatch_all count" 2 !count
86
87let test_dispatch_all_empty () =
88 let count = ref 0 in
89 let handler =
90 object
91 inherit H.default
92 method! on_text _t = incr count
93 end
94 in
95 H.dispatch_all handler [];
96 Alcotest.(check int) "empty dispatch" 0 !count
97
98let suite =
99 ( "handler",
100 [
101 Alcotest.test_case "default handler text" `Quick test_default_handler_text;
102 Alcotest.test_case "default handler init" `Quick test_default_handler_init;
103 Alcotest.test_case "default handler error" `Quick
104 test_default_handler_error;
105 Alcotest.test_case "default handler complete" `Quick
106 test_default_handler_complete;
107 Alcotest.test_case "custom handler dispatch" `Quick
108 test_custom_handler_dispatch;
109 Alcotest.test_case "dispatch_all" `Quick test_dispatch_all;
110 Alcotest.test_case "dispatch_all empty" `Quick test_dispatch_all_empty;
111 ] )