use super::super::types::{gen_enum_from_i32, gen_enum_from_i32_rs_helper, gen_enum_to_i32};
use crate::core::ir::*;
use std::collections::HashSet;
const HOST_CRATE: &str = "my_lib";
fn sample_enum(owner_crate: &str, extra_cfg: &str) -> EnumDef {
EnumDef {
name: "SampleMode".to_string(),
rust_path: format!("{owner_crate}::SampleMode"),
variants: vec![
EnumVariant {
name: "Base".to_string(),
..EnumVariant::default()
},
EnumVariant {
name: "Middle".to_string(),
..EnumVariant::default()
},
EnumVariant {
name: "Extra".to_string(),
cfg: Some(extra_cfg.to_string()),
..EnumVariant::default()
},
],
..EnumDef::default()
}
}
#[test]
fn foreign_variant_proven_unreachable_is_rejected_by_from_i32_and_to_i32() {
let en = sample_enum("dep_crate", r#"feature = "testkit""#);
let configured: HashSet<&str> = HashSet::new();
let from_i32 = gen_enum_from_i32(&en, "alef", HOST_CRATE, Some(&configured));
assert!(
from_i32.contains("0 => 0, // Base") && from_i32.contains("1 => 1, // Middle"),
"the two reachable variants must still validate, got:\n{from_i32}"
);
assert!(
!from_i32.contains("2 =>"),
"the proven-unreachable discriminant must not validate as accepted input, got:\n{from_i32}"
);
let to_i32 = gen_enum_to_i32(&en, "alef", HOST_CRATE, Some(&configured));
assert!(
to_i32.contains("\"Base\" => 0,") && to_i32.contains("\"Middle\" => 1,"),
"the two reachable variants' wire names must still validate, got:\n{to_i32}"
);
assert!(
!to_i32.contains("\"Extra\""),
"a proven-unreachable variant's wire name must not be advertised as accepted input, got:\n{to_i32}"
);
let helper = gen_enum_from_i32_rs_helper(&en, "dep_crate", HOST_CRATE);
assert!(
!helper.contains("2 => Some"),
"apparatus check: the reconstruction helper must have no arm for discriminant 2 either, got:\n{helper}"
);
}
#[test]
fn foreign_variant_not_proven_unreachable_is_accepted_by_from_i32_and_to_i32() {
let en = sample_enum("dep_crate", r#"feature = "testkit""#);
let from_i32 = gen_enum_from_i32(&en, "alef", HOST_CRATE, None);
assert!(
from_i32.contains("2 => 2, // Extra"),
"an unproven foreign variant must still validate, got:\n{from_i32}"
);
let to_i32 = gen_enum_to_i32(&en, "alef", HOST_CRATE, None);
assert!(
to_i32.contains("\"Extra\" => 2,"),
"an unproven foreign variant's wire name must still validate, got:\n{to_i32}"
);
}
#[test]
fn host_owned_cfg_gated_variant_is_accepted_by_from_i32_and_to_i32_regardless_of_configured_features() {
let en = sample_enum(HOST_CRATE, r#"feature = "extra_feature""#);
let configured: HashSet<&str> = HashSet::new();
let from_i32 = gen_enum_from_i32(&en, "alef", HOST_CRATE, Some(&configured));
assert!(
from_i32.contains("2 => 2, // Extra"),
"a host-owned cfg-gated variant must stay accepted, got:\n{from_i32}"
);
let to_i32 = gen_enum_to_i32(&en, "alef", HOST_CRATE, Some(&configured));
assert!(
to_i32.contains("\"Extra\" => 2,"),
"a host-owned cfg-gated variant's wire name must stay accepted, got:\n{to_i32}"
);
}
#[test]
fn dropping_a_variant_does_not_renumber_the_variants_that_follow_it() {
let mut en = sample_enum("dep_crate", r#"feature = "testkit""#);
en.variants.push(EnumVariant {
name: "Trailing".to_string(),
..EnumVariant::default()
});
let configured: HashSet<&str> = HashSet::new();
let from_i32 = gen_enum_from_i32(&en, "alef", HOST_CRATE, Some(&configured));
assert!(
from_i32.contains("3 => 3, // Trailing"),
"the variant after the dropped one must keep its ORIGINAL discriminant (3), not be \
renumbered down to 2, got:\n{from_i32}"
);
}