@@ -17,6 +17,7 @@ pub struct IntValueTree {
17
17
/// If true cannot be simplified or complexified
18
18
fixed : bool ,
19
19
}
20
+
20
21
impl IntValueTree {
21
22
/// Create a new tree
22
23
/// # Arguments
@@ -37,25 +38,30 @@ impl IntValueTree {
37
38
true
38
39
}
39
40
}
41
+
40
42
fn magnitude_greater ( lhs : I256 , rhs : I256 ) -> bool {
41
43
if lhs. is_zero ( ) {
42
44
return false
43
45
}
44
46
( lhs > rhs) ^ ( lhs. is_negative ( ) )
45
47
}
46
48
}
49
+
47
50
impl ValueTree for IntValueTree {
48
51
type Value = I256 ;
52
+
49
53
fn current ( & self ) -> Self :: Value {
50
54
self . curr
51
55
}
56
+
52
57
fn simplify ( & mut self ) -> bool {
53
58
if self . fixed || !IntValueTree :: magnitude_greater ( self . hi , self . lo ) {
54
59
return false
55
60
}
56
61
self . hi = self . curr ;
57
62
self . reposition ( )
58
63
}
64
+
59
65
fn complicate ( & mut self ) -> bool {
60
66
if self . fixed || !IntValueTree :: magnitude_greater ( self . hi , self . lo ) {
61
67
return false
@@ -66,6 +72,7 @@ impl ValueTree for IntValueTree {
66
72
self . reposition ( )
67
73
}
68
74
}
75
+
69
76
/// Value tree for signed ints (up to int256).
70
77
/// The strategy combines 3 different strategies, each assigned a specific weight:
71
78
/// 1. Generate purely random value in a range. This will first choose bit size uniformly (up `bits`
@@ -85,6 +92,7 @@ pub struct IntStrategy {
85
92
/// The weight for purely random values
86
93
random_weight : usize ,
87
94
}
95
+
88
96
impl IntStrategy {
89
97
/// Create a new strategy.
90
98
/// #Arguments
@@ -99,6 +107,7 @@ impl IntStrategy {
99
107
random_weight : 50usize ,
100
108
}
101
109
}
110
+
102
111
fn generate_edge_tree ( & self , runner : & mut TestRunner ) -> NewTree < Self > {
103
112
let rng = runner. rng ( ) ;
104
113
@@ -117,6 +126,7 @@ impl IntStrategy {
117
126
} ;
118
127
Ok ( IntValueTree :: new ( start, false ) )
119
128
}
129
+
120
130
fn generate_fixtures_tree ( & self , runner : & mut TestRunner ) -> NewTree < Self > {
121
131
// generate edge cases if there's no fixtures
122
132
if self . fixtures . is_empty ( ) {
@@ -125,8 +135,10 @@ impl IntStrategy {
125
135
let idx = runner. rng ( ) . gen_range ( 0 ..self . fixtures . len ( ) ) ;
126
136
Ok ( IntValueTree :: new ( self . fixtures [ idx] , false ) )
127
137
}
138
+
128
139
fn generate_random_tree ( & self , runner : & mut TestRunner ) -> NewTree < Self > {
129
140
let rng = runner. rng ( ) ;
141
+
130
142
// generate random number of bits uniformly
131
143
let bits = rng. gen_range ( 0 ..=self . bits ) ;
132
144
@@ -137,6 +149,7 @@ impl IntStrategy {
137
149
// init 2 128-bit randoms
138
150
let mut higher: u128 = rng. gen_range ( 0 ..=u128:: MAX ) ;
139
151
let mut lower: u128 = rng. gen_range ( 0 ..=u128:: MAX ) ;
152
+
140
153
// cut 2 randoms according to bits size
141
154
match bits - 1 {
142
155
x if x < 128 => {
@@ -154,17 +167,20 @@ impl IntStrategy {
154
167
inner[ 1 ] = ( lower >> 64 ) as u64 ;
155
168
inner[ 2 ] = ( higher & mask64) as u64 ;
156
169
inner[ 3 ] = ( higher >> 64 ) as u64 ;
157
- let sign = if rng . gen_bool ( 0.5 ) { Sign :: Positive } else { Sign :: Negative } ;
170
+
158
171
// we have a small bias here, i.e. intN::min will never be generated
159
172
// but it's ok since it's generated in `fn generate_edge_tree(...)`
173
+ let sign = if rng. gen_bool ( 0.5 ) { Sign :: Positive } else { Sign :: Negative } ;
160
174
let ( start, _) = I256 :: overflowing_from_sign_and_abs ( sign, U256 :: from_limbs ( inner) ) ;
161
175
162
176
Ok ( IntValueTree :: new ( start, false ) )
163
177
}
164
178
}
179
+
165
180
impl Strategy for IntStrategy {
166
181
type Tree = IntValueTree ;
167
182
type Value = I256 ;
183
+
168
184
fn new_tree ( & self , runner : & mut TestRunner ) -> NewTree < Self > {
169
185
let total_weight = self . random_weight + self . fixtures_weight + self . edge_weight ;
170
186
let bias = runner. rng ( ) . gen_range ( 0 ..total_weight) ;
0 commit comments