Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions packages/core/src/scopes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,10 @@ impl ScopeId {
/// use dioxus::prelude::*;
/// let my_persistent_state = Signal::new_in_scope(String::new(), ScopeId::APP);
/// ```
// Refer to `RootScopeWrapper` (root_wrapper.rs) to see where these constants come from.
// ScopeId(0) is the root scope wrapper
// ScopeId(1) is the default error boundary
// ScopeId(2) is the default suspense boundary
// ScopeId(1) is the default suspense boundary
// ScopeId(2) is the default error boundary
// ScopeId(3) is the users root scope
pub const APP: ScopeId = ScopeId(3);

Expand Down
1 change: 1 addition & 0 deletions packages/core/tests/bubble_error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ fn app() -> Element {
}

#[test]
#[ignore] // Test doesn't do anything.
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I might have misunderstood but I don't think this test generates any errors to bubble? I've marked it as ignore to flag it, but I'm open to changing or removing it.

fn bubbles_error() {
let mut dom = VirtualDom::new(app);

Expand Down
3 changes: 2 additions & 1 deletion packages/core/tests/conditional_formatted_attributes.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use dioxus::prelude::*;

/// Make sure that rsx! handles conditional attributes with one formatted branch correctly
/// Regression test for https://github.com/DioxusLabs/dioxus/issues/2997
/// Regression test for https://github.com/DioxusLabs/dioxus/issues/2997. There are no assertions in
/// this test as it primarily checks that the RSX can be compiled correctly.
#[test]
fn partially_formatted_conditional_attribute() {
let width = "1px";
Expand Down
2 changes: 1 addition & 1 deletion packages/core/tests/diff_keyed_list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
//!
//! These tests only verify that the diffing algorithm works properly for single components.
//!
//! It does not validated that component lifecycles work properly. This is done in another test file.
//! It does not validate that component lifecycles work properly. This is done in another test file.

use dioxus::dioxus_core::{ElementId, Mutation::*};
use dioxus::prelude::*;
Expand Down
2 changes: 1 addition & 1 deletion packages/core/tests/diff_unkeyed_list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -464,7 +464,7 @@ fn replace_and_add_items() {
);
}

// Rerendering adds an a static template
// Rerendering adds a static template
{
dom.mark_dirty(ScopeId::APP);
let edits = dom.render_immediate_to_vec();
Expand Down
19 changes: 17 additions & 2 deletions packages/core/tests/error_boundary.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ fn clear_error_boundary() {

#[component]
pub fn ThrowsError() -> Element {
if THREW_ERROR.load(std::sync::atomic::Ordering::SeqCst) {
if !THREW_ERROR.load(std::sync::atomic::Ordering::SeqCst) {
THREW_ERROR.store(true, std::sync::atomic::Ordering::SeqCst);
Err(CapturedError::from_display("This is an error").into())
} else {
Expand Down Expand Up @@ -73,7 +73,22 @@ fn clear_error_boundary() {

let mut dom = VirtualDom::new(App);
dom.rebuild(&mut dioxus_core::NoOpMutations);
let out = dioxus_ssr::render(&dom);
// The DOM will now contain no text - the error was thrown by ThrowsError and caught by the
// ErrorBoundary. This calls `needs_update()`, but the update hasn't been processed yet.

dom.render_immediate(&mut dioxus_core::NoOpMutations);
// The ErrorBoundary has now called its `handle_error` handler. The DOM contains the string
// "We cleared it", and `needs_update()` has been called again (by `error.clear_errors()`)

dom.render_immediate(&mut dioxus_core::NoOpMutations);
// `ThrowsError` is re-rendered, but this time does not throw an error, so at the end the DOM
// contains "We should see this"

let out = dioxus_ssr::render(&dom);
assert_eq!(out, "We should see this");

// There should be no errors left in the error boundary
dom.in_runtime(|| {
ScopeId::APP.in_runtime(|| assert!(consume_context::<ErrorContext>().errors().is_empty()))
})
}
10 changes: 10 additions & 0 deletions packages/core/tests/fuzzing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,11 @@ fn create() {
let mut vdom =
VirtualDom::new_with_props(create_random_element, DepthProps { depth: 0, root: true });
vdom.rebuild(&mut NoOpMutations);

vdom.in_runtime(|| {
ScopeId::APP
.in_runtime(|| assert!(consume_context::<ErrorContext>().errors().is_empty()))
})
}
}

Expand Down Expand Up @@ -317,6 +322,11 @@ fn diff() {
));
}
}

vdom.in_runtime(|| {
ScopeId::APP
.in_runtime(|| assert!(consume_context::<ErrorContext>().errors().is_empty()))
})
}
}

Expand Down
2 changes: 2 additions & 0 deletions packages/core/tests/miri_full_app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ use dioxus_core::ElementId;
use dioxus_elements::SerializedHtmlEventConverter;
use std::{any::Any, rc::Rc};

// This test is intended to be run with Miri, and contains no assertions. If it completes under
// Miri, it has passed.
#[test]
fn miri_rollover() {
set_event_converter(Box::new(SerializedHtmlEventConverter));
Expand Down
3 changes: 3 additions & 0 deletions packages/core/tests/miri_simple.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
use dioxus::prelude::*;
use dioxus_core::generation;

// The tests in this file are intended to be run with Miri, and contain no assertions. If they
// complete under Miri, they have passed.

#[test]
fn app_drops() {
fn app() -> Element {
Expand Down
3 changes: 3 additions & 0 deletions packages/core/tests/miri_stress.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ use std::rc::Rc;
use dioxus::prelude::*;
use dioxus_core::{generation, NoOpMutations};

// The tests in this file are intended to be run with Miri, so not all of them contain assertions.
// If the tests complete under Miri, they have passed.

/// This test checks that we should release all memory used by the virtualdom when it exits.
///
/// When miri runs, it'll let us know if we leaked or aliased.
Expand Down
32 changes: 0 additions & 32 deletions packages/core/tests/suspense.rs
Original file line number Diff line number Diff line change
Expand Up @@ -217,22 +217,6 @@ fn suspended_nodes_dont_trigger_effects() {
}
}

#[component]
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This component was unused

fn RerendersFrequently() -> Element {
let mut count = use_signal(|| 0);

use_future(move || async move {
for _ in 0..100 {
tokio::time::sleep(std::time::Duration::from_millis(10)).await;
count.set(count() + 1);
}
});

rsx! {
div { "rerenders frequently" }
}
}

#[component]
fn Child() -> Element {
let mut future_resolved = use_signal(|| false);
Expand Down Expand Up @@ -474,22 +458,6 @@ fn toggle_suspense() {
fn nested_suspense_resolves_client() {
use Mutation::*;

async fn poll_three_times() {
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This exactly duplicated a function at the top of the file so removed for DRYness

// Poll each task 3 times
let mut count = 0;
poll_fn(|cx| {
println!("polling... {}", count);
if count < 3 {
count += 1;
cx.waker().wake_by_ref();
Poll::Pending
} else {
Poll::Ready(())
}
})
.await;
}

fn app() -> Element {
rsx! {
SuspenseBoundary {
Expand Down
42 changes: 32 additions & 10 deletions packages/signals/tests/create.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#![allow(unused, non_upper_case_globals, non_snake_case)]

use dioxus::prelude::*;
use dioxus_core::{generation, ElementId, NoOpMutations};
use dioxus_core::{generation, ElementId, Mutation, NoOpMutations};
use dioxus_signals::*;

#[test]
Expand All @@ -22,35 +22,57 @@ fn create_signals_global() {
}
}

dom.rebuild_in_place();

fn create_without_cx() -> Signal<String> {
Signal::new("hello world".to_string())
}

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wasn't sure if this level of checking was overkill, but it checks that the signals are working...

let muts = dom.rebuild_to_vec();

// 11 edits: 10x CreateTextNode and 1x AppendChildren. These assertions rely on the VirtualDOM's
// logic, but doing this means not introducing a dependency on a renderer.
assert_eq!(11, muts.edits.len());
for i in 0..10 {
assert_eq!(
&muts.edits[i],
&Mutation::CreateTextNode {
value: ("hello world".to_string()),
id: ElementId(i + 1)
}
);
}
assert_eq!(
&muts.edits[10],
&Mutation::AppendChildren {
id: ElementId(0),
m: 10
}
)
}

#[test]
fn deref_signal() {
use std::sync::atomic::{AtomicBool, Ordering};
static STRINGS_MATCH: AtomicBool = AtomicBool::new(false);

let mut dom = VirtualDom::new(|| {
rsx! {
for _ in 0..10 {
Child {}
}
}
rsx! { 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");
let result = &*signal();
STRINGS_MATCH.store(result.eq("hello world"), Ordering::Relaxed);

rsx! {
"hello world"
"arbitrary text"
}
}

dom.rebuild_in_place();

assert!(STRINGS_MATCH.load(Ordering::Relaxed));
}

#[test]
Expand Down
6 changes: 5 additions & 1 deletion packages/signals/tests/memo.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
#![allow(unused, non_upper_case_globals, non_snake_case)]
use dioxus::html::p;
use dioxus::prelude::*;
use dioxus_core::NoOpMutations;
use dioxus_core::{generation, ElementId};
use dioxus_core::{NoOpMutations, ScopeState};
use dioxus_signals::*;
use std::cell::RefCell;
use std::collections::HashMap;
Expand Down Expand Up @@ -141,6 +141,10 @@ fn memos_prevents_component_rerun() {
assert_eq!(current_counter.component, 2);
assert_eq!(current_counter.memo, 3);
}

dom.in_runtime(|| {
ScopeId(3).in_runtime(|| assert!(consume_context::<ErrorContext>().errors().is_empty()))
});
}

// Regression test for https://github.com/DioxusLabs/dioxus/issues/2990
Expand Down