Christopher Meiklejohn
February 02, 2014
110

A Brief Introduction to Dialyzer and Proper

Christopher Meiklejohn

February 02, 2014

Transcript

4. -opaque gcounter() :: orddict:orddict(). ! -type gcounter_op() :: increment |

{increment, pos_integer()}. ! %% @doc Create a new, empty `gcounter()' -spec new() -> gcounter(). new() -> orddict:new(). ! %% @doc Create a `gcounter()' with an initial update -spec new(term(), pos_integer()) -> gcounter(). new(Id, Count) when is_integer(Count), Count > 0 -> {ok, Cnt} = update({increment, Count}, Id, new()), Cnt.
5. %% @doc Create a `gcounter()' with an initial update -spec

new(term(), atom()) -> gcounter(). new(Id, Count) when is_integer(Count), Count > 0 -> {ok, Cnt} = update({increment, Count}, Id, new()), Cnt.
6. riak_dt_gcounter.erl:63: Invalid type specification for function riak_dt_gcounter:new/2. The success typing

is (_,pos_integer()) -> riak_dt_gcounter:gcounter()
7. %% @doc Create a `gcounter()' with an initial update -spec

new(riak_dt:actor(), pos_integer()) -> gcounter(). new(Id, Count) when is_integer(Count), Count > 0 -> {ok, Cnt} = update({increment, Count}, Id, new()), Cnt. ! %% @doc `increment' the entry in `GCnt' for `Actor' by 1 or `{increment, Amt}'. %% returns an updated `gcounter()' or error if `Amt' is not a `pos_integer()' -spec update(gcounter_op(), riak_dt:actor(), gcounter()) -> {ok, gcounter()}. update(increment, Actor, GCnt) -> {ok, increment_by(1, Actor, GCnt)}; update({increment, Amount}, Actor, GCnt) when is_integer(Amount), Amount > 0 -> {ok, increment_by(Amount, Actor, GCnt)}.
8. riak_dt_gcounter.erl:64: Function new/2 has no local return riak_dt_gcounter.erl:65: The call

riak_dt_gcounter:update({'incremet',pos_integer()},Id::any(),riak_dt_g counter:gcounter()) breaks the contract (gcounter_op(),riak_dt:actor(),gcounter()) -> {‘ok',gcounter()}
9. %% @doc Create a `gcounter()' with an initial update -spec

new(riak_dt:actor(), pos_integer()) -> gcounter(). new(Id, Count) when is_integer(Count), Count > 0 -> {ok, Cnt} = update({increment, Count}, Id, new()), Cnt. ! %% @doc `increment' the entry in `GCnt' for `Actor' by 1 or `{increment, Amt}'. %% returns an updated `gcounter()' or error if `Amt' is not a `pos_integer()' -spec update(gcounter_op(), riak_dt:actor(), gcounter()) -> {ok, gcounter()}. update(increment, Actor, GCnt) -> {ok, increment_by(1, Actor, GCnt)}.
10. riak_dt_gcounter.erl:64: Function new/2 has no local return riak_dt_pncounter.erl:216: The created

fun has no local return

16. -module(simple_props). ! %% Properties are automatically exported. -include_lib("proper/include/proper.hrl"). ! %%

Functions that start with prop_ are considered properties prop_t2b_b2t() -> ?FORALL(T, term(), T =:= binary_to_term(term_to_binary(T))).

test(s) true

19. -spec new() -> stack(_T). new() -> {0, []}. ! -spec

push(T, stack(T)) -> stack(T). push(X, {N,Elems}) -> {N+1, [X|Elems]}. ! -spec pop(stack(T)) -> {T,stack(T)}. pop({0, []}) -> throw(stack_empty); pop({N, [Top|Rest]}) when N > 0 -> {Top, {N-1,Rest}}.

Y end).
21. Eshell V5.10.3 (abort with ^G) 1> proper:quickcheck(stack:prop_push_pop()). ...................................................................... .............................. OK:

Passed 100 test(s). true

26. 16> proper:quickcheck(lists_proper:prop_delete()). ........! Failed: After 9 test(s). [-1,-1] -1 !

Shrinking (0 time(s)) [-1,-1] -1 false 17>
27. 17> proper:quickcheck(lists_proper:prop_delete()). ..................................! Failed: After 35 test(s). [2,-10,-7,13,70,2] 2 !

Shrinking ......(6 time(s)) [2,2] 2 false
28. prop_delete() -> ?FORALL(L, non_empty(list(integer())), ?FORALL(X, elements(L), lists:foldl(fun(Y, Acc) -> case

Y of X -> Acc + 1; _ -> Acc end end, 0, L) - 1 == lists:foldl(fun(Y, Acc) -> case Y of X -> Acc + 1; _ -> Acc end end, 0, lists:delete(X, L)))).