forked from
anil.recoil.org/ocaml-requests
A batteries included HTTP/1.1 client in OCaml
1(*---------------------------------------------------------------------------
2 Copyright (c) 2025 Anil Madhavapeddy <anil@recoil.org>. All rights reserved.
3 SPDX-License-Identifier: ISC
4 ---------------------------------------------------------------------------*)
5
6(** Tests for Cache module - HTTP response caching per RFC 9111 *)
7
8module Headers = Requests.Headers
9
10(** Run a test inside the Eio event loop (needed for Eio.Mutex) *)
11let run f () = Eio_main.run @@ fun _env -> f ()
12
13(** {1 Memory.create and Memory.size Tests} *)
14
15let test_create_size () =
16 let c = Cache.Memory.create () in
17 Alcotest.(check int) "fresh cache size is 0" 0 (Cache.Memory.size c)
18
19(** {1 Memory.stats Tests} *)
20
21let test_create_stats () =
22 let c = Cache.Memory.create () in
23 let hits, misses, stores = Cache.Memory.stats c in
24 Alcotest.(check int) "hits" 0 hits;
25 Alcotest.(check int) "misses" 0 misses;
26 Alcotest.(check int) "stores" 0 stores
27
28(** {1 Memory.clear Tests} *)
29
30let test_clear_empty () =
31 let c = Cache.Memory.create () in
32 Cache.Memory.clear c;
33 Alcotest.(check int) "size after clear" 0 (Cache.Memory.size c)
34
35(** {1 parse_vary Tests} *)
36
37let test_parse_vary () =
38 let result = Cache.parse_vary "Accept, Accept-Language" in
39 Alcotest.(check (list string))
40 "parsed vary"
41 [ "accept"; "accept-language" ]
42 result
43
44(** {1 is_not_modified Tests} *)
45
46let test_is_not_modified_304 () =
47 Alcotest.(check bool)
48 "304 is not modified" true
49 (Cache.is_not_modified ~status:304)
50
51let test_is_not_modified_200 () =
52 Alcotest.(check bool)
53 "200 is modified" false
54 (Cache.is_not_modified ~status:200)
55
56(** {1 vary_matches Tests} *)
57
58let test_vary_matches () =
59 let request_headers =
60 Headers.empty |> Headers.add_string "accept" "text/html"
61 in
62 let cached_vary = [ ("accept", "text/html") ] in
63 Alcotest.(check bool)
64 "matching vary" true
65 (Cache.vary_matches ~cached_vary ~request_headers)
66
67let test_vary_no_match () =
68 let request_headers =
69 Headers.empty |> Headers.add_string "accept" "application/json"
70 in
71 let cached_vary = [ ("accept", "text/html") ] in
72 Alcotest.(check bool)
73 "non-matching vary" false
74 (Cache.vary_matches ~cached_vary ~request_headers)
75
76(** {1 Test Suite} *)
77
78let suite =
79 ( "cache",
80 [
81 Alcotest.test_case "create size 0" `Quick (run test_create_size);
82 Alcotest.test_case "create stats zeros" `Quick (run test_create_stats);
83 Alcotest.test_case "clear empty" `Quick (run test_clear_empty);
84 Alcotest.test_case "parse_vary" `Quick test_parse_vary;
85 Alcotest.test_case "is_not_modified 304" `Quick test_is_not_modified_304;
86 Alcotest.test_case "is_not_modified 200" `Quick test_is_not_modified_200;
87 Alcotest.test_case "vary matches" `Quick test_vary_matches;
88 Alcotest.test_case "vary no match" `Quick test_vary_no_match;
89 ] )