diff options
Diffstat (limited to 'lib/stdlib/test')
-rw-r--r-- | lib/stdlib/test/lists_SUITE.erl | 242 | ||||
-rw-r--r-- | lib/stdlib/test/lists_property_test_SUITE.erl | 50 | ||||
-rw-r--r-- | lib/stdlib/test/property_test/lists_prop.erl | 131 |
3 files changed, 413 insertions, 10 deletions
diff --git a/lib/stdlib/test/lists_SUITE.erl b/lib/stdlib/test/lists_SUITE.erl index b5cbcd98c7..792a94702a 100644 --- a/lib/stdlib/test/lists_SUITE.erl +++ b/lib/stdlib/test/lists_SUITE.erl @@ -441,6 +441,8 @@ keyreplace(Config) when is_list(Config) -> merge(Config) when is_list(Config) -> + Singleton = id([a, b, c]), + %% merge list of lists [] = lists:merge([]), [] = lists:merge([[]]), @@ -463,6 +465,33 @@ merge(Config) when is_list(Config) -> Seq = lists:seq(1,100), true = Seq == lists:merge(lists:map(fun(E) -> [E] end, Seq)), + true = erts_debug:same(Singleton, lists:merge([Singleton])), + true = erts_debug:same(Singleton, lists:merge([Singleton, []])), + true = erts_debug:same(Singleton, lists:merge([[], Singleton])), + true = erts_debug:same(Singleton, lists:merge([Singleton, [], []])), + true = erts_debug:same(Singleton, lists:merge([[], Singleton, []])), + true = erts_debug:same(Singleton, lists:merge([[], [], Singleton])), + + {'EXIT', _} = (catch lists:merge([a])), + {'EXIT', _} = (catch lists:merge([a, b])), + {'EXIT', _} = (catch lists:merge([a, []])), + {'EXIT', _} = (catch lists:merge([[], b])), + {'EXIT', _} = (catch lists:merge([a, [1, 2, 3]])), + {'EXIT', _} = (catch lists:merge([[1, 2, 3], b])), + {'EXIT', _} = (catch lists:merge([a, b, c])), + {'EXIT', _} = (catch lists:merge([a, b, []])), + {'EXIT', _} = (catch lists:merge([a, [], c])), + {'EXIT', _} = (catch lists:merge([a, [], []])), + {'EXIT', _} = (catch lists:merge([[], b, c])), + {'EXIT', _} = (catch lists:merge([[], b, []])), + {'EXIT', _} = (catch lists:merge([[], [], c])), + {'EXIT', _} = (catch lists:merge([a, b, [1, 2, 3]])), + {'EXIT', _} = (catch lists:merge([a, [1, 2, 3], c])), + {'EXIT', _} = (catch lists:merge([a, [1, 2, 3], [4, 5, 6]])), + {'EXIT', _} = (catch lists:merge([[1, 2, 3], b, c])), + {'EXIT', _} = (catch lists:merge([[1, 2, 3], b, [4, 5, 6]])), + {'EXIT', _} = (catch lists:merge([[1, 2, 3], [4, 5, 6], c])), + Two = [1,2], Six = [1,2,3,4,5,6], @@ -482,6 +511,15 @@ merge(Config) when is_list(Config) -> [1,2,3,4,5,7] = lists:merge([2,4], [1,3,5,7]), [1,2,3,4,5,6,7] = lists:merge([2,4,6], [1,3,5,7]), + true = erts_debug:same(Singleton, lists:merge([], Singleton)), + true = erts_debug:same(Singleton, lists:merge(Singleton, [])), + + {'EXIT', _} = (catch lists:merge(a, b)), + {'EXIT', _} = (catch lists:merge(a, [])), + {'EXIT', _} = (catch lists:merge([], b)), + {'EXIT', _} = (catch lists:merge(a, [1, 2, 3])), + {'EXIT', _} = (catch lists:merge([1, 2, 3], b)), + %% 3-way merge [] = lists:merge3([], [], []), Two = lists:merge3([], [], Two), @@ -498,11 +536,28 @@ merge(Config) when is_list(Config) -> Nine = lists:merge3([7,8,9],[4,5,6],[1,2,3]), Nine = lists:merge3([4,5,6],[7,8,9],[1,2,3]), + true = erts_debug:same(Singleton, lists:merge3([], [], Singleton)), + true = erts_debug:same(Singleton, lists:merge3([], Singleton, [])), + true = erts_debug:same(Singleton, lists:merge3(Singleton, [], [])), + + {'EXIT', _} = (catch lists:merge3(a, b, c)), + {'EXIT', _} = (catch lists:merge3(a, b, [])), + {'EXIT', _} = (catch lists:merge3(a, [], c)), + {'EXIT', _} = (catch lists:merge3(a, [], [])), + {'EXIT', _} = (catch lists:merge3([], b, [])), + {'EXIT', _} = (catch lists:merge3([], [], c)), + {'EXIT', _} = (catch lists:merge3(a, b, [1, 2, 3])), + {'EXIT', _} = (catch lists:merge3(a, [1, 2, 3], c)), + {'EXIT', _} = (catch lists:merge3(a, [1, 2, 3], [4, 5, 6])), + {'EXIT', _} = (catch lists:merge3([1, 2, 3], b, [4, 5, 6])), + {'EXIT', _} = (catch lists:merge3([1, 2, 3], [4, 5, 6], c)), + ok. %% reverse merge functions rmerge(Config) when is_list(Config) -> + Singleton = id([a, b, c]), Two = [2,1], Six = [6,5,4,3,2,1], @@ -522,6 +577,15 @@ rmerge(Config) when is_list(Config) -> [7,5,4,3,2,1] = lists:rmerge([4,2], [7,5,3,1]), [7,6,5,4,3,2,1] = lists:rmerge([6,4,2], [7,5,3,1]), + true = erts_debug:same(Singleton, lists:rmerge([], Singleton)), + true = erts_debug:same(Singleton, lists:rmerge(Singleton, [])), + + {'EXIT', _} = (catch lists:rmerge(a, b)), + {'EXIT', _} = (catch lists:rmerge(a, [])), + {'EXIT', _} = (catch lists:rmerge([], b)), + {'EXIT', _} = (catch lists:rmerge(a, [1, 2, 3])), + {'EXIT', _} = (catch lists:rmerge([1, 2, 3], b)), + Nine = [9,8,7,6,5,4,3,2,1], %% 3-way reversed merge @@ -540,6 +604,22 @@ rmerge(Config) when is_list(Config) -> Nine = lists:rmerge3([9,8,7],[6,5,4],[3,2,1]), Nine = lists:rmerge3([6,5,4],[9,8,7],[3,2,1]), + true = erts_debug:same(Singleton, lists:rmerge3([], [], Singleton)), + true = erts_debug:same(Singleton, lists:rmerge3([], Singleton, [])), + true = erts_debug:same(Singleton, lists:rmerge3(Singleton, [], [])), + + {'EXIT', _} = (catch lists:rmerge3(a, b, c)), + {'EXIT', _} = (catch lists:rmerge3(a, b, [])), + {'EXIT', _} = (catch lists:rmerge3(a, [], c)), + {'EXIT', _} = (catch lists:rmerge3(a, [], [])), + {'EXIT', _} = (catch lists:rmerge3([], b, [])), + {'EXIT', _} = (catch lists:rmerge3([], [], c)), + {'EXIT', _} = (catch lists:rmerge3(a, b, [1, 2, 3])), + {'EXIT', _} = (catch lists:rmerge3(a, [1, 2, 3], c)), + {'EXIT', _} = (catch lists:rmerge3(a, [1, 2, 3], [4, 5, 6])), + {'EXIT', _} = (catch lists:rmerge3([1, 2, 3], b, [4, 5, 6])), + {'EXIT', _} = (catch lists:rmerge3([1, 2, 3], [4, 5, 6], c)), + ok. sort_1(Config) when is_list(Config) -> @@ -640,6 +720,8 @@ usort_1(Conf) when is_list(Conf) -> ok. umerge(Conf) when is_list(Conf) -> + Singleton = id([a, b, c]), + %% merge list of lists [] = lists:umerge([]), [] = lists:umerge([[]]), @@ -663,6 +745,33 @@ umerge(Conf) when is_list(Conf) -> Seq = lists:seq(1,100), true = Seq == lists:umerge(lists:map(fun(E) -> [E] end, Seq)), + true = erts_debug:same(Singleton, lists:umerge([Singleton])), + true = erts_debug:same(Singleton, lists:umerge([Singleton, []])), + true = erts_debug:same(Singleton, lists:umerge([[], Singleton])), + true = erts_debug:same(Singleton, lists:umerge([Singleton, [], []])), + true = erts_debug:same(Singleton, lists:umerge([[], Singleton, []])), + true = erts_debug:same(Singleton, lists:umerge([[], [], Singleton])), + + {'EXIT', _} = (catch lists:umerge([a])), + {'EXIT', _} = (catch lists:umerge([a, b])), + {'EXIT', _} = (catch lists:umerge([a, []])), + {'EXIT', _} = (catch lists:umerge([[], b])), + {'EXIT', _} = (catch lists:umerge([a, [1, 2, 3]])), + {'EXIT', _} = (catch lists:umerge([[1, 2, 3], b])), + {'EXIT', _} = (catch lists:umerge([a, b, c])), + {'EXIT', _} = (catch lists:umerge([a, b, []])), + {'EXIT', _} = (catch lists:umerge([a, [], c])), + {'EXIT', _} = (catch lists:umerge([a, [], []])), + {'EXIT', _} = (catch lists:umerge([[], b, c])), + {'EXIT', _} = (catch lists:umerge([[], b, []])), + {'EXIT', _} = (catch lists:umerge([[], [], c])), + {'EXIT', _} = (catch lists:umerge([a, b, [1, 2, 3]])), + {'EXIT', _} = (catch lists:umerge([a, [1, 2, 3], c])), + {'EXIT', _} = (catch lists:umerge([a, [1, 2, 3], [4, 5, 6]])), + {'EXIT', _} = (catch lists:umerge([[1, 2, 3], b, c])), + {'EXIT', _} = (catch lists:umerge([[1, 2, 3], b, [4, 5, 6]])), + {'EXIT', _} = (catch lists:umerge([[1, 2, 3], [4, 5, 6], c])), + Two = [1,2], Six = [1,2,3,4,5,6], @@ -689,6 +798,15 @@ umerge(Conf) when is_list(Conf) -> [1,2,3,4,5,7] = lists:umerge([2,4], [1,2,3,4,5,7]), [1,2,3,4,5,6,7] = lists:umerge([2,4,6], [1,2,3,4,5,6,7]), + true = erts_debug:same(Singleton, lists:umerge([], Singleton)), + true = erts_debug:same(Singleton, lists:umerge(Singleton, [])), + + {'EXIT', _} = (catch lists:umerge(a, b)), + {'EXIT', _} = (catch lists:umerge(a, [])), + {'EXIT', _} = (catch lists:umerge([], b)), + {'EXIT', _} = (catch lists:umerge(a, [1, 2, 3])), + {'EXIT', _} = (catch lists:umerge([1, 2, 3], b)), + %% 3-way unique merge [] = lists:umerge3([], [], []), Two = lists:umerge3([], [], Two), @@ -710,9 +828,27 @@ umerge(Conf) when is_list(Conf) -> [1,2,3] = lists:umerge3([1,2,3],[2,3],[1,2,3]), [1,2,3,4] = lists:umerge3([2,3,4],[3,4],[1,2,3]), + true = erts_debug:same(Singleton, lists:umerge3([], [], Singleton)), + true = erts_debug:same(Singleton, lists:umerge3([], Singleton, [])), + true = erts_debug:same(Singleton, lists:umerge3(Singleton, [], [])), + + {'EXIT', _} = (catch lists:umerge3(a, b, c)), + {'EXIT', _} = (catch lists:umerge3(a, b, [])), + {'EXIT', _} = (catch lists:umerge3(a, [], c)), + {'EXIT', _} = (catch lists:umerge3(a, [], [])), + {'EXIT', _} = (catch lists:umerge3([], b, [])), + {'EXIT', _} = (catch lists:umerge3([], [], c)), + {'EXIT', _} = (catch lists:umerge3(a, b, [1, 2, 3])), + {'EXIT', _} = (catch lists:umerge3(a, [1, 2, 3], c)), + {'EXIT', _} = (catch lists:umerge3(a, [1, 2, 3], [4, 5, 6])), + {'EXIT', _} = (catch lists:umerge3([1, 2, 3], b, [4, 5, 6])), + {'EXIT', _} = (catch lists:umerge3([1, 2, 3], [4, 5, 6], c)), + ok. rumerge(Conf) when is_list(Conf) -> + Singleton = id([a, b, c]), + Two = [2,1], Six = [6,5,4,3,2,1], @@ -739,6 +875,15 @@ rumerge(Conf) when is_list(Conf) -> [7,5,4,3,2,1] = lists:rumerge([4,2], [7,5,4,3,2,1]), [7,6,5,4,3,2,1] = lists:rumerge([6,4,2], [7,6,5,4,3,2,1]), + true = erts_debug:same(Singleton, lists:rumerge([], Singleton)), + true = erts_debug:same(Singleton, lists:rumerge(Singleton, [])), + + {'EXIT', _} = (catch lists:rumerge(a, b)), + {'EXIT', _} = (catch lists:rumerge(a, [])), + {'EXIT', _} = (catch lists:rumerge([], b)), + {'EXIT', _} = (catch lists:rumerge(a, [1, 2, 3])), + {'EXIT', _} = (catch lists:rumerge([1, 2, 3], b)), + Nine = [9,8,7,6,5,4,3,2,1], %% 3-way reversed unique merge @@ -767,6 +912,23 @@ rumerge(Conf) when is_list(Conf) -> true = lists:umerge(L1, L2) == lists:reverse(lists:rumerge(lists:reverse(L1), lists:reverse(L2))), + + true = erts_debug:same(Singleton, lists:rumerge3([], [], Singleton)), + true = erts_debug:same(Singleton, lists:rumerge3([], Singleton, [])), + true = erts_debug:same(Singleton, lists:rumerge3(Singleton, [], [])), + + {'EXIT', _} = (catch lists:rumerge3(a, b, c)), + {'EXIT', _} = (catch lists:rumerge3(a, b, [])), + {'EXIT', _} = (catch lists:rumerge3(a, [], c)), + {'EXIT', _} = (catch lists:rumerge3(a, [], [])), + {'EXIT', _} = (catch lists:rumerge3([], b, [])), + {'EXIT', _} = (catch lists:rumerge3([], [], c)), + {'EXIT', _} = (catch lists:rumerge3(a, b, [1, 2, 3])), + {'EXIT', _} = (catch lists:rumerge3(a, [1, 2, 3], c)), + {'EXIT', _} = (catch lists:rumerge3(a, [1, 2, 3], [4, 5, 6])), + {'EXIT', _} = (catch lists:rumerge3([1, 2, 3], b, [4, 5, 6])), + {'EXIT', _} = (catch lists:rumerge3([1, 2, 3], [4, 5, 6], c)), + ok. %% usort/1 on big randomized lists. @@ -823,6 +985,7 @@ ucheck_stability(L) -> %% Key merge two lists. keymerge(Config) when is_list(Config) -> + Singleton = id([{1, a}, {2, b}, {3, c}]), Two = [{1,a},{2,b}], Six = [{1,a},{2,b},{3,c},{4,d},{5,e},{6,f}], @@ -851,11 +1014,21 @@ keymerge(Config) when is_list(Config) -> [{b,2},{c,11},{c,12},{c,21},{c,22},{e,5}] = lists:keymerge(1,[{c,11},{c,12},{e,5}], [{b,2},{c,21},{c,22}]), + true = erts_debug:same(Singleton, lists:keymerge(1, Singleton, [])), + true = erts_debug:same(Singleton, lists:keymerge(1, [], Singleton)), + + {'EXIT', _} = (catch lists:keymerge(1, a, b)), + {'EXIT', _} = (catch lists:keymerge(1, a, [])), + {'EXIT', _} = (catch lists:keymerge(1, [], b)), + {'EXIT', _} = (catch lists:keymerge(1, a, [{1, a}, {2, b}, {3, c}])), + {'EXIT', _} = (catch lists:keymerge(1, [{1, a}, {2, b}, {3, c}], b)), + ok. %% Reverse key merge two lists. rkeymerge(Config) when is_list(Config) -> + Singleton = id([{1, a}, {2, b}, {3, c}]), Two = [{2,b},{1,a}], Six = [{6,f},{5,e},{4,d},{3,c},{2,b},{1,a}], @@ -888,6 +1061,15 @@ rkeymerge(Config) when is_list(Config) -> lists:reverse(lists:rkeymerge(1,lists:reverse(L1), lists:reverse(L2))), + true = erts_debug:same(Singleton, lists:rkeymerge(1, Singleton, [])), + true = erts_debug:same(Singleton, lists:rkeymerge(1, [], Singleton)), + + {'EXIT', _} = (catch lists:rkeymerge(1, a, b)), + {'EXIT', _} = (catch lists:rkeymerge(1, a, [])), + {'EXIT', _} = (catch lists:rkeymerge(1, [], b)), + {'EXIT', _} = (catch lists:rkeymerge(1, a, [{1, a}, {2, b}, {3, c}])), + {'EXIT', _} = (catch lists:rkeymerge(1, [{1, a}, {2, b}, {3, c}], b)), + ok. keysort_1(Config) when is_list(Config) -> @@ -1006,6 +1188,7 @@ keycompare(I, J, A, B) when element(I, A) == element(I, B), %% Merge two lists while removing duplicates. ukeymerge(Conf) when is_list(Conf) -> + Singleton = id([{1, a}, {2, b}, {3, c}]), Two = [{1,a},{2,b}], Six = [{1,a},{2,b},{3,c},{4,d},{5,e},{6,f}], @@ -1055,11 +1238,21 @@ ukeymerge(Conf) when is_list(Conf) -> L2 = [{b,1},{b,3},{b,5},{b,7}], L1 = lists:ukeymerge(2, L1, L2), + true = erts_debug:same(Singleton, lists:ukeymerge(1, Singleton, [])), + true = erts_debug:same(Singleton, lists:ukeymerge(1, [], Singleton)), + + {'EXIT', _} = (catch lists:ukeymerge(1, a, b)), + {'EXIT', _} = (catch lists:ukeymerge(1, a, [])), + {'EXIT', _} = (catch lists:ukeymerge(1, [], b)), + {'EXIT', _} = (catch lists:ukeymerge(1, a, [{1, a}, {2, b}, {3, c}])), + {'EXIT', _} = (catch lists:ukeymerge(1, [{1, a}, {2, b}, {3, c}], b)), + ok. %% Reverse merge two lists while removing duplicates. rukeymerge(Conf) when is_list(Conf) -> + Singleton = id([{1, a}, {2, b}, {3, c}]), Two = [{2,b},{1,a}], Six = [{6,f},{5,e},{4,d},{3,c},{2,b},{1,a}], @@ -1109,6 +1302,15 @@ rukeymerge(Conf) when is_list(Conf) -> lists:reverse(lists:rukeymerge(2, lists:reverse(L1), lists:reverse(L2))), + true = erts_debug:same(Singleton, lists:rukeymerge(1, Singleton, [])), + true = erts_debug:same(Singleton, lists:rukeymerge(1, [], Singleton)), + + {'EXIT', _} = (catch lists:rukeymerge(1, a, b)), + {'EXIT', _} = (catch lists:rukeymerge(1, a, [])), + {'EXIT', _} = (catch lists:rukeymerge(1, [], b)), + {'EXIT', _} = (catch lists:rukeymerge(1, a, [{1, a}, {2, b}, {3, c}])), + {'EXIT', _} = (catch lists:rukeymerge(1, [{1, a}, {2, b}, {3, c}], b)), + ok. ukeysort_1(Config) when is_list(Config) -> @@ -1286,6 +1488,7 @@ ukeycompare(I, J, A, B) when A =/= B, %% Merge two lists using a fun. funmerge(Config) when is_list(Config) -> + Singleton = id([a, b, c]), Two = [1,2], Six = [1,2,3,4,5,6], F = fun(X, Y) -> X =< Y end, @@ -1310,11 +1513,21 @@ funmerge(Config) when is_list(Config) -> [{b,2},{c,11},{c,12},{c,21},{c,22},{e,5}] = lists:merge(F2,[{c,11},{c,12},{e,5}], [{b,2},{c,21},{c,22}]), + true = erts_debug:same(Singleton, lists:merge(F, Singleton, [])), + true = erts_debug:same(Singleton, lists:merge(F, [], Singleton)), + + {'EXIT', _} = (catch lists:merge(F, a, b)), + {'EXIT', _} = (catch lists:merge(F, a, [])), + {'EXIT', _} = (catch lists:merge(F, [], b)), + {'EXIT', _} = (catch lists:merge(F, a, [1, 2, 3])), + {'EXIT', _} = (catch lists:merge(F, [1, 2, 3], b)), + ok. %% Reverse merge two lists using a fun. rfunmerge(Config) when is_list(Config) -> + Singleton = id([a, b, c]), Two = [2,1], Six = [6,5,4,3,2,1], F = fun(X, Y) -> X =< Y end, @@ -1342,6 +1555,15 @@ rfunmerge(Config) when is_list(Config) -> lists:merge(F2, L1, L2) == lists:reverse(lists:rmerge(F2,lists:reverse(L1), lists:reverse(L2))), + true = erts_debug:same(Singleton, lists:rmerge(F, Singleton, [])), + true = erts_debug:same(Singleton, lists:rmerge(F, [], Singleton)), + + {'EXIT', _} = (catch lists:rmerge(F, a, b)), + {'EXIT', _} = (catch lists:rmerge(F, a, [])), + {'EXIT', _} = (catch lists:rmerge(F, [], b)), + {'EXIT', _} = (catch lists:rmerge(F, a, [1, 2, 3])), + {'EXIT', _} = (catch lists:rmerge(F, [1, 2, 3], b)), + ok. @@ -1411,6 +1633,7 @@ funsort_check(I, Input, Expected) -> %% Merge two lists while removing duplicates using a fun. ufunmerge(Conf) when is_list(Conf) -> + Singleton = id([a, b, c]), Two = [1,2], Six = [1,2,3,4,5,6], F = fun(X, Y) -> X =< Y end, @@ -1445,10 +1668,20 @@ ufunmerge(Conf) when is_list(Conf) -> [{b,2},{e,5},{c,11},{c,12},{c,21},{c,22}] = lists:umerge(F2, [{e,5},{c,11},{c,12}], [{b,2},{c,21},{c,22}]), + true = erts_debug:same(Singleton, lists:umerge(F, Singleton, [])), + true = erts_debug:same(Singleton, lists:umerge(F, [], Singleton)), + + {'EXIT', _} = (catch lists:umerge(F, a, b)), + {'EXIT', _} = (catch lists:umerge(F, a, [])), + {'EXIT', _} = (catch lists:umerge(F, [], b)), + {'EXIT', _} = (catch lists:umerge(F, a, [1, 2, 3])), + {'EXIT', _} = (catch lists:umerge(F, [1, 2, 3], b)), + ok. %% Reverse merge two lists while removing duplicates using a fun. rufunmerge(Conf) when is_list(Conf) -> + Singleton = id([a, b, c]), Two = [2,1], Six = [6,5,4,3,2,1], F = fun(X, Y) -> X =< Y end, @@ -1488,6 +1721,15 @@ rufunmerge(Conf) when is_list(Conf) -> lists:umerge(F2, L3, L4) == lists:reverse(lists:rumerge(F2,lists:reverse(L3), lists:reverse(L4))), + true = erts_debug:same(Singleton, lists:rumerge(F, Singleton, [])), + true = erts_debug:same(Singleton, lists:rumerge(F, [], Singleton)), + + {'EXIT', _} = (catch lists:rumerge(F, a, b)), + {'EXIT', _} = (catch lists:rumerge(F, a, [])), + {'EXIT', _} = (catch lists:rumerge(F, [], b)), + {'EXIT', _} = (catch lists:rumerge(F, a, [1, 2, 3])), + {'EXIT', _} = (catch lists:rumerge(F, [1, 2, 3], b)), + ok. ufunsort_1(Config) when is_list(Config) -> diff --git a/lib/stdlib/test/lists_property_test_SUITE.erl b/lib/stdlib/test/lists_property_test_SUITE.erl index 617fed6af8..4b366d730a 100644 --- a/lib/stdlib/test/lists_property_test_SUITE.erl +++ b/lib/stdlib/test/lists_property_test_SUITE.erl @@ -49,7 +49,7 @@ all() -> keyfind_case, keyfind_absent_case, keymap_case, keymember_case, keymember_absent_case, - keymerge_case, + keymerge_case, keymerge_invalid_case, keyreplace_case, keyreplace_absent_case, keysearch_case, keysearch_absent_case, keysort_case, @@ -61,10 +61,10 @@ all() -> mapfoldr_case, max_case, member_case, member_absent_case, - merge_1_case, - merge_2_case, - merge_3_case, - merge3_case, + merge_1_case, merge_1_invalid_case, + merge_2_case, merge_2_invalid_case, + merge_3_case, merge_3_invalid_case, + merge3_case, merge3_invalid_case, min_case, nth_case, nth_outofrange_case, nthtail_case, nthtail_outofrange_case, @@ -85,12 +85,12 @@ all() -> suffix_case, sum_case, takewhile_case, - ukeymerge_case, + ukeymerge_case, ukeymerge_invalid_case, ukeysort_case, - umerge_1_case, - umerge_2_case, - umerge_3_case, - umerge3_case, + umerge_1_case, umerge_1_invalid_case, + umerge_2_case, umerge_2_invalid_case, + umerge_3_case, umerge_3_invalid_case, + umerge3_case, umerge3_invalid_case, uniq_1_case, uniq_2_case, unzip_case, @@ -213,6 +213,9 @@ keymember_absent_case(Config) -> keymerge_case(Config) -> do_proptest(prop_keymerge, Config). +keymerge_invalid_case(Config) -> + do_proptest(prop_keymerge_invalid, Config). + keyreplace_case(Config) -> do_proptest(prop_keyreplace, Config). @@ -264,15 +267,27 @@ member_absent_case(Config) -> merge_1_case(Config) -> do_proptest(prop_merge_1, Config). +merge_1_invalid_case(Config) -> + do_proptest(prop_merge_1_invalid, Config). + merge_2_case(Config) -> do_proptest(prop_merge_2, Config). +merge_2_invalid_case(Config) -> + do_proptest(prop_merge_2_invalid, Config). + merge_3_case(Config) -> do_proptest(prop_merge_3, Config). +merge_3_invalid_case(Config) -> + do_proptest(prop_merge_3_invalid, Config). + merge3_case(Config) -> do_proptest(prop_merge3, Config). +merge3_invalid_case(Config) -> + do_proptest(prop_merge3_invalid, Config). + min_case(Config) -> do_proptest(prop_min, Config). @@ -348,21 +363,36 @@ takewhile_case(Config) -> ukeymerge_case(Config) -> do_proptest(prop_ukeymerge, Config). +ukeymerge_invalid_case(Config) -> + do_proptest(prop_ukeymerge_invalid, Config). + ukeysort_case(Config) -> do_proptest(prop_ukeysort, Config). umerge_1_case(Config) -> do_proptest(prop_umerge_1, Config). +umerge_1_invalid_case(Config) -> + do_proptest(prop_umerge_1_invalid, Config). + umerge_2_case(Config) -> do_proptest(prop_umerge_2, Config). +umerge_2_invalid_case(Config) -> + do_proptest(prop_umerge_2_invalid, Config). + umerge_3_case(Config) -> do_proptest(prop_umerge_3, Config). +umerge_3_invalid_case(Config) -> + do_proptest(prop_umerge_3_invalid, Config). + umerge3_case(Config) -> do_proptest(prop_umerge3, Config). +umerge3_invalid_case(Config) -> + do_proptest(prop_umerge3_invalid, Config). + uniq_1_case(Config) -> do_proptest(prop_uniq_1, Config). diff --git a/lib/stdlib/test/property_test/lists_prop.erl b/lib/stdlib/test/property_test/lists_prop.erl index 4d5809b262..00b518ff83 100644 --- a/lib/stdlib/test/property_test/lists_prop.erl +++ b/lib/stdlib/test/property_test/lists_prop.erl @@ -513,6 +513,23 @@ prop_keymerge() -> ) ). +prop_keymerge_invalid() -> + ?FORALL( + {N, InList, X, Y}, + ?LET( + N, + range(1, 5), + ?LET( + {L, X, Y}, + {list(gen_tuple(N, N+3)), non_list(), non_list()}, + {N, L, X, Y} + ) + ), + expect_error(fun lists:keymerge/3, [N, InList, Y]) andalso + expect_error(fun lists:keymerge/3, [N, X, InList]) andalso + expect_error(fun lists:keymerge/3, [N, X, Y]) + ). + %% keyreplace/4 prop_keyreplace() -> ?FORALL( @@ -745,6 +762,17 @@ prop_merge_1() -> check_merged(fun erlang:'=<'/2, InLists, lists:merge(InLists)) ). +prop_merge_1_invalid() -> + ?FORALL( + InLists, + ?LET( + {L1, X, L2}, + {list(oneof([non_list(), gen_list()])), non_list(), list(oneof([non_list(), gen_list()]))}, + L1 ++ [X|L2] + ), + expect_error(fun lists:merge/1, [InLists]) + ). + %% merge/2 prop_merge_2() -> ?FORALL( @@ -757,6 +785,15 @@ prop_merge_2() -> check_merged(fun erlang:'=<'/2, [InList1, InList2], lists:merge(InList1, InList2)) ). +prop_merge_2_invalid() -> + ?FORALL( + {InList, X, Y}, + {gen_list(), non_list(), non_list()}, + expect_error(fun lists:merge/2, [InList, X]) andalso + expect_error(fun lists:merge/2, [X, InList]) andalso + expect_error(fun lists:merge/2, [X, Y]) + ). + %% merge/3 prop_merge_3() -> ?FORALL( @@ -769,6 +806,15 @@ prop_merge_3() -> check_merged(SortFn, [InList1, InList2], lists:merge(SortFn, InList1, InList2)) ). +prop_merge_3_invalid() -> + ?FORALL( + {SortFn, InList, X, Y}, + {gen_ordering_fun(), gen_list(), non_list(), non_list()}, + expect_error(fun lists:merge/3, [SortFn, InList, Y]) andalso + expect_error(fun lists:merge/3, [SortFn, X, InList]) andalso + expect_error(fun lists:merge/3, [SortFn, X, Y]) + ). + %% merge3/3 prop_merge3() -> ?FORALL( @@ -781,6 +827,18 @@ prop_merge3() -> check_merged(fun erlang:'=<'/2, [InList1, InList2, InList3], lists:merge3(InList1, InList2, InList3)) ). +prop_merge3_invalid() -> + ?FORALL( + {InList, X, Y, Z}, + {gen_list(), non_list(), non_list(), non_list()}, + expect_error(fun lists:merge/3, [InList, InList, Z]) andalso + expect_error(fun lists:merge/3, [InList, Y, InList]) andalso + expect_error(fun lists:merge/3, [InList, Y, Z]) andalso + expect_error(fun lists:merge/3, [X, InList, Z]) andalso + expect_error(fun lists:merge/3, [X, Y, InList]) andalso + expect_error(fun lists:merge/3, [X, Y, Z]) + ). + %% min/1 prop_min() -> ?FORALL( @@ -1132,6 +1190,23 @@ prop_ukeymerge() -> ) ). +prop_ukeymerge_invalid() -> + ?FORALL( + {N, InList, X, Y}, + ?LET( + N, + range(1, 5), + ?LET( + {L, X, Y}, + {list(gen_tuple(N, N+3)), non_list(), non_list()}, + {N, L, X, Y} + ) + ), + expect_error(fun lists:ukeymerge/3, [N, InList, Y]) andalso + expect_error(fun lists:ukeymerge/3, [N, X, InList]) andalso + expect_error(fun lists:ukeymerge/3, [N, X, Y]) + ). + %% ukeysort/2 prop_ukeysort() -> ?FORALL( @@ -1156,6 +1231,17 @@ prop_umerge_1() -> check_umerged(InLists, lists:umerge(InLists)) ). +prop_umerge_1_invalid() -> + ?FORALL( + InList, + ?LET( + {L1, X, L2}, + {list(oneof([non_list(), gen_list()])), non_list(), list(oneof([non_list(), gen_list()]))}, + L1 ++ [X|L2] + ), + expect_error(fun lists:umerge/1, [InList]) + ). + %% umerge/2 prop_umerge_2() -> ?FORALL( @@ -1168,6 +1254,15 @@ prop_umerge_2() -> check_umerged([InList1, InList2], lists:umerge(InList1, InList2)) ). +prop_umerge_2_invalid() -> + ?FORALL( + {InList, X, Y}, + {gen_list(), non_list(), non_list()}, + expect_error(fun lists:umerge/2, [InList, Y]) andalso + expect_error(fun lists:umerge/2, [X, InList]) andalso + expect_error(fun lists:umerge/2, [X, Y]) + ). + %% umerge/3 prop_umerge_3() -> ?FORALL( @@ -1180,6 +1275,15 @@ prop_umerge_3() -> check_umerged(SortFn, [InList1, InList2], lists:umerge(SortFn, InList1, InList2)) ). +prop_umerge_3_invalid() -> + ?FORALL( + {SortFn, InList, X, Y}, + {gen_ordering_fun(), gen_list(), non_list(), non_list()}, + expect_error(fun lists:umerge/3, [SortFn, InList, Y]) andalso + expect_error(fun lists:umerge/3, [SortFn, X, InList]) andalso + expect_error(fun lists:umerge/3, [SortFn, X, Y]) + ). + %% umerge3/3 prop_umerge3() -> ?FORALL( @@ -1192,6 +1296,19 @@ prop_umerge3() -> check_umerged([InList1, InList2, InList3], lists:umerge3(InList1, InList2, InList3)) ). +prop_umerge3_invalid() -> + ?FORALL( + {InList, X, Y, Z}, + {gen_list(), non_list(), non_list(), non_list()}, + expect_error(fun lists:umerge3/3, [InList, InList, Z]) andalso + expect_error(fun lists:umerge3/3, [InList, Y, InList]) andalso + expect_error(fun lists:umerge3/3, [InList, Y, Z]) andalso + expect_error(fun lists:umerge3/3, [X, InList, InList]) andalso + expect_error(fun lists:umerge3/3, [X, InList, Z]) andalso + expect_error(fun lists:umerge3/3, [X, Y, InList]) andalso + expect_error(fun lists:umerge3/3, [X, Y, Z]) + ). + %% uniq/1 prop_uniq_1() -> ?FORALL( @@ -1530,6 +1647,9 @@ prop_zipwith3_5() -> %%% Generators %%% %%%%%%%%%%%%%%%%%% +non_list() -> + ?SUCHTHAT(NonList, gen_any(), not is_list(NonList)). + %% Generator for lists of the given type, folding the given function %% over values on the top level as they are generated. The first generated %% value serves as the initial accumulator. @@ -1740,6 +1860,17 @@ gen_ordering_fun() -> %%%%%%%%%%%%%%% %% -------------------------------------------------------------------- +expect_error(Fn, Args) when is_function(Fn, length(Args))-> + try + erlang:apply(Fn, Args) + of + _ -> false + catch + error:_ -> true; + _:_ -> false + end. + +%% -------------------------------------------------------------------- check_appended([], []) -> true; check_appended([[]|Ls], AL) -> |