use std::collections::HashMap;
use unity_asset_core::{UnityClass, UnityDocument, UnityValue};
use unity_asset_yaml::{SerdeUnityLoader, UnityYamlSerializer, YamlDocument};
#[test]
fn test_serialize_simple_gameobject() {
let mut gameobject = UnityClass::new(1, "GameObject".to_string(), "123456789".to_string());
gameobject.set("m_ObjectHideFlags".to_string(), UnityValue::Integer(0));
gameobject.set(
"m_Name".to_string(),
UnityValue::String("TestObject".to_string()),
);
gameobject.set(
"m_TagString".to_string(),
UnityValue::String("Untagged".to_string()),
);
gameobject.set("m_Layer".to_string(), UnityValue::Integer(0));
gameobject.set("m_IsActive".to_string(), UnityValue::Bool(true));
let mut serializer = UnityYamlSerializer::new();
let yaml_output = serializer.serialize_to_string(&[gameobject]).unwrap();
assert!(yaml_output.contains("%YAML 1.1"));
assert!(yaml_output.contains("%TAG !u! tag:unity3d.com,2011:"));
assert!(yaml_output.contains("--- !u!1 &123456789"));
assert!(yaml_output.contains("GameObject:"));
assert!(yaml_output.contains("m_Name: TestObject"));
assert!(yaml_output.contains("m_IsActive: 1"));
println!("Generated YAML:\n{}", yaml_output);
}
#[test]
fn test_serialize_complex_transform() {
let mut transform = UnityClass::new(4, "Transform".to_string(), "987654321".to_string());
let mut position = HashMap::new();
position.insert("x".to_string(), UnityValue::Float(1.5));
position.insert("y".to_string(), UnityValue::Float(2.0));
position.insert("z".to_string(), UnityValue::Float(-0.5));
transform.set(
"m_LocalPosition".to_string(),
UnityValue::Object(position.into_iter().collect()),
);
let mut rotation = HashMap::new();
rotation.insert("x".to_string(), UnityValue::Float(0.0));
rotation.insert("y".to_string(), UnityValue::Float(0.0));
rotation.insert("z".to_string(), UnityValue::Float(0.0));
rotation.insert("w".to_string(), UnityValue::Float(1.0));
transform.set(
"m_LocalRotation".to_string(),
UnityValue::Object(rotation.into_iter().collect()),
);
let children = vec![
UnityValue::Integer(111111),
UnityValue::Integer(222222),
UnityValue::Integer(333333),
];
transform.set("m_Children".to_string(), UnityValue::Array(children));
let mut serializer = UnityYamlSerializer::new();
let yaml_output = serializer.serialize_to_string(&[transform]).unwrap();
assert!(yaml_output.contains("--- !u!4 &987654321"));
assert!(yaml_output.contains("Transform:"));
assert!(yaml_output.contains("m_LocalPosition:"));
assert!(yaml_output.contains("m_LocalRotation:"));
assert!(yaml_output.contains("m_Children:"));
println!("Generated complex YAML:\n{}", yaml_output);
}
#[test]
fn test_round_trip_serialization() {
let mut gameobject = UnityClass::new(1, "GameObject".to_string(), "123456789".to_string());
gameobject.set(
"m_Name".to_string(),
UnityValue::String("RoundTripTest".to_string()),
);
gameobject.set("m_IsActive".to_string(), UnityValue::Bool(true));
let mut position = HashMap::new();
position.insert("x".to_string(), UnityValue::Float(1.0));
position.insert("y".to_string(), UnityValue::Float(2.0));
position.insert("z".to_string(), UnityValue::Float(3.0));
gameobject.set(
"m_Position".to_string(),
UnityValue::Object(position.into_iter().collect()),
);
let original_classes = vec![gameobject];
let mut serializer = UnityYamlSerializer::new();
let yaml1 = serializer.serialize_to_string(&original_classes).unwrap();
let loader = SerdeUnityLoader::new();
let parsed_classes = loader.load_from_str(&yaml1).unwrap();
let yaml2 = serializer.serialize_to_string(&parsed_classes).unwrap();
assert_eq!(original_classes.len(), parsed_classes.len());
let original = &original_classes[0];
let parsed = &parsed_classes[0];
assert_eq!(original.class_name, parsed.class_name);
assert_eq!(original.class_id, parsed.class_id);
assert_eq!(original.anchor, parsed.anchor);
assert_eq!(original.get("m_Name"), parsed.get("m_Name"));
match (original.get("m_IsActive"), parsed.get("m_IsActive")) {
(Some(UnityValue::Bool(true)), Some(UnityValue::Integer(1))) => {
}
(Some(UnityValue::Bool(false)), Some(UnityValue::Integer(0))) => {
}
(orig, parsed) => {
panic!("Unexpected boolean conversion: {:?} -> {:?}", orig, parsed);
}
}
println!("First YAML:\n{}", yaml1);
println!("Second YAML:\n{}", yaml2);
}
#[test]
fn test_serialize_multiple_documents() {
let mut gameobject = UnityClass::new(1, "GameObject".to_string(), "123".to_string());
gameobject.set(
"m_Name".to_string(),
UnityValue::String("Object1".to_string()),
);
let mut transform = UnityClass::new(4, "Transform".to_string(), "456".to_string());
let mut pos = HashMap::new();
pos.insert("x".to_string(), UnityValue::Float(0.0));
pos.insert("y".to_string(), UnityValue::Float(0.0));
pos.insert("z".to_string(), UnityValue::Float(0.0));
transform.set(
"m_LocalPosition".to_string(),
UnityValue::Object(pos.into_iter().collect()),
);
let mut monobehaviour = UnityClass::new(114, "MonoBehaviour".to_string(), "789".to_string());
monobehaviour.set("m_Enabled".to_string(), UnityValue::Bool(true));
let classes = vec![gameobject, transform, monobehaviour];
let mut serializer = UnityYamlSerializer::new();
let yaml_output = serializer.serialize_to_string(&classes).unwrap();
let yaml_header_count = yaml_output.matches("%YAML 1.1").count();
assert_eq!(yaml_header_count, 1);
let doc_separator_count = yaml_output.matches("--- !u!").count();
assert_eq!(doc_separator_count, 3);
assert!(yaml_output.contains("GameObject:"));
assert!(yaml_output.contains("Transform:"));
assert!(yaml_output.contains("MonoBehaviour:"));
println!("Multi-document YAML:\n{}", yaml_output);
}
#[test]
fn test_yaml_document_serialization() {
let mut doc = YamlDocument::new();
let mut gameobject = UnityClass::new(1, "GameObject".to_string(), "123".to_string());
gameobject.set(
"m_Name".to_string(),
UnityValue::String("DocumentTest".to_string()),
);
gameobject.set("m_IsActive".to_string(), UnityValue::Bool(true));
doc.add_entry(gameobject);
let mut transform = UnityClass::new(4, "Transform".to_string(), "456".to_string());
let mut pos = HashMap::new();
pos.insert("x".to_string(), UnityValue::Float(1.0));
pos.insert("y".to_string(), UnityValue::Float(2.0));
pos.insert("z".to_string(), UnityValue::Float(3.0));
transform.set(
"m_LocalPosition".to_string(),
UnityValue::Object(pos.into_iter().collect()),
);
doc.add_entry(transform);
let yaml_content = doc.dump_yaml().unwrap();
assert!(yaml_content.contains("%YAML 1.1"));
assert!(yaml_content.contains("GameObject:"));
assert!(yaml_content.contains("Transform:"));
assert!(yaml_content.contains("m_Name: DocumentTest"));
assert!(yaml_content.contains("m_LocalPosition:"));
let loader = SerdeUnityLoader::new();
let parsed_classes = loader.load_from_str(&yaml_content).unwrap();
assert_eq!(parsed_classes.len(), 2);
assert_eq!(parsed_classes[0].class_name, "GameObject");
assert_eq!(parsed_classes[1].class_name, "Transform");
println!("YamlDocument YAML:\n{}", yaml_content);
}
#[test]
fn test_serialize_special_cases() {
let mut test_class = UnityClass::new(114, "MonoBehaviour".to_string(), "special".to_string());
test_class.set(
"empty_string".to_string(),
UnityValue::String("".to_string()),
);
test_class.set(
"quoted_string".to_string(),
UnityValue::String("Hello \"World\"".to_string()),
);
test_class.set(
"multiline_string".to_string(),
UnityValue::String("Line 1\nLine 2".to_string()),
);
test_class.set(
"special_chars".to_string(),
UnityValue::String("Special: []{},".to_string()),
);
test_class.set("zero_int".to_string(), UnityValue::Integer(0));
test_class.set("negative_int".to_string(), UnityValue::Integer(-42));
test_class.set("zero_float".to_string(), UnityValue::Float(0.0));
test_class.set(
"negative_float".to_string(),
UnityValue::Float(-std::f64::consts::PI),
);
test_class.set("empty_array".to_string(), UnityValue::Array(vec![]));
test_class.set(
"empty_object".to_string(),
UnityValue::Object(indexmap::IndexMap::new()),
);
test_class.set("null_value".to_string(), UnityValue::Null);
let mut serializer = UnityYamlSerializer::new();
let yaml_output = serializer.serialize_to_string(&[test_class]).unwrap();
assert!(yaml_output.contains("empty_string:"));
assert!(yaml_output.contains("quoted_string:"));
assert!(yaml_output.contains("empty_array: []"));
assert!(yaml_output.contains("empty_object: {}"));
assert!(yaml_output.contains("null_value: {fileID: 0}"));
let loader = SerdeUnityLoader::new();
let parsed_classes = loader.load_from_str(&yaml_output).unwrap();
assert_eq!(parsed_classes.len(), 1);
println!("Special cases YAML:\n{}", yaml_output);
}