123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214 |
- #![allow(non_snake_case)]
- use std::rc::Rc;
- use dioxus::prelude::*;
- /// 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.
- #[test]
- fn test_memory_leak() {
- fn app(cx: Scope) -> Element {
- let val = cx.generation();
- cx.spawn(async {});
- if val == 2 || val == 4 {
- return cx.render(rsx!(()));
- }
- let name = cx.use_hook(|| String::from("numbers: "));
- name.push_str("123 ");
- cx.render(rsx!(
- div { "Hello, world!" }
- Child {}
- Child {}
- Child {}
- Child {}
- Child {}
- Child {}
- BorrowedChild { name: name }
- BorrowedChild { name: name }
- BorrowedChild { name: name }
- BorrowedChild { name: name }
- BorrowedChild { name: name }
- ))
- }
- #[derive(Props)]
- struct BorrowedProps<'a> {
- name: &'a str,
- }
- fn BorrowedChild<'a>(cx: Scope<'a, BorrowedProps<'a>>) -> Element {
- cx.render(rsx! {
- div {
- "goodbye {cx.props.name}"
- Child {}
- Child {}
- }
- })
- }
- fn Child(cx: Scope) -> Element {
- render!(div { "goodbye world" })
- }
- let mut dom = VirtualDom::new(app);
- _ = dom.rebuild();
- for _ in 0..5 {
- dom.mark_dirty(ScopeId(0));
- _ = dom.render_immediate();
- }
- }
- #[test]
- fn memo_works_properly() {
- fn app(cx: Scope) -> Element {
- let val = cx.generation();
- if val == 2 || val == 4 {
- return cx.render(rsx!(()));
- }
- let name = cx.use_hook(|| String::from("asd"));
- cx.render(rsx!(
- div { "Hello, world! {name}" }
- Child { na: "asdfg".to_string() }
- ))
- }
- #[derive(PartialEq, Props)]
- struct ChildProps {
- na: String,
- }
- fn Child(cx: Scope<ChildProps>) -> Element {
- render!(div { "goodbye world" })
- }
- let mut dom = VirtualDom::new(app);
- _ = dom.rebuild();
- // todo!()
- // dom.hard_diff(ScopeId(0));
- // dom.hard_diff(ScopeId(0));
- // dom.hard_diff(ScopeId(0));
- // dom.hard_diff(ScopeId(0));
- // dom.hard_diff(ScopeId(0));
- // dom.hard_diff(ScopeId(0));
- // dom.hard_diff(ScopeId(0));
- }
- #[test]
- fn free_works_on_root_hooks() {
- /*
- On Drop, scopearena drops all the hook contents. and props
- */
- #[derive(PartialEq, Clone, Props)]
- struct AppProps {
- inner: Rc<String>,
- }
- fn app(cx: Scope<AppProps>) -> Element {
- let name: &AppProps = cx.use_hook(|| cx.props.clone());
- render!(child_component { inner: name.inner.clone() })
- }
- fn child_component(cx: Scope<AppProps>) -> Element {
- render!(div { "{cx.props.inner}" })
- }
- let ptr = Rc::new("asdasd".to_string());
- let mut dom = VirtualDom::new_with_props(app, AppProps { inner: ptr.clone() });
- let _ = dom.rebuild();
- // ptr gets cloned into props and then into the hook
- assert_eq!(Rc::strong_count(&ptr), 4);
- drop(dom);
- assert_eq!(Rc::strong_count(&ptr), 1);
- }
- #[test]
- fn supports_async() {
- use std::time::Duration;
- use tokio::time::sleep;
- fn app(cx: Scope) -> Element {
- let colors = use_state(cx, || vec!["green", "blue", "red"]);
- let padding = use_state(cx, || 10);
- use_effect(cx, colors, |colors| async move {
- sleep(Duration::from_millis(1000)).await;
- colors.with_mut(|colors| colors.reverse());
- });
- use_effect(cx, padding, |padding| async move {
- sleep(Duration::from_millis(10)).await;
- padding.with_mut(|padding| {
- if *padding < 65 {
- *padding += 1;
- } else {
- *padding = 5;
- }
- });
- });
- let big = colors[0];
- let mid = colors[1];
- let small = colors[2];
- cx.render(rsx! {
- div {
- background: "{big}",
- height: "stretch",
- width: "stretch",
- padding: "50",
- label {
- "hello",
- }
- div {
- background: "{mid}",
- height: "auto",
- width: "stretch",
- padding: "{padding}",
- label {
- "World",
- }
- div {
- background: "{small}",
- height: "auto",
- width: "stretch",
- padding: "20",
- label {
- "ddddddd",
- }
- }
- },
- }
- })
- }
- let rt = tokio::runtime::Builder::new_current_thread()
- .enable_time()
- .build()
- .unwrap();
- rt.block_on(async {
- let mut dom = VirtualDom::new(app);
- let _ = dom.rebuild();
- for _ in 0..10 {
- dom.wait_for_work().await;
- let _edits = dom.render_immediate();
- }
- });
- }
|