ligo/test/proto_alpha_isolate/test_isolate_michelson.ml
2018-02-01 18:20:47 +01:00

502 lines
27 KiB
OCaml

(**************************************************************************)
(* *)
(* Copyright (c) 2014 - 2016. *)
(* Dynamic Ledger Solutions, Inc. <contact@tezos.com> *)
(* *)
(* All rights reserved. No warranty, explicit or implicit, provided. *)
(* *)
(**************************************************************************)
let name = "Isolate Michelson"
module Logger = Logging.Make(struct let name = name end)
let section = Lwt_log.Section.make name
let () =
Lwt_log.Section.set_level section Lwt_log.Debug(*.Warning*)
open Logger
open Isolate_helpers
open Shorthands
let (>>??) = Assert.(>>??)
let (>>=??) = Assert.(>>=??)
open Tezos_micheline
let parse_param s : Proto_alpha.Tezos_context.Script.expr =
let (parsed, _) = Michelson_v1_parser.parse_expression s in
parsed.expanded
let parse_script code_str storage_str : Proto_alpha.Tezos_context.Script.t =
let code = parse_param code_str in
let storage = parse_param storage_str in
let return: Proto_alpha.Tezos_context.Script.t = {code ; storage} in
return
let program param ret st code =
let storage s = " storage " ^ s ^ " ; \n" in
let parameter s = " parameter " ^ s ^ " ; \n" in
let return s = " return " ^ s ^ " ; \n" in
"{\n" ^ (storage st) ^ (parameter param) ^ (return ret) ^ " " ^ code ^ "}"
let quote s = "\"" ^ s ^ "\""
let test parse_execute =
let dir_path = "test/contracts/" in
let test ?tc (file_name: string) (storage: string) (input: string) =
let full_path = dir_path ^ file_name ^ ".tz" in
let file = Helpers_misc.read_file full_path in
let spaced_file = Str.global_replace (Str.regexp_string "\n") "\n " file in
let program = "{" ^ spaced_file ^ "}" in
parse_execute ?tc program input storage
in
test
let test_fails ?location parse_execute f s i =
test parse_execute f s i >>= fun x ->
let msg = Option.unopt ~default:"Not failing" location in
Assert.generic_economic_error ~msg x ;
return ()
let string_of_canon output_prim =
let output_can = Proto_alpha.Michelson_v1_primitives.strings_of_prims output_prim in
let location_maker _ =
let ret : Micheline_printer.location = {comment=None} in
ret in
let output_node = Micheline.inject_locations location_maker output_can in
Format.fprintf
Format.str_formatter "%a" Micheline_printer.print_expr output_node ;
let output = Format.flush_str_formatter () in
output
let test_print parse_execute fn s i =
test parse_execute fn s i >>=? fun (sp, op, _) ->
let ss = string_of_canon sp in
let os = string_of_canon op in
debug "Storage : %s" ss ;
debug "Output : %s" os ;
return ()
let test_output parse_execute ?location (file_name: string) (storage: string) (input: string) (expected_output: string) =
test parse_execute file_name storage input >>=? fun (_storage_prim, output_prim, _tc, _contracts) ->
let output = string_of_canon output_prim in
let msg = Option.unopt ~default:"strings aren't equal" location in
Assert.equal_string ~msg expected_output output ;
return ()
let test_tc ?tc parse_execute (file_name: string) (storage: string) (input: string) =
test parse_execute ?tc file_name storage input >>=? fun (_storage_prim, _output_prim, tc, _contracts) ->
return (tc)
let test_contract ?tc parse_execute (file_name: string) (storage: string) (input: string) =
test parse_execute ?tc file_name storage input >>=? fun (_storage_prim, _output_prim, tc, contracts) ->
return (contracts, tc)
let test_storage parse_execute ?location (file_name: string) (storage: string) (input: string) (expected_storage: string) =
test parse_execute file_name storage input >>=? fun (storage_prim, _output_prim, _tc, _contracts) ->
let storage = string_of_canon storage_prim in
let msg = Option.unopt ~default:"strings aren't equal" location in
Assert.equal_string ~msg expected_storage storage ;
return ()
let test_example parse_execute sb =
let test_output ?location a b c d =
test_output ?location parse_execute a b c d >>= function
| Ok(x) -> return x
| Error(errs) -> (
match location with
| None -> ()
| Some(loc) -> debug "loc : %s" loc
) ; Lwt.return (Error(errs))
in
let test_fails ?location = test_fails ?location parse_execute in
let test_tc ?tc = test_tc ?tc parse_execute in
let test_contract ?tc = test_contract ?tc parse_execute in
(* let test_print ?location = test_print ?location parse_execute in*)
let test_storage ?location = test_storage ?location parse_execute in
(* FORMAT: assert_output contract_file storage input expected_result *)
test_output ~location: __LOC__ "ret_int" "Unit" "Unit" "300" >>=? fun _ ->
(* Identity on strings *)
test_output ~location: __LOC__ "str_id" "Unit" "\"Hello\"" "\"Hello\"" >>=? fun _ ->
test_output ~location: __LOC__ "str_id" "Unit" "\"abcd\"" "\"abcd\"" >>=? fun _ ->
(* Identity on pairs *)
test_output ~location: __LOC__ "pair_id" "Unit" "(Pair True False)" "(Pair True False)" >>=? fun _ ->
test_output ~location: __LOC__ "pair_id" "Unit" "(Pair False True)" "(Pair False True)" >>=? fun _ ->
test_output ~location: __LOC__ "pair_id" "Unit" "(Pair True True)" "(Pair True True)" >>=? fun _ ->
test_output ~location: __LOC__ "pair_id" "Unit" "(Pair False False)" "(Pair False False)" >>=? fun _ ->
(* Logical not *)
test_output ~location: __LOC__ "not" "Unit" "True" "False" >>=? fun _ ->
test_output ~location: __LOC__ "not" "Unit" "False" "True" >>=? fun _ ->
(* Logical and *)
test_output ~location: __LOC__ "and" "Unit" "(Pair False False)" "False" >>=? fun _ ->
test_output ~location: __LOC__ "and" "Unit" "(Pair False True)" "False" >>=? fun _ ->
test_output ~location: __LOC__ "and" "Unit" "(Pair True False)" "False" >>=? fun _ ->
test_output ~location: __LOC__ "and" "Unit" "(Pair True True)" "True" >>=? fun _ ->
(* Logical or *)
test_output ~location: __LOC__ "or" "Unit" "(Pair False False)" "False" >>=? fun _ ->
test_output ~location: __LOC__ "or" "Unit" "(Pair False True)" "True" >>=? fun _ ->
test_output ~location: __LOC__ "or" "Unit" "(Pair True False)" "True" >>=? fun _ ->
test_output ~location: __LOC__ "or" "Unit" "(Pair True True)" "True" >>=? fun _ ->
(* XOR *)
test_output ~location: __LOC__ "xor" "Unit" "(Pair False False)" "False" >>=? fun _ ->
test_output ~location: __LOC__ "xor" "Unit" "(Pair False True)" "True" >>=? fun _ ->
test_output ~location: __LOC__ "xor" "Unit" "(Pair True False)" "True" >>=? fun _ ->
test_output ~location: __LOC__ "xor" "Unit" "(Pair True True)" "False" >>=? fun _ ->
(* Build list *)
test_output ~location: __LOC__ "build_list" "Unit" "0" "{ 0 }" >>=? fun _ ->
test_output ~location: __LOC__ "build_list" "Unit" "3" "{ 0 ; 1 ; 2 ; 3 }" >>=? fun _ ->
test_output ~location: __LOC__ "build_list" "Unit" "10" "{ 0 ; 1 ; 2 ; 3 ; 4 ; 5 ; 6 ; 7 ; 8 ; 9 ; 10 }" >>=? fun _ ->
(* Concatenate all strings of a list into one string *)
test_output ~location: __LOC__ "concat_list" "Unit" "{ \"a\" ; \"b\" ; \"c\" }" "\"abc\"" >>=? fun _ ->
test_output ~location: __LOC__ "concat_list" "Unit" "{}" "\"\"" >>=? fun _ ->
test_output ~location: __LOC__ "concat_list" "Unit" "{ \"Hello\" ; \" \" ; \"World\" ; \"!\" }" "\"Hello World!\"" >>=? fun _ ->
(* Find maximum int in list -- returns None if not found *)
test_output ~location: __LOC__ "max_in_list" "Unit" "{}" "None" >>=? fun _ ->
test_output ~location: __LOC__ "max_in_list" "Unit" "{ 1 }" "(Some 1)" >>=? fun _ ->
test_output ~location: __LOC__ "max_in_list" "Unit" "{ -1 }" "(Some -1)" >>=? fun _ ->
test_output ~location: __LOC__ "max_in_list" "Unit" "{ 10 ; -1 ; -20 ; 100 ; 0 }" "(Some 100)" >>=? fun _ ->
test_output ~location: __LOC__ "max_in_list" "Unit" "{ 10 ; -1 ; -20 ; 100 ; 0 }" "(Some 100)" >>=? fun _ ->
test_output ~location: __LOC__ "max_in_list" "Unit" "{ -10 ; -1 ; -20 ; -100 }" "(Some -1)" >>=? fun _ ->
(* Identity on lists *)
test_output ~location: __LOC__ "list_id" "Unit" "{ \"1\" ; \"2\" ; \"3\" }" "{ \"1\" ; \"2\" ; \"3\" }" >>=? fun _ ->
test_output ~location: __LOC__ "list_id" "Unit" "{}" "{}" >>=? fun _ ->
test_output ~location: __LOC__ "list_id" "Unit" "{ \"a\" ; \"b\" ; \"c\" }" "{ \"a\" ; \"b\" ; \"c\" }" >>=? fun _ ->
test_output ~location: __LOC__ "list_id_map" "Unit" "{ \"1\" ; \"2\" ; \"3\" }" "{ \"1\" ; \"2\" ; \"3\" }" >>=? fun _ ->
test_output ~location: __LOC__ "list_id_map" "Unit" "{}" "{}" >>=? fun _ ->
test_output ~location: __LOC__ "list_id_map" "Unit" "{ \"a\" ; \"b\" ; \"c\" }" "{ \"a\" ; \"b\" ; \"c\" }" >>=? fun _ ->
(* Identity on maps *)
test_output ~location: __LOC__ "map_id" "Unit" "{ Elt 0 1 }" "{ Elt 0 1 }" >>=? fun _ ->
test_output ~location: __LOC__ "map_id" "Unit" "{ Elt 0 0 }" "{ Elt 0 0 }" >>=? fun _ ->
test_output ~location: __LOC__ "map_id" "Unit" "{ Elt 0 0 ; Elt 3 4 }" "{ Elt 0 0 ; Elt 3 4 }" >>=? fun _ ->
(* Map block on lists *)
test_output ~location: __LOC__ "list_map_block" "Unit" "{}" "{}" >>=? fun _ ->
test_output ~location: __LOC__ "list_map_block" "Unit" "{ 1 ; 1 ; 1 ; 1 }" "{ 1 ; 2 ; 3 ; 4 }" >>=? fun _ ->
test_output ~location: __LOC__ "list_map_block" "Unit" "{ 1 ; 2 ; 3 ; 0 }" "{ 1 ; 3 ; 5 ; 3 }" >>=? fun _ ->
(* List iter *)
test_output ~location: __LOC__ "list_iter" "Unit" "{ 10 ; 2 ; 1 }" "20" >>=? fun _ ->
test_output ~location: __LOC__ "list_iter" "Unit" "{ 3 ; 6 ; 9 }" "162" >>=? fun _ ->
test_output ~location: __LOC__ "list_iter2" "Unit" "{ \"a\" ; \"b\" ; \"c\" }" "\"cba\"" >>=? fun _ ->
test_output ~location: __LOC__ "list_iter2" "Unit" "{}" "\"\"" >>=? fun _ ->
(* Identity on sets *)
test_output ~location: __LOC__ "set_id" "Unit" "{ \"a\" ; \"b\" ; \"c\" }" "{ \"a\" ; \"b\" ; \"c\" }" >>=? fun _ ->
test_output ~location: __LOC__ "set_id" "Unit" "{}" "{}" >>=? fun _ ->
test_output ~location: __LOC__ "set_id" "Unit" "{ \"asdf\" ; \"bcde\" }" "{ \"asdf\" ; \"bcde\" }" >>=? fun _ ->
(* Set member -- set is in storage *)
test_output ~location: __LOC__ "set_member" "{}" "\"Hi\"" "False" >>=? fun _ ->
test_output ~location: __LOC__ "set_member" "{ \"Hi\" }" "\"Hi\"" "True" >>=? fun _ ->
test_output ~location: __LOC__ "set_member" "{ \"Hello\" ; \"World\" }" "\"\"" "False" >>=? fun _ ->
(* Set size *)
test_output ~location: __LOC__ "set_size" "Unit" "{}" "0" >>=? fun _ ->
test_output ~location: __LOC__ "set_size" "Unit" "{ 1 }" "1" >>=? fun _ ->
test_output ~location: __LOC__ "set_size" "Unit" "{ 1 ; 2 ; 3 }" "3" >>=? fun _ ->
test_output ~location: __LOC__ "set_size" "Unit" "{ 1 ; 2 ; 3 ; 4 ; 5 ; 6 }" "6" >>=? fun _ ->
(* Set iter *)
test_output ~location: __LOC__ "set_iter" "Unit" "{}" "0" >>=? fun _ ->
test_output ~location: __LOC__ "set_iter" "Unit" "{ 1 }" "1" >>=? fun _ ->
test_output ~location: __LOC__ "set_iter" "Unit" "{ -100 ; 1 ; 2 ; 3 }" "-94" >>=? fun _ ->
(* Map size *)
test_output ~location: __LOC__ "map_size" "Unit" "{}" "0" >>=? fun _ ->
test_output ~location: __LOC__ "map_size" "Unit" "{ Elt \"a\" 1 }" "1" >>=? fun _ ->
test_output ~location: __LOC__ "map_size" "Unit" "{ Elt \"a\" 1 ; Elt \"b\" 2 ; Elt \"c\" 3 }" "3" >>=? fun _ ->
test_output ~location: __LOC__ "map_size" "Unit" "{ Elt \"a\" 1 ; Elt \"b\" 2 ; Elt \"c\" 3 ; Elt \"d\" 4 ; Elt \"e\" 5 ; Elt \"f\" 6 }" "6" >>=? fun _ ->
(* Contains all elements -- does the second list contain all of the same elements *)
(* as the first one? I'm ignoring element multiplicity *)
test_output ~location: __LOC__ "contains_all" "Unit" "(Pair {} {})" "True" >>=? fun _ ->
test_output ~location: __LOC__ "contains_all" "Unit" "(Pair { \"a\" } { \"B\" })" "False" >>=? fun _ ->
test_output ~location: __LOC__ "contains_all" "Unit" "(Pair { \"A\" } { \"B\" })" "False" >>=? fun _ ->
test_output ~location: __LOC__ "contains_all" "Unit" "(Pair { \"B\" } { \"B\" })" "True" >>=? fun _ ->
test_output ~location: __LOC__ "contains_all" "Unit" "(Pair { \"B\" ; \"C\" ; \"asdf\" } { \"B\" ; \"B\" ; \"asdf\" ; \"C\" })" "True" >>=? fun _ ->
test_output ~location: __LOC__ "contains_all" "Unit" "(Pair { \"B\" ; \"B\" ; \"asdf\" ; \"C\" } { \"B\" ; \"C\" ; \"asdf\" })" "True" >>=? fun _ ->
(* Concatenate the string in storage with all strings in the given list *)
test_output ~location: __LOC__ "concat_hello" "Unit" "{ \"World!\" }" "{ \"Hello World!\" }" >>=? fun _ ->
test_output ~location: __LOC__ "concat_hello" "Unit" "{}" "{}" >>=? fun _ ->
test_output ~location: __LOC__ "concat_hello" "Unit" "{ \"test1\" ; \"test2\" }" "{ \"Hello test1\" ; \"Hello test2\" }" >>=? fun _ ->
(* Create an empty map and add a string to it *)
test_output ~location: __LOC__ "empty_map" "Unit" "Unit" "{ Elt \"hello\" \"world\" }" >>=? fun _ ->
(* Get the value stored at the given key in the map *)
test_output ~location: __LOC__ "get_map_value" "{ Elt \"hello\" \"hi\" }" "\"hello\"" "(Some \"hi\")" >>=? fun _ ->
test_output ~location: __LOC__ "get_map_value" "{ Elt \"hello\" \"hi\" }" "\"\"" "None" >>=? fun _ ->
test_output ~location: __LOC__ "get_map_value" "{ Elt \"1\" \"one\" ; Elt \"2\" \"two\" }" "\"1\"" "(Some \"one\")" >>=? fun _ ->
(* Map iter *)
test_output ~location: __LOC__ "map_iter" "Unit" "{ Elt 0 100 ; Elt 2 100 }" "(Pair 2 200)" >>=? fun _ ->
test_output ~location: __LOC__ "map_iter" "Unit" "{ Elt 1 1 ; Elt 2 100 }" "(Pair 3 101)" >>=? fun _ ->
(* Return True if True branch of if was taken and False otherwise *)
test_output ~location: __LOC__ "if" "Unit" "True" "True" >>=? fun _ ->
test_output ~location: __LOC__ "if" "Unit" "False" "False" >>=? fun _ ->
(* Generate a pair of or types *)
test_output ~location: __LOC__ "swap_left_right" "Unit" "(Left True)" "(Right True)" >>=? fun _ ->
test_output ~location: __LOC__ "swap_left_right" "Unit" "(Right \"a\")" "(Left \"a\")" >>=? fun _ ->
(* Reverse a list *)
test_output ~location: __LOC__ "reverse" "Unit" "{}" "{}" >>=? fun _ ->
test_output ~location: __LOC__ "reverse" "Unit" "{ \"c\" ; \"b\" ; \"a\" }" "{ \"a\" ; \"b\" ; \"c\" }" >>=? fun _ ->
test_output ~location: __LOC__ "reverse_loop" "Unit" "{}" "{}" >>=? fun _ ->
test_output ~location: __LOC__ "reverse_loop" "Unit" "{ \"c\" ; \"b\" ; \"a\" }" "{ \"a\" ; \"b\" ; \"c\" }" >>=? fun _ ->
(* Reverse using LOOP_LEFT *)
test_output ~location: __LOC__ "loop_left" "Unit" "{}" "{}" >>=? fun _ ->
test_output ~location: __LOC__ "loop_left" "Unit" "{ \"c\" ; \"b\" ; \"a\" }" "{ \"a\" ; \"b\" ; \"c\" }" >>=? fun _ ->
(* Exec concat contract *)
test_output ~location: __LOC__ "exec_concat" "Unit" "\"\"" "\"_abc\"" >>=? fun _ ->
test_output ~location: __LOC__ "exec_concat" "Unit" "\"test\"" "\"test_abc\"" >>=? fun _ ->
(* Get current steps to quota *)
test_output ~location: __LOC__ "steps_to_quota" "Unit" "Unit" "39991" >>=? fun _ ->
let bootstrap_0 = List.nth Account.bootstrap_accounts 0 in
get_balance_res bootstrap_0 sb >>=?? fun _balance ->
let amount = Proto_alpha.Tezos_context.Tez.to_string @@ Cast.cents_of_int Script.init_amount in
(* Get the current balance of the contract *)
test_output ~location: __LOC__ "balance" "Unit" "Unit" ("\"" ^ amount ^ "\"") >>=? fun _ ->
(* Test comparisons on tez { EQ ; GT ; LT ; GE ; LE } *)
test_output ~location: __LOC__ "compare" "Unit" "(Pair \"1.00\" \"2.00\")" "{ False ; False ; True ; False ; True }" >>=? fun _ ->
test_output ~location: __LOC__ "compare" "Unit" "(Pair \"2.00\" \"1.00\")" "{ False ; True ; False ; True ; False }" >>=? fun _ ->
test_output ~location: __LOC__ "compare" "Unit" "(Pair \"2.37\" \"2.37\")" "{ True ; False ; False ; True ; True }" >>=? fun _ ->
(* Test addition and subtraction on tez *)
test_output ~location: __LOC__ "tez_add_sub" "Unit" "(Pair \"2\" \"1\")" "(Pair \"3\" \"1\")" >>=? fun _ ->
test_output ~location: __LOC__ "tez_add_sub" "Unit" "(Pair \"2.31\" \"1.01\")" "(Pair \"3.32\" \"1.3\")" >>=? fun _ ->
(* Test get first element of list *)
test_output ~location: __LOC__ "first" "Unit" "{ 1 ; 2 ; 3 ; 4 }" "1" >>=? fun _ ->
test_output ~location: __LOC__ "first" "Unit" "{ 4 }" "4" >>=? fun _ ->
(* Hash input string *)
(* Test assumed to be correct -- hash is based on encoding of AST *)
test_output ~location: __LOC__ "hash_string" "Unit" "\"abcdefg\"" "\"exprv3MnhXvjthGzZ7jDtXRRFremZyey9rsGtL7JRkeaQX1fThN7WF\"" >>=? fun _ ->
test_output ~location: __LOC__ "hash_string" "Unit" "\"12345\"" "\"expru81QVHsW2qaWLNHnMHSxDNhqtat17ajadri6mKUvXyc2EWHZC3\"" >>=? fun _ ->
(* Test ASSERT *)
test_output ~location: __LOC__ "assert" "Unit" "True" "Unit" >>=? fun _ ->
test_fails ~location: __LOC__ "assert" "Unit" "False" >>=? fun _ ->
(* COMPARE ; ASSERT_ *)
test_output ~location: __LOC__ "assert_eq" "Unit" "(Pair -1 -1)" "Unit" >>=? fun _ ->
test_fails ~location: __LOC__ "assert_eq" "Unit" "(Pair 0 -1)" >>=? fun _ ->
test_output ~location: __LOC__ "assert_eq" "Unit" "(Pair -1 -1)" "Unit" >>=? fun _ ->
test_fails ~location: __LOC__ "assert_eq" "Unit" "(Pair 0 -1)" >>=? fun _ ->
test_output ~location: __LOC__ "assert_neq" "Unit" "(Pair 0 -1)" "Unit" >>=? fun _ ->
test_fails ~location: __LOC__ "assert_neq" "Unit" "(Pair -1 -1)" >>=? fun _ ->
test_output ~location: __LOC__ "assert_lt" "Unit" "(Pair -1 0)" "Unit" >>=? fun _ ->
test_fails ~location: __LOC__ "assert_lt" "Unit" "(Pair 0 -1)" >>=? fun _ ->
test_fails ~location: __LOC__ "assert_lt" "Unit" "(Pair 0 0)" >>=? fun _ ->
test_output ~location: __LOC__ "assert_le" "Unit" "(Pair 0 0)" "Unit" >>=? fun _ ->
test_output ~location: __LOC__ "assert_le" "Unit" "(Pair -1 0)" "Unit" >>=? fun _ ->
test_fails ~location: __LOC__ "assert_le" "Unit" "(Pair 0 -1)" >>=? fun _ ->
test_output ~location: __LOC__ "assert_gt" "Unit" "(Pair 0 -1)" "Unit" >>=? fun _ ->
test_fails ~location: __LOC__ "assert_gt" "Unit" "(Pair -1 0)" >>=? fun _ ->
test_fails ~location: __LOC__ "assert_gt" "Unit" "(Pair 0 0)" >>=? fun _ ->
test_output ~location: __LOC__ "assert_ge" "Unit" "(Pair 0 0)" "Unit" >>=? fun _ ->
test_output ~location: __LOC__ "assert_ge" "Unit" "(Pair 0 -1)" "Unit" >>=? fun _ ->
test_fails ~location: __LOC__ "assert_ge" "Unit" "(Pair -1 0)" >>=? fun _ ->
(* ASSERT_CMP *)
test_output ~location: __LOC__ "assert_cmpeq" "Unit" "(Pair -1 -1)" "Unit" >>=? fun _ ->
test_fails ~location: __LOC__ "assert_cmpeq" "Unit" "(Pair 0 -1)" >>=? fun _ ->
test_output ~location: __LOC__ "assert_cmpeq" "Unit" "(Pair -1 -1)" "Unit" >>=? fun _ ->
test_fails ~location: __LOC__ "assert_cmpeq" "Unit" "(Pair 0 -1)" >>=? fun _ ->
test_output ~location: __LOC__ "assert_cmpneq" "Unit" "(Pair 0 -1)" "Unit" >>=? fun _ ->
test_fails ~location: __LOC__ "assert_cmpneq" "Unit" "(Pair -1 -1)" >>=? fun _ ->
test_output ~location: __LOC__ "assert_cmplt" "Unit" "(Pair -1 0)" "Unit" >>=? fun _ ->
test_fails ~location: __LOC__ "assert_cmplt" "Unit" "(Pair 0 -1)" >>=? fun _ ->
test_fails ~location: __LOC__ "assert_cmplt" "Unit" "(Pair 0 0)" >>=? fun _ ->
test_output ~location: __LOC__ "assert_cmple" "Unit" "(Pair 0 0)" "Unit" >>=? fun _ ->
test_output ~location: __LOC__ "assert_cmple" "Unit" "(Pair -1 0)" "Unit" >>=? fun _ ->
test_fails ~location: __LOC__ "assert_cmple" "Unit" "(Pair 0 -1)" >>=? fun _ ->
test_output ~location: __LOC__ "assert_cmpgt" "Unit" "(Pair 0 -1)" "Unit" >>=? fun _ ->
test_fails ~location: __LOC__ "assert_cmpgt" "Unit" "(Pair -1 0)" >>=? fun _ ->
test_fails ~location: __LOC__ "assert_cmpgt" "Unit" "(Pair 0 0)" >>=? fun _ ->
test_output ~location: __LOC__ "assert_cmpge" "Unit" "(Pair 0 0)" "Unit" >>=? fun _ ->
test_output ~location: __LOC__ "assert_cmpge" "Unit" "(Pair 0 -1)" "Unit" >>=? fun _ ->
test_fails ~location: __LOC__ "assert_cmpge" "Unit" "(Pair -1 0)" >>=? fun _ ->
(* IF_SOME *)
test_output ~location: __LOC__ "if_some" "Unit" "(Some \"hello\")" "\"hello\"" >>=? fun _ ->
test_output ~location: __LOC__ "if_some" "Unit" "None" "\"\"" >>=? fun _ ->
(* Tests the SET_CAR and SET_CDR instructions *)
test_output ~location: __LOC__ "set_car" "(Pair \"hello\" 0)" "\"world\"" "(Pair \"world\" 0)" >>=? fun _ ->
test_output ~location: __LOC__ "set_car" "(Pair \"hello\" 0)" "\"abc\"" "(Pair \"abc\" 0)" >>=? fun _ ->
test_output ~location: __LOC__ "set_car" "(Pair \"hello\" 0)" "\"\"" "(Pair \"\" 0)" >>=? fun _ ->
test_output ~location: __LOC__ "set_cdr" "(Pair \"hello\" 0)" "1" "(Pair \"hello\" 1)" >>=? fun _ ->
test_output ~location: __LOC__ "set_cdr" "(Pair \"hello\" 500)" "3" "(Pair \"hello\" 3)" >>=? fun _ ->
test_output ~location: __LOC__ "set_cdr" "(Pair \"hello\" 7)" "100" "(Pair \"hello\" 100)" >>=? fun _ ->
test_storage ~location: __LOC__ "set_caddaadr" "(Pair (Pair 1 (Pair 2 (Pair (Pair (Pair 3 \"0\") 4) 5))) 6)" "\"3\"" "(Pair (Pair 1 (Pair 2 (Pair (Pair (Pair 3 \"3\") 4) 5))) 6)" >>=? fun _ ->
test_storage ~location: __LOC__ "map_caddaadr" "(Pair (Pair 1 (Pair 2 (Pair (Pair (Pair 3 \"0\") 4) 5))) 6)" "Unit" "(Pair (Pair 1 (Pair 2 (Pair (Pair (Pair 3 \"1\") 4) 5))) 6)" >>=? fun _ ->
(* Did the given key sign the string? (key is bootstrap1) *)
test_output ~location: __LOC__ "check_signature" "(Pair \"26981d372a7b3866621bf79713d249197fe6d518ef702fa65738e1715bde9da54df04fefbcc84287ecaa9f74ad9296462731aa24bbcece63c6bf73a8f5752309\" \"hello\")" "\"edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav\"" "True" >>=? fun _ ->
test_output ~location: __LOC__ "check_signature" "(Pair \"26981d372a7b3866621bf79713d249197fe6d518ef702fa65738e1715bde9da54df04fefbcc84287ecaa9f74ad9296462731aa24bbcece63c6bf73a8f5752309\" \"abcd\")" "\"edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav\"" "False" >>=? fun _ ->
(* Convert a public key to a public key hash *)
test_output ~location: __LOC__ "hash_key" "Unit" "\"edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav\"" "\"tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx\"" >>=? fun _ ->
test_output ~location: __LOC__ "hash_key" "Unit" "\"edpkuJqtDcA2m2muMxViSM47MPsGQzmyjnNTawUPqR8vZTAMcx61ES\"" "\"tz1XPTDmvT3vVE5Uunngmixm7gj7zmdbPq6k\"" >>=? fun _ ->
(* Test timestamp operations *)
test_output ~location: __LOC__ "add_timestamp_delta" "Unit" "(Pair 100 100)" "\"1970-01-01T00:03:20Z\"" >>=? fun _ ->
test_output ~location: __LOC__ "add_timestamp_delta" "Unit" "(Pair 100 -100)" "\"1970-01-01T00:00:00Z\"" >>=? fun _ ->
test_output ~location: __LOC__ "add_timestamp_delta" "Unit" "(Pair \"1970-01-01T00:00:00Z\" 0)" "\"1970-01-01T00:00:00Z\"" >>=? fun _ ->
test_output ~location: __LOC__ "add_delta_timestamp" "Unit" "(Pair 100 100)" "\"1970-01-01T00:03:20Z\"" >>=? fun _ ->
test_output ~location: __LOC__ "add_delta_timestamp" "Unit" "(Pair -100 100)" "\"1970-01-01T00:00:00Z\"" >>=? fun _ ->
test_output ~location: __LOC__ "add_delta_timestamp" "Unit" "(Pair 0 \"1970-01-01T00:00:00Z\")" "\"1970-01-01T00:00:00Z\"" >>=? fun _ ->
test_output ~location: __LOC__ "sub_timestamp_delta" "Unit" "(Pair 100 100)" "\"1970-01-01T00:00:00Z\"" >>=? fun _ ->
test_output ~location: __LOC__ "sub_timestamp_delta" "Unit" "(Pair 100 -100)" "\"1970-01-01T00:03:20Z\"" >>=? fun _ ->
test_output ~location: __LOC__ "sub_timestamp_delta" "Unit" "(Pair 100 2000000000000000000)" "-1999999999999999900" >>=? fun _ ->
test_output ~location: __LOC__ "diff_timestamps" "Unit" "(Pair 0 0)" "0" >>=? fun _ ->
test_output ~location: __LOC__ "diff_timestamps" "Unit" "(Pair 0 1)" "-1" >>=? fun _ ->
test_output ~location: __LOC__ "diff_timestamps" "Unit" "(Pair 1 0)" "1" >>=? fun _ ->
test_output ~location: __LOC__ "diff_timestamps" "Unit" "(Pair \"1970-01-01T00:03:20Z\" \"1970-01-01T00:00:00Z\")" "200" >>=? fun _ ->
(* Test NOW *)
let now = sb.tezos_header.shell.timestamp in
let now_str = quote @@ Tezos_base.Time.to_notation now in
test_storage ~location: __LOC__ "store_now" "\"1970-01-01T00:03:20Z\"" "Unit" now_str >>=? fun _ ->
(* Test TRANSFER_TO *)
Account.make_account ~tc: sb.tezos_context >>=?? fun (account, tc) ->
let account_str = quote @@ Ed25519.Public_key_hash.to_b58check account.hpub in
test_tc ~tc "transfer_to" "Unit" account_str >>=? fun tc ->
let amount = Account.init_amount + 100 in
Assert.equal_cents_balance ~tc (account.contract, amount * 100) >>=?? fun _ ->
(* Test CREATE_ACCOUNT *)
Account.make_account ~tc: sb.tezos_context >>=?? fun (account, tc) ->
let account_str = quote @@ Ed25519.Public_key_hash.to_b58check account.hpub in
test_contract ~tc "create_account" account_str account_str >>=? fun (cs, tc) ->
Assert.equal_int 1 @@ List.length cs ;
(* Test CREATE_CONTRACT *)
test_contract ~tc "create_contract" account_str account_str >>=? fun (cs, tc) ->
Assert.equal_int 1 @@ List.length cs ;
let contract = List.hd cs in
Proto_alpha.Tezos_context.Contract.get_script tc contract >>=?? fun res ->
let script = Option.unopt_exn (Failure "get_script") res in
Script.execute_code_pred ~tc sb script (parse_param "\"abc\"") >>=?? fun (_, ret, _, _, _) ->
Assert.equal_string ~msg: __LOC__ "\"abc\"" @@ string_of_canon ret ;
(* Test DEFAULT_ACCOUNT *)
let account = Account.new_account () in
let b_str = quote @@ Ed25519.Public_key_hash.to_b58check account.hpub in
test_contract ~tc "default_account" "Unit" b_str >>=? fun (_cs, tc) ->
Assert.equal_cents_balance ~tc (account.contract, 100 * 100) >>=?? fun _ ->
return ()
let test_program parse_execute =
let open Error_monad in
let id_code = "code
{ DUP ;
PAIR ;
CAR }" in
let id_int_program =
program "int" "int" "int" id_code in
let id_ill_param_program =
program "string" "int" "string" id_code in
let id_ill_return_program =
program "int" "string" "int" id_code in
let id_pbool_program =
program "(pair bool bool)" "(pair bool bool)" "unit" id_code in
let push_300_code = "code
{ CAR ;
PUSH nat 300 ;
PAIR }" in
let push_300 =
program "unit" "nat" "unit" push_300_code in
parse_execute id_int_program "2" "3" >>=? fun _ ->
parse_execute id_ill_param_program "2" "3" >>= fun x ->
Assert.ill_typed_data_error ~msg: "Good data type" x ;
parse_execute id_ill_return_program "2" "3" >>= fun x ->
Assert.ill_typed_return_error ~msg: "Good return type" x ;
parse_execute push_300 "Unit" "Unit" >>=? fun _ ->
parse_execute id_pbool_program "(Pair True True)" "Unit" >>=? fun _ ->
return ()
let main (): unit Error_monad.tzresult Lwt.t =
Init.main () >>=? fun sb ->
let execute_code ?tc = Script.execute_code_pred ?tc sb in
let parse_execute ?tc code_str param_str storage_str =
let param = parse_param param_str in
let script = parse_script code_str storage_str in
execute_code ?tc script param >>=?? fun (ret, st, _, tc, nonce) ->
let contracts = Proto_alpha.Tezos_context.Contract.originated_contracts nonce in
return (ret, st, tc, contracts)
in
test_program parse_execute >>=? fun _x ->
test_example parse_execute sb >>=? fun _x ->
return ()
let tests = [
"main", (fun _ -> main ()) ;
]
let main () =
Test.run "michelson." tests