use super::{gen_enum_from_binding_to_core, gen_enum_from_core_to_binding};
use crate::core::ir::{EnumDef, EnumVariant};
fn simple_enum() -> EnumDef {
EnumDef {
name: "Backend".to_string(),
rust_path: "my_crate::Backend".to_string(),
variants: vec![
EnumVariant {
name: "Cpu".to_string(),
..Default::default()
},
EnumVariant {
name: "Gpu".to_string(),
..Default::default()
},
],
..Default::default()
}
}
#[test]
fn host_cfg_variant_keeps_its_arm_and_gains_a_cfg_guard_in_both_directions() {
let mut enum_def = simple_enum();
enum_def.variants[1].cfg = Some(r#"feature = "gpu-accel""#.to_string());
let core_to_binding = gen_enum_from_core_to_binding(&enum_def, "my_crate");
assert!(
core_to_binding.contains("my_crate::Backend::Gpu => Self::Gpu"),
"host-owned variant's From<CoreType> arm must still be emitted, got:\n{core_to_binding}"
);
assert_eq!(
core_to_binding.matches("#[cfg(feature = \"gpu-accel\")]").count(),
1,
"the From<CoreType> arm must carry the #[cfg] guard exactly once, got:\n{core_to_binding}"
);
let binding_to_core = gen_enum_from_binding_to_core(&enum_def, "my_crate");
assert!(
binding_to_core.contains("Backend::Gpu => Self::Gpu"),
"host-owned variant's From<BindingEnum> arm must still be emitted, got:\n{binding_to_core}"
);
assert_eq!(
binding_to_core.matches("#[cfg(feature = \"gpu-accel\")]").count(),
1,
"the From<BindingEnum> arm must carry the #[cfg] guard exactly once, got:\n{binding_to_core}"
);
}
#[test]
fn foreign_cfg_variant_arm_is_dropped_not_gated_in_both_directions() {
let mut enum_def = simple_enum();
enum_def.rust_path = "dep_crate::Backend".to_string();
enum_def.variants[1].cfg = Some(r#"feature = "testkit""#.to_string());
let core_to_binding = gen_enum_from_core_to_binding(&enum_def, "my_crate");
assert!(
!core_to_binding.contains("#[cfg(feature = \"testkit\")]"),
"no invalid #[cfg] naming an undeclared feature may be emitted, got:\n{core_to_binding}"
);
assert!(
!core_to_binding.contains("dep_crate::Backend::Gpu =>"),
"a foreign-crate cfg-gated variant must not be referenced in the From<CoreType> match, got:\n{core_to_binding}"
);
assert!(
core_to_binding.contains("_ => Default::default()"),
"dropping the arm must still leave the match exhaustive via the catch-all, got:\n{core_to_binding}"
);
let binding_to_core = gen_enum_from_binding_to_core(&enum_def, "my_crate");
assert!(
!binding_to_core.contains("#[cfg(feature = \"testkit\")]"),
"no invalid #[cfg] naming an undeclared feature may be emitted, got:\n{binding_to_core}"
);
assert!(
!binding_to_core.contains("Backend::Gpu => Self::Gpu"),
"a foreign-crate cfg-gated variant must not be referenced in the From<BindingEnum> match, got:\n{binding_to_core}"
);
}
#[test]
fn ungated_enum_emits_no_cfg_in_either_direction() {
let enum_def = simple_enum();
let core_to_binding = gen_enum_from_core_to_binding(&enum_def, "my_crate");
assert!(
!core_to_binding.contains("#[cfg("),
"ungated enum must not emit #[cfg(...)] in From<CoreType> impl, got:\n{core_to_binding}"
);
let binding_to_core = gen_enum_from_binding_to_core(&enum_def, "my_crate");
assert!(
!binding_to_core.contains("#[cfg("),
"ungated enum must not emit #[cfg(...)] in From<BindingEnum> impl, got:\n{binding_to_core}"
);
}