Skip to content

Commit b477cf5

Browse files
committed
fix issues #6 and #7
1 parent 208e927 commit b477cf5

File tree

1 file changed

+52
-37
lines changed

1 file changed

+52
-37
lines changed

lain/src/mutatable.rs

Lines changed: 52 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,7 @@ where
209209
constraints: Option<&Constraints<Self::RangeType>>,
210210
) {
211211
const CHANCE_TO_RESIZE_VEC: f64 = 0.01;
212+
const CHANCE_TO_RESIZE_EMPTY_VEC: f64 = 0.33;
212213

213214
if T::max_default_object_size() == 0 {
214215
return;
@@ -224,29 +225,35 @@ where
224225
})
225226
.unwrap_or(false);
226227

227-
if mutator.gen_chance(CHANCE_TO_RESIZE_VEC) {
228-
let resize_type = VecResizeType::new_fuzzed(mutator, None);
229-
if resize_type == VecResizeType::Grow && can_grow {
228+
if self.is_empty() {
229+
if mutator.gen_chance(CHANCE_TO_RESIZE_EMPTY_VEC) {
230230
grow_vec(self, mutator, constraints.and_then(|c| c.max_size));
231-
} else {
232-
shrink_vec(self, mutator);
233231
}
234232
} else {
235-
// Recreate the constraints so that the min/max types match
236-
let constraints = constraints.and_then(|c| {
237-
if c.max_size.is_none() {
238-
None
233+
if mutator.gen_chance(CHANCE_TO_RESIZE_VEC) {
234+
let resize_type = VecResizeType::new_fuzzed(mutator, None);
235+
if resize_type == VecResizeType::Grow && can_grow {
236+
grow_vec(self, mutator, constraints.and_then(|c| c.max_size));
239237
} else {
240-
let mut new_constraints = Constraints::new();
241-
new_constraints.base_object_size_accounted_for =
242-
c.base_object_size_accounted_for;
243-
new_constraints.max_size = c.max_size;
244-
245-
Some(new_constraints)
238+
shrink_vec(self, mutator);
246239
}
247-
});
240+
} else {
241+
// Recreate the constraints so that the min/max types match
242+
let constraints = constraints.and_then(|c| {
243+
if c.max_size.is_none() {
244+
None
245+
} else {
246+
let mut new_constraints = Constraints::new();
247+
new_constraints.base_object_size_accounted_for =
248+
c.base_object_size_accounted_for;
249+
new_constraints.max_size = c.max_size;
248250

249-
self.as_mut_slice().mutate(mutator, constraints.as_ref());
251+
Some(new_constraints)
252+
}
253+
});
254+
255+
self.as_mut_slice().mutate(mutator, constraints.as_ref());
256+
}
250257
}
251258
}
252259
}
@@ -264,6 +271,7 @@ where
264271
constraints: Option<&Constraints<Self::RangeType>>,
265272
) {
266273
const CHANCE_TO_RESIZE_VEC: f64 = 0.01;
274+
const CHANCE_TO_RESIZE_EMPTY_VEC: f64 = 0.33;
267275

268276
if T::max_default_object_size() == 0 {
269277
return;
@@ -275,29 +283,35 @@ where
275283
.map(|c| c.max_size.map(|s| s > 0).unwrap_or(true))
276284
.unwrap_or(false);
277285

278-
if mutator.gen_chance(CHANCE_TO_RESIZE_VEC) {
279-
let resize_type = VecResizeType::new_fuzzed(mutator, None);
280-
if resize_type == VecResizeType::Grow && can_grow {
286+
if self.is_empty() {
287+
if mutator.gen_chance(CHANCE_TO_RESIZE_EMPTY_VEC) {
281288
grow_vec(self, mutator, constraints.and_then(|c| c.max_size));
282-
} else {
283-
shrink_vec(self, mutator);
284289
}
285290
} else {
286-
// Recreate the constraints so that the min/max types match
287-
let constraints = constraints.and_then(|c| {
288-
if c.max_size.is_none() {
289-
None
291+
if mutator.gen_chance(CHANCE_TO_RESIZE_VEC) {
292+
let resize_type = VecResizeType::new_fuzzed(mutator, None);
293+
if resize_type == VecResizeType::Grow && can_grow {
294+
grow_vec(self, mutator, constraints.and_then(|c| c.max_size));
290295
} else {
291-
let mut new_constraints = Constraints::new();
292-
new_constraints.base_object_size_accounted_for =
293-
c.base_object_size_accounted_for;
294-
new_constraints.max_size = c.max_size;
295-
296-
Some(new_constraints)
296+
shrink_vec(self, mutator);
297297
}
298-
});
298+
} else {
299+
// Recreate the constraints so that the min/max types match
300+
let constraints = constraints.and_then(|c| {
301+
if c.max_size.is_none() {
302+
None
303+
} else {
304+
let mut new_constraints = Constraints::new();
305+
new_constraints.base_object_size_accounted_for =
306+
c.base_object_size_accounted_for;
307+
new_constraints.max_size = c.max_size;
299308

300-
self.as_mut_slice().mutate(mutator, constraints.as_ref());
309+
Some(new_constraints)
310+
}
311+
});
312+
313+
self.as_mut_slice().mutate(mutator, constraints.as_ref());
314+
}
301315
}
302316
}
303317
}
@@ -618,18 +632,19 @@ where
618632
mutator: &mut Mutator<R>,
619633
constraints: Option<&Constraints<Self::RangeType>>,
620634
) {
621-
const CHANCE_TO_FLIP_OPTION_STATE: f64 = 0.01;
635+
const CHANCE_TO_FLIP_SOME_STATE: f64 = 0.05;
636+
const CHANCE_TO_FLIP_NONE_STATE: f64 = 0.10;
622637
match self {
623638
Some(inner) => {
624639
// small chance to make this None
625-
if mutator.gen_chance(CHANCE_TO_FLIP_OPTION_STATE) {
640+
if mutator.gen_chance(CHANCE_TO_FLIP_SOME_STATE) {
626641
*self = None;
627642
} else {
628643
inner.mutate(mutator, constraints);
629644
}
630645
}
631646
None => {
632-
if mutator.gen_chance(CHANCE_TO_FLIP_OPTION_STATE) {
647+
if mutator.gen_chance(CHANCE_TO_FLIP_NONE_STATE) {
633648
let new_item = T::new_fuzzed(mutator, constraints);
634649

635650
*self = Some(new_item);

0 commit comments

Comments
 (0)