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 data_node_and_process_result() -> Vec<TypeDef> {
vec![
TypeDef {
name: "DataNode".to_string(),
has_serde: true,
fields: vec![
FieldDef {
name: "kind".to_string(),
ty: TypeRef::String,
..FieldDef::default()
},
FieldDef {
name: "children".to_string(),
ty: TypeRef::Vec(Box::new(TypeRef::Named("DataNode".to_string()))),
..FieldDef::default()
},
],
..TypeDef::default()
},
TypeDef {
name: "ProcessResult".to_string(),
has_serde: true,
fields: vec![FieldDef {
name: "data".to_string(),
ty: TypeRef::Optional(Box::new(TypeRef::Named("DataNode".to_string()))),
..FieldDef::default()
}],
..TypeDef::default()
},
]
}
#[test]
fn the_binding_classifier_cascades_the_bootstrap_through_an_optional_named_field() {
let api = ApiSurface {
types: data_node_and_process_result(),
..ApiSurface::default()
};
let known = compute_first_class_dto_names(&api, &HashSet::new());
assert!(
known.contains("DataNode"),
"control: DataNode must bootstrap first, got: {known:?}"
);
assert!(
known.contains("ProcessResult"),
"control: the promotion must cascade to ProcessResult through Option<DataNode>, got: {known:?}"
);
}
#[test]
fn the_e2e_classifier_agrees_on_both_the_bootstrapped_type_and_its_cascaded_parent() {
let type_defs = data_node_and_process_result();
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("DataNode")),
"e2e classifier must promote DataNode via the self-reference bootstrap"
);
assert!(
map.is_first_class(Some("ProcessResult")),
"e2e classifier must cascade the promotion to ProcessResult through Option<DataNode> -- \
a miss here reproduces the reported whole-result-flips-to-opaque symptom, since \
`SwiftFirstClassMap::is_first_class(None)` and `is_first_class(Some(\"ProcessResult\"))` \
degrade identically to method-call syntax when ProcessResult is absent from the map"
);
}