fix(derive): fail missing surface generation
Make #[slhx::surface] report a compile-time error when slhx.generated.rs is absent instead of silently expanding to an empty module. Add compile-fail coverage for the missing generated include path. req: build/004 req: test/003
This commit is contained in:
@@ -0,0 +1,4 @@
|
|||||||
|
fn main() {
|
||||||
|
let out = std::path::PathBuf::from(std::env::var_os("OUT_DIR").unwrap());
|
||||||
|
std::fs::write(out.join("slhx.generated.rs"), "").unwrap();
|
||||||
|
}
|
||||||
+11
-2
@@ -66,13 +66,22 @@ fn inject_surface_include(item: TokenStream) -> TokenStream {
|
|||||||
|
|
||||||
fn surface_include() -> String {
|
fn surface_include() -> String {
|
||||||
let Some(path) = generated_path("slhx.generated.rs") else {
|
let Some(path) = generated_path("slhx.generated.rs") else {
|
||||||
return String::new();
|
return format!(
|
||||||
|
" compile_error!({:?}); ",
|
||||||
|
"#[slhx::surface] requires OUT_DIR; run inside a Cargo crate with slhx_build::app() in build.rs"
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
if path.exists() {
|
if path.exists() {
|
||||||
format!(" include!({:?}); ", path.display().to_string())
|
format!(" include!({:?}); ", path.display().to_string())
|
||||||
} else {
|
} else {
|
||||||
String::new()
|
format!(
|
||||||
|
" compile_error!({:?}); ",
|
||||||
|
format!(
|
||||||
|
"#[slhx::surface] could not find {}; add slhx_build::app().run()? to build.rs or check template generation",
|
||||||
|
path.display()
|
||||||
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -46,14 +46,7 @@ fn known() {}
|
|||||||
"#,
|
"#,
|
||||||
);
|
);
|
||||||
|
|
||||||
let output = Command::new("cargo")
|
let output = check_fixture(&fixture);
|
||||||
.arg("check")
|
|
||||||
.arg("--quiet")
|
|
||||||
.arg("--manifest-path")
|
|
||||||
.arg(fixture.path.join("Cargo.toml"))
|
|
||||||
.env("CARGO_TARGET_DIR", fixture.path.join("target"))
|
|
||||||
.output()
|
|
||||||
.expect("cargo check fixture runs");
|
|
||||||
|
|
||||||
assert!(!output.status.success(), "fixture unexpectedly compiled");
|
assert!(!output.status.success(), "fixture unexpectedly compiled");
|
||||||
let stderr = String::from_utf8_lossy(&output.stderr);
|
let stderr = String::from_utf8_lossy(&output.stderr);
|
||||||
@@ -67,6 +60,55 @@ fn known() {}
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn surface_macro_reports_missing_generated_include() {
|
||||||
|
// req: build/004 req: test/003
|
||||||
|
let fixture = Fixture::new("slhx-derive-surface-include-fail");
|
||||||
|
fixture.write(
|
||||||
|
"Cargo.toml",
|
||||||
|
&format!(
|
||||||
|
r#"[package]
|
||||||
|
name = "slhx-derive-surface-include-fail"
|
||||||
|
version = "0.0.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
path = "src/lib.rs"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
slhx = {{ path = {:?} }}
|
||||||
|
"#,
|
||||||
|
repo_path("slhx")
|
||||||
|
),
|
||||||
|
);
|
||||||
|
fixture.write(
|
||||||
|
"build.rs",
|
||||||
|
r#"fn main() {
|
||||||
|
println!("cargo:rerun-if-changed=build.rs");
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
);
|
||||||
|
fixture.write(
|
||||||
|
"src/lib.rs",
|
||||||
|
r#"#[slhx::surface]
|
||||||
|
pub mod ui {}
|
||||||
|
"#,
|
||||||
|
);
|
||||||
|
|
||||||
|
let output = check_fixture(&fixture);
|
||||||
|
|
||||||
|
assert!(!output.status.success(), "fixture unexpectedly compiled");
|
||||||
|
let stderr = String::from_utf8_lossy(&output.stderr);
|
||||||
|
assert!(
|
||||||
|
stderr.contains("#[slhx::surface] could not find"),
|
||||||
|
"missing surface include diagnostic in stderr:\n{stderr}"
|
||||||
|
);
|
||||||
|
assert!(
|
||||||
|
stderr.contains("add slhx_build::app().run()? to build.rs"),
|
||||||
|
"missing build.rs hint in stderr:\n{stderr}"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn generated_resource_references_fail_when_name_is_absent() {
|
fn generated_resource_references_fail_when_name_is_absent() {
|
||||||
// req: style/002 req: codegen/001 req: test/003
|
// req: style/002 req: codegen/001 req: test/003
|
||||||
@@ -110,14 +152,7 @@ pub const MISSING: slhx::CssClass = ui::classes::missing;
|
|||||||
"#,
|
"#,
|
||||||
);
|
);
|
||||||
|
|
||||||
let output = Command::new("cargo")
|
let output = check_fixture(&fixture);
|
||||||
.arg("check")
|
|
||||||
.arg("--quiet")
|
|
||||||
.arg("--manifest-path")
|
|
||||||
.arg(fixture.path.join("Cargo.toml"))
|
|
||||||
.env("CARGO_TARGET_DIR", fixture.path.join("target"))
|
|
||||||
.output()
|
|
||||||
.expect("cargo check fixture runs");
|
|
||||||
|
|
||||||
assert!(!output.status.success(), "fixture unexpectedly compiled");
|
assert!(!output.status.success(), "fixture unexpectedly compiled");
|
||||||
let stderr = String::from_utf8_lossy(&output.stderr);
|
let stderr = String::from_utf8_lossy(&output.stderr);
|
||||||
@@ -127,6 +162,17 @@ pub const MISSING: slhx::CssClass = ui::classes::missing;
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn check_fixture(fixture: &Fixture) -> std::process::Output {
|
||||||
|
Command::new("cargo")
|
||||||
|
.arg("check")
|
||||||
|
.arg("--quiet")
|
||||||
|
.arg("--manifest-path")
|
||||||
|
.arg(fixture.path.join("Cargo.toml"))
|
||||||
|
.env("CARGO_TARGET_DIR", fixture.path.join("target"))
|
||||||
|
.output()
|
||||||
|
.expect("cargo check fixture runs")
|
||||||
|
}
|
||||||
|
|
||||||
fn repo_path(crate_name: &str) -> PathBuf {
|
fn repo_path(crate_name: &str) -> PathBuf {
|
||||||
Path::new(env!("CARGO_MANIFEST_DIR"))
|
Path::new(env!("CARGO_MANIFEST_DIR"))
|
||||||
.parent()
|
.parent()
|
||||||
|
|||||||
@@ -6,6 +6,6 @@ mod ui {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn surface_macro_preserves_inline_module_without_generated_file() {
|
fn surface_macro_preserves_inline_module_with_generated_file() {
|
||||||
assert_eq!(ui::EXISTING, 1);
|
assert_eq!(ui::EXISTING, 1);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user