HomeKit Accessory Protocol (HAP) for OCaml
1(*---------------------------------------------------------------------------
2 Copyright (c) 2025 Thomas Gazagnaire. All rights reserved.
3 SPDX-License-Identifier: MIT
4 ---------------------------------------------------------------------------*)
5
6(* TLV encoding tests *)
7
8let test_tlv_empty () =
9 let encoded = Hap.Tlv.encode Hap.Tlv.empty in
10 Alcotest.(check string) "empty TLV" "" encoded
11
12let test_tlv_single () =
13 let tlv = Hap.Tlv.(add 0x01 "hello" empty) in
14 let encoded = Hap.Tlv.encode tlv in
15 (* Type 0x01, Length 5, "hello" *)
16 let expected = "\x01\x05hello" in
17 Alcotest.(check string) "single TLV" expected encoded
18
19let test_tlv_roundtrip () =
20 let tlv = Hap.Tlv.(add 0x01 "hello" (add 0x02 "world" empty)) in
21 let encoded = Hap.Tlv.encode tlv in
22 let decoded = Hap.Tlv.decode encoded in
23 Alcotest.(check (option string))
24 "get type 1" (Some "hello") (Hap.Tlv.get 0x01 decoded);
25 Alcotest.(check (option string))
26 "get type 2" (Some "world") (Hap.Tlv.get 0x02 decoded)
27
28let test_tlv_long_value () =
29 (* TLV8 fragments values longer than 255 bytes *)
30 let long_value = String.make 300 'x' in
31 let tlv = Hap.Tlv.(add 0x03 long_value empty) in
32 let encoded = Hap.Tlv.encode tlv in
33 let decoded = Hap.Tlv.decode encoded in
34 Alcotest.(check (option string))
35 "long value roundtrip" (Some long_value) (Hap.Tlv.get 0x03 decoded)
36
37(* Category name tests *)
38
39let test_category_names () =
40 Alcotest.(check string) "category 1" "Other" (Hap.category_name 1);
41 Alcotest.(check string) "category 2" "Bridge" (Hap.category_name 2);
42 Alcotest.(check string)
43 "category 4" "Garage Door Opener" (Hap.category_name 4);
44 Alcotest.(check string) "category 5" "Lightbulb" (Hap.category_name 5);
45 Alcotest.(check string) "category 7" "Outlet" (Hap.category_name 7);
46 Alcotest.(check string) "category 8" "Switch" (Hap.category_name 8);
47 Alcotest.(check string) "category 10" "Sensor" (Hap.category_name 10);
48 Alcotest.(check string) "category 999" "Unknown" (Hap.category_name 999)
49
50(* TLV type constants tests *)
51
52let test_tlv_type_constants () =
53 Alcotest.(check int) "method" 0x00 Hap.Tlv_type.method_;
54 Alcotest.(check int) "identifier" 0x01 Hap.Tlv_type.identifier;
55 Alcotest.(check int) "salt" 0x02 Hap.Tlv_type.salt;
56 Alcotest.(check int) "public_key" 0x03 Hap.Tlv_type.public_key;
57 Alcotest.(check int) "proof" 0x04 Hap.Tlv_type.proof;
58 Alcotest.(check int) "encrypted_data" 0x05 Hap.Tlv_type.encrypted_data;
59 Alcotest.(check int) "state" 0x06 Hap.Tlv_type.state;
60 Alcotest.(check int) "error" 0x07 Hap.Tlv_type.error;
61 Alcotest.(check int) "signature" 0x0a Hap.Tlv_type.signature
62
63(* HAP error constants tests *)
64
65let test_hap_error_constants () =
66 Alcotest.(check int) "unknown" 0x01 Hap.Hap_error.unknown;
67 Alcotest.(check int) "authentication" 0x02 Hap.Hap_error.authentication;
68 Alcotest.(check int) "backoff" 0x03 Hap.Hap_error.backoff;
69 Alcotest.(check int) "max_peers" 0x04 Hap.Hap_error.max_peers;
70 Alcotest.(check int) "max_tries" 0x05 Hap.Hap_error.max_tries;
71 Alcotest.(check int) "unavailable" 0x06 Hap.Hap_error.unavailable;
72 Alcotest.(check int) "busy" 0x07 Hap.Hap_error.busy
73
74let suite =
75 ( "hap",
76 [
77 Alcotest.test_case "TLV empty" `Quick test_tlv_empty;
78 Alcotest.test_case "TLV single" `Quick test_tlv_single;
79 Alcotest.test_case "TLV roundtrip" `Quick test_tlv_roundtrip;
80 Alcotest.test_case "TLV long value" `Quick test_tlv_long_value;
81 Alcotest.test_case "category names" `Quick test_category_names;
82 Alcotest.test_case "Tlv_type constants" `Quick test_tlv_type_constants;
83 Alcotest.test_case "Hap_error constants" `Quick test_hap_error_constants;
84 ] )