use super::*;
use crate::core::ir::DefaultValue;
#[test]
fn enum_field_default_resolves_to_the_marked_default_variant() {
let source = r#"
#[derive(Default, Clone, Copy)]
pub enum Mode {
Fast,
#[default]
Balanced,
Slow,
}
pub struct Config {
pub mode: Mode,
}
impl Default for Config {
fn default() -> Self {
Self { mode: Mode::default() }
}
}
"#;
let surface = extract_from_source(source);
let config = surface.types.iter().find(|typ| typ.name == "Config").unwrap();
let mode_field = config.fields.iter().find(|field| field.name == "mode").unwrap();
assert_eq!(
mode_field.typed_default,
Some(DefaultValue::EnumVariant("Balanced".to_string())),
"a field defaulting to an enum's own `default()` must resolve to the `#[default]`-marked variant"
);
}
#[test]
fn enum_field_default_reads_the_variant_a_manual_default_impl_returns() {
let source = r#"
#[derive(Clone, Copy)]
pub enum Priority {
Low,
Medium,
High,
}
impl Default for Priority {
fn default() -> Self {
Priority::Medium
}
}
pub struct Task {
pub priority: Priority,
}
impl Default for Task {
fn default() -> Self {
Self { priority: Priority::default() }
}
}
"#;
let surface = extract_from_source(source);
let priority_enum = surface.enums.iter().find(|e| e.name == "Priority").unwrap();
assert!(
priority_enum.has_default,
"a manual `impl Default for Priority` must still set `has_default=true`"
);
assert_eq!(
priority_enum
.variants
.iter()
.filter(|v| v.is_default)
.map(|v| v.name.as_str())
.collect::<Vec<_>>(),
vec!["Medium"],
"the manual impl's returned variant must be marked `is_default`, and only that variant"
);
let task = surface.types.iter().find(|typ| typ.name == "Task").unwrap();
let priority_field = task.fields.iter().find(|field| field.name == "priority").unwrap();
assert_eq!(
priority_field.typed_default,
Some(DefaultValue::EnumVariant("Medium".to_string())),
"the field must resolve to the variant the manual impl returns, not the first declared one"
);
}
#[test]
fn enum_field_default_stays_empty_when_the_default_variant_carries_data() {
let source = r#"
pub enum NodeContent {
Heading { level: u8, text: String },
Paragraph { text: String },
}
impl Default for NodeContent {
fn default() -> Self {
Self::Heading { level: 1, text: String::new() }
}
}
pub struct Node {
pub content: NodeContent,
}
impl Default for Node {
fn default() -> Self {
Self { content: NodeContent::default() }
}
}
"#;
let surface = extract_from_source(source);
let node_content = surface.enums.iter().find(|e| e.name == "NodeContent").unwrap();
assert!(
node_content.variants.iter().all(|v| !v.is_default),
"a struct-variant default body must not mark any variant `is_default`"
);
let node = surface.types.iter().find(|typ| typ.name == "Node").unwrap();
let content_field = node.fields.iter().find(|field| field.name == "content").unwrap();
assert_eq!(
content_field.typed_default,
Some(DefaultValue::Empty),
"a data-carrying default variant must stay `Empty` rather than become a bare variant name"
);
}
#[test]
fn enum_field_default_stays_empty_when_the_enum_has_no_default_impl() {
let source = r#"
pub enum Format {
Plain,
Rich,
}
pub struct Document {
pub format: Format,
}
impl Default for Document {
fn default() -> Self {
Self { format: Format::default() }
}
}
"#;
let surface = extract_from_source(source);
let format_enum = surface.enums.iter().find(|e| e.name == "Format").unwrap();
assert!(
!format_enum.has_default,
"`Format` derives no `Default` and has no manual impl in this fixture"
);
let document = surface.types.iter().find(|typ| typ.name == "Document").unwrap();
let format_field = document.fields.iter().find(|field| field.name == "format").unwrap();
assert_eq!(
format_field.typed_default,
Some(DefaultValue::Empty),
"a field whose enum type has no knowable default must stay `Empty`, not a guessed variant"
);
}