diff --git a/mito.go b/mito.go index b9910bd..814b5b0 100644 --- a/mito.go +++ b/mito.go @@ -211,10 +211,19 @@ func Main() int { fmt.Fprintln(os.Stderr, err) return 2 } - input = map[string]interface{}{root: input} + if *maxExecutions > 0 { + // Only provide remaining_executions if we have set a limit. + input = map[string]interface{}{ + root: input, + "remaining_executions": *maxExecutions - 1, + } + } else { + input = map[string]interface{}{root: input} + } } var cov lib.Coverage + budget := *maxExecutions - 1 for n := int(0); *maxExecutions < 0 || n < *maxExecutions; n++ { res, val, dump, c, err := eval(string(b), root, input, *fold, *dumpState != "", *coverage != "", libs...) if err := cov.Merge(c); err != nil { @@ -242,7 +251,17 @@ func Main() int { if more, _ := state["want_more"].(bool); !more { break } - input = map[string]any{"state": val} + if budget > 0 { + budget-- + input = map[string]any{ + "state": val, + "remaining_executions": budget, + } + } else { + input = map[string]any{ + "state": val, + } + } } if *coverage != "" { f, err := os.Create(*coverage) @@ -404,7 +423,10 @@ func eval(src, root string, input interface{}, fold, details, coverage bool, lib func compile(src, root string, fold, details, coverage bool, libs ...cel.EnvOption) (cel.Program, *cel.Ast, *lib.Coverage, error) { opts := append([]cel.EnvOption{ - cel.VariableDecls(decls.NewVariable(root, types.DynType)), + cel.VariableDecls( + decls.NewVariable(root, types.DynType), + decls.NewVariable("remaining_executions", types.IntType), + ), }, libs...) env, err := cel.NewEnv(opts...) if err != nil { diff --git a/testdata/remaining.txt b/testdata/remaining.txt new file mode 100644 index 0000000..6c3a87b --- /dev/null +++ b/testdata/remaining.txt @@ -0,0 +1,28 @@ +mito -data state.json -max_executions 3 src.cel +! stderr . +cmp stdout want.txt + +-- state.json -- +{"n": 0} +-- src.cel -- +int(state.n).as(n, { + "n": n+1, + "remaining": remaining_executions, + "want_more": n+1 < 5, +}) +-- want.txt -- +{ + "n": 1, + "remaining": 2, + "want_more": true +} +{ + "n": 2, + "remaining": 1, + "want_more": true +} +{ + "n": 3, + "remaining": 0, + "want_more": true +}