147 lines
5.3 KiB
Rust
147 lines
5.3 KiB
Rust
// 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::{IndependentSample, Range};
|
|
use rand::Rng;
|
|
use tendril::StrTendril;
|
|
|
|
fn fuzz() {
|
|
let mut rng = rand::thread_rng();
|
|
let capacity = Range::new(0u32, 1 << 14).ind_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.ind_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).ind_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).ind_sample(rng);
|
|
let end = Range::new(start, text.len() + 1).ind_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();
|
|
}
|