use super::*;
use bacnet_types::enums::ObjectType;
use bacnet_types::primitives::ObjectIdentifier;
fn ai_ref(instance: u32, property: u32) -> BACnetObjectPropertyReference {
BACnetObjectPropertyReference::new(
ObjectIdentifier::new(ObjectType::ANALOG_INPUT, instance).unwrap(),
property,
)
}
#[test]
fn golden_vector_unindexed() {
let mut buf = BytesMut::new();
encode_object_property_reference(&mut buf, &ai_ref(5, 85));
assert_eq!(buf.as_ref(), &[0x0C, 0x00, 0x00, 0x00, 0x05, 0x19, 0x55]);
let decoded = decode_object_property_reference(&buf).unwrap();
assert_eq!(decoded, ai_ref(5, 85));
}
#[test]
fn golden_vector_indexed() {
let mut buf = BytesMut::new();
encode_object_property_reference(
&mut buf,
&BACnetObjectPropertyReference::new_indexed(
ObjectIdentifier::new(ObjectType::ANALOG_OUTPUT, 3).unwrap(),
87,
2,
),
);
assert_eq!(
buf.as_ref(),
&[0x0C, 0x00, 0x40, 0x00, 0x03, 0x19, 0x57, 0x29, 0x02]
);
let decoded = decode_object_property_reference(&buf).unwrap();
assert_eq!(decoded.property_array_index, Some(2));
}
#[test]
fn setpoint_reference_golden_vector() {
let mut buf = BytesMut::new();
encode_setpoint_reference(&mut buf, &ai_ref(10, 85));
assert_eq!(
buf.as_ref(),
&[0x0E, 0x0C, 0x00, 0x00, 0x00, 0x0A, 0x19, 0x55, 0x0F]
);
assert_eq!(
decode_setpoint_reference(&buf).unwrap(),
Some(ai_ref(10, 85))
);
}
#[test]
fn setpoint_reference_golden_vector_indexed() {
let indexed = BACnetObjectPropertyReference::new_indexed(
ObjectIdentifier::new(ObjectType::ANALOG_VALUE, 10).unwrap(),
85,
7,
);
let mut buf = BytesMut::new();
encode_setpoint_reference(&mut buf, &indexed);
assert_eq!(
buf.as_ref(),
&[0x0E, 0x0C, 0x00, 0x80, 0x00, 0x0A, 0x19, 0x55, 0x29, 0x07, 0x0F]
);
assert_eq!(decode_setpoint_reference(&buf).unwrap(), Some(indexed));
}
#[test]
fn setpoint_reference_empty_frame_is_the_absent_alternative() {
assert_eq!(decode_setpoint_reference(&[0x0E, 0x0F]).unwrap(), None);
}
#[test]
fn bare_decode_rejects_device_qualified_reference() {
let mut buf = BytesMut::new();
encode_object_property_reference(&mut buf, &ai_ref(5, 85));
crate::primitives::encode_ctx_object_id(
&mut buf,
3,
&ObjectIdentifier::new(ObjectType::DEVICE, 77).unwrap(),
);
assert!(decode_object_property_reference(&buf).is_err());
}
#[test]
fn bare_decode_rejects_unknown_trailing_context_tag() {
let mut buf = BytesMut::new();
encode_object_property_reference(&mut buf, &ai_ref(5, 85));
crate::primitives::encode_ctx_unsigned(&mut buf, 4, 1);
assert!(decode_object_property_reference(&buf).is_err());
}
#[test]
fn bare_decode_rejects_partial_and_empty() {
let mut buf = BytesMut::new();
crate::primitives::encode_ctx_object_id(
&mut buf,
0,
&ObjectIdentifier::new(ObjectType::ANALOG_INPUT, 5).unwrap(),
);
assert!(decode_object_property_reference(&buf).is_err());
assert!(decode_object_property_reference(&[]).is_err());
}
#[test]
fn setpoint_decode_requires_the_frame_and_full_consumption() {
let mut buf = BytesMut::new();
encode_object_property_reference(&mut buf, &ai_ref(5, 85));
assert!(decode_setpoint_reference(&buf).is_err());
let mut wrapped = BytesMut::new();
encode_setpoint_reference(&mut wrapped, &ai_ref(5, 85));
assert!(decode_object_property_reference(&wrapped).is_err());
let truncated = &wrapped[..wrapped.len() - 1];
assert!(decode_setpoint_reference(truncated).is_err());
let mut extra = wrapped.to_vec();
extra.push(0x21);
extra.push(0x01);
assert!(decode_setpoint_reference(&extra).is_err());
}