소스 검색

expanded fuzzing

Evan Almloff 2 년 전
부모
커밋
fe162f4a79
1개의 변경된 파일64개의 추가작업 그리고 11개의 파일을 삭제
  1. 64 11
      packages/core/tests/fuzzing.rs

+ 64 - 11
packages/core/tests/fuzzing.rs

@@ -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 {
-            let _ = vdom.render_immediate();
+        // A list of all elements that have had event listeners
+        // 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);
+                    }
+                }
+            }
         }
         }
     }
     }
 }
 }