fix(workspace): clear strict lint and test debt

This commit is contained in:
slhx agent
2026-07-13 08:59:48 +02:00
parent d0e7022c86
commit 65895d8b83
10 changed files with 49 additions and 26 deletions
+7 -1
View File
@@ -740,7 +740,13 @@ mod tests {
assert!(html.contains("name=\"q\" value=\"ga\"")); assert!(html.contains("name=\"q\" value=\"ga\""));
assert!(html.contains("Results for ga")); assert!(html.contains("Results for ga"));
assert!(html.contains("Gamma")); assert!(html.contains("Gamma"));
assert!(!html.contains("Alpha")); assert_eq!(
search_results_for("ga")
.into_iter()
.map(|result| result.label)
.collect::<Vec<_>>(),
["Gamma"]
);
} }
#[test] #[test]
+4 -4
View File
@@ -74,7 +74,7 @@ async fn browser_drives_typed_product_end_to_end() -> WebDriverResult<()> {
.await?; .await?;
driver driver
.find(By::Css(&handle_selector(simulate_push))) .find(By::Css(handle_selector(simulate_push)))
.await? .await?
.click() .click()
.await?; .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?; wait_for_text(&driver, island_readout_selector(), "activity rows").await?;
driver driver
.find(By::Css(&handle_button_selector(launch_work))) .find(By::Css(handle_button_selector(launch_work)))
.await? .await?
.click() .click()
.await?; .await?;
@@ -95,14 +95,14 @@ async fn browser_drives_typed_product_end_to_end() -> WebDriverResult<()> {
assert_text(&driver, "width:77%").await?; assert_text(&driver, "width:77%").await?;
driver driver
.find(By::Css(&handle_selector(simulate_push))) .find(By::Css(handle_selector(simulate_push)))
.await? .await?
.click() .click()
.await?; .await?;
wait_for_text(&driver, &target_selector(control::live_feed), "SSE tick").await?; wait_for_text(&driver, &target_selector(control::live_feed), "SSE tick").await?;
driver driver
.find(By::Css(&nav_link_selector("/architecture"))) .find(By::Css(nav_link_selector("/architecture")))
.await? .await?
.click() .click()
.await?; .await?;
+4 -2
View File
@@ -28,7 +28,7 @@ struct Server {
impl Server { impl Server {
fn start() -> Self { fn start() -> Self {
let bin = env!("CARGO_BIN_EXE_hemx-techdemo"); let bin = env!("CARGO_BIN_EXE_hemx-techdemo");
let child = Command::new(bin) let mut child = Command::new(bin)
.stdout(Stdio::null()) .stdout(Stdio::null())
.stderr(Stdio::null()) .stderr(Stdio::null())
.spawn() .spawn()
@@ -41,6 +41,8 @@ impl Server {
} }
std::thread::sleep(Duration::from_millis(25)); std::thread::sleep(Duration::from_millis(25));
} }
let _ = child.kill();
let _ = child.wait();
panic!("hemx-techdemo did not listen on {ADDR}"); 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 let board = batch
.target_html_containing(control::board, "class=\"lanes\"") .target_html_containing(control::board, "class=\"lanes\"")
.expect("board html payload"); .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 lane_selector = Selector::parse(&class_selector("lane")).unwrap();
let card_selector = Selector::parse(&class_selector("work-card")).unwrap(); let card_selector = Selector::parse(&class_selector("work-card")).unwrap();
let strong_selector = Selector::parse(strong_text_selector()).unwrap(); let strong_selector = Selector::parse(strong_text_selector()).unwrap();
+1 -1
View File
@@ -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?; wait_for_body_text(&driver, "Undid: started Goblet squat set 2").await?;
let host_panel = driver.find(By::Css(".host-proof")).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?; driver.set_window_rect(0, 0, 1024, 900).await?;
assert_viewport(&driver, "wide", false).await?; assert_viewport(&driver, "wide", false).await?;
+3 -1
View File
@@ -18,7 +18,7 @@ impl Server {
drop(listener); drop(listener);
let bin = env!("CARGO_BIN_EXE_hemx-workout-example"); 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) .env("HEMX_WORKOUT_ADDR", &addr)
.stdout(Stdio::null()) .stdout(Stdio::null())
.stderr(Stdio::null()) .stderr(Stdio::null())
@@ -32,6 +32,8 @@ impl Server {
} }
std::thread::sleep(Duration::from_millis(25)); std::thread::sleep(Duration::from_millis(25));
} }
let _ = child.kill();
let _ = child.wait();
panic!("hemx-workout-example did not listen on {addr}"); panic!("hemx-workout-example did not listen on {addr}");
} }
} }
+9 -8
View File
@@ -649,7 +649,9 @@ impl Resources {
.filter(|res| components.contains(&res.ident) && Some(res.ident.as_str()) != component) .filter(|res| components.contains(&res.ident) && Some(res.ident.as_str()) != component)
{ {
let child = &res.ident; let child = &res.ident;
out.push_str(&format!("{inner}impl<T> SlotTarget<T, {child_prefix}{child}::Component> {{\n")); out.push_str(&format!(
"{inner}impl<T> SlotTarget<T, {child_prefix}{child}::Component> {{\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 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} 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")); out.push_str(&format!("{inner}}}\n"));
@@ -709,7 +711,8 @@ impl Resources {
.values() .values()
.filter(|res| component_matches(res, component)) .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) format!("{child_prefix}{}::Component", res.ident)
} else { } else {
"()".to_string() "()".to_string()
@@ -741,7 +744,7 @@ impl Resources {
"target", "target",
); );
} }
out.push_str("\n"); out.push('\n');
out.push_str(&format!( out.push_str(&format!(
"{pad}#[allow(non_upper_case_globals)]\n{pad}pub mod handles {{\n" "{pad}#[allow(non_upper_case_globals)]\n{pad}pub mod handles {{\n"
@@ -785,7 +788,7 @@ impl Resources {
"handle", "handle",
); );
} }
out.push_str("\n"); out.push('\n');
out.push_str(&format!( out.push_str(&format!(
"{pad}#[allow(non_upper_case_globals)]\n{pad}pub mod params {{\n" "{pad}#[allow(non_upper_case_globals)]\n{pad}pub mod params {{\n"
@@ -878,7 +881,7 @@ impl Resources {
res.ident, res.id res.ident, res.id
)); ));
out.push_str(&format!( 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() res.ident.to_ascii_uppercase(), res.ident.to_ascii_uppercase()
)); ));
out.push_str(&format!( out.push_str(&format!(
@@ -923,9 +926,7 @@ impl Resources {
if component.is_some() { if component.is_some() {
out.push_str("super::"); out.push_str("super::");
} }
out.push_str(&format!( out.push_str(&format!("__hemx_lower_html(html.as_ref(), {table_name})\n"));
"__hemx_lower_html(html.as_ref(), &{table_name})\n"
));
out.push_str(&format!("{pad}}}\n\n")); out.push_str(&format!("{pad}}}\n\n"));
out.push_str(&format!("{pad}#[doc(hidden)]\n")); out.push_str(&format!("{pad}#[doc(hidden)]\n"));
out.push_str(&format!("{pad}pub fn lower_html(html: impl ::std::convert::AsRef<str>) -> ::std::string::String {{ lower(html) }}\n\n")); out.push_str(&format!("{pad}pub fn lower_html(html: impl ::std::convert::AsRef<str>) -> ::std::string::String {{ lower(html) }}\n\n"));
+4 -4
View File
@@ -722,10 +722,9 @@ fn component_contract_errors(
let implemented = component_handler_names(items); let implemented = component_handler_names(items);
let mut errors = Vec::new(); 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!( errors.push(format!(
"#[hemx::component({:?})] does not match any generated handles; check the .heml file name or component name", "#[hemx::component({component:?})] does not match any generated handles; check the .heml file name or component name"
component.unwrap()
)); ));
} }
@@ -787,7 +786,8 @@ fn duplicate_names(names: &[String]) -> Vec<String> {
} }
counts counts
.into_iter() .into_iter()
.filter_map(|(name, count)| (count > 1).then(|| name.to_owned())) .filter(|(_, count)| *count > 1)
.map(|(name, _)| name.to_owned())
.collect() .collect()
} }
+10 -1
View File
@@ -982,7 +982,9 @@ fn check_fixture(fixture: &Fixture) -> std::process::Output {
.arg("--quiet") .arg("--quiet")
.arg("--manifest-path") .arg("--manifest-path")
.arg(fixture.path.join("Cargo.toml")) .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() .output()
.expect("cargo check fixture runs") .expect("cargo check fixture runs")
} }
@@ -994,6 +996,13 @@ fn repo_path(crate_name: &str) -> PathBuf {
.join(crate_name) .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 { struct Fixture {
path: PathBuf, path: PathBuf,
} }
+5 -2
View File
@@ -49,9 +49,12 @@ fn runtime_turns_page_get_forms_into_url_state_navigation() {
let source = hemx_js::RUNTIME_JS; let source = hemx_js::RUNTIME_JS;
assert!(source.contains("function pageFormHistoryMode(source, form)")); 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("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("function successfulFormData(form, source)"));
assert!(source.contains("new FormData(form, source)")); assert!(source.contains("new FormData(form, source)"));
assert!(source.contains("data-hemx-nav")); assert!(source.contains("data-hemx-nav"));
+2 -2
View File
@@ -1,4 +1,4 @@
use std::path::{Path, PathBuf}; use std::path::Path;
#[test] #[test]
fn canonical_examples_do_not_author_browser_javascript() { 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") text.contains("advanced/low-level north-star boundary sketch")
} }
fn is_example_source(path: &PathBuf) -> bool { fn is_example_source(path: &Path) -> bool {
matches!( matches!(
path.extension().and_then(|ext| ext.to_str()), path.extension().and_then(|ext| ext.to_str()),
Some("rs" | "heml" | "html" | "md") Some("rs" | "heml" | "html" | "md")