File 2331-Property-based-tests-for-the-sets-module.patch of Package erlang

From cc63f8cea5c3be92e6297abed3c29ac0cc73967e Mon Sep 17 00:00:00 2001
From: Maria Scott <maria-12648430@hnc-agency.org>
Date: Fri, 18 Aug 2023 11:51:00 +0200
Subject: [PATCH] Property-based tests for the sets module

Co-authored-by: Jan Uhlig <juhlig@hnc-agency.org>
---
 lib/stdlib/test/Makefile                     |   1 +
 lib/stdlib/test/property_test/sets_prop.erl  | 653 +++++++++++++++++++
 lib/stdlib/test/sets_property_test_SUITE.erl | 122 ++++
 3 files changed, 776 insertions(+)
 create mode 100644 lib/stdlib/test/property_test/sets_prop.erl
 create mode 100644 lib/stdlib/test/sets_property_test_SUITE.erl

diff --git a/lib/stdlib/test/Makefile b/lib/stdlib/test/Makefile
index bdac775256..cb87124377 100644
--- a/lib/stdlib/test/Makefile
+++ b/lib/stdlib/test/Makefile
@@ -71,6 +71,7 @@ MODULES= \
 	re_testoutput1_split_test \
 	slave_SUITE \
 	sets_SUITE \
+	sets_property_test_SUITE \
 	sets_test_lib \
 	sofs_SUITE \
 	stdlib_SUITE \
