use crate::core::ir::{EnumDef, EnumVariant, FieldDef, TypeDef, TypeRef};
use crate::e2e::field_access::FieldResolver;
use super::values::java_builder_expression;
fn data_node_kind_enum() -> EnumDef {
EnumDef {
name: "DataNodeKind".to_string(),
variants: vec![
EnumVariant {
name: "Fenced".to_string(),
..EnumVariant::default()
},
EnumVariant {
name: "Indented".to_string(),
..EnumVariant::default()
},
],
..EnumDef::default()
}
}
fn style_field(ty: TypeRef) -> FieldDef {
FieldDef {
name: "style".to_string(),
ty,
..FieldDef::default()
}
}
fn table_ir() -> (Vec<TypeDef>, Vec<EnumDef>) {
let type_defs = vec![
TypeDef {
name: "ChunkOptions".to_string(),
fields: vec![style_field(TypeRef::Named("DataNodeKind".to_string()))],
..TypeDef::default()
},
TypeDef {
name: "OtherOptions".to_string(),
fields: vec![style_field(TypeRef::String)],
..TypeDef::default()
},
];
(type_defs, vec![data_node_kind_enum()])
}
fn style_obj() -> serde_json::Map<String, serde_json::Value> {
let mut obj = serde_json::Map::new();
obj.insert("style".to_string(), serde_json::Value::String("fenced".to_string()));
obj
}
const ENUM_MARKER: &str = ".withStyle(Style.Fenced)";
const RAW_MARKER: &str = ".withStyle(\"fenced\")";
struct Case {
name: &'static str,
type_name: &'static str,
expect_enum_branch: bool,
}
const CASES: &[Case] = &[
Case {
name: "an enum-typed field with no enum_fields config is classified as enum via the IR",
type_name: "ChunkOptions",
expect_enum_branch: true,
},
Case {
name: "a same-named non-enum field on an unrelated type is not misclassified as enum",
type_name: "OtherOptions",
expect_enum_branch: false,
},
];
#[test]
fn enum_field_classification_table() {
let (type_defs, enums) = table_ir();
let ir_enum_map = FieldResolver::ir_enum_fields(&type_defs, &enums);
for case in CASES {
let out = java_builder_expression(
&style_obj(),
case.type_name,
&std::collections::HashSet::new(),
&std::collections::HashMap::new(),
true,
&[],
&ir_enum_map,
);
assert_eq!(
out.contains(ENUM_MARKER),
case.expect_enum_branch,
"{}: expected enum branch = {}, got:\n{out}",
case.name,
case.expect_enum_branch
);
assert_eq!(
out.contains(RAW_MARKER),
!case.expect_enum_branch,
"{}: a raw String literal must be emitted only for the non-enum field, got:\n{out}",
case.name
);
}
}
#[test]
fn an_explicit_enum_fields_config_entry_still_classifies_as_enum() {
let (type_defs, enums) = table_ir();
let ir_enum_map = FieldResolver::ir_enum_fields(&type_defs, &enums);
let enum_fields: std::collections::HashSet<String> = ["style".to_string()].into_iter().collect();
let out = java_builder_expression(
&style_obj(),
"OtherOptions",
&enum_fields,
&std::collections::HashMap::new(),
true,
&[],
&ir_enum_map,
);
assert!(
out.contains(ENUM_MARKER),
"explicit enum_fields config must still classify the field as enum, got:\n{out}"
);
}