12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697open!Coreopen!Async_kernelopenBonsai_webletschedule_and_print_responsecallback=Vdom.Effect.Expert.handle_non_dom_event_exn(let%bind.Effectr=callbackinprint_s[%message"this is userdata"(r:int)];Vdom.Effect.Ignore);;let%expect_test"synchronous callback"=letincrement=Effect.of_sync_fun(funa->a+1)inschedule_and_print_response(increment1);[%expect{| ("this is userdata" (r 2)) |}];;let%expect_test"bind and return"=letopenEffect.Let_syntaxinletincrement=Effect.of_sync_fun(funa->a+1)inletcallback=let%binda=increment1inlet%bindb=increment2inreturn(a+b)inschedule_and_print_responsecallback;[%expect{| ("this is userdata" (r 5)) |}];;let%expect_test"of_deferred_fun"=(* Note that there is no module that can drive the async_kernel scheduler that is
compatible with javascript tests. The only way therefore of testing of_deferred_fun
is to instruct the scheduler ourselves. *)letopenAsync_kernelinletstate=Int.Table.create()inletcallback=Effect.of_deferred_fun(funn->Ivar.read(Hashtbl.find_or_addstaten~default:Ivar.create))inschedule_and_print_response(callback1);schedule_and_print_response(callback2);schedule_and_print_response(callback3);[%expect{||}];print_s[%sexp(Hashtbl.keysstate:intlist)];[%expect{| (1 3 2) |}];Ivar.fill(Hashtbl.find_and_removestate1|>Option.value_exn)42;(* Nothing yet, because the scheduler has not run a cycle *)[%expect{||}];(* Tell async_kernel to run a cycle manually to see that the effect is responded to *)Async_kernel_scheduler.Private.run_cycles_until_no_jobs_remain();[%expect{| ("this is userdata" (r 42)) |}];Hashtbl.iteristate~f:(fun~key:query~data:ivar->Ivar.fillivar(10*query));Async_kernel_scheduler.Private.run_cycles_until_no_jobs_remain();[%expect{|
("this is userdata" (r 20))
("this is userdata" (r 30)) |}];;let%expect_test"svar"=letin_flight_query_and_response=refNoneinletcallback=Effect.For_testing.of_svar_fun(funquery->letsvar=Effect.For_testing.Svar.create()inin_flight_query_and_response:=Some(query,svar);svar)inschedule_and_print_response(callback1);[%expect{||}];letquery,response=Option.value_exn!in_flight_query_and_responseinEffect.For_testing.Svar.fill_if_emptyresponse(query+1);[%expect{| ("this is userdata" (r 2)) |}];;let%expect_test"Query_response_tracker"=letqrt=Effect.For_testing.Query_response_tracker.create()inletcallback=Effect.For_testing.of_query_response_trackerqrtinschedule_and_print_response(callback1);schedule_and_print_response(callback2);schedule_and_print_response(callback3);[%expect{||}];Effect.For_testing.Query_response_tracker.maybe_respondqrt~f:(funi->ifi%2=0thenRespond(10*i)elseNo_response_yet);[%expect{| ("this is userdata" (r 20)) |}];printf!"%{sexp: int list}"(Effect.For_testing.Query_response_tracker.queries_pending_responseqrt);[%expect{| (3 1) |}];Effect.For_testing.Query_response_tracker.maybe_respondqrt~f:(funi->Respond(20*i));[%expect{|
("this is userdata" (r 60))
("this is userdata" (r 20)) |}];printf!"%{sexp: int list}"(Effect.For_testing.Query_response_tracker.queries_pending_responseqrt);[%expect{| () |}];;