use super::*;
#[test]
fn a_struct_variant_default_folds_with_its_field_values() {
let resolved = defaults_for_typed(
r#"
pub struct Cfg { pub kind: Kind }
impl Default for Cfg {
fn default() -> Self {
Self { kind: Kind::Curated { label: "balanced".to_string(), weight: 3 } }
}
}
"#,
"Cfg",
&[("kind", TypeRef::Named("Kind".to_string()))],
);
assert_eq!(
resolved,
vec![(
"kind".to_string(),
DefaultValue::StructVariant(
"Curated".to_string(),
vec![
("label".to_string(), DefaultValue::StringLiteral("balanced".to_string())),
("weight".to_string(), DefaultValue::IntLiteral(3)),
],
),
)],
"a struct-variant enum default must fold into its own field values, not stay Unresolved"
);
}
#[test]
fn a_tuple_variant_default_folds_with_its_argument_values() {
let resolved = defaults_for_typed(
r#"
pub struct Cfg { pub kind: Kind }
impl Default for Cfg {
fn default() -> Self {
Self { kind: Kind::Scaled(5, "x".to_string()) }
}
}
"#,
"Cfg",
&[("kind", TypeRef::Named("Kind".to_string()))],
);
assert_eq!(
resolved,
vec![(
"kind".to_string(),
DefaultValue::TupleVariant(
"Scaled".to_string(),
vec![
DefaultValue::IntLiteral(5),
DefaultValue::StringLiteral("x".to_string())
],
),
)],
"a tuple-variant enum default must fold into its own argument values, not stay Unresolved"
);
}
#[test]
fn a_unit_variant_default_still_folds_to_a_bare_enum_variant() {
let resolved = defaults_for_typed(
r#"
pub struct Cfg { pub kind: Kind }
impl Default for Cfg {
fn default() -> Self {
Self { kind: Kind::Auto }
}
}
"#,
"Cfg",
&[("kind", TypeRef::Named("Kind".to_string()))],
);
assert_eq!(
resolved,
vec![("kind".to_string(), DefaultValue::EnumVariant("Auto".to_string()))],
"a unit-variant default already folded before this change and must keep doing so"
);
}
#[test]
fn a_struct_variants_unfoldable_field_keeps_the_whole_default_unresolved_not_empty() {
let resolved = defaults_for_typed(
r#"
pub struct Cfg { pub kind: Kind }
impl Default for Cfg {
fn default() -> Self {
Self { kind: Kind::Curated { label: compute_label() } }
}
}
"#,
"Cfg",
&[("kind", TypeRef::Named("Kind".to_string()))],
);
assert!(
matches!(resolved.as_slice(), [(_, DefaultValue::Unresolved(_))]),
"an unfoldable inner field must leave the whole variant default Unresolved; got {resolved:?}"
);
assert_ne!(
resolved[0].1,
DefaultValue::Empty,
"collapsing an unfoldable struct-variant field to `Empty` is the conflation this fixes"
);
}
#[test]
fn a_tuple_variants_unfoldable_argument_keeps_the_whole_default_unresolved_not_empty() {
let resolved = defaults_for_typed(
r#"
pub struct Cfg { pub kind: Kind }
impl Default for Cfg {
fn default() -> Self {
Self { kind: Kind::Scaled(compute_scale()) }
}
}
"#,
"Cfg",
&[("kind", TypeRef::Named("Kind".to_string()))],
);
assert!(
matches!(resolved.as_slice(), [(_, DefaultValue::Unresolved(_))]),
"an unfoldable argument must leave the whole variant default Unresolved; got {resolved:?}"
);
}
#[test]
fn a_struct_variant_with_a_rest_base_stays_unresolved() {
let resolved = defaults_for_typed(
r#"
pub struct Cfg { pub kind: Kind }
impl Default for Cfg {
fn default() -> Self {
Self { kind: Kind::Curated { label: "x".to_string(), ..Default::default() } }
}
}
"#,
"Cfg",
&[("kind", TypeRef::Named("Kind".to_string()))],
);
assert!(
matches!(resolved.as_slice(), [(_, DefaultValue::Unresolved(_))]),
"a `..base` spread can carry fields this pass never saw; folding without it would guess; \
got {resolved:?}"
);
}