use super::complex_types::ComplexTypeParser;
use super::types::CqlTypeId;
use super::vint::encode_vint;
use crate::schema::CqlType;
use crate::types::Value;
#[test]
fn test_list_text_parsing() {
let _parser = ComplexTypeParser::new();
let mut data = Vec::new();
data.extend_from_slice(&encode_vint(3)); data.push(CqlTypeId::Varchar as u8);
data.extend_from_slice(&encode_vint(5));
data.extend_from_slice(b"hello");
data.extend_from_slice(&encode_vint(5));
data.extend_from_slice(b"world");
data.extend_from_slice(&encode_vint(4));
data.extend_from_slice(b"test");
let (remaining, parsed_value) = crate::parser::types::parse_list_v5_format(&data).unwrap();
assert!(remaining.is_empty());
match parsed_value {
Value::List(elements) => {
assert_eq!(elements.len(), 3);
assert_eq!(elements[0], Value::Text("hello".to_string()));
assert_eq!(elements[1], Value::Text("world".to_string()));
assert_eq!(elements[2], Value::Text("test".to_string()));
}
_ => panic!("Expected List value, got {:?}", parsed_value),
}
}
#[test]
fn test_set_int_parsing() {
let _parser = ComplexTypeParser::new();
let mut data = Vec::new();
data.extend_from_slice(&encode_vint(5)); data.push(CqlTypeId::Int as u8);
for i in 1..=5 {
data.extend_from_slice(&(i as i32).to_be_bytes());
}
let (remaining, parsed_value) = crate::parser::types::parse_set_v5_format(&data).unwrap();
assert!(remaining.is_empty());
match parsed_value {
Value::Set(elements) => {
assert_eq!(elements.len(), 5);
for (i, element) in elements.iter().enumerate() {
assert_eq!(*element, Value::Integer((i + 1) as i32));
}
}
_ => panic!("Expected Set value, got {:?}", parsed_value),
}
}
#[test]
fn test_map_text_int_parsing() {
let _parser = ComplexTypeParser::new();
let mut data = Vec::new();
data.extend_from_slice(&encode_vint(2)); data.push(CqlTypeId::Varchar as u8); data.push(CqlTypeId::Int as u8);
data.extend_from_slice(&encode_vint(4));
data.extend_from_slice(b"key1");
data.extend_from_slice(&10i32.to_be_bytes());
data.extend_from_slice(&encode_vint(4));
data.extend_from_slice(b"key2");
data.extend_from_slice(&20i32.to_be_bytes());
let (remaining, parsed_value) = crate::parser::types::parse_map_v5_format(&data).unwrap();
assert!(remaining.is_empty());
match parsed_value {
Value::Map(pairs) => {
assert_eq!(pairs.len(), 2);
assert_eq!(
pairs[0],
(Value::Text("key1".to_string()), Value::Integer(10))
);
assert_eq!(
pairs[1],
(Value::Text("key2".to_string()), Value::Integer(20))
);
}
_ => panic!("Expected Map value, got {:?}", parsed_value),
}
}
#[test]
#[ignore = "parse_frozen_list method not implemented"]
fn test_frozen_list_parsing() {
}
#[test]
#[ignore = "with_test_udts method not implemented"]
fn test_address_udt_parsing() {
let mut data = Vec::new();
data.extend_from_slice(&encode_vint(4));
data.extend_from_slice(&encode_vint(11)); data.extend_from_slice(&encode_vint(11));
data.extend_from_slice(b"123 Main St");
data.extend_from_slice(&encode_vint(9)); data.extend_from_slice(&encode_vint(9));
data.extend_from_slice(b"Test City");
data.extend_from_slice(&encode_vint(2)); data.extend_from_slice(&encode_vint(2));
data.extend_from_slice(b"TC");
data.extend_from_slice(&encode_vint(5)); data.extend_from_slice(&encode_vint(5));
data.extend_from_slice(b"12345");
let (remaining, parsed_value) = parser.parse_udt(&data, "address", "test_keyspace").unwrap();
assert!(remaining.is_empty());
match parsed_value {
Value::Udt(udt_value) => {
assert_eq!(udt_value.type_name, "address");
assert_eq!(udt_value.keyspace, "test_keyspace");
assert_eq!(udt_value.fields.len(), 4);
assert_eq!(udt_value.fields[0].name, "street");
assert_eq!(
udt_value.fields[0].value,
Some(Value::Text("123 Main St".to_string()))
);
assert_eq!(udt_value.fields[1].name, "city");
assert_eq!(
udt_value.fields[1].value,
Some(Value::Text("Test City".to_string()))
);
assert_eq!(udt_value.fields[2].name, "state");
assert_eq!(
udt_value.fields[2].value,
Some(Value::Text("TC".to_string()))
);
assert_eq!(udt_value.fields[3].name, "zip_code");
assert_eq!(
udt_value.fields[3].value,
Some(Value::Text("12345".to_string()))
);
}
_ => panic!("Expected UDT value, got {:?}", parsed_value),
}
}
#[test]
#[ignore = "with_test_udts method not implemented"]
fn test_person_udt_with_nested_address() {
let parser = ComplexTypeParser::with_test_udts();
let person_udt = parser
.udt_registry
.get_udt("test_keyspace", "person")
.unwrap();
assert_eq!(person_udt.fields.len(), 3);
assert_eq!(person_udt.fields[0].name, "name");
assert_eq!(person_udt.fields[1].name, "age");
assert_eq!(person_udt.fields[2].name, "address");
match &person_udt.fields[2].field_type {
CqlType::Frozen(inner) => match inner.as_ref() {
CqlType::Udt(type_name, _) => {
assert_eq!(type_name, "address");
}
_ => panic!("Expected nested UDT type, got {:?}", inner),
},
_ => panic!(
"Expected Frozen type, got {:?}",
person_udt.fields[2].field_type
),
}
}
#[test]
fn test_empty_collections() {
let _parser = ComplexTypeParser::new();
let data = encode_vint(0);
let (_, value) = parser.parse_list_v5(&data).unwrap();
assert_eq!(value, Value::List(Vec::new()));
let (_, value) = parser.parse_set_v5(&data).unwrap();
assert_eq!(value, Value::Set(Vec::new()));
let (_, value) = parser.parse_map_v5(&data).unwrap();
assert_eq!(value, Value::Map(Vec::new()));
}
#[test]
fn test_collection_serialization_roundtrip() {
let _parser = ComplexTypeParser::new();
let original_list = vec![
Value::Text("item1".to_string()),
Value::Text("item2".to_string()),
Value::Text("item3".to_string()),
];
let serialized = serialize_list_v5(&original_list).unwrap();
let (_, parsed) = parser.parse_list_v5(&serialized).unwrap();
assert_eq!(Value::List(original_list), parsed);
let original_set = vec![Value::Integer(10), Value::Integer(20), Value::Integer(30)];
let serialized = serialize_set_v5(&original_set).unwrap();
let (_, parsed) = parser.parse_set_v5(&serialized).unwrap();
assert_eq!(Value::Set(original_set), parsed);
let original_map = vec![
(Value::Text("key1".to_string()), Value::Integer(100)),
(Value::Text("key2".to_string()), Value::Integer(200)),
];
let serialized = serialize_map_v5(&original_map).unwrap();
let (_, parsed) = parser.parse_map_v5(&serialized).unwrap();
assert_eq!(Value::Map(original_map), parsed);
}
#[test]
fn test_large_collection_limits() {
let _parser = ComplexTypeParser::new();
let mut data = Vec::new();
data.extend_from_slice(&encode_vint(1000)); data.push(CqlTypeId::Int as u8);
for i in 0..1000 {
data.extend_from_slice(&(i as i32).to_be_bytes());
}
let (remaining, parsed_value) = crate::parser::types::parse_list_v5_format(&data).unwrap();
assert!(remaining.is_empty());
match parsed_value {
Value::List(elements) => {
assert_eq!(elements.len(), 1000);
assert_eq!(elements[0], Value::Integer(0));
assert_eq!(elements[999], Value::Integer(999));
}
_ => panic!("Expected List value"),
}
}
#[test]
fn test_nested_collections() {
let _parser = ComplexTypeParser::new();
let nested_list_type = CqlType::List(Box::new(CqlType::List(Box::new(CqlType::Int))));
assert!(nested_list_type.is_collection());
let nested_map_type = CqlType::Map(
Box::new(CqlType::Text),
Box::new(CqlType::List(Box::new(CqlType::Int))),
);
assert!(nested_map_type.is_collection());
}
#[test]
#[ignore = "with_test_udts method not implemented"]
fn test_udt_null_fields() {
let parser = ComplexTypeParser::with_test_udts();
let mut data = Vec::new();
data.extend_from_slice(&encode_vint(4));
data.extend_from_slice(&encode_vint(11));
data.extend_from_slice(&encode_vint(11));
data.extend_from_slice(b"123 Main St");
data.extend_from_slice(&encode_vint(-1));
data.extend_from_slice(&encode_vint(2));
data.extend_from_slice(&encode_vint(2));
data.extend_from_slice(b"TC");
data.extend_from_slice(&encode_vint(-1));
let (remaining, parsed_value) = parser.parse_udt(&data, "address", "test_keyspace").unwrap();
assert!(remaining.is_empty());
match parsed_value {
Value::Udt(udt_value) => {
assert_eq!(udt_value.fields.len(), 4);
assert_eq!(
udt_value.fields[0].value,
Some(Value::Text("123 Main St".to_string()))
);
assert_eq!(udt_value.fields[1].value, None); assert_eq!(
udt_value.fields[2].value,
Some(Value::Text("TC".to_string()))
);
assert_eq!(udt_value.fields[3].value, None); }
_ => panic!("Expected UDT value, got {:?}", parsed_value),
}
}