A fork of mtelver's day10 project
at main2 202 lines 6.8 kB view raw
1(** Node.js test for MIME output infrastructure. 2 3 This tests that the MIME output infrastructure is wired up correctly: 4 - exec_result.mime_vals field is returned 5 - Field is empty when no MIME output occurs 6 - API types are correctly defined 7 8 Note: The mime_printer library is used internally by the worker to 9 capture MIME output. User code can call Mime_printer.push to produce 10 MIME values when the mime_printer package is loaded in the toplevel. 11*) 12 13open Js_top_worker 14open Impl 15 16(* Flusher that writes to process.stdout in Node.js *) 17let console_flusher (s : string) : unit = 18 let open Js_of_ocaml in 19 let process = Js.Unsafe.get Js.Unsafe.global (Js.string "process") in 20 let stdout = Js.Unsafe.get process (Js.string "stdout") in 21 let write = Js.Unsafe.get stdout (Js.string "write") in 22 ignore (Js.Unsafe.call write stdout [| Js.Unsafe.inject (Js.string s) |]) 23 24let capture : (unit -> 'a) -> unit -> Impl.captured * 'a = 25 fun f () -> 26 let stdout_buff = Buffer.create 1024 in 27 let stderr_buff = Buffer.create 1024 in 28 Js_of_ocaml.Sys_js.set_channel_flusher stdout (Buffer.add_string stdout_buff); 29 let x = f () in 30 let captured = 31 { 32 Impl.stdout = Buffer.contents stdout_buff; 33 stderr = Buffer.contents stderr_buff; 34 } 35 in 36 Js_of_ocaml.Sys_js.set_channel_flusher stdout console_flusher; 37 (captured, x) 38 39module S : Impl.S = struct 40 type findlib_t = Js_top_worker_web.Findlibish.t 41 42 let capture = capture 43 44 let sync_get f = 45 let f = Fpath.v ("_opam/" ^ f) in 46 try Some (In_channel.with_open_bin (Fpath.to_string f) In_channel.input_all) 47 with _ -> None 48 49 let async_get f = 50 let f = Fpath.v ("_opam/" ^ f) in 51 try 52 let content = 53 In_channel.with_open_bin (Fpath.to_string f) In_channel.input_all 54 in 55 Lwt.return (Ok content) 56 with e -> Lwt.return (Error (`Msg (Printexc.to_string e))) 57 58 let create_file = Js_of_ocaml.Sys_js.create_file 59 60 let import_scripts urls = 61 let open Js_of_ocaml.Js in 62 let import_scripts_fn = Unsafe.get Unsafe.global (string "importScripts") in 63 List.iter 64 (fun url -> 65 let (_ : 'a) = 66 Unsafe.fun_call import_scripts_fn [| Unsafe.inject (string url) |] 67 in 68 ()) 69 urls 70 71 let init_function _ () = failwith "Not implemented" 72 let findlib_init = Js_top_worker_web.Findlibish.init async_get 73 74 let get_stdlib_dcs uri = 75 Js_top_worker_web.Findlibish.fetch_dynamic_cmis sync_get uri 76 |> Result.to_list 77 78 let find_stdlib_dcs v = 79 let pkg = match Js_top_worker_web.Findlibish.find_dcs_url v "stdlib" with 80 | Some _ as r -> r 81 | None -> Js_top_worker_web.Findlibish.find_dcs_url v "ocaml" 82 in 83 match pkg with 84 | Some url -> 85 Js_top_worker_web.Findlibish.fetch_dynamic_cmis sync_get url 86 |> Result.to_list 87 | None -> [] 88 89 let require b v = function 90 | [] -> [] 91 | packages -> 92 Js_top_worker_web.Findlibish.require ~import_scripts sync_get b v 93 packages 94 95 let path = "/static/cmis" 96end 97 98module U = Impl.Make (S) 99 100(* Test result tracking *) 101let total_tests = ref 0 102let passed_tests = ref 0 103 104let test name check message = 105 incr total_tests; 106 let passed = check in 107 if passed then incr passed_tests; 108 let status = if passed then "PASS" else "FAIL" in 109 Printf.printf "[%s] %s: %s\n%!" status name message 110 111let _ = 112 Printf.printf "=== Node.js MIME Infrastructure Tests ===\n\n%!"; 113 114 Logs.set_reporter (Logs_fmt.reporter ()); 115 Logs.set_level (Some Logs.Info); 116 117 let ( let* ) m f = 118 let open Lwt in 119 m >>= function 120 | Ok x -> f x 121 | Error e -> return (Error e) 122 in 123 124 let run_exec code = U.execute "" code in 125 126 let init_config = 127 { stdlib_dcs = None; findlib_requires = []; findlib_index = None; execute = true } 128 in 129 130 let test_sequence = 131 (* Initialize *) 132 let* _ = U.init init_config in 133 let* _ = U.setup "" in 134 135 Printf.printf "--- Section 1: exec_result Has mime_vals Field ---\n%!"; 136 137 (* Basic execution returns a result with mime_vals *) 138 let* r = run_exec {|let x = 1 + 2;;|} in 139 test "has_mime_vals_field" true "exec_result has mime_vals field"; 140 test "mime_vals_is_list" (List.length r.mime_vals >= 0) 141 (Printf.sprintf "mime_vals is a list (length=%d)" (List.length r.mime_vals)); 142 test "mime_vals_empty_no_output" (List.length r.mime_vals = 0) 143 "mime_vals is empty when no MIME output"; 144 145 Printf.printf "\n--- Section 2: MIME Type Definitions ---\n%!"; 146 147 (* Verify API types are accessible *) 148 let mime_val_example : mime_val = { 149 mime_type = "text/html"; 150 encoding = Mime_printer.Noencoding; 151 data = "<b>test</b>"; 152 } in 153 test "mime_type_field" (mime_val_example.mime_type = "text/html") 154 "mime_val has mime_type field"; 155 test "encoding_noencoding" (mime_val_example.encoding = Mime_printer.Noencoding) 156 "Noencoding variant works"; 157 test "data_field" (mime_val_example.data = "<b>test</b>") 158 "mime_val has data field"; 159 160 let mime_val_base64 : mime_val = { 161 mime_type = "image/png"; 162 encoding = Mime_printer.Base64; 163 data = "iVBORw0KGgo="; 164 } in 165 test "encoding_base64" (mime_val_base64.encoding = Mime_printer.Base64) 166 "Base64 variant works"; 167 168 Printf.printf "\n--- Section 3: Multiple Executions ---\n%!"; 169 170 (* Verify mime_vals is fresh for each execution *) 171 let* r1 = run_exec {|let a = 1;;|} in 172 let* r2 = run_exec {|let b = 2;;|} in 173 let* r3 = run_exec {|let c = 3;;|} in 174 test "r1_mime_empty" (List.length r1.mime_vals = 0) "First exec: mime_vals empty"; 175 test "r2_mime_empty" (List.length r2.mime_vals = 0) "Second exec: mime_vals empty"; 176 test "r3_mime_empty" (List.length r3.mime_vals = 0) "Third exec: mime_vals empty"; 177 178 Printf.printf "\n--- Section 4: exec_toplevel Has mime_vals ---\n%!"; 179 180 (* exec_toplevel also returns mime_vals *) 181 let* tr = U.exec_toplevel "" "# let z = 42;;" in 182 test "toplevel_has_mime_vals" true "exec_toplevel_result has mime_vals field"; 183 test "toplevel_mime_vals_list" (List.length tr.mime_vals >= 0) 184 (Printf.sprintf "toplevel mime_vals is a list (length=%d)" (List.length tr.mime_vals)); 185 186 Lwt.return (Ok ()) 187 in 188 189 let promise = test_sequence in 190 (match Lwt.state promise with 191 | Lwt.Return (Ok ()) -> () 192 | Lwt.Return (Error (InternalError s)) -> 193 Printf.printf "\n[ERROR] Test failed with: %s\n%!" s 194 | Lwt.Fail e -> 195 Printf.printf "\n[ERROR] Exception: %s\n%!" (Printexc.to_string e) 196 | Lwt.Sleep -> Printf.printf "\n[ERROR] Promise still pending\n%!"); 197 198 Printf.printf "\n=== Results: %d/%d tests passed ===\n%!" !passed_tests 199 !total_tests; 200 if !passed_tests = !total_tests then 201 Printf.printf "SUCCESS: All MIME infrastructure tests passed!\n%!" 202 else Printf.printf "FAILURE: Some tests failed.\n%!"