improved documentation and refactored naming to be more self-explanatory
This commit is contained in:
1 parent
e4d60c8dfc
commit
adfbb6c380
91 files changed
+1663
-1553
No files matched your search
@@ -36,13 +36,14 @@ fn sort_bfs(paths: &[&'static [u8]]) -> Vec<(usize, &'static [u8])> {
|
||||
#[test]
|
||||
#[cfg(debug_assertions)]
|
||||
fn sorting() {
|
||||
let r: [(usize, &[u8]); 5] = [
|
||||
(0, &[0, 1]),
|
||||
(1, &[0, 2]),
|
||||
(2, &[1, 0]),
|
||||
(3, &[1, 0, 1]),
|
||||
(4, &[1, 2]),
|
||||
];
|
||||
let r: [(usize, &[u8]); 5] =
|
||||
[
|
||||
(0, &[0, 1]),
|
||||
(1, &[0, 2]),
|
||||
(2, &[1, 0]),
|
||||
(3, &[1, 0, 1]),
|
||||
(4, &[1, 2]),
|
||||
];
|
||||
assert_eq!(
|
||||
sort_bfs(&[&[0, 1,], &[0, 2,], &[1, 0,], &[1, 0, 1,], &[1, 2,],]),
|
||||
r
|
||||
|
||||
@@ -531,9 +531,9 @@ impl<'a> From<&'a AttributeValue<'a>> for BorrowedAttributeValue<'a> {
|
||||
}
|
||||
AttributeValue::Any(value) => {
|
||||
let value = value.borrow();
|
||||
BorrowedAttributeValue::Any(std::cell::Ref::map(value, |value| {
|
||||
&**value.as_ref().unwrap()
|
||||
}))
|
||||
BorrowedAttributeValue::Any(
|
||||
std::cell::Ref::map(value, |value| &**value.as_ref().unwrap())
|
||||
)
|
||||
}
|
||||
AttributeValue::None => BorrowedAttributeValue::None,
|
||||
}
|
||||
|
||||
@@ -267,10 +267,11 @@ impl VirtualDom {
|
||||
suspended_scopes: Default::default(),
|
||||
};
|
||||
|
||||
let root = dom.new_scope(
|
||||
Box::new(VProps::new(root, |_, _| unreachable!(), root_props)),
|
||||
"app",
|
||||
);
|
||||
let root =
|
||||
dom.new_scope(
|
||||
Box::new(VProps::new(root, |_, _| unreachable!(), root_props)),
|
||||
"app",
|
||||
);
|
||||
|
||||
// Unlike react, we provide a default error boundary that just renders the error as a string
|
||||
root.provide_context(Rc::new(ErrorBoundary::new(ScopeId::ROOT)));
|
||||
|
||||
@@ -9,20 +9,23 @@ use dioxus_core::BorrowedAttributeValue;
|
||||
|
||||
#[test]
|
||||
fn attrs_cycle() {
|
||||
let mut dom = VirtualDom::new(|cx| {
|
||||
let id = cx.generation();
|
||||
match cx.generation() % 2 {
|
||||
0 => cx.render(rsx! {
|
||||
div {}
|
||||
}),
|
||||
1 => cx.render(rsx! {
|
||||
div {
|
||||
h1 { class: "{id}", id: "{id}" }
|
||||
let mut dom =
|
||||
VirtualDom::new(|cx| {
|
||||
let id = cx.generation();
|
||||
match cx.generation() % 2 {
|
||||
0 => {
|
||||
cx.render(rsx! {
|
||||
div {}
|
||||
})
|
||||
}
|
||||
}),
|
||||
_ => unreachable!(),
|
||||
}
|
||||
});
|
||||
1 => cx.render(rsx! {
|
||||
div {
|
||||
h1 { class: "{id}", id: "{id}" }
|
||||
}
|
||||
}),
|
||||
_ => unreachable!(),
|
||||
}
|
||||
});
|
||||
|
||||
let bump = Bump::new();
|
||||
|
||||
|
||||
@@ -3,11 +3,12 @@
|
||||
use dioxus::prelude::*;
|
||||
|
||||
fn app(cx: Scope) -> Element {
|
||||
let raw = match cx.generation() % 2 {
|
||||
0 => "123.123",
|
||||
1 => "123.123.123",
|
||||
_ => unreachable!(),
|
||||
};
|
||||
let raw =
|
||||
match cx.generation() % 2 {
|
||||
0 => "123.123",
|
||||
1 => "123.123.123",
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
let value = raw.parse::<f32>().unwrap_or(123.123);
|
||||
|
||||
|
||||
@@ -11,15 +11,16 @@ use dioxus_core::ElementId;
|
||||
|
||||
#[test]
|
||||
fn test_original_diff() {
|
||||
let mut dom = VirtualDom::new(|cx| {
|
||||
cx.render(rsx! {
|
||||
div {
|
||||
let mut dom =
|
||||
VirtualDom::new(|cx| {
|
||||
cx.render(rsx! {
|
||||
div {
|
||||
"Hello, world!"
|
||||
div {
|
||||
"Hello, world!"
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
});
|
||||
})
|
||||
});
|
||||
|
||||
let edits = dom.rebuild().santize();
|
||||
|
||||
@@ -82,11 +83,12 @@ fn create() {
|
||||
|
||||
#[test]
|
||||
fn create_list() {
|
||||
let mut dom = VirtualDom::new(|cx| {
|
||||
cx.render(rsx! {
|
||||
(0..3).map(|f| rsx!( div { "hello" } ))
|
||||
})
|
||||
});
|
||||
let mut dom =
|
||||
VirtualDom::new(|cx| {
|
||||
cx.render(rsx! {
|
||||
(0..3).map(|f| rsx!( div { "hello" } ))
|
||||
})
|
||||
});
|
||||
|
||||
let _edits = dom.rebuild().santize();
|
||||
|
||||
@@ -160,16 +162,17 @@ fn create_components() {
|
||||
|
||||
#[test]
|
||||
fn anchors() {
|
||||
let mut dom = VirtualDom::new(|cx| {
|
||||
cx.render(rsx! {
|
||||
if true {
|
||||
rsx!( div { "hello" } )
|
||||
}
|
||||
if false {
|
||||
rsx!( div { "goodbye" } )
|
||||
}
|
||||
})
|
||||
});
|
||||
let mut dom =
|
||||
VirtualDom::new(|cx| {
|
||||
cx.render(rsx! {
|
||||
if true {
|
||||
rsx!( div { "hello" } )
|
||||
}
|
||||
if false {
|
||||
rsx!( div { "goodbye" } )
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
// note that the template under "false" doesn't show up since it's not loaded
|
||||
let edits = dom.rebuild().santize();
|
||||
|
||||
@@ -24,12 +24,13 @@ fn empty_fragment_creates_nothing() {
|
||||
|
||||
#[test]
|
||||
fn root_fragments_work() {
|
||||
let mut vdom = VirtualDom::new(|cx| {
|
||||
cx.render(rsx!(
|
||||
div { "hello" }
|
||||
div { "goodbye" }
|
||||
))
|
||||
});
|
||||
let mut vdom =
|
||||
VirtualDom::new(|cx| {
|
||||
cx.render(rsx!(
|
||||
div { "hello" }
|
||||
div { "goodbye" }
|
||||
))
|
||||
});
|
||||
|
||||
assert_eq!(
|
||||
vdom.rebuild().edits.last().unwrap(),
|
||||
|
||||
@@ -4,17 +4,18 @@ use pretty_assertions::assert_eq;
|
||||
|
||||
#[test]
|
||||
fn list_creates_one_by_one() {
|
||||
let mut dom = VirtualDom::new(|cx| {
|
||||
let gen = cx.generation();
|
||||
let mut dom =
|
||||
VirtualDom::new(|cx| {
|
||||
let gen = cx.generation();
|
||||
|
||||
cx.render(rsx! {
|
||||
div {
|
||||
(0..gen).map(|i| rsx! {
|
||||
div { "{i}" }
|
||||
})
|
||||
}
|
||||
})
|
||||
});
|
||||
cx.render(rsx! {
|
||||
div {
|
||||
(0..gen).map(|i| rsx! {
|
||||
div { "{i}" }
|
||||
})
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
// load the div and then assign the empty fragment as a placeholder
|
||||
assert_eq!(
|
||||
@@ -73,17 +74,18 @@ fn list_creates_one_by_one() {
|
||||
|
||||
#[test]
|
||||
fn removes_one_by_one() {
|
||||
let mut dom = VirtualDom::new(|cx| {
|
||||
let gen = 3 - cx.generation() % 4;
|
||||
let mut dom =
|
||||
VirtualDom::new(|cx| {
|
||||
let gen = 3 - cx.generation() % 4;
|
||||
|
||||
cx.render(rsx! {
|
||||
div {
|
||||
(0..gen).map(|i| rsx! {
|
||||
div { "{i}" }
|
||||
})
|
||||
}
|
||||
})
|
||||
});
|
||||
cx.render(rsx! {
|
||||
div {
|
||||
(0..gen).map(|i| rsx! {
|
||||
div { "{i}" }
|
||||
})
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
// load the div and then assign the empty fragment as a placeholder
|
||||
assert_eq!(
|
||||
@@ -150,16 +152,17 @@ fn removes_one_by_one() {
|
||||
|
||||
#[test]
|
||||
fn list_shrink_multiroot() {
|
||||
let mut dom = VirtualDom::new(|cx| {
|
||||
cx.render(rsx! {
|
||||
div {
|
||||
(0..cx.generation()).map(|i| rsx! {
|
||||
div { "{i}" }
|
||||
div { "{i}" }
|
||||
})
|
||||
}
|
||||
})
|
||||
});
|
||||
let mut dom =
|
||||
VirtualDom::new(|cx| {
|
||||
cx.render(rsx! {
|
||||
div {
|
||||
(0..cx.generation()).map(|i| rsx! {
|
||||
div { "{i}" }
|
||||
div { "{i}" }
|
||||
})
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
assert_eq!(
|
||||
dom.rebuild().santize().edits,
|
||||
|
||||
@@ -8,9 +8,7 @@ fn random_ns() -> Option<&'static str> {
|
||||
let namespace = rand::random::<u8>() % 2;
|
||||
match namespace {
|
||||
0 => None,
|
||||
1 => Some(Box::leak(
|
||||
format!("ns{}", rand::random::<usize>()).into_boxed_str(),
|
||||
)),
|
||||
1 => Some(Box::leak(format!("ns{}", rand::random::<usize>()).into_boxed_str())),
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
@@ -22,13 +20,15 @@ fn create_random_attribute(attr_idx: &mut usize) -> TemplateAttribute<'static> {
|
||||
value: Box::leak(format!("value{}", rand::random::<usize>()).into_boxed_str()),
|
||||
namespace: random_ns(),
|
||||
},
|
||||
1 => TemplateAttribute::Dynamic {
|
||||
id: {
|
||||
let old_idx = *attr_idx;
|
||||
*attr_idx += 1;
|
||||
old_idx
|
||||
},
|
||||
},
|
||||
1 => {
|
||||
TemplateAttribute::Dynamic {
|
||||
id: {
|
||||
let old_idx = *attr_idx;
|
||||
*attr_idx += 1;
|
||||
old_idx
|
||||
},
|
||||
}
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
@@ -73,22 +73,26 @@ fn create_random_template_node(
|
||||
1 => TemplateNode::Text {
|
||||
text: Box::leak(format!("{}", rand::random::<usize>()).into_boxed_str()),
|
||||
},
|
||||
2 => TemplateNode::DynamicText {
|
||||
id: {
|
||||
let old_idx = *template_idx;
|
||||
*template_idx += 1;
|
||||
dynamic_node_types.push(DynamicNodeType::Text);
|
||||
old_idx
|
||||
},
|
||||
},
|
||||
3 => TemplateNode::Dynamic {
|
||||
id: {
|
||||
let old_idx = *template_idx;
|
||||
*template_idx += 1;
|
||||
dynamic_node_types.push(DynamicNodeType::Other);
|
||||
old_idx
|
||||
},
|
||||
},
|
||||
2 => {
|
||||
TemplateNode::DynamicText {
|
||||
id: {
|
||||
let old_idx = *template_idx;
|
||||
*template_idx += 1;
|
||||
dynamic_node_types.push(DynamicNodeType::Text);
|
||||
old_idx
|
||||
},
|
||||
}
|
||||
}
|
||||
3 => {
|
||||
TemplateNode::Dynamic {
|
||||
id: {
|
||||
let old_idx = *template_idx;
|
||||
*template_idx += 1;
|
||||
dynamic_node_types.push(DynamicNodeType::Other);
|
||||
old_idx
|
||||
},
|
||||
}
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
@@ -207,9 +211,9 @@ fn create_random_dynamic_node(cx: &ScopeState, depth: usize) -> DynamicNode {
|
||||
|
||||
fn create_random_dynamic_attr(cx: &ScopeState) -> Attribute {
|
||||
let value = match rand::random::<u8>() % 7 {
|
||||
0 => AttributeValue::Text(Box::leak(
|
||||
format!("{}", rand::random::<usize>()).into_boxed_str(),
|
||||
)),
|
||||
0 => {
|
||||
AttributeValue::Text(Box::leak(format!("{}", rand::random::<usize>()).into_boxed_str()))
|
||||
}
|
||||
1 => AttributeValue::Float(rand::random()),
|
||||
2 => AttributeValue::Int(rand::random()),
|
||||
3 => AttributeValue::Bool(rand::random()),
|
||||
@@ -272,31 +276,32 @@ fn create_random_element(cx: Scope<DepthProps>) -> Element {
|
||||
.into_boxed_str(),
|
||||
));
|
||||
// println!("{template:#?}");
|
||||
let node = VNode {
|
||||
key: None,
|
||||
parent: None,
|
||||
template: Cell::new(template),
|
||||
root_ids: bumpalo::collections::Vec::new_in(cx.bump()).into(),
|
||||
dynamic_nodes: {
|
||||
let dynamic_nodes: Vec<_> = dynamic_node_types
|
||||
.iter()
|
||||
.map(|ty| match ty {
|
||||
DynamicNodeType::Text => DynamicNode::Text(VText::new(Box::leak(
|
||||
format!("{}", rand::random::<usize>()).into_boxed_str(),
|
||||
))),
|
||||
DynamicNodeType::Other => {
|
||||
create_random_dynamic_node(cx, cx.props.depth + 1)
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
cx.bump().alloc(dynamic_nodes)
|
||||
},
|
||||
dynamic_attrs: cx.bump().alloc(
|
||||
(0..template.attr_paths.len())
|
||||
.map(|_| create_random_dynamic_attr(cx))
|
||||
.collect::<Vec<_>>(),
|
||||
),
|
||||
};
|
||||
let node =
|
||||
VNode {
|
||||
key: None,
|
||||
parent: None,
|
||||
template: Cell::new(template),
|
||||
root_ids: bumpalo::collections::Vec::new_in(cx.bump()).into(),
|
||||
dynamic_nodes: {
|
||||
let dynamic_nodes: Vec<_> = dynamic_node_types
|
||||
.iter()
|
||||
.map(|ty| match ty {
|
||||
DynamicNodeType::Text => DynamicNode::Text(VText::new(Box::leak(
|
||||
format!("{}", rand::random::<usize>()).into_boxed_str(),
|
||||
))),
|
||||
DynamicNodeType::Other => {
|
||||
create_random_dynamic_node(cx, cx.props.depth + 1)
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
cx.bump().alloc(dynamic_nodes)
|
||||
},
|
||||
dynamic_attrs: cx.bump().alloc(
|
||||
(0..template.attr_paths.len())
|
||||
.map(|_| create_random_dynamic_attr(cx))
|
||||
.collect::<Vec<_>>(),
|
||||
),
|
||||
};
|
||||
Some(node)
|
||||
}
|
||||
_ => None,
|
||||
|
||||
Reference in new issue
Block a user