use crate::backends::swift::gen_bindings::dto::compute_first_class_dto_names;
use crate::core::ir::{ApiSurface, FieldDef, TypeDef, TypeRef};
use crate::e2e::config::{CallConfig, E2eConfig};
use std::collections::HashSet;
fn recursive_tree_node() -> TypeDef {
TypeDef {
name: "TreeNode".to_string(),
has_serde: true,
fields: vec![
FieldDef {
name: "label".to_string(),
ty: TypeRef::String,
..FieldDef::default()
},
FieldDef {
name: "children".to_string(),
ty: TypeRef::Vec(Box::new(TypeRef::Named("TreeNode".to_string()))),
..FieldDef::default()
},
],
..TypeDef::default()
}
}
#[test]
fn the_binding_classifier_accepts_a_vec_self_recursive_dto() {
let type_def = recursive_tree_node();
let api = ApiSurface {
types: vec![type_def],
..ApiSurface::default()
};
let known = compute_first_class_dto_names(&api, &HashSet::new());
assert!(
known.contains("TreeNode"),
"binding classifier must accept a Vec<Self>-recursive DTO as first-class, got: {known:?}"
);
}
#[test]
fn the_e2e_classifier_agrees_with_the_binding_classifier_on_a_vec_self_recursive_dto() {
let type_def = recursive_tree_node();
let type_defs = vec![type_def];
let e2e_config = E2eConfig::default();
let call_config = CallConfig::default();
let map = super::values::build_swift_first_class_map(&type_defs, &[], &e2e_config, &call_config);
assert!(
map.is_first_class(Some("TreeNode")),
"e2e classifier disagreed with the binding classifier: TreeNode is first-class on the \
binding side (stored properties) but the e2e generator still classified it opaque \
(method-call syntax), which is exactly the compile-break shape a two-predicate drift \
produces"
);
}