this repo has no description
at main 155 lines 4.9 kB view raw
1(* Test incremental output *) 2open Js_top_worker 3open Impl 4 5let capture : (unit -> 'a) -> unit -> Impl.captured * 'a = 6 fun f () -> 7 let stdout_buff = Buffer.create 1024 in 8 let stderr_buff = Buffer.create 1024 in 9 Js_of_ocaml.Sys_js.set_channel_flusher stdout (Buffer.add_string stdout_buff); 10 11 let x = f () in 12 let captured = 13 { 14 Impl.stdout = Buffer.contents stdout_buff; 15 stderr = Buffer.contents stderr_buff; 16 } 17 in 18 (captured, x) 19 20module S : Impl.S = struct 21 type findlib_t = Js_top_worker_web.Findlibish.t 22 23 let capture = capture 24 25 let sync_get f = 26 let f = Fpath.v ("_opam/" ^ f) in 27 Logs.info (fun m -> m "sync_get: %a" Fpath.pp f); 28 try Some (In_channel.with_open_bin (Fpath.to_string f) In_channel.input_all) 29 with e -> 30 Logs.err (fun m -> 31 m "Error reading file %a: %s" Fpath.pp f (Printexc.to_string e)); 32 None 33 34 let async_get f = 35 let f = Fpath.v ("_opam/" ^ f) in 36 Logs.info (fun m -> m "async_get: %a" Fpath.pp f); 37 try 38 let content = 39 In_channel.with_open_bin (Fpath.to_string f) In_channel.input_all 40 in 41 Lwt.return (Ok content) 42 with e -> 43 Logs.err (fun m -> 44 m "Error reading file %a: %s" Fpath.pp f (Printexc.to_string e)); 45 Lwt.return (Error (`Msg (Printexc.to_string e))) 46 47 let create_file = Js_of_ocaml.Sys_js.create_file 48 49 let import_scripts urls = 50 let open Js_of_ocaml.Js in 51 let import_scripts_fn = Unsafe.get Unsafe.global (string "importScripts") in 52 List.iter 53 (fun url -> 54 let (_ : 'a) = 55 Unsafe.fun_call import_scripts_fn [| Unsafe.inject (string url) |] 56 in 57 ()) 58 urls 59 60 let init_function _ () = failwith "Not implemented" 61 let findlib_init = Js_top_worker_web.Findlibish.init async_get 62 63 let get_stdlib_dcs uri = 64 Js_top_worker_web.Findlibish.fetch_dynamic_cmis sync_get uri 65 |> Result.to_list 66 67 let find_stdlib_dcs v = 68 let pkg = match Js_top_worker_web.Findlibish.find_dcs_url v "stdlib" with 69 | Some _ as r -> r 70 | None -> Js_top_worker_web.Findlibish.find_dcs_url v "ocaml" 71 in 72 match pkg with 73 | Some url -> 74 Js_top_worker_web.Findlibish.fetch_dynamic_cmis sync_get url 75 |> Result.to_list 76 | None -> [] 77 78 let require b v = function 79 | [] -> [] 80 | packages -> Js_top_worker_web.Findlibish.require ~import_scripts sync_get b v packages 81 82 let path = "/static/cmis" 83end 84 85module U = Impl.Make (S) 86 87let _ = 88 Logs.set_reporter (Logs_fmt.reporter ()); 89 Logs.set_level (Some Logs.Info); 90 91 let ( let* ) m f = 92 let open Lwt in 93 m >>= function 94 | Ok x -> f x 95 | Error e -> return (Error e) 96 in 97 98 let init_config = 99 { stdlib_dcs = None; findlib_requires = []; findlib_index = None; execute = true } 100 in 101 102 let x = 103 let* _ = U.init init_config in 104 let* _ = U.setup "" in 105 Logs.info (fun m -> m "Setup complete, testing incremental output..."); 106 107 (* Test incremental output with multiple phrases *) 108 let phrase_outputs = ref [] in 109 let on_phrase_output (p : U.phrase_output) = 110 Logs.info (fun m -> m " OutputAt: loc=%d caml_ppf=%s" 111 p.loc 112 (Option.value ~default:"<none>" p.caml_ppf)); 113 phrase_outputs := p :: !phrase_outputs 114 in 115 116 let code = "let x = 1;; let y = 2;; let z = x + y;;" in 117 Logs.info (fun m -> m "Evaluating: %s" code); 118 119 let* result = U.execute_incremental "" code ~on_phrase_output in 120 121 let num_callbacks = List.length !phrase_outputs in 122 Logs.info (fun m -> m "Number of OutputAt callbacks: %d (expected 3)" num_callbacks); 123 124 (* Verify we got 3 callbacks (one per phrase) *) 125 if num_callbacks <> 3 then 126 Logs.err (fun m -> m "FAIL: Expected 3 callbacks, got %d" num_callbacks) 127 else 128 Logs.info (fun m -> m "PASS: Got expected number of callbacks"); 129 130 (* Verify the locations are increasing *) 131 let locs = List.rev_map (fun (p : U.phrase_output) -> p.loc) !phrase_outputs in 132 let sorted = List.sort compare locs in 133 if locs = sorted then 134 Logs.info (fun m -> m "PASS: Locations are in increasing order: %s" 135 (String.concat ", " (List.map string_of_int locs))) 136 else 137 Logs.err (fun m -> m "FAIL: Locations are not in order"); 138 139 (* Verify final result has expected values *) 140 Logs.info (fun m -> m "Final result caml_ppf: %s" 141 (Option.value ~default:"<none>" result.caml_ppf)); 142 Logs.info (fun m -> m "Final result stdout: %s" 143 (Option.value ~default:"<none>" result.stdout)); 144 145 Lwt.return (Ok ()) 146 in 147 148 let promise = x in 149 match Lwt.state promise with 150 | Lwt.Return (Ok ()) -> Logs.info (fun m -> m "Test completed successfully") 151 | Lwt.Return (Error (InternalError s)) -> Logs.err (fun m -> m "Error: %s" s) 152 | Lwt.Fail e -> 153 Logs.err (fun m -> m "Unexpected failure: %s" (Printexc.to_string e)) 154 | Lwt.Sleep -> 155 Logs.err (fun m -> m "Error: Promise is still pending")