use std::sync::Arc;
use crate::dynamic::message::DynamicMessage;
use crate::dynamic::schema::{FieldType, MessageSchema};
use crate::dynamic::serdes::DynamicSerdeCdrSerdes;
use crate::msg::{ZDeserializer, ZSerializer};
fn create_test_schema() -> Arc<MessageSchema> {
MessageSchema::builder("std_msgs/msg/String")
.field("data", FieldType::String)
.build()
.unwrap()
}
fn create_point_schema() -> Arc<MessageSchema> {
MessageSchema::builder("geometry_msgs/msg/Point")
.field("x", FieldType::Float64)
.field("y", FieldType::Float64)
.field("z", FieldType::Float64)
.build()
.unwrap()
}
#[test]
fn test_builder_creation() {
let schema = create_test_schema();
assert_eq!(schema.type_name, "std_msgs/msg/String");
assert_eq!(schema.fields.len(), 1);
assert_eq!(schema.fields[0].name, "data");
}
#[test]
fn test_complex_schema_for_pubsub() {
let vector3 = MessageSchema::builder("geometry_msgs/msg/Vector3")
.field("x", FieldType::Float64)
.field("y", FieldType::Float64)
.field("z", FieldType::Float64)
.build()
.unwrap();
let twist = MessageSchema::builder("geometry_msgs/msg/Twist")
.field("linear", FieldType::Message(vector3.clone()))
.field("angular", FieldType::Message(vector3))
.build()
.unwrap();
assert_eq!(twist.type_name, "geometry_msgs/msg/Twist");
assert_eq!(twist.fields.len(), 2);
}
#[test]
fn test_dynamic_cdr_serdes_roundtrip() {
let schema = create_point_schema();
let mut msg = DynamicMessage::new(&schema);
msg.set("x", 1.5f64).unwrap();
msg.set("y", 2.5f64).unwrap();
msg.set("z", 3.5f64).unwrap();
let bytes = DynamicSerdeCdrSerdes::serialize(&msg);
assert!(!bytes.is_empty());
let deserialized = DynamicSerdeCdrSerdes::deserialize((&bytes, &schema)).unwrap();
assert_eq!(deserialized.get::<f64>("x").unwrap(), 1.5);
assert_eq!(deserialized.get::<f64>("y").unwrap(), 2.5);
assert_eq!(deserialized.get::<f64>("z").unwrap(), 3.5);
}
#[test]
fn test_dynamic_cdr_serdes_zbuf() {
use zenoh_buffers::buffer::{Buffer, SplitBuffer};
let schema = create_test_schema();
let mut msg = DynamicMessage::new(&schema);
msg.set("data", "Hello, unified pubsub!").unwrap();
let zbuf = DynamicSerdeCdrSerdes::serialize_to_zbuf(&msg);
assert!(zbuf.len() > 0);
let bytes: Vec<u8> = zbuf.contiguous().to_vec();
let deserialized = DynamicSerdeCdrSerdes::deserialize((&bytes, &schema)).unwrap();
assert_eq!(
deserialized.get::<String>("data").unwrap(),
"Hello, unified pubsub!"
);
}
#[test]
fn test_dynamic_cdr_serdes_to_buf() {
let schema = create_point_schema();
let mut msg = DynamicMessage::new(&schema);
msg.set("x", 10.0f64).unwrap();
msg.set("y", 20.0f64).unwrap();
msg.set("z", 30.0f64).unwrap();
let mut buffer = Vec::new();
DynamicSerdeCdrSerdes::serialize_to_buf(&msg, &mut buffer);
let direct = DynamicSerdeCdrSerdes::serialize(&msg);
assert_eq!(buffer, direct);
let deserialized = DynamicSerdeCdrSerdes::deserialize((&buffer, &schema)).unwrap();
assert_eq!(deserialized.get::<f64>("x").unwrap(), 10.0);
}
#[test]
fn test_zmessage_impl_for_dynamic_message() {
use crate::msg::ZMessage;
let schema = create_point_schema();
let mut msg = DynamicMessage::new(&schema);
msg.set("x", 5.0f64).unwrap();
msg.set("y", 6.0f64).unwrap();
msg.set("z", 7.0f64).unwrap();
let bytes = <DynamicMessage as ZMessage>::serialize(&msg);
assert!(!bytes.is_empty());
assert_eq!(&bytes[0..4], &[0x00, 0x01, 0x00, 0x00]);
}
#[test]
fn test_type_aliases_exist() {
use crate::dynamic::{DynPub, DynPubBuilder, DynSub, DynSubBuilder};
fn _check_types() {
let _: Option<DynPub> = None;
let _: Option<DynSub> = None;
let _: Option<DynPubBuilder> = None;
let _: Option<DynSubBuilder> = None;
}
}
#[test]
fn test_zpub_builder_with_dyn_schema() {
use crate::dynamic::DynamicMessage;
use crate::pubsub::ZPubBuilder;
use std::marker::PhantomData;
let schema = create_point_schema();
let session = zenoh::Wait::wait(zenoh::open(zenoh::Config::default())).unwrap();
let graph = std::sync::Arc::new(
crate::graph::Graph::new(&session, 0, hiroz_protocol::KeyExprFormat::default()).unwrap(),
);
let builder: ZPubBuilder<DynamicMessage> = ZPubBuilder {
entity: crate::entity::EndpointEntity {
id: 0,
node: None,
kind: crate::entity::EndpointKind::Publisher,
topic: String::new(),
type_info: None,
qos: hiroz_protocol::qos::QosProfile::default(),
},
session: std::sync::Arc::new(session),
graph,
clock: crate::time::ZClock::default(),
keyexpr_format: hiroz_protocol::KeyExprFormat::default(),
with_attachment: true,
shm_config: None,
dyn_schema: None,
encoding: None,
_phantom_data: PhantomData,
};
let builder = builder.with_dyn_schema(schema.clone());
assert!(builder.dyn_schema.is_some());
assert_eq!(
builder.dyn_schema.as_ref().unwrap().type_name,
"geometry_msgs/msg/Point"
);
}
#[test]
fn test_zpub_builder_with_serdes_preserves_schema() {
use crate::dynamic::{DynamicMessage, DynamicSerdeCdrSerdes};
use crate::pubsub::ZPubBuilder;
use std::marker::PhantomData;
let schema = create_test_schema();
let session = zenoh::Wait::wait(zenoh::open(zenoh::Config::default())).unwrap();
let graph = std::sync::Arc::new(
crate::graph::Graph::new(&session, 0, hiroz_protocol::KeyExprFormat::default()).unwrap(),
);
let builder: ZPubBuilder<DynamicMessage> = ZPubBuilder {
entity: crate::entity::EndpointEntity {
id: 0,
node: None,
kind: crate::entity::EndpointKind::Publisher,
topic: String::new(),
type_info: None,
qos: hiroz_protocol::qos::QosProfile::default(),
},
session: std::sync::Arc::new(session),
graph,
clock: crate::time::ZClock::default(),
keyexpr_format: hiroz_protocol::KeyExprFormat::default(),
with_attachment: true,
shm_config: None,
dyn_schema: Some(schema.clone()),
encoding: None,
_phantom_data: PhantomData,
};
let builder: ZPubBuilder<DynamicMessage, DynamicSerdeCdrSerdes> = builder.with_serdes();
assert!(builder.dyn_schema.is_some());
assert_eq!(
builder.dyn_schema.as_ref().unwrap().type_name,
"std_msgs/msg/String"
);
}