Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix: #2095, #1990 #2096

Merged
merged 3 commits into from
Mar 18, 2024
Merged
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
31 changes: 31 additions & 0 deletions packages/core/tests/attributes_pass.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
use dioxus::prelude::*;

/// Make sure that rsx! is parsing templates and their attributes properly
#[test]
fn attributes_pass_properly() {
let h = rsx! {
circle {
cx: 50,
cy: 50,
r: 40,
stroke: "green",
fill: "yellow"
}
};

let o = h.unwrap();

let template = &o.template.get();

assert_eq!(template.attr_paths.len(), 3);

let _circle = template.roots[0];
let TemplateNode::Element { attrs, tag, namespace, children } = _circle else {
panic!("Expected an element");
};

assert_eq!(tag, "circle");
assert_eq!(namespace, Some("http://www.w3.org/2000/svg"));
assert_eq!(children.len(), 0);
assert_eq!(attrs.len(), 5);
}
25 changes: 23 additions & 2 deletions packages/hot-reload/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,31 @@ pub enum HotReloadMsg {
/// Connect to the hot reloading listener. The callback provided will be called every time a template change is detected
pub fn connect(mut callback: impl FnMut(HotReloadMsg) + Send + 'static) {
std::thread::spawn(move || {
let path = PathBuf::from("./").join("target").join("dioxusin");
// get the cargo manifest directory, where the target dir lives
let mut path = PathBuf::from(env!("CARGO_MANIFEST_DIR"));

// walk the path until we a find a socket named `dioxusin` inside that folder's target directory
loop {
let maybe = path.join("target").join("dioxusin");

if maybe.exists() {
path = maybe;
break;
}

// It's likely we're running under just cargo and not dx
path = match path.parent() {
Some(parent) => parent.to_path_buf(),
None => return,
};
}

// There might be a socket since the we're not running under the hot reloading server
let Ok(socket) = LocalSocketStream::connect(path) else {
let Ok(socket) = LocalSocketStream::connect(path.clone()) else {
println!(
"could not find hot reloading server at {:?}, make sure it's running",
path
);
return;
};

Expand Down
24 changes: 12 additions & 12 deletions packages/playwright-tests/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion packages/playwright-tests/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,6 @@
"author": "",
"license": "ISC",
"devDependencies": {
"@playwright/test": "^1.41.2"
"@playwright/test": "^1.42.1"
}
}
22 changes: 6 additions & 16 deletions packages/rsx/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -453,7 +453,8 @@ impl<'a> DynamicContext<'a> {
}
}

fn render_static_node(&mut self, root: &'a BodyNode) -> TokenStream2 {
/// Render a portion of an rsx callbody to a token stream
pub fn render_static_node(&mut self, root: &'a BodyNode) -> TokenStream2 {
match root {
BodyNode::Element(el) => {
let el_name = &el.name;
Expand Down Expand Up @@ -499,20 +500,10 @@ impl<'a> DynamicContext<'a> {
}

_ => {
// If this attribute is dynamic, but it already exists in the template, we can reuse the index
if let Some(attribute_index) = self
.attr_paths
.iter()
.position(|path| path == &self.current_path)
{
self.dynamic_attributes[attribute_index].push(attr);
quote! {}
} else {
let ct = self.dynamic_attributes.len();
self.dynamic_attributes.push(vec![attr]);
self.attr_paths.push(self.current_path.clone());
quote! { dioxus_core::TemplateAttribute::Dynamic { id: #ct }, }
}
let ct = self.dynamic_attributes.len();
self.dynamic_attributes.push(vec![attr]);
self.attr_paths.push(self.current_path.clone());
quote! { dioxus_core::TemplateAttribute::Dynamic { id: #ct }, }
}
});

Expand All @@ -525,7 +516,6 @@ impl<'a> DynamicContext<'a> {
out
});

let _opt = el.children.len() == 1;
let children = quote! { #(#children),* };

let ns = ns(quote!(NAME_SPACE));
Expand Down
10 changes: 10 additions & 0 deletions packages/rsx/tests/hotreloads.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,16 @@ fn hotreloads() {
diff_rsx(&new, &old),
DiffResult::RsxChanged { .. }
));

let (old, new) = load_files(
include_str!("./valid/combo.old.rsx"),
include_str!("./valid/combo.new.rsx"),
);

assert!(matches!(
diff_rsx(&new, &old),
DiffResult::RsxChanged { .. }
));
}

#[test]
Expand Down
44 changes: 44 additions & 0 deletions packages/rsx/tests/parsing.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
use dioxus_rsx::{CallBody, DynamicContext};
use syn::Item;

#[test]
fn rsx_writeout_snapshot() {
let body = parse_from_str(include_str!("./parsing/multiexpr.rsx"));

assert_eq!(body.roots.len(), 1);

let root = &body.roots[0];

let el = match root {
dioxus_rsx::BodyNode::Element(el) => el,
_ => panic!("Expected an element"),
};

assert_eq!(el.name, "circle");

assert_eq!(el.attributes.len(), 5);

let mut context = DynamicContext::default();
let o = context.render_static_node(&body.roots[0]);

// hi!!!!!
// you're probably here because you changed something in how rsx! generates templates and need to update the snapshot
// This is a snapshot test. Make sure the contents are checked before committing a new snapshot.
let stability_tested = o.to_string();
assert_eq!(
stability_tested.trim(),
include_str!("./parsing/multiexpr.expanded.rsx").trim()
);
}

fn parse_from_str(contents: &str) -> CallBody {
// Parse the file
let file = syn::parse_file(contents).unwrap();

// The first token should be the macro call
let Item::Macro(call) = file.items.first().unwrap() else {
panic!("Expected a macro call");
};

call.mac.parse_body().unwrap()
}
1 change: 1 addition & 0 deletions packages/rsx/tests/parsing/multiexpr.expanded.rsx
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
dioxus_core :: TemplateNode :: Element { tag : dioxus_elements :: circle :: TAG_NAME , namespace : dioxus_elements :: circle :: NAME_SPACE , attrs : & [dioxus_core :: TemplateAttribute :: Dynamic { id : 0usize } , dioxus_core :: TemplateAttribute :: Dynamic { id : 1usize } , dioxus_core :: TemplateAttribute :: Dynamic { id : 2usize } , dioxus_core :: TemplateAttribute :: Static { name : dioxus_elements :: circle :: stroke . 0 , namespace : dioxus_elements :: circle :: stroke . 1 , value : "green" , } , dioxus_core :: TemplateAttribute :: Static { name : dioxus_elements :: circle :: fill . 0 , namespace : dioxus_elements :: circle :: fill . 1 , value : "yellow" , } ,] , children : & [] , }
11 changes: 11 additions & 0 deletions packages/rsx/tests/parsing/multiexpr.rsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@

rsx! {
circle {
cx: 50,
cy: 50,
r: 40,
stroke: "green",
fill: "yellow"
}
}

58 changes: 58 additions & 0 deletions packages/rsx/tests/valid/combo.new.rsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
// This test is used by playwright configured in the root of the repo

use dioxus::prelude::*;

fn app() -> Element {
let mut num = use_signal(|| 0);
let mut eval_result = use_signal(String::new);
let a = 123;

rsx! {
div {
"hello axum! {num}"
button { class: "increment-button", onclick: move |_| num += 1, "Increment" }
}
svg { circle { cx: 50, cy: 50, r: 40, stroke: "green", fill: "yellow" } }
div { class: "raw-attribute-div", "raw-attribute": "raw-attribute-value" }
div { class: "hidden-attribute-div", hidden: true }
div {
class: "dangerous-inner-html-div",
dangerous_inner_html: "<p>hello dangerous inner html</p>"
}
input { value: "hello input" }
div { class: "style-div", color: "red", "colored text" }
div { class: "style-div", color: "red", "colored text" }
button {
class: "eval-button",
onclick: move |_| async move {
let mut eval = eval(
r#"
window.document.title = 'Hello from Dioxus Eval!';
dioxus.send("returned eval value");
"#,
);

let result = eval.recv().await;
if let Ok(serde_json::Value::String(string)) = result {
eval_result.set(string);
}
},
"Eval!!!!"
"Eval!!!!"
"Eval!!!!!"
"Eval!!!!"
"Eval!!!!"
"Eval!!!!"
}
div { class: "eval-result", "{eval_result}" }
}
}

fn main() {
// tracing_wasm::set_as_global_default_with_config(
// tracing_wasm::WASMLayerConfigBuilder::default()
// .set_max_level(tracing::Level::TRACE)
// .build(),
// );
launch(app);
}
57 changes: 57 additions & 0 deletions packages/rsx/tests/valid/combo.old.rsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
// This test is used by playwright configured in the root of the repo

use dioxus::prelude::*;

fn app() -> Element {
let mut num = use_signal(|| 0);
let mut eval_result = use_signal(String::new);
let a = 123;

rsx! {
div {
"hello axum! {num}"
button { class: "increment-button", onclick: move |_| num += 1, "Increment" }
}
svg { circle { cx: 50, cy: 50, r: 40, stroke: "green", fill: "yellow" } }
div { class: "raw-attribute-div", "raw-attribute": "raw-attribute-value" }
div { class: "hidden-attribute-div", hidden: true }
div {
class: "dangerous-inner-html-div",
dangerous_inner_html: "<p>hello dangerous inner html</p>"
}
input { value: "hello input" }
div { class: "style-div", color: "red", "colored text" }
div { class: "style-div", color: "red", "colored text" }
button {
class: "eval-button",
onclick: move |_| async move {
let mut eval = eval(
r#"
window.document.title = 'Hello from Dioxus Eval!';
dioxus.send("returned eval value");
"#,
);

let result = eval.recv().await;
if let Ok(serde_json::Value::String(string)) = result {
eval_result.set(string);
}
},
"Eval!!!!"
"Eval!!!!"
"Eval!!!!!"
"Eval!!!!"
"Eval!!!!"
}
div { class: "eval-result", "{eval_result}" }
}
}

fn main() {
// tracing_wasm::set_as_global_default_with_config(
// tracing_wasm::WASMLayerConfigBuilder::default()
// .set_max_level(tracing::Level::TRACE)
// .build(),
// );
launch(app);
}
Loading