|
142 | 142 | -export([integer/2, float/2, atom/0, binary/0, binary/1, bitstring/0, |
143 | 143 | bitstring/1, list/1, vector/2, union/1, weighted_union/1, tuple/1, |
144 | 144 | loose_tuple/1, exactly/1, fixed_list/1, fixed_map/1, function/2, map/0, |
145 | | - map/2, any/0, shrink_list/1, safe_union/1, safe_weighted_union/1]). |
| 145 | + map/1, map/2, any/0, shrink_list/1, safe_union/1, safe_weighted_union/1]). |
146 | 146 | -export([integer/0, non_neg_integer/0, pos_integer/0, neg_integer/0, range/2, |
147 | 147 | float/0, non_neg_float/0, number/0, boolean/0, byte/0, char/0, nil/0, |
148 | 148 | list/0, tuple/0, string/0, wunion/1, term/0, timeout/0, arity/0]). |
149 | 149 | -export([int/0, nat/0, largeint/0, real/0, bool/0, choose/2, elements/1, |
150 | 150 | oneof/1, frequency/1, return/1, default/2, orderedlist/1, function0/1, |
151 | | - function1/1, function2/1, function3/1, function4/1, |
| 151 | + function1/1, function2/1, function3/1, function4/1, map_union/1, |
152 | 152 | weighted_default/2]). |
153 | 153 | -export([resize/2, non_empty/1, noshrink/1]). |
154 | 154 |
|
@@ -1120,28 +1120,49 @@ function_is_instance(Type, X) -> |
1120 | 1120 | map() -> |
1121 | 1121 | ?LAZY(map(any(), any())). |
1122 | 1122 |
|
| 1123 | +%% @doc A map whose keys and values are defined by the given `Map'. |
| 1124 | +%% |
| 1125 | +%% Shrinks towards the empty map. That is, all keys are assumed to be optional. |
| 1126 | +%% |
| 1127 | +%% Also written simply as a {@link maps. map}. |
| 1128 | +-spec map(#{Key::raw_type() => Value::raw_type()}) -> proper_types:type(). |
| 1129 | +map(Map) when is_map(Map) -> |
| 1130 | + MapType = maps:map(fun(_Key, Value) -> cook_outer(Value) end, Map), |
| 1131 | + ?CONTAINER([ |
| 1132 | + {generator, {typed, fun map_gen/1}}, |
| 1133 | + {is_instance, {typed, fun map_is_instance/2}}, |
| 1134 | + {internal_types, MapType}, |
| 1135 | + {get_length, fun maps:size/1}, |
| 1136 | + {join, fun maps:merge/2}, |
| 1137 | + {get_indices, fun fixed_map_get_keys/2}, |
| 1138 | + {remove, fun maps:remove/2}, |
| 1139 | + {retrieve, fun maps:get/2}, |
| 1140 | + {update, fun maps:update/3} |
| 1141 | + ]). |
| 1142 | + |
1123 | 1143 | %% @doc A map whose keys are defined by the generator `K' and values |
1124 | 1144 | %% by the generator `V'. |
1125 | 1145 | -spec map(K::raw_type(), V::raw_type()) -> proper_types:type(). |
1126 | 1146 | map(K, V) -> |
1127 | 1147 | ?LET(L, list({K, V}), maps:from_list(L)). |
1128 | 1148 |
|
| 1149 | +%% @doc A map merged from the given map generators. |
| 1150 | +-spec map_union([Map::raw_type()]) -> proper_types:type(). |
| 1151 | +map_union(RawMaps) when is_list(RawMaps) -> |
| 1152 | + ?LET(Maps, RawMaps, lists:foldl(fun maps:merge/2, #{}, Maps)). |
| 1153 | + |
1129 | 1154 | %% @doc A map whose keys and values are defined by the given `Map'. |
1130 | 1155 | %% Also written simply as a {@link maps. map}. |
1131 | 1156 | -spec fixed_map(#{Key::raw_type() => Value::raw_type()}) -> proper_types:type(). |
1132 | | -% fixed_map(Map) when is_map(Map) -> |
1133 | | -% Pairs = maps:to_list(Map), |
1134 | | -% ?LET(L, fixed_list(Pairs), maps:from_list(L)). |
1135 | | - |
1136 | 1157 | fixed_map(Map) when is_map(Map) -> |
| 1158 | + MapType = maps:map(fun(_Key, Value) -> cook_outer(Value) end, Map), |
1137 | 1159 | ?CONTAINER([ |
1138 | 1160 | {generator, {typed, fun map_gen/1}}, |
1139 | 1161 | {is_instance, {typed, fun map_is_instance/2}}, |
1140 | | - {internal_types, Map}, |
| 1162 | + {internal_types, MapType}, |
1141 | 1163 | {get_length, fun maps:size/1}, |
1142 | 1164 | {join, fun maps:merge/2}, |
1143 | | - {get_indices, fun maps:keys/1}, |
1144 | | - {remove, fun maps:remove/2}, |
| 1165 | + {get_indices, fun fixed_map_get_keys/2}, |
1145 | 1166 | {retrieve, fun maps:get/2}, |
1146 | 1167 | {update, fun maps:update/3} |
1147 | 1168 | ]). |
@@ -1184,6 +1205,10 @@ map_all_internal(Fun, none, Result) when is_function(Fun, 2) andalso is_boolean( |
1184 | 1205 | map_all_internal(Fun, {Key, Value, NextIterator}, true) when is_function(Fun, 2) -> |
1185 | 1206 | map_all_internal(Fun, NextIterator, Fun(Key, Value)). |
1186 | 1207 |
|
| 1208 | +fixed_map_get_keys(Type, _X) -> |
| 1209 | + Map = get_prop(internal_types, Type), |
| 1210 | + maps:keys(Map). |
| 1211 | + |
1187 | 1212 | %% @doc All Erlang terms (that PropEr can produce). For reasons of efficiency, |
1188 | 1213 | %% functions are never produced as instances of this type.<br /> |
1189 | 1214 | %% CAUTION: Instances of this type are expensive to produce, shrink and instance- |
|
0 commit comments