add tests for the interperter
This commit is contained in:
1 parent
9be8cc503f
commit
0f2ff34a30
3 files changed
+366
-1
No files matched your search
@@ -17,3 +17,7 @@ dioxus-ssr = { path = "../ssr" }
|
|||||||
dioxus-core = { path = "../core" }
|
dioxus-core = { path = "../core" }
|
||||||
dioxus-html = { path = "../html" }
|
dioxus-html = { path = "../html" }
|
||||||
dioxus-hooks = { path = "../hooks"}
|
dioxus-hooks = { path = "../hooks"}
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
dioxus-core-macro = { path = "../core-macro" }
|
||||||
|
bumpalo = { version = "3.6", features = ["collections", "boxed"] }
|
||||||
@@ -53,7 +53,12 @@ pub fn build<'a>(
|
|||||||
for child in rsx.roots {
|
for child in rsx.roots {
|
||||||
children_built.push(build_node(child, &mut ctx, factory)?);
|
children_built.push(build_node(child, &mut ctx, factory)?);
|
||||||
}
|
}
|
||||||
Ok(factory.fragment_from_iter(children_built.iter()))
|
|
||||||
|
if children_built.len() == 1 {
|
||||||
|
return Ok(children_built.pop().unwrap());
|
||||||
|
} else {
|
||||||
|
Ok(factory.fragment_from_iter(children_built.iter()))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_node<'a>(
|
fn build_node<'a>(
|
||||||
|
|||||||
@@ -0,0 +1,356 @@
|
|||||||
|
use std::cell::{Cell, RefCell};
|
||||||
|
|
||||||
|
use bumpalo::boxed::Box;
|
||||||
|
use dioxus_core::{prelude::*, AnyEvent};
|
||||||
|
use dioxus_core_macro::*;
|
||||||
|
use dioxus_html as dioxus_elements;
|
||||||
|
use dioxus_rsx_interpreter::{
|
||||||
|
captuered_context::{CapturedContext, FormattedArg, IfmtArgs},
|
||||||
|
CodeLocation, ErrorHandler,
|
||||||
|
};
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
fn render_basic() {
|
||||||
|
fn Base(cx: Scope) -> Element {
|
||||||
|
rsx!(cx, div {})
|
||||||
|
}
|
||||||
|
|
||||||
|
let dom = VirtualDom::new(Base);
|
||||||
|
let static_vnodes = rsx!(div{"hello world"});
|
||||||
|
let location = CodeLocation {
|
||||||
|
file: String::new(),
|
||||||
|
line: 0,
|
||||||
|
column: 0,
|
||||||
|
};
|
||||||
|
let empty_context = CapturedContext {
|
||||||
|
captured: IfmtArgs {
|
||||||
|
named_args: Vec::new(),
|
||||||
|
},
|
||||||
|
components: Vec::new(),
|
||||||
|
iterators: Vec::new(),
|
||||||
|
expressions: Vec::new(),
|
||||||
|
listeners: Vec::new(),
|
||||||
|
location: location.clone(),
|
||||||
|
};
|
||||||
|
let interperted_vnodes = LazyNodes::new(|factory| {
|
||||||
|
dioxus_rsx_interpreter::resolve_scope(
|
||||||
|
location,
|
||||||
|
"div{\"hello world\"}",
|
||||||
|
empty_context,
|
||||||
|
factory,
|
||||||
|
)
|
||||||
|
});
|
||||||
|
|
||||||
|
let interperted_vnodes = dom.render_vnodes(interperted_vnodes);
|
||||||
|
let static_vnodes = dom.render_vnodes(static_vnodes);
|
||||||
|
assert!(check_eq(interperted_vnodes, static_vnodes));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
fn render_nested() {
|
||||||
|
fn Base(cx: Scope) -> Element {
|
||||||
|
rsx!(cx, div {})
|
||||||
|
}
|
||||||
|
|
||||||
|
let dom = VirtualDom::new(Base);
|
||||||
|
let static_vnodes = rsx! {
|
||||||
|
div {
|
||||||
|
p { "hello world" }
|
||||||
|
div {
|
||||||
|
p { "hello world" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let location = CodeLocation {
|
||||||
|
file: String::new(),
|
||||||
|
line: 1,
|
||||||
|
column: 0,
|
||||||
|
};
|
||||||
|
let empty_context = CapturedContext {
|
||||||
|
captured: IfmtArgs {
|
||||||
|
named_args: Vec::new(),
|
||||||
|
},
|
||||||
|
components: Vec::new(),
|
||||||
|
iterators: Vec::new(),
|
||||||
|
expressions: Vec::new(),
|
||||||
|
listeners: Vec::new(),
|
||||||
|
location: location.clone(),
|
||||||
|
};
|
||||||
|
let interperted_vnodes = LazyNodes::new(|factory| {
|
||||||
|
dioxus_rsx_interpreter::resolve_scope(
|
||||||
|
location,
|
||||||
|
r#"div {
|
||||||
|
p { "hello world" }
|
||||||
|
div {
|
||||||
|
p { "hello world" }
|
||||||
|
}
|
||||||
|
}"#,
|
||||||
|
empty_context,
|
||||||
|
factory,
|
||||||
|
)
|
||||||
|
});
|
||||||
|
|
||||||
|
let interperted_vnodes = dom.render_vnodes(interperted_vnodes);
|
||||||
|
let static_vnodes = dom.render_vnodes(static_vnodes);
|
||||||
|
assert!(check_eq(interperted_vnodes, static_vnodes));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
fn render_component() {
|
||||||
|
fn Comp(cx: Scope) -> Element {
|
||||||
|
rsx!(cx, div {})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn Base(cx: Scope) -> Element {
|
||||||
|
rsx!(cx, div {})
|
||||||
|
}
|
||||||
|
|
||||||
|
let dom = VirtualDom::new(Base);
|
||||||
|
let static_vnodes = rsx! {
|
||||||
|
div {
|
||||||
|
Comp {}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let location = CodeLocation {
|
||||||
|
file: String::new(),
|
||||||
|
line: 2,
|
||||||
|
column: 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
let interperted_vnodes = LazyNodes::new(|factory| {
|
||||||
|
let context = CapturedContext {
|
||||||
|
captured: IfmtArgs {
|
||||||
|
named_args: Vec::new(),
|
||||||
|
},
|
||||||
|
components: vec![(
|
||||||
|
r#"__cx.component(Comp, fc_to_builder(Comp).build(), None, "Comp")"#,
|
||||||
|
factory.component(Comp, (), None, "Comp"),
|
||||||
|
)],
|
||||||
|
iterators: Vec::new(),
|
||||||
|
expressions: Vec::new(),
|
||||||
|
listeners: Vec::new(),
|
||||||
|
location: location.clone(),
|
||||||
|
};
|
||||||
|
dioxus_rsx_interpreter::resolve_scope(
|
||||||
|
location,
|
||||||
|
r#"div {
|
||||||
|
Comp {}
|
||||||
|
}"#,
|
||||||
|
context,
|
||||||
|
factory,
|
||||||
|
)
|
||||||
|
});
|
||||||
|
|
||||||
|
let interperted_vnodes = dom.render_vnodes(interperted_vnodes);
|
||||||
|
let static_vnodes = dom.render_vnodes(static_vnodes);
|
||||||
|
println!("{:#?}", interperted_vnodes);
|
||||||
|
println!("{:#?}", static_vnodes);
|
||||||
|
assert!(check_eq(interperted_vnodes, static_vnodes));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
fn render_iterator() {
|
||||||
|
fn Base(cx: Scope) -> Element {
|
||||||
|
rsx!(cx, div {})
|
||||||
|
}
|
||||||
|
|
||||||
|
let dom = VirtualDom::new(Base);
|
||||||
|
let iter = (0..10).map(|i| dom.render_vnodes(rsx! {"{i}"}));
|
||||||
|
let static_vnodes = rsx! {
|
||||||
|
div {
|
||||||
|
iter
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let location = CodeLocation {
|
||||||
|
file: String::new(),
|
||||||
|
line: 3,
|
||||||
|
column: 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
let interperted_vnodes = LazyNodes::new(|factory| {
|
||||||
|
let context = CapturedContext {
|
||||||
|
captured: IfmtArgs {
|
||||||
|
named_args: Vec::new(),
|
||||||
|
},
|
||||||
|
components: Vec::new(),
|
||||||
|
iterators: vec![(
|
||||||
|
r#"
|
||||||
|
(0..10).map(|i| dom.render_vnodes(rsx!{"{i}"}))"#,
|
||||||
|
factory.fragment_from_iter((0..10).map(|i| factory.text(format_args!("{i}")))),
|
||||||
|
)],
|
||||||
|
expressions: Vec::new(),
|
||||||
|
listeners: Vec::new(),
|
||||||
|
location: location.clone(),
|
||||||
|
};
|
||||||
|
dioxus_rsx_interpreter::resolve_scope(
|
||||||
|
location,
|
||||||
|
r#"div {
|
||||||
|
(0..10).map(|i| dom.render_vnodes(rsx!{"{i}"}))
|
||||||
|
}"#,
|
||||||
|
context,
|
||||||
|
factory,
|
||||||
|
)
|
||||||
|
});
|
||||||
|
|
||||||
|
let interperted_vnodes = dom.render_vnodes(interperted_vnodes);
|
||||||
|
let static_vnodes = dom.render_vnodes(static_vnodes);
|
||||||
|
println!("{:#?}", interperted_vnodes);
|
||||||
|
println!("{:#?}", static_vnodes);
|
||||||
|
assert!(check_eq(interperted_vnodes, static_vnodes));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
fn render_captured_variable() {
|
||||||
|
fn Base(cx: Scope) -> Element {
|
||||||
|
rsx!(cx, div {})
|
||||||
|
}
|
||||||
|
|
||||||
|
let dom = VirtualDom::new(Base);
|
||||||
|
|
||||||
|
let x = 10;
|
||||||
|
let static_vnodes = rsx! {
|
||||||
|
div {
|
||||||
|
"{x}"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let location = CodeLocation {
|
||||||
|
file: String::new(),
|
||||||
|
line: 4,
|
||||||
|
column: 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
let interperted_vnodes = LazyNodes::new(|factory| {
|
||||||
|
let context = CapturedContext {
|
||||||
|
captured: IfmtArgs {
|
||||||
|
named_args: vec![FormattedArg {
|
||||||
|
expr: "x",
|
||||||
|
format_args: "",
|
||||||
|
result: x.to_string(),
|
||||||
|
}],
|
||||||
|
},
|
||||||
|
components: Vec::new(),
|
||||||
|
iterators: Vec::new(),
|
||||||
|
expressions: Vec::new(),
|
||||||
|
listeners: Vec::new(),
|
||||||
|
location: location.clone(),
|
||||||
|
};
|
||||||
|
dioxus_rsx_interpreter::resolve_scope(
|
||||||
|
location,
|
||||||
|
r#"div {
|
||||||
|
"{x}"
|
||||||
|
}"#,
|
||||||
|
context,
|
||||||
|
factory,
|
||||||
|
)
|
||||||
|
});
|
||||||
|
|
||||||
|
let interperted_vnodes = dom.render_vnodes(interperted_vnodes);
|
||||||
|
let static_vnodes = dom.render_vnodes(static_vnodes);
|
||||||
|
println!("{:#?}", interperted_vnodes);
|
||||||
|
println!("{:#?}", static_vnodes);
|
||||||
|
assert!(check_eq(interperted_vnodes, static_vnodes));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
fn render_listener() {
|
||||||
|
fn Base(cx: Scope) -> Element {
|
||||||
|
rsx!(cx, div {})
|
||||||
|
}
|
||||||
|
|
||||||
|
let dom = VirtualDom::new(Base);
|
||||||
|
let static_vnodes = rsx! {
|
||||||
|
div {
|
||||||
|
onclick: |_| println!("clicked")
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let location = CodeLocation {
|
||||||
|
file: String::new(),
|
||||||
|
line: 5,
|
||||||
|
column: 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
let interperted_vnodes = LazyNodes::new(|factory| {
|
||||||
|
let f = |_| println!("clicked");
|
||||||
|
let f = factory.bump().alloc(f);
|
||||||
|
let context = CapturedContext {
|
||||||
|
captured: IfmtArgs {
|
||||||
|
named_args: Vec::new(),
|
||||||
|
},
|
||||||
|
components: Vec::new(),
|
||||||
|
iterators: Vec::new(),
|
||||||
|
expressions: Vec::new(),
|
||||||
|
listeners: vec![(
|
||||||
|
r#"dioxus_elements::on::onclick(__cx, |_| println!("clicked"))"#,
|
||||||
|
dioxus_elements::on::onclick(factory, f),
|
||||||
|
)],
|
||||||
|
location: location.clone(),
|
||||||
|
};
|
||||||
|
dioxus_rsx_interpreter::resolve_scope(
|
||||||
|
location,
|
||||||
|
r#"div {
|
||||||
|
onclick: |_| println!("clicked")
|
||||||
|
}"#,
|
||||||
|
context,
|
||||||
|
factory,
|
||||||
|
)
|
||||||
|
});
|
||||||
|
|
||||||
|
let interperted_vnodes = dom.render_vnodes(interperted_vnodes);
|
||||||
|
let static_vnodes = dom.render_vnodes(static_vnodes);
|
||||||
|
println!("{:#?}", interperted_vnodes);
|
||||||
|
println!("{:#?}", static_vnodes);
|
||||||
|
assert!(check_eq(interperted_vnodes, static_vnodes));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn check_eq<'a>(a: &'a VNode<'a>, b: &'a VNode<'a>) -> bool {
|
||||||
|
match (a, b) {
|
||||||
|
(VNode::Text(t_a), VNode::Text(t_b)) => t_a.text == t_b.text,
|
||||||
|
(VNode::Element(e_a), VNode::Element(e_b)) => {
|
||||||
|
e_a.attributes
|
||||||
|
.iter()
|
||||||
|
.zip(e_b.attributes.iter())
|
||||||
|
.all(|(a, b)| {
|
||||||
|
a.is_static == b.is_static
|
||||||
|
&& a.is_volatile == b.is_volatile
|
||||||
|
&& a.name == b.name
|
||||||
|
&& a.value == b.value
|
||||||
|
&& a.namespace == b.namespace
|
||||||
|
})
|
||||||
|
&& e_a
|
||||||
|
.children
|
||||||
|
.iter()
|
||||||
|
.zip(e_b.children.iter())
|
||||||
|
.all(|(a, b)| check_eq(a, b))
|
||||||
|
&& e_a.key == e_b.key
|
||||||
|
&& e_a.tag == e_b.tag
|
||||||
|
&& e_a.namespace == e_b.namespace
|
||||||
|
&& e_a
|
||||||
|
.listeners
|
||||||
|
.iter()
|
||||||
|
.zip(e_b.listeners.iter())
|
||||||
|
.all(|(a, b)| a.event == b.event)
|
||||||
|
}
|
||||||
|
(VNode::Fragment(f_a), VNode::Fragment(f_b)) => {
|
||||||
|
f_a.key == f_b.key
|
||||||
|
&& f_a
|
||||||
|
.children
|
||||||
|
.iter()
|
||||||
|
.zip(f_b.children.iter())
|
||||||
|
.all(|(a, b)| check_eq(a, b))
|
||||||
|
}
|
||||||
|
(VNode::Component(c_a), VNode::Component(c_b)) => {
|
||||||
|
c_a.can_memoize == c_b.can_memoize
|
||||||
|
&& c_a.key == c_b.key
|
||||||
|
&& c_a.fn_name == c_b.fn_name
|
||||||
|
&& c_a.user_fc == c_b.user_fc
|
||||||
|
}
|
||||||
|
(VNode::Placeholder(_), VNode::Placeholder(_)) => true,
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in new issue
Block a user