1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//! A simple fuzz tester for the library.
//#![deny(warnings)]
extern crate rand;
extern crate tendril;
use std::borrow::ToOwned;
use rand::distributions::Distribution;
use rand::distributions::uniform::Uniform as Range;
use rand::Rng;
use tendril::StrTendril;
fn fuzz() {
let mut rng = rand::thread_rng();
let capacity = Range::new(0u32, 1 << 14).sample(&mut rng);
let mut buf_string = String::with_capacity(capacity as usize);
let mut buf_tendril = StrTendril::with_capacity(capacity);
let mut string_slices = vec![];
let mut tendril_slices = vec![];
for _ in 1..100_000 {
if buf_string.len() > (1 << 30) {
buf_string.truncate(0);
buf_tendril.clear();
}
let dist_action = Range::new(0, 100);
match dist_action.sample(&mut rng) {
0..=15 => {
let (start, end) = random_slice(&mut rng, TEXT);
let snip = &TEXT[start..end];
buf_string.push_str(snip);
buf_tendril.push_slice(snip);
assert_eq!(&*buf_string, &*buf_tendril);
}
16..=31 => {
let (start, end) = random_slice(&mut rng, &buf_string);
let snip = &buf_string[start..end].to_owned();
buf_string.push_str(&snip);
buf_tendril.push_slice(&snip);
assert_eq!(&*buf_string, &*buf_tendril);
}
32..=47 => {
let lenstr = format!("[length = {}]", buf_tendril.len());
buf_string.push_str(&lenstr);
buf_tendril.push_slice(&lenstr);
assert_eq!(&*buf_string, &*buf_tendril);
}
48..=63 => {
let n = random_boundary(&mut rng, &buf_string);
buf_tendril.pop_front(n as u32);
buf_string = buf_string[n..].to_owned();
assert_eq!(&*buf_string, &*buf_tendril);
}
64..=79 => {
let new_len = random_boundary(&mut rng, &buf_string);
let n = buf_string.len() - new_len;
buf_string.truncate(new_len);
buf_tendril.pop_back(n as u32);
assert_eq!(&*buf_string, &*buf_tendril);
}
80..=90 => {
let (start, end) = random_slice(&mut rng, &buf_string);
buf_string = buf_string[start..end].to_owned();
buf_tendril = buf_tendril.subtendril(start as u32, (end - start) as u32);
assert_eq!(&*buf_string, &*buf_tendril);
}
91..=96 => {
let c = rng.gen();
buf_string.push(c);
assert!(buf_tendril.try_push_char(c).is_ok());
assert_eq!(&*buf_string, &*buf_tendril);
}
97 => {
buf_string.truncate(0);
buf_tendril.clear();
assert_eq!(&*buf_string, &*buf_tendril);
}
_ => {
let (start, end) = random_slice(&mut rng, &buf_string);
string_slices.push(buf_string[start..end].to_owned());
tendril_slices.push(buf_tendril.subtendril(start as u32, (end - start) as u32));
assert_eq!(string_slices.len(), tendril_slices.len());
assert!(string_slices
.iter()
.zip(tendril_slices.iter())
.all(|(s, t)| **s == **t));
}
}
}
}
fn random_boundary<R: Rng>(rng: &mut R, text: &str) -> usize {
loop {
let i = Range::new(0, text.len() + 1).sample(rng);
if text.is_char_boundary(i) {
return i;
}
}
}
fn random_slice<R: Rng>(rng: &mut R, text: &str) -> (usize, usize) {
loop {
let start = Range::new(0, text.len() + 1).sample(rng);
let end = Range::new(start, text.len() + 1).sample(rng);
if !text.is_char_boundary(start) {
continue;
}
if end < text.len() && !text.is_char_boundary(end) {
continue;
}
return (start, end);
}
}
static TEXT: &'static str =
"It was from the artists and poets that the pertinent answers came, and I \
know that panic would have broken loose had they been able to compare notes. \
As it was, lacking their original letters, I half suspected the compiler of \
having asked leading questions, or of having edited the correspondence in \
corroboration of what he had latently resolved to see.\
\
˙ǝǝs oʇ pǝʌʃosǝɹ ʎʃʇuǝʇɐʃ pɐɥ ǝɥ ʇɐɥʍ ɟo uoıʇɐɹoqoɹɹoɔ uı ǝɔuǝpuodsǝɹɹoɔ ǝɥʇ \
pǝʇıpǝ ƃuıʌɐɥ ɟo ɹo 'suoıʇsǝnb ƃuıpɐǝʃ pǝʞsɐ ƃuıʌɐɥ ɟo ɹǝʃıdɯoɔ ǝɥʇ pǝʇɔǝdsns \
ɟʃɐɥ I 'sɹǝʇʇǝʃ ʃɐuıƃıɹo ɹıǝɥʇ ƃuıʞɔɐʃ 'sɐʍ ʇı s∀ ˙sǝʇou ǝɹɐdɯoɔ oʇ ǝʃqɐ uǝǝq \
ʎǝɥʇ pɐɥ ǝsooʃ uǝʞoɹq ǝʌɐɥ pʃnoʍ ɔıuɐd ʇɐɥʇ ʍouʞ I puɐ 'ǝɯɐɔ sɹǝʍsuɐ ʇuǝuıʇɹǝd \
ǝɥʇ ʇɐɥʇ sʇǝod puɐ sʇsıʇɹɐ ǝɥʇ ɯoɹɟ sɐʍ ʇI";
fn main() {
fuzz();
}
|