use std::io::Cursor;
use wow_cdbc::{DbcHeader, DbcParser, FieldType, Schema, SchemaField, StringRef, Value};
#[test]
fn test_header_parsing() {
let data = create_test_dbc();
let mut cursor = Cursor::new(&data);
let header = DbcHeader::parse(&mut cursor).unwrap();
assert_eq!(header.magic, *b"WDBC");
assert_eq!(header.record_count, 2);
assert_eq!(header.field_count, 3);
assert_eq!(header.record_size, 12);
assert_eq!(header.string_block_size, 19);
}
#[test]
fn test_schema_validation() {
let data = create_test_dbc();
let mut cursor = Cursor::new(&data);
let parser = DbcParser::parse(&mut cursor).unwrap();
let header = parser.header();
let mut schema = Schema::new("Test");
schema.add_field(SchemaField::new("ID", FieldType::UInt32));
schema.add_field(SchemaField::new("Name", FieldType::String));
schema.add_field(SchemaField::new("Value", FieldType::UInt32));
schema.set_key_field("ID");
assert!(
schema
.validate(header.field_count, header.record_size)
.is_ok()
);
let mut invalid_schema = Schema::new("Invalid");
invalid_schema.add_field(SchemaField::new("ID", FieldType::UInt32));
invalid_schema.add_field(SchemaField::new("Name", FieldType::String));
assert!(
invalid_schema
.validate(header.field_count, header.record_size)
.is_err()
);
}
#[test]
fn test_record_parsing() {
let data = create_test_dbc();
let parser = DbcParser::parse_bytes(&data).unwrap();
let mut schema = Schema::new("Test");
schema.add_field(SchemaField::new("ID", FieldType::UInt32));
schema.add_field(SchemaField::new("Name", FieldType::String));
schema.add_field(SchemaField::new("Value", FieldType::UInt32));
schema.set_key_field("ID");
let parser = parser.with_schema(schema).unwrap();
let record_set = parser.parse_records().unwrap();
assert_eq!(record_set.len(), 2);
let record = record_set.get_record(0).unwrap();
if let Value::UInt32(id) = record.get_value_by_name("ID").unwrap() {
assert_eq!(*id, 1);
} else {
panic!("Expected UInt32 for ID");
}
if let Value::StringRef(name_ref) = record.get_value_by_name("Name").unwrap() {
let name = record_set.get_string(*name_ref).unwrap();
assert_eq!(name, "First");
} else {
panic!("Expected StringRef for Name");
}
if let Value::UInt32(value) = record.get_value_by_name("Value").unwrap() {
assert_eq!(*value, 100);
} else {
panic!("Expected UInt32 for Value");
}
let record = record_set.get_record(1).unwrap();
if let Value::UInt32(id) = record.get_value_by_name("ID").unwrap() {
assert_eq!(*id, 2);
} else {
panic!("Expected UInt32 for ID");
}
if let Value::StringRef(name_ref) = record.get_value_by_name("Name").unwrap() {
let name = record_set.get_string(*name_ref).unwrap();
assert_eq!(name, "Second");
} else {
panic!("Expected StringRef for Name");
}
if let Value::UInt32(value) = record.get_value_by_name("Value").unwrap() {
assert_eq!(*value, 200);
} else {
panic!("Expected UInt32 for Value");
}
}
#[test]
fn test_key_lookup() {
let data = create_test_dbc();
let parser = DbcParser::parse_bytes(&data).unwrap();
let mut schema = Schema::new("Test");
schema.add_field(SchemaField::new("ID", FieldType::UInt32));
schema.add_field(SchemaField::new("Name", FieldType::String));
schema.add_field(SchemaField::new("Value", FieldType::UInt32));
schema.set_key_field("ID");
let parser = parser.with_schema(schema).unwrap();
let record_set = parser.parse_records().unwrap();
let record = record_set.get_record_by_key(2).unwrap();
if let Value::StringRef(name_ref) = record.get_value_by_name("Name").unwrap() {
let name = record_set.get_string(*name_ref).unwrap();
assert_eq!(name, "Second");
} else {
panic!("Expected StringRef for Name");
}
let record = record_set.get_record_by_key(999);
assert!(record.is_none());
}
#[test]
fn test_string_block() {
let data = create_test_dbc();
let parser = DbcParser::parse_bytes(&data).unwrap();
let record_set = parser.parse_records().unwrap();
let string = record_set.get_string(StringRef::new(0)).unwrap();
assert_eq!(string, "First");
let string = record_set.get_string(StringRef::new(6)).unwrap();
assert_eq!(string, "Second");
let string = record_set.get_string(StringRef::new(13)).unwrap();
assert_eq!(string, "Extra");
let result = record_set.get_string(StringRef::new(999));
assert!(result.is_err());
}
#[test]
fn test_array_fields() {
let data = create_test_dbc_with_arrays();
let mut cursor = Cursor::new(&data);
let parser = DbcParser::parse(&mut cursor).unwrap();
let mut schema = Schema::new("TestArray");
schema.add_field(SchemaField::new("ID", FieldType::UInt32));
schema.add_field(SchemaField::new_array("Values", FieldType::UInt32, 3));
schema.set_key_field("ID");
let parser = parser.with_schema(schema).unwrap();
let record_set = parser.parse_records().unwrap();
assert_eq!(record_set.len(), 2);
let record = record_set.get_record(0).unwrap();
if let Value::UInt32(id) = record.get_value_by_name("ID").unwrap() {
assert_eq!(*id, 1);
} else {
panic!("Expected UInt32 for ID");
}
if let Value::Array(values) = record.get_value_by_name("Values").unwrap() {
assert_eq!(values.len(), 3);
if let Value::UInt32(v1) = &values[0] {
assert_eq!(*v1, 10);
} else {
panic!("Expected UInt32 for Values[0]");
}
if let Value::UInt32(v2) = &values[1] {
assert_eq!(*v2, 20);
} else {
panic!("Expected UInt32 for Values[1]");
}
if let Value::UInt32(v3) = &values[2] {
assert_eq!(*v3, 30);
} else {
panic!("Expected UInt32 for Values[2]");
}
} else {
panic!("Expected Array for Values");
}
}
fn create_test_dbc() -> Vec<u8> {
let mut data = Vec::new();
data.extend_from_slice(b"WDBC"); data.extend_from_slice(&2u32.to_le_bytes()); data.extend_from_slice(&3u32.to_le_bytes()); data.extend_from_slice(&12u32.to_le_bytes()); data.extend_from_slice(&19u32.to_le_bytes());
data.extend_from_slice(&1u32.to_le_bytes()); data.extend_from_slice(&0u32.to_le_bytes()); data.extend_from_slice(&100u32.to_le_bytes());
data.extend_from_slice(&2u32.to_le_bytes()); data.extend_from_slice(&6u32.to_le_bytes()); data.extend_from_slice(&200u32.to_le_bytes());
data.extend_from_slice(b"First\0Second\0Extra\0");
data
}
fn create_test_dbc_with_arrays() -> Vec<u8> {
let mut data = Vec::new();
data.extend_from_slice(b"WDBC"); data.extend_from_slice(&2u32.to_le_bytes()); data.extend_from_slice(&4u32.to_le_bytes()); data.extend_from_slice(&16u32.to_le_bytes()); data.extend_from_slice(&0u32.to_le_bytes());
data.extend_from_slice(&1u32.to_le_bytes()); data.extend_from_slice(&10u32.to_le_bytes()); data.extend_from_slice(&20u32.to_le_bytes()); data.extend_from_slice(&30u32.to_le_bytes());
data.extend_from_slice(&2u32.to_le_bytes()); data.extend_from_slice(&40u32.to_le_bytes()); data.extend_from_slice(&50u32.to_le_bytes()); data.extend_from_slice(&60u32.to_le_bytes());
data
}