@@ -7,14 +7,16 @@ use proptest::{
77} ;
88use rand:: Rng ;
99
10+ type BinarySearch = proptest:: num:: u128:: BinarySearch ;
11+
1012/// Value tree for unsigned ints (up to u128).
1113/// The strategy combines 2 different strategies, each assigned a specific weight:
1214/// 1. Generate purely random value in a range. This will first choose bit size uniformly (up `bits`
1315/// param). Then generate a value for this bit size.
1416/// 2. Generate a random value around the edges (+/- 3 around 0 and max possible value)
1517#[ derive( Debug ) ]
1618pub struct UintStrategy {
17- /// Bit size of uint (e.g. 128 )
19+ /// Bit size of uint (e.g. 64 )
1820 bits : usize ,
1921 /// A set of fixtures to be generated
2022 fixtures : Vec < FieldElement > ,
@@ -31,25 +33,29 @@ impl UintStrategy {
3133 /// # Arguments
3234 /// * `bits` - Size of uint in bits
3335 /// * `fixtures` - Set of `FieldElements` representing values which the fuzzer weight towards testing.
34- pub fn new ( bits : usize , fixtures : HashSet < FieldElement > ) -> Self {
36+ pub fn new ( bits : usize , fixtures : & HashSet < FieldElement > ) -> Self {
3537 Self {
3638 bits,
37- fixtures : fixtures. into_iter ( ) . collect ( ) ,
39+ // We can only consider the fixtures which fit into the bit width.
40+ fixtures : fixtures. iter ( ) . filter ( |f| f. num_bits ( ) <= bits as u32 ) . copied ( ) . collect ( ) ,
3841 edge_weight : 10usize ,
3942 fixtures_weight : 40usize ,
4043 random_weight : 50usize ,
4144 }
4245 }
4346
47+ /// Generate random numbers starting from near 0 or the maximum of the range.
4448 fn generate_edge_tree ( & self , runner : & mut TestRunner ) -> NewTree < Self > {
4549 let rng = runner. rng ( ) ;
4650 // Choose if we want values around 0 or max
4751 let is_min = rng. gen_bool ( 0.5 ) ;
4852 let offset = rng. gen_range ( 0 ..4 ) ;
4953 let start = if is_min { offset } else { self . type_max ( ) . saturating_sub ( offset) } ;
50- Ok ( proptest :: num :: u128 :: BinarySearch :: new ( start) )
54+ Ok ( BinarySearch :: new ( start) )
5155 }
5256
57+ /// Pick a random `FieldElement` from the `fixtures` as a starting point for
58+ /// generating random numbers.
5359 fn generate_fixtures_tree ( & self , runner : & mut TestRunner ) -> NewTree < Self > {
5460 // generate random cases if there's no fixtures
5561 if self . fixtures . is_empty ( ) {
@@ -58,21 +64,19 @@ impl UintStrategy {
5864
5965 // Generate value tree from fixture.
6066 let fixture = & self . fixtures [ runner. rng ( ) . gen_range ( 0 ..self . fixtures . len ( ) ) ] ;
61- if fixture. num_bits ( ) <= self . bits as u32 {
62- return Ok ( proptest:: num:: u128:: BinarySearch :: new ( fixture. to_u128 ( ) ) ) ;
63- }
6467
65- // If fixture is not a valid type, generate random value.
66- self . generate_random_tree ( runner)
68+ Ok ( BinarySearch :: new ( fixture. to_u128 ( ) ) )
6769 }
6870
71+ /// Generate random values between 0 and the MAX with the given bit width.
6972 fn generate_random_tree ( & self , runner : & mut TestRunner ) -> NewTree < Self > {
7073 let rng = runner. rng ( ) ;
7174 let start = rng. gen_range ( 0 ..=self . type_max ( ) ) ;
7275
73- Ok ( proptest :: num :: u128 :: BinarySearch :: new ( start) )
76+ Ok ( BinarySearch :: new ( start) )
7477 }
7578
79+ /// Maximum integer that fits in the given bit width.
7680 fn type_max ( & self ) -> u128 {
7781 if self . bits < 128 {
7882 ( 1 << self . bits ) - 1
@@ -83,8 +87,10 @@ impl UintStrategy {
8387}
8488
8589impl Strategy for UintStrategy {
86- type Tree = proptest :: num :: u128 :: BinarySearch ;
90+ type Tree = BinarySearch ;
8791 type Value = u128 ;
92+
93+ /// Pick randomly from the 3 available strategies for generating unsigned integers.
8894 fn new_tree ( & self , runner : & mut TestRunner ) -> NewTree < Self > {
8995 let total_weight = self . random_weight + self . fixtures_weight + self . edge_weight ;
9096 let bias = runner. rng ( ) . gen_range ( 0 ..total_weight) ;
0 commit comments