expanded fuzzing

This commit is contained in:
Evan Almloff committed 2023-06-02 14:20:03 -05:00
1 parent 563a2b0953
commit fe162f4a79
1 file changed
+64 -11
+64 -11
View File
@@ -1,6 +1,6 @@
use dioxus::prelude::Props; use dioxus::prelude::Props;
use dioxus_core::*; use dioxus_core::*;
use std::cell::Cell; use std::{cell::Cell, collections::HashSet};
fn random_ns() -> Option<&'static str> { fn random_ns() -> Option<&'static str> {
let namespace = rand::random::<u8>() % 2; let namespace = rand::random::<u8>() % 2;
@@ -165,7 +165,7 @@ fn create_random_template(name: &'static str) -> (Template<'static>, Vec<Dynamic
} }
fn create_random_dynamic_node(cx: &ScopeState, depth: usize) -> DynamicNode { fn create_random_dynamic_node(cx: &ScopeState, depth: usize) -> DynamicNode {
let range = if depth > 3 { 1 } else { 3 }; let range = if depth > 5 { 1 } else { 4 };
match rand::random::<u8>() % range { match rand::random::<u8>() % range {
0 => DynamicNode::Placeholder(Default::default()), 0 => DynamicNode::Placeholder(Default::default()),
1 => cx.make_node((0..(rand::random::<u8>() % 5)).map(|_| VNode { 1 => cx.make_node((0..(rand::random::<u8>() % 5)).map(|_| VNode {
@@ -190,12 +190,21 @@ fn create_random_dynamic_node(cx: &ScopeState, depth: usize) -> DynamicNode {
DepthProps { depth, root: false }, DepthProps { depth, root: false },
"create_random_element", "create_random_element",
), ),
3 => {
let data = String::from("borrowed data");
let bumpped = cx.bump().alloc(data);
cx.component(
create_random_element_borrowed,
BorrowedDepthProps { borrow: &*bumpped, inner: DepthProps { depth, root: false } },
"create_random_element_borrowed",
)
}
_ => unreachable!(), _ => unreachable!(),
} }
} }
fn create_random_dynamic_attr(cx: &ScopeState) -> Attribute { fn create_random_dynamic_attr(cx: &ScopeState) -> Attribute {
let value = match rand::random::<u8>() % 6 { let value = match rand::random::<u8>() % 7 {
0 => AttributeValue::Text(Box::leak( 0 => AttributeValue::Text(Box::leak(
format!("{}", rand::random::<usize>()).into_boxed_str(), format!("{}", rand::random::<usize>()).into_boxed_str(),
)), )),
@@ -204,7 +213,16 @@ fn create_random_dynamic_attr(cx: &ScopeState) -> Attribute {
3 => AttributeValue::Bool(rand::random()), 3 => AttributeValue::Bool(rand::random()),
4 => cx.any_value(rand::random::<usize>()), 4 => cx.any_value(rand::random::<usize>()),
5 => AttributeValue::None, 5 => AttributeValue::None,
// Listener(RefCell<Option<ListenerCb<'a>>>), 6 => {
let value = cx.listener(|e: Event<String>| println!("{:?}", e));
return Attribute {
name: "ondata",
value,
namespace: None,
mounted_element: Default::default(),
volatile: false,
};
}
_ => unreachable!(), _ => unreachable!(),
}; };
Attribute { Attribute {
@@ -218,6 +236,19 @@ fn create_random_dynamic_attr(cx: &ScopeState) -> Attribute {
static mut TEMPLATE_COUNT: usize = 0; static mut TEMPLATE_COUNT: usize = 0;
#[derive(Props)]
struct BorrowedDepthProps<'a> {
borrow: &'a str,
inner: DepthProps,
}
fn create_random_element_borrowed<'a>(cx: Scope<'a, BorrowedDepthProps<'a>>) -> Element<'a> {
println!("{}", cx.props.borrow);
let bump = cx.bump();
let allocated = bump.alloc(Scoped { scope: cx, props: &cx.props.inner });
create_random_element(allocated)
}
#[derive(PartialEq, Props)] #[derive(PartialEq, Props)]
struct DepthProps { struct DepthProps {
depth: usize, depth: usize,
@@ -225,7 +256,9 @@ struct DepthProps {
} }
fn create_random_element(cx: Scope<DepthProps>) -> Element { fn create_random_element(cx: Scope<DepthProps>) -> Element {
cx.needs_update(); if rand::random::<usize>() % 10 == 0 {
cx.needs_update();
}
let range = if cx.props.root { 2 } else { 3 }; let range = if cx.props.root { 2 } else { 3 };
let node = match rand::random::<usize>() % range { let node = match rand::random::<usize>() % range {
0 | 1 => { 0 | 1 => {
@@ -243,7 +276,7 @@ fn create_random_element(cx: Scope<DepthProps>) -> Element {
) )
.into_boxed_str(), .into_boxed_str(),
)); ));
println!("{template:#?}"); // println!("{template:#?}");
let node = VNode { let node = VNode {
key: None, key: None,
parent: None, parent: None,
@@ -276,14 +309,14 @@ fn create_random_element(cx: Scope<DepthProps>) -> Element {
} }
_ => None, _ => None,
}; };
println!("{node:#?}"); // println!("{node:#?}");
node node
} }
// test for panics when creating random nodes and templates // test for panics when creating random nodes and templates
#[test] #[test]
fn create() { fn create() {
for _ in 0..100 { for _ in 0..1000 {
let mut vdom = let mut vdom =
VirtualDom::new_with_props(create_random_element, DepthProps { depth: 0, root: true }); VirtualDom::new_with_props(create_random_element, DepthProps { depth: 0, root: true });
let _ = vdom.rebuild(); let _ = vdom.rebuild();
@@ -294,12 +327,32 @@ fn create() {
// This test will change the template every render which is not very realistic, but it helps stress the system // This test will change the template every render which is not very realistic, but it helps stress the system
#[test] #[test]
fn diff() { fn diff() {
for _ in 0..10 { for _ in 0..100000 {
let mut vdom = let mut vdom =
VirtualDom::new_with_props(create_random_element, DepthProps { depth: 0, root: true }); VirtualDom::new_with_props(create_random_element, DepthProps { depth: 0, root: true });
let _ = vdom.rebuild(); let _ = vdom.rebuild();
for _ in 0..10 { // A list of all elements that have had event listeners
let _ = vdom.render_immediate(); // This is intentionally never cleared, so that we can test that calling event listeners that are removed doesn't cause a panic
let mut event_listeners = HashSet::new();
for _ in 0..100 {
for &id in &event_listeners {
println!("firing event on {:?}", id);
vdom.handle_event(
"data",
std::rc::Rc::new(String::from("hello world")),
id,
true,
);
}
{
let muts = vdom.render_immediate();
for mut_ in muts.edits {
if let Mutation::NewEventListener { name, id } = mut_ {
println!("new event listener on {:?} for {:?}", id, name);
event_listeners.insert(id);
}
}
}
} }
} }
} }