Testing framework: a library
This MR adds an explicit Test.
library in code.
As an example, we remove a few functions (e.g. Test.michelson_equal
, Test.get_storage
and Test.compile_value
) and replace them by LIGO code:
type test_exec_error = Rejected of (michelson_program * address) | Other
type test_exec_result = Success of nat | Fail of test_exec_error
module Internal__Test = struct
module CURRY = struct
let get_storage (type p s) (t : (p, s) typed_address) : s =
let c : p contract = Test.to_contract t in
let a : address = Tezos.address c in
let s : michelson_program = Test.get_storage_of_address a in
let s : s = Test.decompile s in
s
let eval (type a) (x : a) : michelson_program = Test.run (fun (x : a) -> x) x
let compile_value (type a) (x : a) : michelson_program = Test.run (fun (x : a) -> x) x
let to_address (type p s) (t : (p, s) typed_address) : address = Tezos.address (Test.to_contract t)
let transfer (a : address) (mp : michelson_program) (m : tez) : test_exec_result =
let ta : (unit, unit) typed_address = Test.cast_address a in
let c : unit contract = Test.to_contract ta in
Test.transfer_ c mp m
let transfer_exn (a : address) (mp : michelson_program) (m : tez) : nat =
let ta : (unit, unit) typed_address = Test.cast_address a in
let c : unit contract = Test.to_contract ta in
Test.transfer_exn_ c mp m
let transfer_to_contract (type p) (c : p contract) (p : p) (m : tez) : test_exec_result =
let mp : michelson_program = eval p in
Test.transfer_ c mp m
let transfer_to_contract_exn (type p) (c : p contract) (p : p) (m : tez) : nat =
let mp : michelson_program = eval p in
Test.transfer_exn_ c mp m
let transfer_to_typed_address_exn (type p s) (ta : (p, s) typed_address) (p : p) (m : tez) : nat =
let c : p contract = Test.to_contract ta in
transfer_to_contract_exn c p m
let michelson_equal (v : michelson_program) (w : michelson_program) : bool = v = w
end
module UNCURRY = struct
let get_storage (type p s) (t : (p, s) typed_address) : s = CURRY.get_storage t
let eval (type a) (x : a) : michelson_program = CURRY.eval x
let compile_value (type a) (x : a) : michelson_program = CURRY.compile_value x
let to_address (type p s) (t : (p, s) typed_address) : address = CURRY.to_address t
let transfer ((a, p, m) : address * michelson_program * tez) : test_exec_result = CURRY.transfer a p m
let transfer_exn ((a, p, m) : address * michelson_program * tez) : nat = CURRY.transfer_exn a p m
let transfer_to_contract (type p) ((c, p, m) : p contract * p * tez) : test_exec_result = CURRY.transfer_to_contract c p m
let transfer_to_contract_exn (type p) ((c, p, m) : p contract * p * tez) : nat = CURRY.transfer_to_contract_exn c p m
let transfer_to_typed_address_exn (type p s) ((ta, p, m) : (p, s) typed_address * p * tez) : nat = CURRY.transfer_to_typed_address_exn ta p m
let michelson_equal ((v, w) : michelson_program * michelson_program) : bool = CURRY.michelson_equal v w
end
end
We also add two functions to Test.
, which are to_address
and transfer_to_typed_address_exn
, as an example. These functions are not essential, and this is why they were not implemented, but it's nice to provide them to LIGO users. We also remove test_exec_error
and test_exec_result
from the environment, and add them as defined by the library.
Main changes:
- Abstractors: if built-in search fails, constructs regular accessor for module instead of failing.
- Typing: removed those custom typing rules for the constants.
- Vendored build system: only
postprocess : t -> t
is included (it could be kept out, but it could be useful for other things). - Environment: we define what a "library" is there:
type lib = {
code : module_ ;
install_lib : Self_ast_imperative.Syntax.v_syntax -> module_
}
The field code
is the library code (Internal__Test
thing above). The install_lib
is a code installing the library (used in each file, depends on the language to solve curried/uncurried calling convention of functions which are originally operators):
let install_lib = function
| CameLIGO ->
[Location.wrap @@ Ast_typed.Module_alias { alias = "Test" ; binders = List.Ne.of_list ["Internal__Test"; "CURRY"] } ]
| ReasonLIGO | PascaLIGO | JsLIGO ->
[Location.wrap @@ Ast_typed.Module_alias { alias = "Test" ; binders = List.Ne.of_list ["Internal__Test"; "UNCURRY"] } ] in
Environment.{ code ; install_lib }
-
Build: the function
build_context
has an optional parameter for the library. -
API: before calling
eval_test
, we ask for the test library. -
Example with
big_map
s: show how we can simply useTest.transfer_to_typed_address_exn
. -
has a changelog entry