1%%% -*- coding: utf-8 -*- 2%%% -*- erlang-indent-level: 2 -*- 3%%% ------------------------------------------------------------------- 4%%% Copyright 2020- Manolis Papadakis <manopapad@gmail.com>, 5%%% Eirini Arvaniti <eirinibob@gmail.com> 6%%% and Kostis Sagonas <kostis@cs.ntua.gr> 7%%% 8%%% This file is part of PropEr. 9%%% 10%%% PropEr is free software: you can redistribute it and/or modify 11%%% it under the terms of the GNU General Public License as published by 12%%% the Free Software Foundation, either version 3 of the License, or 13%%% (at your option) any later version. 14%%% 15%%% PropEr is distributed in the hope that it will be useful, 16%%% but WITHOUT ANY WARRANTY; without even the implied warranty of 17%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18%%% GNU General Public License for more details. 19%%% 20%%% You should have received a copy of the GNU General Public License 21%%% along with PropEr. If not, see <http://www.gnu.org/licenses/>. 22 23%%% @copyright 2020 Manolis Papadakis, Eirini Arvaniti and Kostis Sagonas 24%%% @version {@version} 25%%% @author Spiros Dontas 26 27%% ----------------------------------------------------------------------------- 28%% Tests inspired by https://github.com/proper-testing/proper/issues/221 29%% ----------------------------------------------------------------------------- 30 31-module(targeted_shrinking_test). 32-include_lib("proper/include/proper.hrl"). 33-include_lib("eunit/include/eunit.hrl"). 34 35%% ----------------------------------------------------------------------------- 36%% Generators 37%% ----------------------------------------------------------------------------- 38 39let_int() -> 40 ?LET(I, integer(), I). 41 42nf_let_int() -> 43 fun (Prev, _T) -> 44 ?LET(I, integer(Prev, inf), I) 45 end. 46 47nf_int_shrink() -> 48 fun (Prev, _T) -> 49 ?SHRINK(integer(Prev, inf), [integer()]) 50 end. 51 52int_user_nf() -> 53 ?USERNF(integer(), nf_let_int()). 54 55let_int_user_nf() -> 56 ?USERNF(let_int(), nf_let_int()). 57 58int_user_nf_shrink_inner() -> 59 ?USERNF(let_int(), nf_int_shrink()). 60 61int_user_nf_shrink_outer() -> 62 ?USERNF(?SHRINK(let_int(), [integer()]), 63 fun(Prev, _T) -> integer(Prev, inf) end). 64 65normal_list() -> 66 list(integer()). 67 68let_list() -> 69 ?LET(L, list(integer()), L). 70 71nf_list() -> 72 fun (Prev, _T) -> 73 {Max, NewLen} = case Prev of 74 [] -> {0, 1}; 75 _ -> {max(0, lists:max(Prev)), length(Prev)} 76 end, 77 ?SHRINK(vector(NewLen * 2, integer(Max, inf)), 78 [list(integer())]) 79 end. 80 81normal_list_user_nf() -> 82 ?USERNF(normal_list(), nf_list()). 83 84let_list_user_nf() -> 85 ?USERNF(let_list(), nf_list()). 86 87%% ----------------------------------------------------------------------------- 88%% Properties 89%% ----------------------------------------------------------------------------- 90 91property_int(I) -> 92 ?MAXIMIZE(I), 93 I < 500. 94 95prop_int() -> 96 ?FORALL_TARGETED(I, int_user_nf(), property_int(I)). 97 98prop_let_int() -> 99 ?FORALL_TARGETED(I, let_int_user_nf(), property_int(I)). 100 101prop_int_shrink_outer() -> 102 ?FORALL_TARGETED(I, int_user_nf_shrink_outer(), property_int(I)). 103 104prop_int_shrink_inner() -> 105 ?FORALL_TARGETED(I, int_user_nf_shrink_inner(), property_int(I)). 106 107property_list(L) -> 108 ?MAXIMIZE(lists:sum(L)), 109 lists:sum(L) < 1000. 110 111prop_normal_list() -> 112 ?FORALL_TARGETED(L, normal_list_user_nf(), property_list(L)). 113 114prop_let_list() -> 115 ?FORALL_TARGETED(L, let_list_user_nf(), property_list(L)). 116 117%% ----------------------------------------------------------------------------- 118%% Tests 119%% ----------------------------------------------------------------------------- 120 121normal_list_test() -> 122 false = proper:quickcheck(prop_normal_list()), 123 [L] = proper:counterexample(), 124 ?_assert(lists:sum(L) =:= 1000). 125 126let_list_test() -> 127 false = proper:quickcheck(prop_let_list()), 128 [L] = proper:counterexample(), 129 ?_assert(lists:sum(L) =:= 1000). 130