test(build): close residual helper mutants
Prove compact Rust type and vector facts plus default template paths, alias collision suppression, data parameter prefixes, keyed descendants, and absent Cargo roots. Classify only hemplate's infallible surface parser seam. req: diagnostics/006 req: diagnostics/004 req: codegen/005 req: test/021
This commit is contained in:
@@ -10,6 +10,7 @@
|
||||
# are behaviorally equivalent at these validated boundaries.
|
||||
# - hemx-build source inspection delegates to hemplate's currently infallible
|
||||
# Surface parser; file I/O and invalid Rust-context errors remain explicitly proven.
|
||||
# The direct surface_for_heml_source unwrap mutant is equivalent for the same seam.
|
||||
# - AppBuilder reuses that same parser seam. Directory-open and recursive errors are
|
||||
# proven, while a per-entry readdir fault cannot be injected portably after a
|
||||
# successful read_dir; its unwrap mutant is classified as infrastructure-only.
|
||||
@@ -35,6 +36,7 @@ exclude_re = [
|
||||
"replace String::from_utf8.* with String::from_utf8.*unwrap\\(\\) in InteractionForm::parse_multipart",
|
||||
"replace HeaderValue::from_str.*runtime_js_hash.* with HeaderValue::from_str.*unwrap\\(\\) in <impl IntoResponse for RuntimeJs>::into_response",
|
||||
'replace "runtime hash is a valid ETag" with "" in <impl IntoResponse for RuntimeJs>::into_response',
|
||||
"replace build_ast.* with build_ast.*unwrap\\(\\) in surface_for_heml_source",
|
||||
"replace surface_for_heml_source.* with surface_for_heml_source.*unwrap\\(\\) in diagnostics_for_heml_source",
|
||||
"replace surface_for_heml_source.* with surface_for_heml_source.*unwrap\\(\\) in generated_targets_for_heml_source",
|
||||
"replace surface_for_heml_source.* with surface_for_heml_source.*unwrap\\(\\) in template_context_facts_for_heml_source",
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
- [ ] **State:** In progress — the package-native capped xtask entry point is reachable, rejects unknown packages, propagates mutest failure, and mutation-tests `hemx-axum`, `hemx-core`, `hemx-js`, and the full `hemx-test` package cleanly; full package closure remains.
|
||||
- **User value:** maintainers can run one bounded repository command and trust that meaningful Rust logic across every mutation-applicable library is either killed or explicitly justified.
|
||||
- **Build:** add a capped `hemx-xtask` mutation command that invokes `/opt/repositories/mutest`/`mutest` through package-native test targets rather than the broken workspace-wide example path; enumerate only current mutation-applicable library/proc-macro packages; finish adversarial tests or simplify code until every survivor is classified; keep equivalent, invariant-only, and infrastructure-inapplicable classifications inspectable and minimal; document the exact local release command in the existing readiness surface.
|
||||
- **Blocked by:** none; broad survivors currently remain in `hemx-build`, `hemx-derive`, and `hemx-lsp` outside already-clean focused contracts. The current `hemx-build` frontier now also mutation-proves all 38 recursive Rust-fact collection mutants and all 115 `Resources::add_surface` mutants, including nested/inline modules, ignored non-Rust/out-of-tree files, invalid parse propagation, atom/handle collisions, and missing form-fact defaults. The focused survivor frontier is closed; rerun the full package mutation gate to expose any remaining uncaught functions. The complete 470-mutant `hemx-axum` package gate now passes with 262 caught and 208 unviable after public page/form/multipart/registry/response/runtime proofs and narrow classification of infallible header parsing and streamed multipart unwrap-equivalent mutants.
|
||||
- **Blocked by:** none; broad survivors currently remain in `hemx-build`, `hemx-derive`, and `hemx-lsp` outside already-clean focused contracts. The current `hemx-build` frontier now also mutation-proves all compact Rust-type/vector-fact and residual default/alias/parameter/keyed-descendant/Cargo-root helper mutants exposed during the full gate. That gate produced no missed-mutant report before the 30-minute command timeout, so the next slice must either complete it with deterministic package shards or expose and close the next shard's survivors. The complete 470-mutant `hemx-axum` package gate now passes with 262 caught and 208 unviable after public page/form/multipart/registry/response/runtime proofs and narrow classification of infallible header parsing and streamed multipart unwrap-equivalent mutants.
|
||||
- **Proof:** the new xtask mutation command exits zero within its documented bound, covers each applicable package, emits no unexplained missed mutant, and a deliberate adjacent mutation makes it fail. `cargo run -p hemx-xtask -- test` remains green. req: test/020 req: test/021
|
||||
|
||||
## 3. Elect and enforce the release license policy
|
||||
|
||||
@@ -1973,6 +1973,7 @@ fn compact_tokens(tokens: &impl ToTokens) -> String {
|
||||
.replace(" < ", "<")
|
||||
.replace(" >", ">")
|
||||
.replace(" ,", ",")
|
||||
.replace(", ", ",")
|
||||
.replace(" & ", "&")
|
||||
.replace("& ", "&")
|
||||
}
|
||||
@@ -2399,6 +2400,47 @@ mod tests {
|
||||
// test req: diagnostics/004 req: diagnostics/006 req: surface/008
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rust_type_facts_are_compact_and_vector_specific() {
|
||||
let qualified: syn::Type =
|
||||
syn::parse_str("std::collections::HashMap<String, &crate::Thing<Left, Right>>")
|
||||
.unwrap();
|
||||
assert_eq!(
|
||||
compact_tokens(&qualified),
|
||||
"std::collections::HashMap<String,&crate::Thing<Left,Right>>"
|
||||
);
|
||||
let mutable: syn::Type = syn::parse_str("&mut crate::Thing").unwrap();
|
||||
assert_eq!(compact_tokens(&mutable), "&mut crate::Thing");
|
||||
let tuple: syn::Type = syn::parse_str("(&crate::Thing, String)").unwrap();
|
||||
assert_eq!(compact_tokens(&tuple), "(&crate::Thing,String)");
|
||||
let function: syn::Type = syn::parse_str("fn(&crate::Thing) -> &crate::Thing").unwrap();
|
||||
assert_eq!(
|
||||
compact_tokens(&function),
|
||||
"fn (&crate::Thing) ->&crate::Thing"
|
||||
);
|
||||
|
||||
assert_eq!(vec_element_type("Vec<String>"), Some("String".into()));
|
||||
assert_eq!(
|
||||
vec_element_type("std::vec::Vec<&crate::Thing<Left,Right>>"),
|
||||
Some("&crate::Thing<Left,Right>".into())
|
||||
);
|
||||
assert_eq!(vec_element_type("Vec< String >"), Some("String".into()));
|
||||
for invalid in [
|
||||
"",
|
||||
"String",
|
||||
"Vec<String",
|
||||
"VecString>",
|
||||
"alloc::vec::Vec<String>",
|
||||
] {
|
||||
assert_eq!(
|
||||
vec_element_type(invalid),
|
||||
None,
|
||||
"accepted non-vector type {invalid:?}"
|
||||
);
|
||||
}
|
||||
// test req: diagnostics/006
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rust_fact_collection_propagates_parse_and_recursive_directory_errors() {
|
||||
let base = test_dir("hemx-build-rust-fact-errors");
|
||||
@@ -2464,6 +2506,18 @@ mod tests {
|
||||
component_ident(root, Path::new("outside.heml")).unwrap(),
|
||||
"outside"
|
||||
);
|
||||
assert_eq!(data_param_ident("data-item-id"), Some("item_id".into()));
|
||||
assert_eq!(data_param_ident("aria-label"), None);
|
||||
assert_eq!(app().template_dir, PathBuf::from("templates"));
|
||||
assert_eq!(nearest_dir_with(Path::new("/"), "hemx-absent-marker"), None);
|
||||
|
||||
let mut exports = String::new();
|
||||
let mut used = BTreeSet::from(["shared".to_owned(), "shared_target".to_owned()]);
|
||||
push_root_export(&mut exports, "", "targets", &mut used, "shared", "target");
|
||||
assert!(
|
||||
exports.is_empty(),
|
||||
"colliding alias must not be emitted twice"
|
||||
);
|
||||
|
||||
let mut resources = BTreeMap::new();
|
||||
let first = insert_resource(
|
||||
@@ -3988,6 +4042,8 @@ fn main() {{
|
||||
assert!(is_inside_keyed_for(&surface, nested_scope));
|
||||
assert!(!is_inside_keyed_for(&surface, sibling_scope));
|
||||
assert!(!is_inside_keyed_for(&surface, ScopeId(u32::MAX)));
|
||||
assert!(has_descendant_keyed_for_scope(&surface, ScopeId(0)));
|
||||
assert!(!has_descendant_keyed_for_scope(&surface, sibling_scope));
|
||||
assert!(unkeyed_generated_target_diagnostic_for_scope(
|
||||
&surface,
|
||||
ScopeId(u32::MAX),
|
||||
|
||||
Reference in New Issue
Block a user