|
| 1 | +%% Copyright (C) 2009-2023 UENISHI Kota |
| 2 | +%% |
| 3 | +%% Licensed under the Apache License, Version 2.0 (the "License"); |
| 4 | +%% you may not use this file except in compliance with the License. |
| 5 | +%% You may obtain a copy of the License at |
| 6 | +%% |
| 7 | +%% http://www.apache.org/licenses/LICENSE-2.0 |
| 8 | +%% |
| 9 | +%% Unless required by applicable law or agreed to in writing, software |
| 10 | +%% distributed under the License is distributed on an "AS IS" BASIS, |
| 11 | +%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 12 | +%% See the License for the specific language governing permissions and |
| 13 | +%% limitations under the License. |
| 14 | +%% |
| 15 | + |
1 | 16 | -module(prop_msgpack). |
2 | 17 | -include_lib("proper/include/proper.hrl"). |
3 | 18 | -include("msgpack.hrl"). |
4 | 19 |
|
5 | 20 |
|
| 21 | +%% -define(NUMTESTS, 16). |
| 22 | +%% -define(QC_OUT(P), |
| 23 | +%% eqc:on_output(fun(Str, Args) -> |
| 24 | +%% io:format(user, Str, Args) end, P)). |
| 25 | +%% -define(_assertProp(S), |
| 26 | +%% {timeout, ?NUMTESTS * 10, |
| 27 | +%% ?_assert(quickcheck(numtests(?NUMTESTS, ?QC_OUT(S))))}). |
| 28 | + |
| 29 | +%% eqc_test_() -> |
| 30 | +%% {inparallel, |
| 31 | +%% [ |
| 32 | +%% ?_assertProp(prop_msgpack()), |
| 33 | +%% ?_assertProp(prop_msgpack([{format, jiffy}])), |
| 34 | +%% ?_assertProp(prop_msgpack([{format, jsx}])) |
| 35 | +%% ]}. |
| 36 | + |
6 | 37 | %%% Primitive Properties %%% |
7 | 38 | prop_uint() -> |
8 | 39 | ?FORALL( |
9 | | - UnsignedInt, |
10 | | - oneof([positive_fixnum(), uint8(), uint16(), uint32(), uint64()]), |
11 | | - pack_and_unpack(UnsignedInt)). |
| 40 | + {UnsignedInt, Opts}, |
| 41 | + {oneof([positive_fixnum(), uint8(), uint16(), uint32(), uint64()]), |
| 42 | + stable_opts()}, |
| 43 | + pack_and_unpack(UnsignedInt, Opts)). |
12 | 44 |
|
13 | 45 | prop_int() -> |
14 | 46 | ?FORALL( |
15 | | - Int, |
16 | | - oneof([positive_fixnum(), negative_fixnum(), int8(), int16(), int32(), int64()]), |
17 | | - pack_and_unpack(Int)). |
| 47 | + {Int, Opts}, |
| 48 | + {oneof([positive_fixnum(), negative_fixnum(), int8(), int16(), int32(), int64()]), |
| 49 | + stable_opts()}, |
| 50 | + pack_and_unpack(Int, Opts)). |
18 | 51 |
|
19 | 52 | prop_binary() -> |
20 | 53 | ?FORALL( |
21 | | - Binary, |
22 | | - oneof([fix_raw(), raw16(), raw32()]), |
23 | | - pack_and_unpack(Binary)). |
| 54 | + {Binary, Opts}, |
| 55 | + {oneof([fix_raw(), raw16(), raw32()]), stable_opts()}, |
| 56 | + pack_and_unpack(Binary, Opts)). |
24 | 57 |
|
25 | 58 | prop_float() -> |
26 | 59 | ?FORALL( |
27 | 60 | Float, |
28 | 61 | proper_types:float(), |
29 | | - pack_and_unpack(Float)). |
| 62 | + pack_and_unpack(Float, [])). |
30 | 63 |
|
31 | 64 | prop_primitive() -> |
32 | 65 | ?FORALL( |
33 | | - PrimObj, |
34 | | - oneof(primitive_types()), |
35 | | - pack_and_unpack(PrimObj)). |
| 66 | + {PrimObj, Opts}, |
| 67 | + {oneof(primitive_types()), stable_opts()}, |
| 68 | + pack_and_unpack(PrimObj, Opts)). |
| 69 | + |
| 70 | +prop_array_primitive() -> |
| 71 | + ?FORALL( |
| 72 | + {Array, Opts}, |
| 73 | + {oneof([fix_array_primitive(), array16_primitive()]), stable_opts()}, |
| 74 | + pack_and_unpack(Array, Opts)). |
| 75 | + |
| 76 | +prop_msgpack() -> |
| 77 | + ?FORALL({Obj, Opts}, |
| 78 | + {msgpack_object(), stable_opts()}, |
| 79 | + pack_and_unpack(Obj, Opts)). |
36 | 80 |
|
37 | 81 |
|
38 | 82 | %%% Helpers %%% |
39 | | -pack_and_unpack(Obj) -> |
40 | | - Bin = msgpack:pack(Obj), |
41 | | - {ok, Obj} = msgpack:unpack(Bin), |
| 83 | +pack_and_unpack(Obj, Opts) -> |
| 84 | + Bin = msgpack:pack(Obj, Opts), |
| 85 | + {ok, Obj} = msgpack:unpack(Bin, Opts), |
42 | 86 | is_binary(Bin). |
43 | 87 |
|
| 88 | + |
44 | 89 | %%% Generators %%% |
| 90 | +stable_opts() -> |
| 91 | + % TODO: build property tests on options |
| 92 | + oneof([ |
| 93 | + [], |
| 94 | + [{map_format, jiffy}], |
| 95 | + [{map_format, jsx}] |
| 96 | + ]). |
| 97 | + |
45 | 98 | null() -> null. |
46 | 99 |
|
47 | 100 | positive_fixnum() -> choose(0, 127). |
@@ -80,3 +133,20 @@ primitive_types() -> |
80 | 133 | proper_types:float(), proper_types:bool(), |
81 | 134 | fix_raw(), raw16(), raw32() |
82 | 135 | ]. |
| 136 | + |
| 137 | + |
| 138 | +container_types() -> |
| 139 | + [ fix_array_primitive(), array16_primitive() ]. |
| 140 | + |
| 141 | +fix_array_primitive() -> |
| 142 | + % up to 2^4-1 |
| 143 | + resize(15, proper_types:list(oneof(primitive_types()))). |
| 144 | + |
| 145 | +array16_primitive() -> |
| 146 | + % Up to 2^16-1, but for performance |
| 147 | + resize(128, proper_types:list(oneof(primitive_types()))). |
| 148 | + |
| 149 | + |
| 150 | +%% TODO: add map |
| 151 | +msgpack_object() -> |
| 152 | + oneof(container_types() ++ primitive_types()). |
0 commit comments