diff --git a/examples/html_examples/src/main.rs b/examples/html_examples/src/main.rs
index 98fe51c..95a169a 100644
--- a/examples/html_examples/src/main.rs
+++ b/examples/html_examples/src/main.rs
@@ -740,7 +740,13 @@ mod tests {
assert!(html.contains("name=\"q\" value=\"ga\""));
assert!(html.contains("Results for ga"));
assert!(html.contains("Gamma"));
- assert!(!html.contains("Alpha"));
+ assert_eq!(
+ search_results_for("ga")
+ .into_iter()
+ .map(|result| result.label)
+ .collect::>(),
+ ["Gamma"]
+ );
}
#[test]
diff --git a/examples/techdemo/tests/browser_e2e.rs b/examples/techdemo/tests/browser_e2e.rs
index 07f785e..6e54196 100644
--- a/examples/techdemo/tests/browser_e2e.rs
+++ b/examples/techdemo/tests/browser_e2e.rs
@@ -74,7 +74,7 @@ async fn browser_drives_typed_product_end_to_end() -> WebDriverResult<()> {
.await?;
driver
- .find(By::Css(&handle_selector(simulate_push)))
+ .find(By::Css(handle_selector(simulate_push)))
.await?
.click()
.await?;
@@ -82,7 +82,7 @@ async fn browser_drives_typed_product_end_to_end() -> WebDriverResult<()> {
wait_for_text(&driver, island_readout_selector(), "activity rows").await?;
driver
- .find(By::Css(&handle_button_selector(launch_work)))
+ .find(By::Css(handle_button_selector(launch_work)))
.await?
.click()
.await?;
@@ -95,14 +95,14 @@ async fn browser_drives_typed_product_end_to_end() -> WebDriverResult<()> {
assert_text(&driver, "width:77%").await?;
driver
- .find(By::Css(&handle_selector(simulate_push)))
+ .find(By::Css(handle_selector(simulate_push)))
.await?
.click()
.await?;
wait_for_text(&driver, &target_selector(control::live_feed), "SSE tick").await?;
driver
- .find(By::Css(&nav_link_selector("/architecture")))
+ .find(By::Css(nav_link_selector("/architecture")))
.await?
.click()
.await?;
diff --git a/examples/techdemo/tests/e2e.rs b/examples/techdemo/tests/e2e.rs
index 351a7bc..7c04410 100644
--- a/examples/techdemo/tests/e2e.rs
+++ b/examples/techdemo/tests/e2e.rs
@@ -28,7 +28,7 @@ struct Server {
impl Server {
fn start() -> Self {
let bin = env!("CARGO_BIN_EXE_hemx-techdemo");
- let child = Command::new(bin)
+ let mut child = Command::new(bin)
.stdout(Stdio::null())
.stderr(Stdio::null())
.spawn()
@@ -41,6 +41,8 @@ impl Server {
}
std::thread::sleep(Duration::from_millis(25));
}
+ let _ = child.kill();
+ let _ = child.wait();
panic!("hemx-techdemo did not listen on {ADDR}");
}
}
@@ -379,7 +381,7 @@ fn assert_card(batch: &EffectInspector, title: &str, lane: &str, stage: &str, im
let board = batch
.target_html_containing(control::board, "class=\"lanes\"")
.expect("board html payload");
- let document = Html::parse_fragment(&board);
+ let document = Html::parse_fragment(board);
let lane_selector = Selector::parse(&class_selector("lane")).unwrap();
let card_selector = Selector::parse(&class_selector("work-card")).unwrap();
let strong_selector = Selector::parse(strong_text_selector()).unwrap();
diff --git a/examples/workout/tests/browser_e2e.rs b/examples/workout/tests/browser_e2e.rs
index 913ed98..39a49e7 100644
--- a/examples/workout/tests/browser_e2e.rs
+++ b/examples/workout/tests/browser_e2e.rs
@@ -75,7 +75,7 @@ async fn browser_proves_phone_first_workout_flow() -> WebDriverResult<()> {
wait_for_body_text(&driver, "Undid: started Goblet squat set 2").await?;
let host_panel = driver.find(By::Css(".host-proof")).await?;
- assert!(!host_panel.attr("open").await?.is_some());
+ assert!(host_panel.attr("open").await?.is_none());
driver.set_window_rect(0, 0, 1024, 900).await?;
assert_viewport(&driver, "wide", false).await?;
diff --git a/examples/workout/tests/e2e.rs b/examples/workout/tests/e2e.rs
index 4fc099e..e4b63e1 100644
--- a/examples/workout/tests/e2e.rs
+++ b/examples/workout/tests/e2e.rs
@@ -18,7 +18,7 @@ impl Server {
drop(listener);
let bin = env!("CARGO_BIN_EXE_hemx-workout-example");
- let child = Command::new(bin)
+ let mut child = Command::new(bin)
.env("HEMX_WORKOUT_ADDR", &addr)
.stdout(Stdio::null())
.stderr(Stdio::null())
@@ -32,6 +32,8 @@ impl Server {
}
std::thread::sleep(Duration::from_millis(25));
}
+ let _ = child.kill();
+ let _ = child.wait();
panic!("hemx-workout-example did not listen on {addr}");
}
}
diff --git a/hemx-build/src/lib.rs b/hemx-build/src/lib.rs
index 1267238..efdf248 100644
--- a/hemx-build/src/lib.rs
+++ b/hemx-build/src/lib.rs
@@ -649,7 +649,9 @@ impl Resources {
.filter(|res| components.contains(&res.ident) && Some(res.ident.as_str()) != component)
{
let child = &res.ident;
- out.push_str(&format!("{inner}impl SlotTarget {{\n"));
+ out.push_str(&format!(
+ "{inner}impl SlotTarget {{\n"
+ ));
out.push_str(&format!("{inner} pub fn put(self, view: &impl ::hemplate::Hemplate) -> ::hemx::advanced::Effect {{ {child_prefix}{child}::put(self.slot, view) }}\n"));
out.push_str(&format!("{inner} pub fn replace(self, view: &impl ::hemplate::Hemplate) -> ::hemx::advanced::Effect {{ {child_prefix}{child}::put(self.slot, view) }}\n"));
out.push_str(&format!("{inner}}}\n"));
@@ -709,7 +711,8 @@ impl Resources {
.values()
.filter(|res| component_matches(res, component))
{
- let marker = if components.contains(&res.ident) && Some(res.ident.as_str()) != component {
+ let marker = if components.contains(&res.ident) && Some(res.ident.as_str()) != component
+ {
format!("{child_prefix}{}::Component", res.ident)
} else {
"()".to_string()
@@ -741,7 +744,7 @@ impl Resources {
"target",
);
}
- out.push_str("\n");
+ out.push('\n');
out.push_str(&format!(
"{pad}#[allow(non_upper_case_globals)]\n{pad}pub mod handles {{\n"
@@ -785,7 +788,7 @@ impl Resources {
"handle",
);
}
- out.push_str("\n");
+ out.push('\n');
out.push_str(&format!(
"{pad}#[allow(non_upper_case_globals)]\n{pad}pub mod params {{\n"
@@ -878,7 +881,7 @@ impl Resources {
res.ident, res.id
));
out.push_str(&format!(
- "{inner}pub const {}_CONTRACT: ::hemx::FormContract = ::hemx::FormContract {{ fields: &{}_FIELDS }};\n",
+ "{inner}pub const {}_CONTRACT: ::hemx::FormContract = ::hemx::FormContract {{ fields: {}_FIELDS }};\n",
res.ident.to_ascii_uppercase(), res.ident.to_ascii_uppercase()
));
out.push_str(&format!(
@@ -923,9 +926,7 @@ impl Resources {
if component.is_some() {
out.push_str("super::");
}
- out.push_str(&format!(
- "__hemx_lower_html(html.as_ref(), &{table_name})\n"
- ));
+ out.push_str(&format!("__hemx_lower_html(html.as_ref(), {table_name})\n"));
out.push_str(&format!("{pad}}}\n\n"));
out.push_str(&format!("{pad}#[doc(hidden)]\n"));
out.push_str(&format!("{pad}pub fn lower_html(html: impl ::std::convert::AsRef) -> ::std::string::String {{ lower(html) }}\n\n"));
diff --git a/hemx-derive/src/lib.rs b/hemx-derive/src/lib.rs
index f82fe2c..a3fc000 100644
--- a/hemx-derive/src/lib.rs
+++ b/hemx-derive/src/lib.rs
@@ -722,10 +722,9 @@ fn component_contract_errors(
let implemented = component_handler_names(items);
let mut errors = Vec::new();
- if component.is_some() && !implemented.is_empty() && generated.is_empty() {
+ if let Some(component) = component.filter(|_| !implemented.is_empty() && generated.is_empty()) {
errors.push(format!(
- "#[hemx::component({:?})] does not match any generated handles; check the .heml file name or component name",
- component.unwrap()
+ "#[hemx::component({component:?})] does not match any generated handles; check the .heml file name or component name"
));
}
@@ -787,7 +786,8 @@ fn duplicate_names(names: &[String]) -> Vec {
}
counts
.into_iter()
- .filter_map(|(name, count)| (count > 1).then(|| name.to_owned()))
+ .filter(|(_, count)| *count > 1)
+ .map(|(name, _)| name.to_owned())
.collect()
}
diff --git a/hemx-derive/tests/compile_fail.rs b/hemx-derive/tests/compile_fail.rs
index 5791df8..f9fd75d 100644
--- a/hemx-derive/tests/compile_fail.rs
+++ b/hemx-derive/tests/compile_fail.rs
@@ -982,7 +982,9 @@ fn check_fixture(fixture: &Fixture) -> std::process::Output {
.arg("--quiet")
.arg("--manifest-path")
.arg(fixture.path.join("Cargo.toml"))
- .env("CARGO_TARGET_DIR", fixture.path.join("target"))
+ // Cargo serializes access to a shared target directory, so all fixtures reuse
+ // the same compiled hemx dependency graph instead of rebuilding it per test.
+ .env("CARGO_TARGET_DIR", fixture_target_dir())
.output()
.expect("cargo check fixture runs")
}
@@ -994,6 +996,13 @@ fn repo_path(crate_name: &str) -> PathBuf {
.join(crate_name)
}
+fn fixture_target_dir() -> PathBuf {
+ Path::new(env!("CARGO_MANIFEST_DIR"))
+ .parent()
+ .expect("crate has workspace parent")
+ .join("target/compile-fixtures")
+}
+
struct Fixture {
path: PathBuf,
}
diff --git a/hemx-js/tests/runtime.rs b/hemx-js/tests/runtime.rs
index 9f9ca43..672f8af 100644
--- a/hemx-js/tests/runtime.rs
+++ b/hemx-js/tests/runtime.rs
@@ -49,9 +49,12 @@ fn runtime_turns_page_get_forms_into_url_state_navigation() {
let source = hemx_js::RUNTIME_JS;
assert!(source.contains("function pageFormHistoryMode(source, form)"));
- assert!(source.contains("const mode = method === \"GET\" && form && pageFormHistoryMode(source, form)"));
+ assert!(source
+ .contains("const mode = method === \"GET\" && form && pageFormHistoryMode(source, form)"));
assert!(source.contains("if (mode)"));
- assert!(source.contains("await navigateUrl(pageRequestUrl(form, source), rootOf(form) || rootOf(el), mode)"));
+ assert!(source.contains(
+ "await navigateUrl(pageRequestUrl(form, source), rootOf(form) || rootOf(el), mode)"
+ ));
assert!(source.contains("function successfulFormData(form, source)"));
assert!(source.contains("new FormData(form, source)"));
assert!(source.contains("data-hemx-nav"));
diff --git a/hemx-test/tests/examples_contract.rs b/hemx-test/tests/examples_contract.rs
index d8d9ee5..8236f93 100644
--- a/hemx-test/tests/examples_contract.rs
+++ b/hemx-test/tests/examples_contract.rs
@@ -1,4 +1,4 @@
-use std::path::{Path, PathBuf};
+use std::path::Path;
#[test]
fn canonical_examples_do_not_author_browser_javascript() {
@@ -343,7 +343,7 @@ fn is_advanced_boundary_doc(text: &str) -> bool {
text.contains("advanced/low-level north-star boundary sketch")
}
-fn is_example_source(path: &PathBuf) -> bool {
+fn is_example_source(path: &Path) -> bool {
matches!(
path.extension().and_then(|ext| ext.to_str()),
Some("rs" | "heml" | "html" | "md")