#!/usr/bin/env python3 import os from pathlib import Path import json from klvm_tools_rs import start_klvm_program, compose_run_function def do_nothing(p): pass def run_until_end(p,printing=do_nothing,spam=True): last = None location = None while not p.is_ended(): step_result = p.step() if step_result is not None: last = step_result if 'Print' in last: printing(last['Print']) if 'Operator-Location' in last: location = last['Operator-Location'] if spam: print(json.dumps(step_result)) return (last, location) def simple_test(): p = start_klvm_program('ff02ffff01ff02ff02ffff04ff02ffff04ff05ff80808080ffff04ffff01ff02ffff03ffff09ff05ffff010180ffff01ff0101ffff01ff12ff05ffff02ff02ffff04ff02ffff04ffff11ff05ffff010180ff808080808080ff0180ff018080', 'ff0580', {"de3687023fa0a095d65396f59415a859dd46fc84ed00504bf4c9724fca08c9de":"factorial"}) last, location = run_until_end(p) assert int(last['Final']) == 120 assert location.startswith('factorial') def complex_test(): mypath = Path(os.path.abspath(__file__)) testpath = mypath.parent.joinpath('steprun') symbols = json.loads(open(str(testpath.joinpath('fact.sym'))).read()) def fact_base_override(env): print('fact_base_override') return 99 p = start_klvm_program(open(str(testpath.joinpath('fact.klvm.hex'))).read(), 'ff0580', symbols, { "fact-base": fact_base_override }) last, location = run_until_end(p) assert int(last['Final']) == 11880 def test_with_printing(): mypath = Path(os.path.abspath(__file__)) testpath = mypath.parent.joinpath('mandelbrot') symbols = json.loads(open(str(testpath.joinpath('mandelbrot.sym'))).read()) p = start_klvm_program(open(str(testpath.joinpath('mandelbrot.klvm.hex'))).read(), 'ff82ff40ff8180ff82ff70ff81a0ff0880', symbols, {}) print_outputs = [] def do_print(p): print(p) print_outputs.append(p) last, location = run_until_end(p,printing=do_print,spam=False) expected_outcome = "||567AAC|68DEEE|78EEEE|78BEEE" want_prints = [ "((\"escape-at\" -152 -104) 14)", "((\"escape-at\" -160 -104) 14)", "((\"escape-at\" -168 -104) 14)", "((\"escape-at\" -176 -104) 11)", "((\"escape-at\" -184 -104) 8)", "((\"escape-at\" -192 -104) 7)", "((\"escape-at\" -152 -112) 14)", "((\"escape-at\" -160 -112) 14)", "((\"escape-at\" -168 -112) 14)", "((\"escape-at\" -176 -112) 14)", "((\"escape-at\" -184 -112) 8)", "((\"escape-at\" -192 -112) 7)", "((\"escape-at\" -152 -120) 14)", "((\"escape-at\" -160 -120) 14)", "((\"escape-at\" -168 -120) 14)", "((\"escape-at\" -176 -120) 13)", "((\"escape-at\" -184 -120) 8)", "((\"escape-at\" -192 -120) 6)", "((\"escape-at\" -152 -128) 12)", "((\"escape-at\" -160 -128) 10)", "((\"escape-at\" -168 -128) 10)", "((\"escape-at\" -176 -128) 7)", "((\"escape-at\" -184 -128) 6)", "((\"escape-at\" -192 -128) 5)", f"(\"result\" \"{expected_outcome}\")" ] assert print_outputs == want_prints to_hex = hex(int(last['Final'])) have_outcome = bytes.fromhex(to_hex[2:]).decode('utf8') assert have_outcome == expected_outcome def single_function_test(): mypath = Path(os.path.abspath(__file__)) testpath = mypath.parent.joinpath('steprun') symbols = json.loads(open(str(testpath.joinpath('twofun.sym'))).read()) start_program = open(str(testpath.joinpath('twofun.klvm.hex'))).read(); torun = compose_run_function(start_program, symbols, "second-fun"); p = start_klvm_program(torun, 'ff0780', symbols) last, location = run_until_end(p) assert int(last['Final']) == 12 if __name__ == '__main__': simple_test() complex_test() single_function_test() test_with_printing()