Skip to content

Commit

Permalink
✅ Add infinite retrying set state test
Browse files Browse the repository at this point in the history
  • Loading branch information
Zeta611 committed Jul 4, 2024
1 parent 5858811 commit ef66d0a
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 3 deletions.
24 changes: 21 additions & 3 deletions lib/interp.ml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,18 @@ type _ eff +=
| Lookup_ent : Path.t -> entry eff
| Update_ent : Path.t * entry -> unit eff

(* For testing nontermination *)
type _ eff += Re_render_limit : int eff

exception Too_many_re_renders

let re_render_limit_h (type a b) (f : b -> a) (x : b) : re_render_limit:int -> a
=
match f x with
| v -> fun ~re_render_limit:_ -> v
| effect Re_render_limit, k ->
fun ~re_render_limit -> continue k re_render_limit ~re_render_limit

let ptph_h (type a b) (f : b -> a) (x : b) : ptph:Path.t * phase -> a =
match f x with
| v ->
Expand Down Expand Up @@ -209,13 +221,19 @@ let rec eval : type a. a Expr.t -> value =
| Times, Int i1, Int i2 -> Int (i1 * i2)
| _, _, _ -> raise Type_error)

let rec eval_mult : type a. a Expr.t -> value =
fun expr ->
let rec eval_mult : type a. ?re_render:int -> a Expr.t -> value =
fun ?(re_render = 1) expr ->
Logger.eval_mult expr;

(* This is a hack only used for testing non-termination. *)
(try if re_render >= perform Re_render_limit then raise Too_many_re_renders
with Stdlib.Effect.Unhandled Re_render_limit -> ());

let v = eval expr in
let path = perform Rd_pt in
match perform (Get_dec path) with
| Retry -> ptph_h eval_mult expr ~ptph:(path, P_retry)
| Retry ->
ptph_h (eval_mult ~re_render:(re_render + 1)) expr ~ptph:(path, P_retry)
| Idle | Update -> v

let rec render (path : Path.t) (vss : view_spec list) : unit =
Expand Down
35 changes: 35 additions & 0 deletions test/test_react_trace.ml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,39 @@ open React_trace

let fuel = 100

let set_in_body_nonterminate () =
let prog =
let open Syntax in
Prog.(
Comp
( {
name = "C";
param = "x";
body =
Expr.(
Stt
{
label = 0;
stt = "s";
set = "setS";
init = Const (Int 42);
body =
Seq
( App
{
fn = Var "setS";
arg = Fn { param = "s"; body = Const (Int 43) };
},
View [ Const Unit ] );
});
},
Expr Expr.(View [ App { fn = Var "C"; arg = Const Unit } ]) ))
in
let run () =
Interp.(re_render_limit_h (run ~fuel) prog ~re_render_limit:25) |> ignore
in
Alcotest.(check_raises) "retry indefintely" Interp.Too_many_re_renders run

let set_in_effect_step_three_times () =
let prog =
let open Syntax in
Expand Down Expand Up @@ -84,6 +117,8 @@ let () =
[
( "steps",
[
test_case "Set in body should not terminate" `Quick
set_in_body_nonterminate;
test_case "Set in effect should step three times" `Quick
set_in_effect_step_three_times;
test_case "Set in effect should step indefintely" `Quick
Expand Down

0 comments on commit ef66d0a

Please sign in to comment.