/test/erlv8_tests.erl
Erlang | 132 lines | 97 code | 29 blank | 6 comment | 1 complexity | db0d89e60c1f5bc8b4d970e3436e2edd MD5 | raw file
1-module(erlv8_tests). 2 3-include_lib("proper/include/proper.hrl"). 4-include_lib("eunit/include/eunit.hrl"). 5 6-behaviour(proper_statem). 7 8-export([initial_state/0, command/1, precondition/2, postcondition/3, 9 next_state/3]). 10 11-compile(export_all). 12 13-record(state, { 14 vms = [], 15 passed = [] 16 }). 17 18%% helpers 19start_vm() -> 20 {ok, VM} = erlv8_vm:start(), 21 VM. 22 23exit_vm(VM) -> 24 erlv8_vm:stop(VM), 25 VM. 26 27run_tests(VM) -> 28 ets:insert(?MODULE, {vm, VM}), 29 proper:module(?MODULE, 30 [{'on_output', 31 fun(Format, Data) -> 32 io:format(standard_error, Format, Data) 33 end}, 34 {numtests, 100}]). 35 36 37%% statem 38 39initial_state() -> 40 #state{}. 41 42command(#state{ vms = VMs, passed = Passed }) -> 43 frequency([ 44 {1 - (length(VMs) + length(Passed)), {call, ?MODULE, start_vm, []}}, 45 {length(Passed), {call, ?MODULE, exit_vm, [oneof(Passed)]}}, 46 {length(VMs), {call, ?MODULE, run_tests, [oneof(VMs)]}} 47 ]). 48 49precondition(_State, _Call) -> 50 true. 51 52postcondition(_S, {call, ?MODULE, run_tests, [_VM]}, []) -> 53 true; 54 55postcondition(_S, {call, ?MODULE, run_tests, [_VM]}, _) -> 56 false; 57 58postcondition(_S, _C, _R) -> 59 true. 60 61next_state(#state{ vms = VMs } = State, V, {call, ?MODULE, start_vm, []}) -> 62 State#state{ vms = [V|VMs] }; 63 64next_state(#state{ passed = VMs } = State, _V, {call, ?MODULE, exit_vm, [VM]}) -> 65 State#state{ passed = VMs -- [VM] }; 66 67next_state(#state{ vms = VMs, passed = Passed } = State, _V, {call, ?MODULE, run_tests, [VM]}) -> 68 State#state{ vms = VMs -- [VM], passed = [VM|Passed] }; 69 70next_state(State, _V, _C) -> 71 State. 72 73 74statem() -> 75 ?FORALL(Cmds, commands(?MODULE), 76 ?TRAPEXIT( 77 begin 78 {History,State,Result} = run_commands(?MODULE, Cmds), 79 [ erlv8_vm:stop(VM) || VM <- State#state.vms ], 80 ?WHENFAIL(io:format("History: ~p\nState: ~p\nResult: ~p\n", 81 [History, State, Result]), 82 aggregate(command_names(Cmds), Result =:= ok)) 83 end)). 84 85%%% generators 86js_string() -> 87 oneof([list(proper_stdgen:utf8_char()), 88 proper_stdgen:utf8_bin()]). 89 90%%% properties 91 92%% type conversion 93prop_to_js_string() -> 94 ?FORALL(String, js_string(), 95 begin 96 [{vm, VM}] = ets:lookup(?MODULE, vm), 97 Bin = unicode:characters_to_binary(String), 98 Obj = erlv8_vm:taint(VM, Bin), 99 case Obj =:= Bin of 100 true -> 101 ok; 102 false -> 103 io:format("->~p/~p~n", [Bin, Obj]), 104 ok 105 end, 106 Obj =:= Bin 107 end). 108 109 110%% eunit 111t_properties() -> 112 ?assertEqual(true, proper:quickcheck(statem(), 113 [{'on_output', 114 fun(Format, Data) -> 115 io:format(standard_error, Format, Data) 116 end}, 117 {numtests, 10}])). 118 119 120erlv8_test_() -> 121 [{setup, 122 fun() -> 123 ets:new(?MODULE,[named_table, public]), 124 ok = application:start(erlv8) 125 end, 126 fun(_) -> 127 ets:delete(?MODULE), 128 application:stop(erlv8) 129 end, 130 [ 131 {timeout, 30, {"PropEr tests", ?_test(t_properties())}} 132 ]}].