use super::*;
#[test]
fn test_pub_use_mirror_of_locally_declared_type_is_not_duplicated() {
let surface = extract_from_source(
r#"
pub mod inner {
pub struct Widget {
pub id: i32,
}
}
pub use inner::Widget;
"#,
);
assert_eq!(surface.types.len(), 1, "Widget must appear once, not once per use path");
assert_eq!(surface.types[0].name, "Widget");
assert_eq!(surface.types[0].rust_path, "test_crate::Widget");
}
#[test]
fn test_type_referenced_from_two_modules_is_extracted_once() {
let surface = extract_from_source(
r#"
pub struct Widget {
pub id: i32,
}
pub mod a {
pub fn make_a(w: super::Widget) -> super::Widget { w }
}
pub mod b {
pub fn make_b(w: super::Widget) -> super::Widget { w }
}
"#,
);
assert_eq!(
surface.types.len(),
1,
"a type referenced from multiple modules must not be re-extracted per referencing module"
);
assert_eq!(surface.types[0].name, "Widget");
assert_eq!(surface.functions.len(), 2);
}
#[test]
fn test_glob_reexport_of_local_module_does_not_duplicate_its_type() {
let surface = extract_from_source(
r#"
pub use inner::*;
pub mod inner {
pub struct Widget {
pub id: i32,
}
}
"#,
);
assert_eq!(surface.types.len(), 1, "a glob-reexported local type must appear once");
assert_eq!(surface.types[0].name, "Widget");
assert_eq!(surface.types[0].rust_path, "test_crate::Widget");
}
#[test]
fn test_named_reexport_of_private_module_keeps_single_entry_and_filters_others() {
let surface = extract_from_source(
r#"
mod inner {
pub struct Widget {
pub id: i32,
}
pub struct Other {
pub value: i32,
}
}
pub use inner::Widget;
"#,
);
assert_eq!(
surface.types.len(),
1,
"only the named-reexported type from a private module should survive, exactly once"
);
assert_eq!(surface.types[0].name, "Widget");
assert_eq!(surface.types[0].rust_path, "test_crate::Widget");
}
#[test]
fn test_cfg_disjoint_same_name_structs_are_not_collapsed_here() {
let surface = extract_from_source(
r#"
#[cfg(feature = "x")]
pub struct Config {
pub timeout: u32,
}
#[cfg(not(feature = "x"))]
pub struct Config {
pub timeout: u32,
pub retries: u32,
}
"#,
);
assert_eq!(
surface.types.len(),
2,
"cfg-disjoint same-name structs are preserved here for downstream dedup, same as functions"
);
assert!(surface.types.iter().all(|t| t.name == "Config"));
assert!(surface.types.iter().all(|t| t.rust_path == "test_crate::Config"));
assert!(surface.types.iter().all(|t| !t.binding_excluded));
let cfgs: std::collections::BTreeSet<_> = surface.types.iter().map(|t| t.cfg.clone()).collect();
assert_eq!(
cfgs.len(),
2,
"the two entries must carry the two distinct cfg gates, not collapse to one"
);
}