Module Mavryk_alpha_test_helpers.Scenario_dsl

exception Test_failed
type ('input, 'output) scenarios =
  1. | Action : ('input -> 'output Mavryk_base.TzPervasives.tzresult Lwt.t) -> ('input, 'output) scenarios
  2. | Empty : ('t, 't) scenarios
  3. | Concat : (('a, 'b) scenarios * ('b, 'c) scenarios) -> ('a, 'c) scenarios
  4. | Branch : (('a, 'b) scenarios * ('a, 'b) scenarios) -> ('a, 'b) scenarios
  5. | Tag : string -> ('t, 't) scenarios
  6. | Slow : ('t, 't) scenarios

A scenario is a succession of actions. We define a branching path as a way to create multiple tests from the same point. This allows easy compositionality of behaviors with minimal code sharing. The Tag allows to give meaningful identifiers to the branches. It is good practice to tag each case in a branch (it's not necessary, but since test names must be unique, at most one branch can remain unnamed, and even then it can create conflicting names.)

type ('input, 'output) single_scenario =
  1. | End_scenario : ('t, 't) single_scenario
  2. | Cons : (('input -> 't Mavryk_base.TzPervasives.tzresult Lwt.t) * ('t, 'output) single_scenario) -> ('input, 'output) single_scenario

Unfolded scenario type

val cat_ss : 'a 'b 'c. ('a, 'b) single_scenario -> ('b, 'c) single_scenario -> ('a, 'c) single_scenario
val combine : ('a -> 'b -> 'c) -> 'd list -> 'e list -> 'f list
val unfold_scenarios : 'input 'output. ('input, 'output) scenarios -> (('input, 'output) single_scenario * string list * bool) list
val run_scenario : 'input 'output. ('input, 'output) single_scenario -> 'input -> 'output Mavryk_base.TzPervasives.tzresult Lwt.t
type test_closure = string * bool * (Tezt_mavryk.Protocol.t -> unit Lwt.t)
val unfolded_to_test : ((unit, unit) single_scenario * string list * bool) -> test_closure
val register_test : __FILE__:string -> tags:string list -> test_closure -> unit
val register_tests : __FILE__:string -> tags:string list -> test_closure list -> unit

Useful aliases and operators

val noop : ('a, 'a) scenarios
val no_tag : ('a, 'a) scenarios
val concat : 'a 'b 'c. ('a, 'b) scenarios -> ('b, 'c) scenarios -> ('a, 'c) scenarios
val branch : 'a 'b. ('a, 'b) scenarios -> ('a, 'b) scenarios -> ('a, 'b) scenarios
val (-->) : ('a, 'b) scenarios -> ('b, 'c) scenarios -> ('a, 'c) scenarios

Continuation connector: execute a then b

val (|+) : ('a, 'b) scenarios -> ('a, 'b) scenarios -> ('a, 'b) scenarios

Branching connector: creates two tests with different execution paths

val end_test : ('a, unit) scenarios

Ends the test. Dump the state, returns unit

val tests_of_scenarios : (string * (unit, 't) scenarios) list -> test_closure list

Transforms scenarios into tests

val exec : ('a -> 'b Mavryk_base.TzPervasives.tzresult Lwt.t) -> ('a, 'b) scenarios

Arbitrary execution

val exec_state : (('a * 'b) -> ('c, Mavryk_base.TzPervasives.tztrace) Stdlib.result Lwt.t) -> ('a * 'b, 'd * 'e) scenarios

Execute a function that does not modify the block, only the state

val exec_unit : ('a -> (unit, Mavryk_base.TzPervasives.tztrace) Stdlib.result Lwt.t) -> ('b, 'c) scenarios

Execute a function that does not modify neither the block nor the state. Usually used for checks/asserts

val fold : ('a -> ('b, 'c) scenarios) -> 'a0 list -> ('b0, 'c0) scenarios

fold f l folds f over l, fails on empty list

val fold_tag : ('a -> ('b, 'c) scenarios) -> (string * 'a) list -> ('b, 'c) scenarios

fold_tag f l folds f over l, l has a tag for each of its elements. Fails on empty list.

val fold_tag_f : ('a -> ('b, 'c) scenarios) -> ('a -> string) -> 'a list -> ('b, 'c) scenarios

fold_tag_f f tag l folds f over l, tag returns a tag for each element of l. Fails on empty list.

val unfold : ('a -> ('b, 'b) scenarios) -> 'a0 list -> ('b0, 'b1) scenarios

unfold f l maps f over l, and runs them in order