use std::collections::BTreeMap;
use oas3::spec::{ObjectOrReference, ObjectSchema, SchemaType, SchemaTypeSet};
use crate::{
generator::{ast::RustType, converter::SchemaConverter},
tests::common::{create_test_graph, default_config},
};
#[test]
fn test_inline_object_generation() -> anyhow::Result<()> {
let mut parent_schema = ObjectSchema {
schema_type: Some(SchemaTypeSet::Single(SchemaType::Object)),
..Default::default()
};
let mut config_schema = ObjectSchema {
schema_type: Some(SchemaTypeSet::Single(SchemaType::Object)),
..Default::default()
};
config_schema.properties.insert(
"timeout".to_string(),
ObjectOrReference::Object(ObjectSchema {
schema_type: Some(SchemaTypeSet::Single(SchemaType::Integer)),
..Default::default()
}),
);
config_schema.properties.insert(
"enabled".to_string(),
ObjectOrReference::Object(ObjectSchema {
schema_type: Some(SchemaTypeSet::Single(SchemaType::Boolean)),
..Default::default()
}),
);
parent_schema
.properties
.insert("config".to_string(), ObjectOrReference::Object(config_schema));
let graph = create_test_graph(BTreeMap::from([("Parent".to_string(), parent_schema)]));
let converter = SchemaConverter::new(&graph, default_config());
let result = converter.convert_schema("Parent", graph.get_schema("Parent").unwrap(), None)?;
let parent_struct = result
.iter()
.find_map(|ty| match ty {
RustType::Struct(def) if def.name == "Parent" => Some(def),
_ => None,
})
.expect("Parent struct should be present");
let config_field = parent_struct
.fields
.iter()
.find(|f| f.name == "config")
.expect("config field should exist");
assert_eq!(
config_field.rust_type.to_rust_type(),
"Option<ParentConfig>",
"Config field should reference generated inline struct"
);
let config_struct = result
.iter()
.find_map(|ty| match ty {
RustType::Struct(def) if def.name == "ParentConfig" => Some(def),
_ => None,
})
.expect("ParentConfig struct should be present");
assert!(config_struct.fields.iter().any(|f| f.name == "timeout"));
assert!(config_struct.fields.iter().any(|f| f.name == "enabled"));
Ok(())
}
#[test]
fn test_inline_object_without_type_field() -> anyhow::Result<()> {
let mut parent_schema = ObjectSchema {
schema_type: Some(SchemaTypeSet::Single(SchemaType::Object)),
..Default::default()
};
let mut meta_schema = ObjectSchema {
schema_type: None, ..Default::default()
};
meta_schema.properties.insert(
"key".to_string(),
ObjectOrReference::Object(ObjectSchema {
schema_type: Some(SchemaTypeSet::Single(SchemaType::String)),
..Default::default()
}),
);
parent_schema
.properties
.insert("metadata".to_string(), ObjectOrReference::Object(meta_schema));
let graph = create_test_graph(BTreeMap::from([("Resource".to_string(), parent_schema)]));
let converter = SchemaConverter::new(&graph, default_config());
let result = converter.convert_schema("Resource", graph.get_schema("Resource").unwrap(), None)?;
let resource_struct = result
.iter()
.find_map(|ty| match ty {
RustType::Struct(def) if def.name == "Resource" => Some(def),
_ => None,
})
.expect("Resource struct should be present");
let meta_field = resource_struct
.fields
.iter()
.find(|f| f.name == "metadata")
.expect("metadata field should exist");
assert_eq!(
meta_field.rust_type.to_rust_type(),
"Option<ResourceMetadata>",
"Metadata field should reference generated inline struct even if type is missing"
);
let meta_struct = result
.iter()
.find_map(|ty| match ty {
RustType::Struct(def) if def.name == "ResourceMetadata" => Some(def),
_ => None,
})
.expect("ResourceMetadata struct should be present");
assert!(meta_struct.fields.iter().any(|f| f.name == "key"));
Ok(())
}