diff --git a/lib/stdlib/test/property_test/sets_prop.erl b/lib/stdlib/test/property_test/sets_prop.erl
new file mode 100644
index 0000000000..2a87aa2614
--- /dev/null
+++ b/lib/stdlib/test/property_test/sets_prop.erl
@@ -0,0 +1,653 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2021-2022. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%%     http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%% %CopyrightEnd%
+%%
+-module(sets_prop).
+
+-include_lib("common_test/include/ct_property_test.hrl").
+
+%%%%%%%%%%%%%%%%%%
+%%% Properties %%%
+%%%%%%%%%%%%%%%%%%
+
+%% --- add_element/2 --------------------------------------------------
+prop_add_element() ->
+    test_all(fun subprop_add_element/1).
+
+subprop_add_element(Mod) ->
+    ?FORALL(
+        {{S0, M0}, Es},
+        ?LET(
+            {L1, L2, B},
+            {ct_proper_ext:safe_list(),
+             ct_proper_ext:safe_list(),
+             ct_proper_ext:safe_list()},
+            {gen_set(Mod, L1 ++ B), L2 ++ B}
+        ),
+        begin
+            {S1, M1} = lists:foldl(fun(E, {SAcc, MAcc}) ->
+                                       {Mod:add_element(E, SAcc),
+                                        model_add_element(E, MAcc)}
+                                   end,
+                                   {S0, M0},
+                                   Es),
+            is_equal(S1, M1)
+        end
+    ).
+
+
+%% --- del_element/2 --------------------------------------------------
+prop_del_element() ->
+    test_all(fun subprop_del_element/1).
+
+subprop_del_element(Mod) ->
+    ?FORALL(
+        {{S0, M0}, Es},
+        ?LET(
+            {L1, L2, B},
+            {ct_proper_ext:safe_list(),
+             ct_proper_ext:safe_list(),
+             ct_proper_ext:safe_list()},
+            {gen_set(Mod, L1 ++ B), L2 ++ B}
+        ),
+        begin
+            {S1, M1} = lists:foldl(fun(E, {SAcc, MAcc}) ->
+                                       {Mod:del_element(E, SAcc),
+                                        model_del_element(E, MAcc)}
+                                   end,
+                                   {S0, M0},
+                                   Es),
+            is_equal(S1, M1)
+        end
+    ).
+
+
+%% --- filter/2 -------------------------------------------------------
+prop_filter() ->
+    test_all(fun subprop_filter/1).
+
+subprop_filter(Mod) ->
+    ?FORALL(
+        {{S0, M0}, Fun},
+        {gen_set(Mod), function1(boolean())},
+        is_equal(Mod:filter(Fun, S0),
+                 model_filter(Fun, M0))
+    ).
+
+
+%% --- filtermap/2 ----------------------------------------------------
+prop_filtermap() ->
+    test_all(fun subprop_filtermap/1).
+
+subprop_filtermap(Mod) ->
+    ?FORALL(
+        {{S0, M0}, Fun},
+	{gen_set(Mod),
+         function1(oneof([true, false, {true, ct_proper_ext:safe_any()}]))},
+	is_equal(Mod:filtermap(Fun, S0),
+                 model_filtermap(Fun, M0))
+    ).
+
+
+%% --- fold/3 ---------------------------------------------------------
+prop_fold() ->
+    test_all(fun subprop_fold/1).
+
+subprop_fold(Mod) ->
+    ?FORALL(
+        {S, M},
+        gen_set(Mod),
+        begin
+            Fun = fun(E, Acc) -> Acc + erlang:phash2(E) end,
+            Mod:fold(Fun, 0, S) =:= model_fold(Fun, 0, M)
+        end
+    ).
+
+
+%% --- from_list/1,2 --------------------------------------------------
+prop_from_list() ->
+    test_all(fun subprop_from_list/1).
+
+subprop_from_list(sets) ->
+    ?FORALL(
+        {L, V},
+        {ct_proper_ext:safe_list(), gen_version()},
+        is_equal(sets:from_list(L, [{version, V}]),
+                 model_from_list(sets, L))
+    );
+subprop_from_list(Mod) ->
+    ?FORALL(
+        L,
+        ct_proper_ext:safe_list(),
+        is_equal(Mod:from_list(L),
+                 model_from_list(Mod, L))
+    ).
+
+
+%% --- intersection/1 -------------------------------------------------
+prop_intersection_1() ->
+    test_all(fun subprop_intersection_1/1).
+
+subprop_intersection_1(Mod) ->
+    ?FORALL(
+        SMs,
+        ?LET(
+            {Ls, A},
+            {non_empty(list(ct_proper_ext:safe_list())),
+             ct_proper_ext:safe_list()},
+            [gen_set(Mod, L ++ A) || L <- Ls]
+        ),
+        begin
+            {Ss, Ms} = lists:unzip(SMs),
+            is_equal(Mod:intersection(Ss),
+                     model_intersection(Ms))
+        end
+    ).
+
+
+%% --- intersection/2 -------------------------------------------------
+prop_intersection_2() ->
+    test_all(fun subprop_intersection_2/1).
+
+subprop_intersection_2(Mod) ->
+    ?FORALL(
+        {{S1, M1}, {S2, M2}},
+        ?LET(
+            {L1, L2, B},
+            {ct_proper_ext:safe_list(),
+             ct_proper_ext:safe_list(),
+             ct_proper_ext:safe_list()},
+            {gen_set(Mod, L1 ++ B), gen_set(Mod, L2 ++ B)}
+        ),
+        is_equal(Mod:intersection(S1, S2),
+                 model_intersection(M1, M2))
+    ).
+
+
+%% --- is_disjoint/2 --------------------------------------------------
+prop_is_disjoint() ->
+    test_all(fun subprop_is_disjoint/1).
+
+subprop_is_disjoint(Mod) ->
+    ?FORALL(
+        {{S1, M1}, {S2, M2}},
+        ?LET(
+            {L1, L2, B},
+            {ct_proper_ext:safe_list(),
+             ct_proper_ext:safe_list(),
+             ct_proper_ext:safe_list()},
+            begin
+                {gen_set(Mod, L1 ++ B), gen_set(Mod, L2 ++ B)}
+            end
+        ),
+        Mod:is_disjoint(S1, S2) =:= model_is_disjoint(M1, M2)
+    ).
+
+
+%% --- is_element/2 ---------------------------------------------------
+prop_is_element() ->
+    test_all(fun subprop_is_element/1).
+
+subprop_is_element(Mod) ->
+    ?FORALL(
+        {{S, M}, Es},
+        ?LET(
+            {L, Extra},
+            {ct_proper_ext:safe_list(), ct_proper_ext:safe_list()},
+            {gen_set(Mod, L), L ++ Extra}
+        ),
+        lists:all(fun(E) ->
+                      Mod:is_element(E, S) =:= model_is_element(E, M)
+                  end,
+                  Es)
+    ).
+
+
+%% --- is_empty/1 -----------------------------------------------------
+prop_is_empty() ->
+    test_all(fun subprop_is_empty/1).
+
+subprop_is_empty(Mod) ->
+    ?FORALL(
+        {S, M},
+        gen_set(Mod),
+        Mod:is_empty(S) =:= model_is_empty(M)
+    ).
+
+
+%% --- is_equal/1 -----------------------------------------------------
+prop_is_equal() ->
+    test_all(fun subprop_is_equal/1).
+
+subprop_is_equal(Mod) ->
+    ?FORALL(
+        {{S1, M1}, {S2, M2}},
+	{gen_set(Mod), gen_set(Mod)},
+	Mod:is_equal(S1, S2)=:=is_equal(S1, M2) andalso
+	Mod:is_equal(S2, S1)=:=is_equal(S2, M1)
+    ).
+
+
+%% --- is_set/1 -------------------------------------------------------
+prop_is_set() ->
+    test_all(fun subprop_is_set/1).
+
+subprop_is_set(sets) ->
+    ?FORALL(
+        {Exp, {S, _M}},
+        oneof([{true, gen_set(sets)},
+               {false, {?SUCHTHAT(T,
+                                  ct_proper_ext:safe_any(),
+                                  not (is_map(T) orelse
+                                       is_tuple(T) andalso
+                                       tuple_size(T)=:=9 andalso
+                                       element(1, T)=:=set)),
+                        undefined}}]),
+        Exp =:= sets:is_set(S)
+    );
+subprop_is_set(ordsets) ->
+    ?FORALL(
+        {Exp, {S, _M}},
+        oneof([{true, gen_set(ordsets)},
+               {false, {?SUCHTHAT(T,
+                                  ct_proper_ext:safe_any(),
+                                  not is_list(T)),
+                        undefined}}]),
+        Exp =:= ordsets:is_set(S)
+    );
+subprop_is_set(gb_sets) ->
+    ?FORALL(
+        {Exp, {S, _M}},
+        oneof([{true, gen_set(gb_sets)},
+               {false, {?SUCHTHAT(T,
+                                  ct_proper_ext:safe_any(),
+                                  not (is_tuple(T) andalso
+                                       tuple_size(T) =:= 2 andalso
+                                       is_integer(element(1, T)) andalso
+                                       element(1, T) >= 0 andalso
+                                       (element(2, T) =:= nil orelse
+                                        is_tuple(element(2, T)) andalso
+                                        tuple_size(element(2, T)) =:= 3))),
+                        undefined}}]),
+        Exp =:= gb_sets:is_set(S)
+    ).
+
+
+%% --- subset/2 -------------------------------------------------------
+%%
+%% +-----------------------------+
+%% | S0 +----------------------+ |
+%% |    | S1   +-------------+ | |
+%% |    |      | S2          | | |
+%% |    | +----+-----------+ | | |
+%% |    | | S3 | +-------+ | | | |
+%% |    | |    | | Empty | | | | |
+%% |    | |    | +-------+ | | | |
+%% |    | |    +-----------+-+ | |
+%% |    | +----------------+   | |
+%% |    +----------------------+ |
+%% +-----------------------------+
+%% * Empty is a subset of S2 and S3
+%%
+%% * S2 is a subset of S1 but not of S3
+%% * S3 is a subset of S1 but not of S2
+%% --> Empty is a subset of S1
+%%
+%% * S1 is a subset of S0
+%% --> S2, S3 and Empty are subsets of S0
+prop_is_subset() ->
+    test_all(fun subprop_is_subset/1).
+
+subprop_is_subset(Mod) ->
+    ?FORALL(
+        SMs,
+        ?LET(
+            {L1, L2},
+            {ct_proper_ext:safe_list(), ct_proper_ext:safe_list()},
+            begin
+                L3Extra = [make_ref()|L2],
+                L2Extra = [make_ref()|L1],
+                L1Extra = [make_ref()|L2Extra ++ L3Extra],
+                L0Extra = [make_ref()|L1Extra],
+                [gen_set(Mod, L0Extra),
+                 gen_set(Mod, L1Extra),
+                 gen_set(Mod, L2Extra),
+                 gen_set(Mod, L3Extra),
+                 gen_set(Mod, [])]
+            end
+        ),
+        lists:all(fun({{S1, M1}, {S2, M2}}) ->
+                      Mod:is_subset(S1, S2) =:= model_is_subset(M1, M2)
+                  end,
+                  [{SM1, SM2} || SM1 <- SMs, SM2 <- SMs])
+    ).
+
+
+%% --- map/2 ----------------------------------------------------------
+prop_map() ->
+    test_all(fun subprop_map/1).
+
+subprop_map(Mod) ->
+    ?FORALL(
+        {{S0, M0}, Fun},
+        {gen_set(Mod), function1(ct_proper_ext:safe_any())},
+        is_equal(Mod:map(Fun, S0),
+                 model_map(Fun, M0))
+    ).
+
+
+%% --- size/1 ---------------------------------------------------------
+prop_size() ->
+    test_all(fun subprop_size/1).
+
+subprop_size(Mod) ->
+    ?FORALL(
+        {S, M},
+        gen_set(Mod),
+        Mod:size(S) =:= model_size(M)
+    ).
+
+
+%% --- subtract/2 -----------------------------------------------------
+prop_subtract() ->
+    test_all(fun subprop_subtract/1).
+
+subprop_subtract(Mod) ->
+    ?FORALL(
+        {{S1, M1}, {S2, M2}},
+        ?LET(
+            {L1, L2, B},
+            {ct_proper_ext:safe_list(),
+             ct_proper_ext:safe_list(),
+             ct_proper_ext:safe_list()},
+            {gen_set(Mod, L1 ++ B), gen_set(Mod, L2 ++ B)}
+        ),
+        is_equal(Mod:subtract(S1, S2),
+                 model_subtract(M1, M2)) andalso
+        is_equal(Mod:subtract(S2, S1),
+                 model_subtract(M2, M1))
+    ).
+
+
+%% --- to_list/1 ------------------------------------------------------
+prop_to_list() ->
+    test_all(fun subprop_to_list/1).
+
+subprop_to_list(Mod) ->
+    ?FORALL(
+        {S, M},
+        gen_set(Mod),
+        list_matchsort(Mod:to_list(S)) =:= list_matchsort(model_to_list(M))
+    ).
+
+
+%% --- union/1 --------------------------------------------------------
+prop_union_1() ->
+    test_all(fun subprop_union_1/1).
+
+subprop_union_1(Mod) ->
+    ?FORALL(
+        SMs,
+        ?LET(
+            {Ls, A},
+            {list(ct_proper_ext:safe_list()), ct_proper_ext:safe_list()},
+            [gen_set(Mod, L ++ A) || L <- Ls]
+        ),
+        begin
+            {Ss, Ms} = lists:unzip(SMs),
+            is_equal(Mod:union(Ss),
+                     model_union(Mod, Ms))
+        end
+    ).
+
+
+%% --- union/2 --------------------------------------------------------
+prop_union_2() ->
+    test_all(fun subprop_union_2/1).
+
+subprop_union_2(Mod) ->
+    ?FORALL(
+        {{S1, M1}, {S2, M2}},
+        ?LET(
+            {L1, L2, B},
+            {ct_proper_ext:safe_list(),
+             ct_proper_ext:safe_list(),
+             ct_proper_ext:safe_list()},
+            {gen_set(Mod, L1 ++ B), gen_set(Mod, L2 ++ B)}
+        ),
+        is_equal(Mod:union(S1, S2),
+                 model_union(Mod, M1, M2))
+    ).
+
+%% --- sequence of modifying operations -------------------------------
+prop_operations() ->
+    test_all(fun subprop_operations/1).
+
+subprop_operations(Mod) ->
+    ?FORALL(
+        {SM0, Ops},
+        {gen_set(Mod),
+         list(oneof([{add_element, ct_proper_ext:safe_any()},
+                     {del_element, ct_proper_ext:safe_any()},
+                     {filter, function1(boolean())},
+                     {filtermap, function1(oneof([true,
+                                                  false,
+                                                  {true, ct_proper_ext:safe_any()}]))},
+                     {intersection, gen_set(Mod)},
+                     {map, function1(ct_proper_ext:safe_any())},
+                     {subtract, gen_set(Mod)},
+                     {union, gen_set(Mod)}]))},
+        begin
+            {S1, M1} = lists:foldl(fun
+                                       ({add_element, E}, {SAcc, MAcc}) ->
+                                           {Mod:add_element(E, SAcc),
+                                            model_add_element(E, MAcc)};
+                                       ({del_element, E}, {SAcc, MAcc}) ->
+                                           {Mod:del_element(E, SAcc),
+                                            model_del_element(E, MAcc)};
+                                       ({filter, Fun}, {SAcc, MAcc}) ->
+                                           {Mod:filter(Fun, SAcc),
+                                            model_filter(Fun, MAcc)};
+                                       ({filtermap, Fun}, {SAcc, MAcc}) ->
+                                           {Mod:filtermap(Fun, SAcc),
+                                            model_filtermap(Fun, MAcc)};
+                                       ({intersection, {S, M}}, {SAcc, MAcc}) ->
+                                           {Mod:intersection(SAcc, S),
+                                            model_intersection(MAcc, M)};
+                                       ({map, Fun}, {SAcc, MAcc}) ->
+                                           {Mod:map(Fun, SAcc),
+                                            model_map(Fun, MAcc)};
+                                       ({subtract, {S, M}}, {SAcc, MAcc}) ->
+                                           {Mod:subtract(SAcc, S),
+                                            model_subtract(MAcc, M)};
+                                       ({union, {S, M}}, {SAcc, MAcc}) ->
+                                           {Mod:union(SAcc, S),
+                                            model_union(Mod, MAcc, M)}
+                                   end,
+                                   SM0,
+                                   Ops),
+            is_equal(S1, M1)
+        end
+    ).
+
+%%%%%%%%%%%%%%%%%%
+%%% Generators %%%
+%%%%%%%%%%%%%%%%%%
+
+gen_version() ->
+    oneof([1, 2]).
+
+gen_set(sets) ->
+    ?LET(
+        {L, V},
+        {ct_proper_ext:safe_list(), gen_version()},
+        gen_set(sets, L, V)
+    );
+gen_set(Mod) ->
+    ?LET(
+        L,
+        ct_proper_ext:safe_list(),
+        gen_set(Mod, L, 0)
+    ).
+
+gen_set(sets, List) when is_list(List) ->
+    ?LET(
+        V,
+        gen_version(),
+        gen_set(sets, List, V)
+    );
+gen_set(Mod, List) when is_list(List) ->
+    gen_set(Mod, List, 0);
+gen_set(Mod, Version) when is_integer(Version) ->
+    ?LET(
+        L,
+        ct_proper_ext:safe_list(),
+        gen_set(Mod, L, Version)
+    ).
+
+gen_set(sets, List, Version) ->
+    {sets:from_list(List, [{version, Version}]),
+     model_from_list(sets, List)};
+gen_set(Mod, List, _Version) ->
+    {Mod:from_list(List),
+     model_from_list(Mod, List)}.
+
+
+%%%%%%%%%%%%%
+%%% Model %%%
+%%%%%%%%%%%%%
+
+-record(model, {type, module, content=#{}}).
+
+model_new(sets) ->
+    #model{type=match, module=sets};
+model_new(ordsets) ->
+    #model{type=equal, module=ordsets};
+model_new(gb_sets) ->
+    #model{type=equal, module=gb_sets}.
+
+model_add_element(E, #model{type=equal, content=C}=M) when is_float(E), trunc(E) == E ->
+    M#model{content=C#{trunc(E) => E}};
+model_add_element(E, #model{content=C}=M) ->
+    M#model{content=C#{E => E}}.
+
+model_del_element(E, #model{type=equal, content=C}=M) when is_float(E), trunc(E) == E ->
+    M#model{content=maps:remove(trunc(E), C)};
+model_del_element(E, #model{content=C}=M) ->
+    M#model{content=maps:remove(E, C)}.
+
+model_from_list(Mod, L) ->
+    lists:foldl(fun model_add_element/2, model_new(Mod), L).
+
+model_to_list(#model{content=C}) ->
+    maps:values(C).
+
+model_is_element(E, #model{type=equal, content=C}) when is_float(E), trunc(E) == E ->
+    maps:is_key(trunc(E), C);
+model_is_element(E, #model{content=C}) ->
+    maps:is_key(E, C).
+
+model_size(#model{content=C}) ->
+    maps:size(C).
+
+model_filter(Fun, #model{content=C}=M) ->
+    M#model{content=maps:filter(fun(_K, V) -> Fun(V) end, C)}.
+
+model_map(Fun, #model{module=Mod, content=C}) ->
+    maps:fold(fun(_K, V, Acc) -> model_add_element(Fun(V), Acc) end, model_new(Mod), C).
+
+model_filtermap(Fun, #model{module=Mod, content=C}) ->
+    maps:fold(fun(_K, V0, Acc) ->
+                  case Fun(V0) of
+                      true ->
+                          model_add_element(V0, Acc);
+                      {true, V1} ->
+                          model_add_element(V1, Acc);
+                      false ->
+                          Acc
+                  end
+              end,
+              model_new(Mod),
+              C).
+
+model_fold(Fun, Acc0, #model{content=C}) ->
+    maps:fold(fun(_K, V, Acc1) -> Fun(V, Acc1) end, Acc0, C).
+
+model_subtract(#model{module=Mod, content=C1}=M1, #model{module=Mod, content=C2}) ->
+    M1#model{content=maps:without(maps:keys(C2), C1)}.
+
+model_intersection([M|Ms]) ->
+    model_intersection_1(Ms, M).
+
+model_intersection(M1, M2) ->
+    model_intersection_1([M1], M2).
+
+model_intersection_1([], Acc) ->
+    Acc;
+model_intersection_1([#model{module=Mod, content=C1}|Ms], #model{module=Mod, content=C2}=Acc) ->
+    model_intersection_1(Ms, Acc#model{content=maps:with(maps:keys(C2), maps:with(maps:keys(C1), C2))}).
+
+model_union(Mod, []) ->
+    model_new(Mod);
+model_union(_Mod, [M|Ms]) ->
+    model_union_1(Ms, M).
+
+model_union(_Mod, M1, M2) ->
+    model_union_1([M1], M2).
+
+model_union_1([], Acc) ->
+    Acc;
+model_union_1([#model{module=Mod, content=C1}|Ms], #model{module=Mod, content=C2}=Acc) ->
+    model_union_1(Ms, Acc#model{content=maps:merge(C2, C1)}).
+
+model_is_subset(#model{module=Mod, content=C1}, #model{module=Mod, content=C2}) ->
+    [] =:= maps:keys(C1) -- maps:keys(C2).
+
+model_is_empty(M) ->
+    0 =:= model_size(M).
+
+model_is_disjoint(M1, M2) ->
+    0 =:= model_size(model_intersection(M1, M2)).
+
+
+%%%%%%%%%%%%%%%
+%%% Helpers %%%
+%%%%%%%%%%%%%%%
+
+test_all(Fun) ->
+    conjunction([{T, Fun(T)} || T <- [sets, ordsets, gb_sets]]).
+
+list_matchsort(L) ->
+    lists:sort(fun
+                   (A, B) when is_float(A), is_integer(B) ->
+                       true;
+                   (A, B) when is_integer(A), is_float(B) ->
+                       false;
+                   (A, B) ->
+                       A =< B
+               end,
+               L).
+
+is_equal(S, #model{type=T, module=Mod, content=C}) ->
+    L1 = list_matchsort(Mod:to_list(S)),
+    L2 = list_matchsort(maps:keys(C)),
+    case T of
+        match -> L1 =:= L2;
+        equal -> L1 == L2
+    end.
+
diff --git a/lib/stdlib/test/sets_property_test_SUITE.erl b/lib/stdlib/test/sets_property_test_SUITE.erl
new file mode 100644
index 0000000000..20e6e0bcb3
--- /dev/null
+++ b/lib/stdlib/test/sets_property_test_SUITE.erl
@@ -0,0 +1,122 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2021-2023. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%%     http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%% %CopyrightEnd%
+%%
+-module(sets_property_test_SUITE).
+
+-include_lib("common_test/include/ct.hrl").
+
+-compile(export_all).
+-compile(nowarn_export_all).
+
+all() ->
+    [
+        add_element_case,
+        del_element_case,
+        filter_case,
+        filtermap_case,
+        fold_case,
+	from_list_case,
+        intersection_1_case,
+        intersection_2_case,
+        is_disjoint_case,
+        is_element_case,
+        is_empty_case,
+        is_equal_case,
+        is_set_case,
+        is_subset_case,
+	map_case,
+        size_case,
+        subtract_case,
+        to_list_case,
+        union_1_case,
+        union_2_case,
+	operations_case
+    ].
+
+init_per_suite(Config) ->
+    ct_property_test:init_per_suite(Config).
+
+end_per_suite(Config) ->
+    Config.
+
+do_proptest(Prop, Config) ->
+    ct_property_test:quickcheck(sets_prop:Prop(), Config).
+
+add_element_case(Config) ->
+    do_proptest(prop_add_element, Config).
+
+del_element_case(Config) ->
+    do_proptest(prop_del_element, Config).
+
+filter_case(Config) ->
+    do_proptest(prop_filter, Config).
+
+filtermap_case(Config) ->
+    do_proptest(prop_filtermap, Config).
+
+fold_case(Config) ->
+    do_proptest(prop_fold, Config).
+
+from_list_case(Config) ->
+    do_proptest(prop_from_list, Config).
+
+intersection_1_case(Config) ->
+    do_proptest(prop_intersection_1, Config).
+
+intersection_2_case(Config) ->
+    do_proptest(prop_intersection_2, Config).
+
+is_disjoint_case(Config) ->
+    do_proptest(prop_is_disjoint, Config).
+
+is_element_case(Config) ->
+    do_proptest(prop_is_element, Config).
+
+is_empty_case(Config) ->
+    do_proptest(prop_is_empty, Config).
+
+is_equal_case(Config) ->
+    do_proptest(prop_is_equal, Config).
+
+is_set_case(Config) ->
+    do_proptest(prop_is_set, Config).
+
+is_subset_case(Config) ->
+    do_proptest(prop_is_subset, Config).
+
+map_case(Config) ->
+    do_proptest(prop_map, Config).
+
+size_case(Config) ->
+    do_proptest(prop_size, Config).
+
+subtract_case(Config) ->
+    do_proptest(prop_subtract, Config).
+
+to_list_case(Config) ->
+    do_proptest(prop_to_list, Config).
+
+union_1_case(Config) ->
+    do_proptest(prop_union_1, Config).
+
+union_2_case(Config) ->
+    do_proptest(prop_union_2, Config).
+
+operations_case(Config) ->
+    do_proptest(prop_operations, Config).
-- 
2.35.3

openSUSE Build Service is sponsored by