26
26
-export ([safe_list /0 ]).
27
27
-export ([safe_tuple /0 ]).
28
28
29
+ -spec safe_list () -> proper_types :type ().
30
+ safe_list () ->
31
+ proper_types :list (safe_any ()).
32
+
33
+
34
+ -spec safe_tuple () -> proper_types :type ().
35
+ safe_tuple () ->
36
+ proper_types :tuple (safe_any ()).
37
+
38
+
29
39
-spec safe_atom () -> proper_types :type ().
30
40
safe_atom () ->
31
41
proper_types :oneof ([proper_types :oneof (['' , true , false , ok ,
@@ -41,16 +51,12 @@ safe_atom() ->
41
51
42
52
-spec existing_atom () -> proper_types :type ().
43
53
existing_atom () ->
44
- proper_types :bind (proper_types :non_neg_integer (),
45
- fun (N ) ->
46
- get_existing_atom (N )
47
- end ,
48
- false ).
54
+ proper_types :lazy (fun () ->
55
+ N = erlang :system_info (atom_count ),
56
+ get_existing_atom (rand_int0 (N - 1 ), N )
57
+ end ).
49
58
50
59
-define (ATOM_TERM_BIN (Index ), <<131 , 75 , Index :24 >>).
51
- get_existing_atom (Index ) ->
52
- get_existing_atom (Index , erlang :system_info (atom_count )).
53
-
54
60
get_existing_atom (Index , Max ) ->
55
61
Index1 = Index rem Max ,
56
62
case binary_to_term (? ATOM_TERM_BIN (Index1 )) of
@@ -73,44 +79,62 @@ safe_any(0) ->
73
79
proper_types :integer (),
74
80
proper_types :float ()]);
75
81
safe_any (Size ) ->
76
- {_ , Choice } = proper_arith :freq_choose ([{3 , simple },
77
- {1 , binary },
78
- {4 , list },
79
- {4 , tuple }]),
80
- NumElements = proper_arith :rand_int (0 , Size ),
81
- case {Choice , NumElements } of
82
- {simple , _NumEls } ->
82
+ case pick_type (Size ) of
83
+ simple ->
83
84
safe_any (0 );
84
- { binary , _NumEls } ->
85
+ binary ->
85
86
proper_types :resize (Size , proper_types :bitstring ());
86
87
{list , 0 } ->
87
88
[];
88
89
{list , 1 } ->
89
- [proper_types :lazy (fun () -> safe_any (Size - 1 ) end )];
90
+ [proper_types :lazy (fun () -> safe_any (Size - 1 ) end )];
90
91
{list , NumEls } ->
91
- ElSizes = proper_arith : distribute (Size - 1 , NumEls ),
92
+ ElSizes = distribute (Size - 1 , NumEls ),
92
93
proper_types :fixed_list ([proper_types :lazy (fun () ->
93
94
safe_any (S )
94
95
end )
95
96
|| S <- ElSizes ]);
96
97
{tuple , 0 } ->
97
98
{};
98
99
{tuple , 1 } ->
99
- {proper_types :lazy (fun () -> safe_any (Size - 1 ) end )};
100
+ {proper_types :lazy (fun () -> safe_any (Size - 1 ) end )};
100
101
{tuple , NumEls } ->
101
- ElSizes = proper_arith : distribute (Size - 1 , NumEls ),
102
+ ElSizes = distribute (Size - 1 , NumEls ),
102
103
proper_types :tuple ([proper_types :lazy (fun () ->
103
104
safe_any (S ) end )
104
105
|| S <- ElSizes ])
105
106
end .
106
107
108
+ pick_type (Size ) ->
109
+ case rand :uniform (100 ) of
110
+ X when X =< 33 ->
111
+ % % 33% tuples
112
+ {tuple , rand_int0 (Size )};
113
+ X when X =< 66 ->
114
+ % % 33% lists
115
+ {list , rand_int0 (Size )};
116
+ X when X =< 75 ->
117
+ % % 9% binaries
118
+ binary ;
119
+ _ ->
120
+ % % 25% simple types
121
+ simple
122
+ end .
107
123
108
- -spec safe_list () -> proper_types :type ().
109
- safe_list () ->
110
- proper_types :list (safe_any ()).
124
+ distribute (Slots , Credits ) ->
125
+ [X || {_ , X } <- lists :sort (distribute_1 (Slots , Credits ))].
111
126
127
+ distribute_1 (0 , 0 ) ->
128
+ [];
129
+ distribute_1 (1 , Credits ) ->
130
+ [{rand :uniform (1000 ), Credits }];
131
+ distribute_1 (Slots , 0 ) ->
132
+ [{rand :uniform (1000 ), 0 } || _ <- lists :seq (1 , Slots )];
133
+ distribute_1 (Slots , Credits ) ->
134
+ N = rand_int0 (Credits ),
135
+ [{rand :uniform (1000 ), N }|distribute_1 (Slots - 1 , Credits - N )].
112
136
113
- -spec safe_tuple () -> proper_types :type ().
114
- safe_tuple () ->
115
- proper_types :tuple (safe_any ()).
116
137
138
+ % % random non-neg integer
139
+ rand_int0 (Max ) ->
140
+ rand :uniform (Max + 1 ) - 1 .
0 commit comments