summaryrefslogtreecommitdiff
path: root/lib/stdlib/test
diff options
context:
space:
mode:
Diffstat (limited to 'lib/stdlib/test')
-rw-r--r--lib/stdlib/test/lists_SUITE.erl242
-rw-r--r--lib/stdlib/test/lists_property_test_SUITE.erl50
-rw-r--r--lib/stdlib/test/property_test/lists_prop.erl131
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) ->