get cargo check --all --examples --tests working!

This commit is contained in:
Jonathan Kelley 2024-01-19 15:01:01 -08:00
parent 83bce6ce97
commit 337c04557b
No known key found for this signature in database
GPG key ID: 1FBB50F7EB0A08BE
18 changed files with 109 additions and 508 deletions

View file

@ -33,14 +33,15 @@ fn key_down() {
dioxus_tui::launch_cfg(app, dioxus_tui::Config::new().with_headless()); dioxus_tui::launch_cfg(app, dioxus_tui::Config::new().with_headless());
fn app() -> Element { fn app() -> Element {
let render_count = use_signal(|| 0); let mut render_count = use_signal(|| 0);
let tui_ctx: TuiContext = cx.consume_context().unwrap(); let mut render_count_handle = render_count.clone();
let render_count_handle = render_count.clone(); let tui_ctx: TuiContext = consume_context();
cx.spawn(async move {
spawn(async move {
PollN::new(3).await; PollN::new(3).await;
render_count_handle.modify(|x| *x + 1); render_count_handle.with_mut(|x| *x + 1);
}); });
if *render_count.get() > 2 { if render_count() > 2 {
panic!("Event was not received"); panic!("Event was not received");
} }
// focus the element // focus the element
@ -74,14 +75,14 @@ fn mouse_down() {
dioxus_tui::launch_cfg(app, dioxus_tui::Config::new().with_headless()); dioxus_tui::launch_cfg(app, dioxus_tui::Config::new().with_headless());
fn app() -> Element { fn app() -> Element {
let render_count = use_signal(|| 0); let mut render_count = use_signal(|| 0);
let tui_ctx: TuiContext = cx.consume_context().unwrap(); let tui_ctx: TuiContext = consume_context();
let render_count_handle = render_count.clone(); let mut render_count_handle = render_count.clone();
cx.spawn(async move { spawn(async move {
PollN::new(2).await; PollN::new(2).await;
render_count_handle.modify(|x| *x + 1); render_count_handle.with_mut(|x| *x + 1);
}); });
if *render_count.get() > 2 { if render_count() > 2 {
panic!("Event was not received"); panic!("Event was not received");
} }
tui_ctx.inject_event(Event::Mouse(MouseEvent { tui_ctx.inject_event(Event::Mouse(MouseEvent {
@ -110,14 +111,14 @@ fn mouse_up() {
dioxus_tui::launch_cfg(app, dioxus_tui::Config::new().with_headless()); dioxus_tui::launch_cfg(app, dioxus_tui::Config::new().with_headless());
fn app() -> Element { fn app() -> Element {
let render_count = use_signal(|| 0); let mut render_count = use_signal(|| 0);
let tui_ctx: TuiContext = cx.consume_context().unwrap(); let tui_ctx: TuiContext = consume_context();
let render_count_handle = render_count.clone(); let mut render_count_handle = render_count.clone();
cx.spawn(async move { spawn(async move {
PollN::new(3).await; PollN::new(3).await;
render_count_handle.modify(|x| *x + 1); render_count_handle.with_mut(|x| *x + 1);
}); });
if *render_count.get() > 2 { if render_count() > 2 {
panic!("Event was not received"); panic!("Event was not received");
} }
tui_ctx.inject_event(Event::Mouse(MouseEvent { tui_ctx.inject_event(Event::Mouse(MouseEvent {
@ -149,14 +150,14 @@ fn mouse_enter() {
dioxus_tui::launch_cfg(app, dioxus_tui::Config::new().with_headless()); dioxus_tui::launch_cfg(app, dioxus_tui::Config::new().with_headless());
fn app() -> Element { fn app() -> Element {
let render_count = use_signal(|| 0); let mut render_count = use_signal(|| 0);
let tui_ctx: TuiContext = cx.consume_context().unwrap(); let mut render_count_handle = render_count.clone();
let render_count_handle = render_count.clone(); let tui_ctx: TuiContext = consume_context();
cx.spawn(async move { spawn(async move {
PollN::new(3).await; PollN::new(3).await;
render_count_handle.modify(|x| *x + 1); render_count_handle.with_mut(|x| *x + 1);
}); });
if *render_count.get() > 2 { if render_count() > 2 {
panic!("Event was not received"); panic!("Event was not received");
} }
tui_ctx.inject_event(Event::Mouse(MouseEvent { tui_ctx.inject_event(Event::Mouse(MouseEvent {
@ -188,14 +189,14 @@ fn mouse_exit() {
dioxus_tui::launch_cfg(app, dioxus_tui::Config::new().with_headless()); dioxus_tui::launch_cfg(app, dioxus_tui::Config::new().with_headless());
fn app() -> Element { fn app() -> Element {
let render_count = use_signal(|| 0); let mut render_count = use_signal(|| 0);
let tui_ctx: TuiContext = cx.consume_context().unwrap(); let tui_ctx: TuiContext = consume_context();
let render_count_handle = render_count.clone(); let mut render_count_handle = render_count.clone();
cx.spawn(async move { spawn(async move {
PollN::new(3).await; PollN::new(3).await;
render_count_handle.modify(|x| *x + 1); render_count_handle.with_mut(|x| *x + 1);
}); });
if *render_count.get() > 2 { if render_count() > 2 {
panic!("Event was not received"); panic!("Event was not received");
} }
tui_ctx.inject_event(Event::Mouse(MouseEvent { tui_ctx.inject_event(Event::Mouse(MouseEvent {
@ -227,14 +228,14 @@ fn mouse_move() {
dioxus_tui::launch_cfg(app, dioxus_tui::Config::new().with_headless()); dioxus_tui::launch_cfg(app, dioxus_tui::Config::new().with_headless());
fn app() -> Element { fn app() -> Element {
let render_count = use_signal(|| 0); let mut render_count = use_signal(|| 0);
let tui_ctx: TuiContext = cx.consume_context().unwrap(); let tui_ctx: TuiContext = consume_context();
let render_count_handle = render_count.clone(); let mut render_count_handle = render_count.clone();
cx.spawn(async move { spawn(async move {
PollN::new(3).await; PollN::new(3).await;
render_count_handle.modify(|x| *x + 1); render_count_handle.with_mut(|x| *x + 1);
}); });
if *render_count.get() > 2 { if render_count() > 2 {
panic!("Event was not received"); panic!("Event was not received");
} }
tui_ctx.inject_event(Event::Mouse(MouseEvent { tui_ctx.inject_event(Event::Mouse(MouseEvent {
@ -266,14 +267,14 @@ fn wheel() {
dioxus_tui::launch_cfg(app, dioxus_tui::Config::new().with_headless()); dioxus_tui::launch_cfg(app, dioxus_tui::Config::new().with_headless());
fn app() -> Element { fn app() -> Element {
let render_count = use_signal(|| 0); let mut render_count = use_signal(|| 0);
let tui_ctx: TuiContext = cx.consume_context().unwrap(); let tui_ctx: TuiContext = consume_context();
let render_count_handle = render_count.clone(); let mut render_count_handle = render_count.clone();
cx.spawn(async move { spawn(async move {
PollN::new(3).await; PollN::new(3).await;
render_count_handle.modify(|x| *x + 1); render_count_handle.with_mut(|x| *x + 1);
}); });
if *render_count.get() > 2 { if render_count() > 2 {
panic!("Event was not received"); panic!("Event was not received");
} }
tui_ctx.inject_event(Event::Mouse(MouseEvent { tui_ctx.inject_event(Event::Mouse(MouseEvent {
@ -306,14 +307,14 @@ fn click() {
dioxus_tui::launch_cfg(app, dioxus_tui::Config::new().with_headless()); dioxus_tui::launch_cfg(app, dioxus_tui::Config::new().with_headless());
fn app() -> Element { fn app() -> Element {
let render_count = use_signal(|| 0); let mut render_count = use_signal(|| 0);
let tui_ctx: TuiContext = cx.consume_context().unwrap(); let tui_ctx: TuiContext = consume_context();
let render_count_handle = render_count.clone(); let mut render_count_handle = render_count.clone();
cx.spawn(async move { spawn(async move {
PollN::new(3).await; PollN::new(3).await;
render_count_handle.modify(|x| *x + 1); render_count_handle.with_mut(|x| *x + 1);
}); });
if *render_count.get() > 2 { if render_count() > 2 {
panic!("Event was not received"); panic!("Event was not received");
} }
tui_ctx.inject_event(Event::Mouse(MouseEvent { tui_ctx.inject_event(Event::Mouse(MouseEvent {
@ -345,14 +346,14 @@ fn context_menu() {
dioxus_tui::launch_cfg(app, dioxus_tui::Config::new().with_headless()); dioxus_tui::launch_cfg(app, dioxus_tui::Config::new().with_headless());
fn app() -> Element { fn app() -> Element {
let render_count = use_signal(|| 0); let mut render_count = use_signal(|| 0);
let tui_ctx: TuiContext = cx.consume_context().unwrap(); let tui_ctx: TuiContext = consume_context();
let render_count_handle = render_count.clone(); let mut render_count_handle = render_count.clone();
cx.spawn(async move { spawn(async move {
PollN::new(3).await; PollN::new(3).await;
render_count_handle.modify(|x| *x + 1); render_count_handle.with_mut(|x| *x + 1);
}); });
if *render_count.get() > 2 { if render_count() > 2 {
panic!("Event was not received"); panic!("Event was not received");
} }
tui_ctx.inject_event(Event::Mouse(MouseEvent { tui_ctx.inject_event(Event::Mouse(MouseEvent {

View file

@ -175,7 +175,7 @@ fn create_random_template(name: &'static str) -> (Template, Vec<DynamicNodeType>
) )
} }
fn create_random_dynamic_node(, depth: usize) -> DynamicNode { fn create_random_dynamic_node(depth: usize) -> DynamicNode {
let range = if depth > 3 { 1 } else { 3 }; let range = if depth > 3 { 1 } else { 3 };
match rand::random::<u8>() % range { match rand::random::<u8>() % range {
0 => DynamicNode::Placeholder(Default::default()), 0 => DynamicNode::Placeholder(Default::default()),

View file

@ -216,13 +216,12 @@ fn traverse() {
} }
let mut vdom = VirtualDom::new(Base); let mut vdom = VirtualDom::new(Base);
let mutations = vdom.rebuild();
let mut rdom: RealDom = RealDom::new([]); let mut rdom: RealDom = RealDom::new([]);
let mut iter = PersistantElementIter::create(&mut rdom); let mut iter = PersistantElementIter::create(&mut rdom);
let mut dioxus_state = DioxusState::create(&mut rdom); let mut dioxus_state = DioxusState::create(&mut rdom);
dioxus_state.apply_mutations(&mut rdom, mutations); vdom.rebuild(&mut dioxus_state.create_mutation_writer(&mut rdom));
let div_tag = "div".to_string(); let div_tag = "div".to_string();
assert!(matches!( assert!(matches!(
@ -317,14 +316,13 @@ fn persist_removes() {
let mut rdom: RealDom = RealDom::new([]); let mut rdom: RealDom = RealDom::new([]);
let build = vdom.rebuild();
println!("{build:#?}");
// this will end on the node that is removed // this will end on the node that is removed
let mut iter1 = PersistantElementIter::create(&mut rdom); let mut iter1 = PersistantElementIter::create(&mut rdom);
// this will end on the after node that is removed // this will end on the after node that is removed
let mut iter2 = PersistantElementIter::create(&mut rdom); let mut iter2 = PersistantElementIter::create(&mut rdom);
let mut dioxus_state = DioxusState::create(&mut rdom); let mut dioxus_state = DioxusState::create(&mut rdom);
dioxus_state.apply_mutations(&mut rdom, build);
vdom.rebuild(&mut dioxus_state.create_mutation_writer(&mut rdom));
// root // root
iter1.next(&rdom).id(); iter1.next(&rdom).id();
@ -350,9 +348,7 @@ fn persist_removes() {
iter2.next(&rdom).id(); iter2.next(&rdom).id();
vdom.mark_dirty(ScopeId::ROOT); vdom.mark_dirty(ScopeId::ROOT);
let update = vdom.render_immediate(); vdom.render_immediate(&mut dioxus_state.create_mutation_writer(&mut rdom));
println!("{update:#?}");
dioxus_state.apply_mutations(&mut rdom, update);
let root_tag = "Root".to_string(); let root_tag = "Root".to_string();
let idx = iter1.next(&rdom).id(); let idx = iter1.next(&rdom).id();
@ -394,8 +390,7 @@ fn persist_instertions_before() {
let mut rdom: RealDom = RealDom::new([]); let mut rdom: RealDom = RealDom::new([]);
let mut dioxus_state = DioxusState::create(&mut rdom); let mut dioxus_state = DioxusState::create(&mut rdom);
let build = vdom.rebuild(); vdom.rebuild(&mut dioxus_state.create_mutation_writer(&mut rdom));
dioxus_state.apply_mutations(&mut rdom, build);
let mut iter = PersistantElementIter::create(&mut rdom); let mut iter = PersistantElementIter::create(&mut rdom);
// div // div
@ -410,8 +405,7 @@ fn persist_instertions_before() {
iter.next(&rdom).id(); iter.next(&rdom).id();
vdom.mark_dirty(ScopeId::ROOT); vdom.mark_dirty(ScopeId::ROOT);
let update = vdom.render_immediate(); vdom.render_immediate(&mut dioxus_state.create_mutation_writer(&mut rdom));
dioxus_state.apply_mutations(&mut rdom, update);
let p_tag = "div".to_string(); let p_tag = "div".to_string();
let idx = iter.next(&rdom).id(); let idx = iter.next(&rdom).id();
@ -448,8 +442,8 @@ fn persist_instertions_after() {
let mut iter = PersistantElementIter::create(&mut rdom); let mut iter = PersistantElementIter::create(&mut rdom);
let mut dioxus_state = DioxusState::create(&mut rdom); let mut dioxus_state = DioxusState::create(&mut rdom);
let build = vdom.rebuild(); let mut writer = dioxus_state.create_mutation_writer(&mut rdom);
dioxus_state.apply_mutations(&mut rdom, build); vdom.rebuild(&mut writer);
// div // div
iter.next(&rdom).id(); iter.next(&rdom).id();
@ -462,8 +456,8 @@ fn persist_instertions_after() {
// "world" // "world"
iter.next(&rdom).id(); iter.next(&rdom).id();
let update = vdom.rebuild(); let mut writer = dioxus_state.create_mutation_writer(&mut rdom);
dioxus_state.apply_mutations(&mut rdom, update); vdom.rebuild(&mut writer);
let p_tag = "p".to_string(); let p_tag = "p".to_string();
let idx = iter.next(&rdom).id(); let idx = iter.next(&rdom).id();

View file

@ -83,15 +83,19 @@ impl From<&Url> for IntoRoutable {
pub struct LinkProps { pub struct LinkProps {
/// A class to apply to the generate HTML anchor tag if the `target` route is active. /// A class to apply to the generate HTML anchor tag if the `target` route is active.
pub active_class: Option<String>, pub active_class: Option<String>,
/// The children to render within the generated HTML anchor tag. /// The children to render within the generated HTML anchor tag.
pub children: Element, pub children: Element,
/// When [`true`], the `target` route will be opened in a new tab. /// When [`true`], the `target` route will be opened in a new tab.
/// ///
/// This does not change whether the [`Link`] is active or not. /// This does not change whether the [`Link`] is active or not.
#[props(default)] #[props(default)]
pub new_tab: bool, pub new_tab: bool,
/// The onclick event handler. /// The onclick event handler.
pub onclick: Option<EventHandler<MouseEvent>>, pub onclick: Option<EventHandler<MouseEvent>>,
#[props(default)] #[props(default)]
/// Whether the default behavior should be executed if an `onclick` handler is provided. /// Whether the default behavior should be executed if an `onclick` handler is provided.
/// ///
@ -100,13 +104,16 @@ pub struct LinkProps {
/// will be executed after the links regular functionality. /// will be executed after the links regular functionality.
/// 3. If `onclick_only` is [`true`], only the provided `onclick` handler will be executed. /// 3. If `onclick_only` is [`true`], only the provided `onclick` handler will be executed.
pub onclick_only: bool, pub onclick_only: bool,
/// The rel attribute for the generated HTML anchor tag. /// The rel attribute for the generated HTML anchor tag.
/// ///
/// For external `a`s, this defaults to `noopener noreferrer`. /// For external `a`s, this defaults to `noopener noreferrer`.
pub rel: Option<String>, pub rel: Option<String>,
/// The navigation target. Roughly equivalent to the href attribute of an HTML anchor tag. /// The navigation target. Roughly equivalent to the href attribute of an HTML anchor tag.
#[props(into)] #[props(into)]
pub to: IntoRoutable, pub to: IntoRoutable,
#[props(extends = GlobalAttributes)] #[props(extends = GlobalAttributes)]
attributes: Vec<Attribute>, attributes: Vec<Attribute>,
} }

View file

@ -12,7 +12,7 @@ where
phantom: std::marker::PhantomData, phantom: std::marker::PhantomData,
}, },
); );
let _ = vdom.rebuild(); vdom.rebuild_in_place();
return dioxus_ssr::render(&vdom); return dioxus_ssr::render(&vdom);
#[derive(Props)] #[derive(Props)]
@ -20,14 +20,21 @@ where
phantom: std::marker::PhantomData<R>, phantom: std::marker::PhantomData<R>,
} }
impl<R: Routable> Clone for AppProps<R> {
fn clone(&self) -> Self {
Self {
phantom: std::marker::PhantomData,
}
}
}
impl<R: Routable> PartialEq for AppProps<R> { impl<R: Routable> PartialEq for AppProps<R> {
fn eq(&self, _other: &Self) -> bool { fn eq(&self, _other: &Self) -> bool {
false false
} }
} }
#[component] fn App<R: Routable>(props: AppProps<R>) -> Element
fn App<R: Routable>(cx: Scope<AppProps<R>>) -> Element
where where
<R as FromStr>::Err: std::fmt::Display, <R as FromStr>::Err: std::fmt::Display,
{ {
@ -51,7 +58,7 @@ fn href_internal() {
} }
#[component] #[component]
fn Test(_cx: Scope) -> Element { fn Test() -> Element {
todo!() todo!()
} }
@ -89,7 +96,7 @@ fn href_external() {
} }
#[component] #[component]
fn Test(_cx: Scope) -> Element { fn Test() -> Element {
todo!() todo!()
} }
@ -127,7 +134,7 @@ fn with_class() {
} }
#[component] #[component]
fn Test(_cx: Scope) -> Element { fn Test() -> Element {
todo!() todo!()
} }
@ -168,7 +175,7 @@ fn with_active_class_active() {
rsx! { rsx! {
Link { Link {
to: Route::Root {}, to: Route::Root {},
active_class: "active_class", active_class: "active_class".to_string(),
class: "test_class", class: "test_class",
"Link" "Link"
} }
@ -199,7 +206,7 @@ fn with_active_class_inactive() {
} }
#[component] #[component]
fn Test(_cx: Scope) -> Element { fn Test() -> Element {
todo!() todo!()
} }
@ -208,7 +215,7 @@ fn with_active_class_inactive() {
rsx! { rsx! {
Link { Link {
to: Route::Test {}, to: Route::Test {},
active_class: "active_class", active_class: "active_class".to_string(),
class: "test_class", class: "test_class",
"Link" "Link"
} }
@ -239,7 +246,7 @@ fn with_id() {
} }
#[component] #[component]
fn Test(_cx: Scope) -> Element { fn Test() -> Element {
todo!() todo!()
} }
@ -278,7 +285,7 @@ fn with_new_tab() {
} }
#[component] #[component]
fn Test(_cx: Scope) -> Element { fn Test() -> Element {
todo!() todo!()
} }
@ -349,7 +356,7 @@ fn with_rel() {
} }
#[component] #[component]
fn Test(_cx: Scope) -> Element { fn Test() -> Element {
todo!() todo!()
} }
@ -358,7 +365,7 @@ fn with_rel() {
rsx! { rsx! {
Link { Link {
to: Route::Test {}, to: Route::Test {},
rel: "test_rel", rel: "test_rel".to_string(),
"Link" "Link"
} }
} }

View file

@ -5,7 +5,7 @@ use dioxus_router::prelude::*;
fn prepare(path: impl Into<String>) -> VirtualDom { fn prepare(path: impl Into<String>) -> VirtualDom {
let mut vdom = VirtualDom::new_with_props(App, AppProps { path: path.into() }); let mut vdom = VirtualDom::new_with_props(App, AppProps { path: path.into() });
let _ = vdom.rebuild(); vdom.rebuild_in_place();
return vdom; return vdom;
#[derive(Routable, Clone)] #[derive(Routable, Clone)]
@ -29,18 +29,13 @@ fn prepare(path: impl Into<String>) -> VirtualDom {
ParameterFixed { id: u8 }, ParameterFixed { id: u8 },
} }
#[derive(Debug, Props, PartialEq)]
struct AppProps {
path: String,
}
#[component] #[component]
fn App(cx: Scope<AppProps>) -> Element { fn App(path: String) -> Element {
rsx! { rsx! {
h1 { "App" } h1 { "App" }
Router::<Route> { Router::<Route> {
config: { config: {
let path = cx.props.path.parse().unwrap(); let path = path.parse().unwrap();
move || RouterConfig::default().history(MemoryHistory::with_initial_path(path)) move || RouterConfig::default().history(MemoryHistory::with_initial_path(path))
} }
} }
@ -49,9 +44,7 @@ fn prepare(path: impl Into<String>) -> VirtualDom {
#[component] #[component]
fn RootIndex() -> Element { fn RootIndex() -> Element {
rsx! { rsx! { h2 { "Root Index" } }
h2 { "Root Index" }
}
} }
#[component] #[component]
@ -64,16 +57,12 @@ fn prepare(path: impl Into<String>) -> VirtualDom {
#[component] #[component]
fn FixedIndex() -> Element { fn FixedIndex() -> Element {
rsx! { rsx! { h3 { "Fixed - Index" } }
h3 { "Fixed - Index" }
}
} }
#[component] #[component]
fn FixedFixed() -> Element { fn FixedFixed() -> Element {
rsx! { rsx! { h3 { "Fixed - Fixed"} }
h3 { "Fixed - Fixed"}
}
} }
#[component] #[component]
@ -86,16 +75,12 @@ fn prepare(path: impl Into<String>) -> VirtualDom {
#[component] #[component]
fn ParameterIndex(id: u8) -> Element { fn ParameterIndex(id: u8) -> Element {
rsx! { rsx! { h3 { "Parameter - Index" } }
h3 { "Parameter - Index" }
}
} }
#[component] #[component]
fn ParameterFixed(id: u8) -> Element { fn ParameterFixed(id: u8) -> Element {
rsx! { rsx! { h3 { "Parameter - Fixed" } }
h3 { "Parameter - Fixed" }
}
} }
} }

View file

@ -662,9 +662,8 @@ fn create_template() {
#[cfg(feature = "hot_reload")] #[cfg(feature = "hot_reload")]
#[test] #[test]
fn diff_template() { fn diff_template() {
use dioxus_core::Scope;
#[allow(unused, non_snake_case)] #[allow(unused, non_snake_case)]
fn Comp(_: Scope) -> dioxus_core::Element { fn Comp() -> dioxus_core::Element {
None None
} }

View file

@ -1,84 +0,0 @@
#![allow(unused, non_upper_case_globals, non_snake_case)]
use dioxus::prelude::*;
use dioxus_core::ElementId;
use dioxus_signals::*;
#[test]
fn create_signals_global() {
let mut dom = VirtualDom::new(|cx| {
rsx! {
for _ in 0..10 {
Child {}
}
}
});
fn Child() -> Element {
let signal = create_without_cx();
rsx! {
"{signal}"
}
}
let _edits = dom.rebuild().santize();
fn create_without_cx() -> Signal<String> {
Signal::new("hello world".to_string())
}
}
#[test]
fn deref_signal() {
let mut dom = VirtualDom::new(|cx| {
rsx! {
for _ in 0..10 {
Child {}
}
}
});
fn Child() -> Element {
let signal = Signal::new("hello world".to_string());
// You can call signals like functions to get a Ref of their value.
assert_eq!(&*signal(), "hello world");
rsx! {
"hello world"
}
}
let _edits = dom.rebuild().santize();
}
#[test]
fn drop_signals() {
let mut dom = VirtualDom::new(|cx| {
let generation = generation();
let count = if generation % 2 == 0 { 10 } else { 0 };
rsx! {
for _ in 0..count {
Child {}
}
}
});
fn Child() -> Element {
let signal = create_without_cx();
rsx! {
"{signal}"
}
}
let _ = dom.rebuild().santize();
dom.mark_dirty(ScopeId::ROOT);
dom.render_immediate();
fn create_without_cx() -> Signal<String> {
Signal::new("hello world".to_string())
}
}

View file

@ -1,47 +0,0 @@
#![allow(unused, non_upper_case_globals, non_snake_case)]
use std::collections::HashMap;
use std::rc::Rc;
use dioxus::prelude::*;
use dioxus_core::ElementId;
use dioxus_signals::*;
#[tokio::test]
async fn effects_rerun() {
simple_logger::SimpleLogger::new().init().unwrap();
#[derive(Default)]
struct RunCounter {
component: usize,
effect: usize,
}
let counter = Rc::new(RefCell::new(RunCounter::default()));
let mut dom = VirtualDom::new_with_props(
|cx| {
let counter = cx.props;
counter.borrow_mut().component += 1;
let mut signal = use_signal(|| 0);
cx.use_hook(move || {
to_owned![counter];
Effect::new(move || {
counter.borrow_mut().effect += 1;
println!("Signal: {:?}", signal);
})
});
signal += 1;
rsx! { div {} }
},
counter.clone(),
);
let _ = dom.rebuild().santize();
dom.render_with_deadline(tokio::time::sleep(std::time::Duration::from_millis(100)))
.await;
let current_counter = counter.borrow();
assert_eq!(current_counter.component, 1);
assert_eq!(current_counter.effect, 2);
}

View file

@ -1,29 +0,0 @@
#![allow(unused, non_upper_case_globals, non_snake_case)]
use dioxus::prelude::*;
use dioxus_core::ElementId;
use dioxus_signals::*;
#[test]
fn create_signals_global() {
let mut dom = VirtualDom::new(|cx| {
render! {
for _ in 0..10 {
Child {}
}
}
});
fn Child(cx: Scope) -> Element {
let signal = create_without_cx();
let mapped = MappedSignal::new(signal, |v| v.as_bytes());
render! { "{signal:?}", "{mapped:?}" }
}
let _edits = dom.rebuild().santize();
fn create_without_cx() -> Signal<String> {
Signal::new("hello world".to_string())
}
}

View file

@ -1,146 +0,0 @@
#![allow(unused, non_upper_case_globals, non_snake_case)]
use std::collections::HashMap;
use std::rc::Rc;
use dioxus::html::p;
use dioxus::prelude::*;
use dioxus_core::ElementId;
use dioxus_signals::*;
#[test]
fn memos_rerun() {
let _ = simple_logger::SimpleLogger::new().init();
#[derive(Default)]
struct RunCounter {
component: usize,
effect: usize,
}
let counter = Rc::new(RefCell::new(RunCounter::default()));
let mut dom = VirtualDom::new_with_props(
|cx| {
let counter = cx.props;
counter.borrow_mut().component += 1;
let mut signal = use_signal(|| 0);
let memo = cx.use_hook(move || {
to_owned![counter];
selector(move || {
counter.borrow_mut().effect += 1;
println!("Signal: {:?}", signal);
signal.cloned()
})
});
let generation = use_signal(cx, || cx.generation());
generation.set(cx.generation());
dioxus_signals::use_effect(cx, move || {
if generation == 1 {
assert_eq!(memo.value(), 0);
}
if generation == 3 {
assert_eq!(memo.value(), 1);
}
});
signal += 1;
rsx! { div {} }
},
counter.clone(),
);
let _ = dom.rebuild().santize();
let _ = dom.render_immediate();
let current_counter = counter.borrow();
assert_eq!(current_counter.component, 1);
assert_eq!(current_counter.effect, 2);
}
#[tokio::test]
async fn memos_prevents_component_rerun() {
let _ = simple_logger::SimpleLogger::new().init();
#[derive(Default)]
struct RunCounter {
component: usize,
effect: usize,
}
let counter = Rc::new(RefCell::new(RunCounter::default()));
let mut dom = VirtualDom::new_with_props(
|cx| {
let mut signal = use_signal(|| 0);
if generation() == 1 {
*signal.write() = 0;
}
if generation() == 2 {
println!("Writing to signal");
*signal.write() = 1;
}
rsx! { Child { signal: signal, counter: cx.props.clone() } }
},
counter.clone(),
);
#[derive(Default, Props)]
struct ChildProps {
signal: Signal<usize>,
counter: Rc<RefCell<RunCounter>>,
}
impl PartialEq for ChildProps {
fn eq(&self, other: &Self) -> bool {
self.signal == other.signal
}
}
fn Child(cx: Scope<ChildProps>) -> Element {
let counter = &cx.props.counter;
let signal = cx.props.signal;
counter.borrow_mut().component += 1;
let memo = cx.use_hook(move || {
to_owned![counter];
selector(move || {
counter.borrow_mut().effect += 1;
println!("Signal: {:?}", signal);
signal.value()
})
});
match generation() {
0 => {
assert_eq!(memo.value(), 0);
}
1 => {
assert_eq!(memo.value(), 1);
}
_ => panic!("Unexpected generation"),
}
rsx! { div {} }
}
let _ = dom.rebuild().santize();
dom.mark_dirty(ScopeId::ROOT);
dom.render_immediate();
dom.render_immediate();
{
let current_counter = counter.borrow();
assert_eq!(current_counter.component, 1);
assert_eq!(current_counter.effect, 2);
}
dom.mark_dirty(ScopeId::ROOT);
dom.render_immediate();
dom.render_immediate();
{
let current_counter = counter.borrow();
assert_eq!(current_counter.component, 2);
assert_eq!(current_counter.effect, 3);
}
}

View file

@ -1,92 +0,0 @@
#![allow(unused, non_upper_case_globals, non_snake_case)]
use std::collections::HashMap;
use std::rc::Rc;
use dioxus::prelude::*;
use dioxus_core::ElementId;
use dioxus_signals::*;
#[test]
fn reading_subscribes() {
simple_logger::SimpleLogger::new().init().unwrap();
#[derive(Default)]
struct RunCounter {
parent: usize,
children: HashMap<ScopeId, usize>,
}
let counter = Rc::new(RefCell::new(RunCounter::default()));
let mut dom = VirtualDom::new_with_props(
|cx| {
let mut signal = use_signal(|| 0);
println!("Parent: {:?}", cx.scope_id());
if generation() == 1 {
signal += 1;
}
cx.props.borrow_mut().parent += 1;
rsx! {
for id in 0..10 {
Child {
signal: signal,
counter: cx.props.clone()
}
}
}
},
counter.clone(),
);
#[derive(Props, Clone)]
struct ChildProps {
signal: Signal<usize>,
counter: Rc<RefCell<RunCounter>>,
}
impl PartialEq for ChildProps {
fn eq(&self, other: &Self) -> bool {
self.signal == other.signal
}
}
fn Child(cx: Scope<ChildProps>) -> Element {
println!("Child: {:?}", cx.scope_id());
*cx.props
.counter
.borrow_mut()
.children
.entry(cx.scope_id())
.or_default() += 1;
rsx! {
"{cx.props.signal}"
}
}
let _ = dom.rebuild().santize();
{
let current_counter = counter.borrow();
assert_eq!(current_counter.parent, 1);
for (scope_id, rerun_count) in current_counter.children.iter() {
assert_eq!(rerun_count, &1);
}
}
dom.mark_dirty(ScopeId::ROOT);
dom.render_immediate();
dom.render_immediate();
{
let current_counter = counter.borrow();
assert_eq!(current_counter.parent, 2);
for (scope_id, rerun_count) in current_counter.children.iter() {
assert_eq!(rerun_count, &2);
}
}
}

View file

@ -27,3 +27,9 @@ pub fn launch_virtual_dom(vdom: VirtualDom, platform_config: Config) {
crate::run(vdom, platform_config).await; crate::run(vdom, platform_config).await;
}); });
} }
///
pub fn launch_cfg(root: fn() -> Element, platform_config: Config) {
let mut vdom = VirtualDom::new(root);
launch_virtual_dom(vdom, platform_config);
}

View file

@ -52,5 +52,5 @@ fn rehydrates() {
.unwrap() .unwrap()
.set_inner_html(&format!("<div id='main'>{out}</div>")); .set_inner_html(&format!("<div id='main'>{out}</div>"));
dioxus_web::launch_cfg(app, Config::new().hydrate(true)); dioxus_web::launch::launch_cfg(app, Config::new().hydrate(true));
} }