use super::super::*;
#[test]
fn msi_read_present_value_default() {
let msi = MultiStateInputObject::new(1, "MSI-1", 4).unwrap();
let val = msi
.read_property(PropertyIdentifier::PRESENT_VALUE, None)
.unwrap();
assert_eq!(val, PropertyValue::Unsigned(1));
}
#[test]
fn msi_read_number_of_states() {
let msi = MultiStateInputObject::new(1, "MSI-1", 4).unwrap();
let val = msi
.read_property(PropertyIdentifier::NUMBER_OF_STATES, None)
.unwrap();
assert_eq!(val, PropertyValue::Unsigned(4));
}
#[test]
fn msi_write_denied_when_in_service() {
let mut msi = MultiStateInputObject::new(1, "MSI-1", 4).unwrap();
let result = msi.write_property_from(
PropertyIdentifier::PRESENT_VALUE,
None,
PropertyValue::Unsigned(2),
None,
&crate::command_source::test_origin(),
);
assert!(result.is_err());
}
#[test]
fn msi_write_allowed_when_out_of_service() {
let mut msi = MultiStateInputObject::new(1, "MSI-1", 4).unwrap();
msi.write_property(
PropertyIdentifier::OUT_OF_SERVICE,
None,
PropertyValue::Boolean(true),
None,
)
.unwrap();
msi.write_property_from(
PropertyIdentifier::PRESENT_VALUE,
None,
PropertyValue::Unsigned(3),
None,
&crate::command_source::test_origin(),
)
.unwrap();
let val = msi
.read_property(PropertyIdentifier::PRESENT_VALUE, None)
.unwrap();
assert_eq!(val, PropertyValue::Unsigned(3));
}
#[test]
fn msi_write_out_of_range_rejected() {
let mut msi = MultiStateInputObject::new(1, "MSI-1", 4).unwrap();
msi.write_property(
PropertyIdentifier::OUT_OF_SERVICE,
None,
PropertyValue::Boolean(true),
None,
)
.unwrap();
assert!(msi
.write_property_from(
PropertyIdentifier::PRESENT_VALUE,
None,
PropertyValue::Unsigned(0),
None,
&crate::command_source::test_origin(),
)
.is_err());
assert!(msi
.write_property_from(
PropertyIdentifier::PRESENT_VALUE,
None,
PropertyValue::Unsigned(5),
None,
&crate::command_source::test_origin(),
)
.is_err());
}
#[test]
fn msi_read_reliability_default() {
let msi = MultiStateInputObject::new(1, "MSI-1", 4).unwrap();
let val = msi
.read_property(PropertyIdentifier::RELIABILITY, None)
.unwrap();
assert_eq!(val, PropertyValue::Enumerated(0)); }
#[test]
fn mso_write_with_priority() {
let mut mso = MultiStateOutputObject::new(1, "MSO-1", 5).unwrap();
mso.write_property_from(
PropertyIdentifier::PRESENT_VALUE,
None,
PropertyValue::Unsigned(3),
Some(8),
&crate::command_source::test_origin(),
)
.unwrap();
let val = mso
.read_property(PropertyIdentifier::PRESENT_VALUE, None)
.unwrap();
assert_eq!(val, PropertyValue::Unsigned(3));
let slot = mso
.read_property(PropertyIdentifier::PRIORITY_ARRAY, Some(8))
.unwrap();
assert_eq!(slot, PropertyValue::Unsigned(3));
}
#[test]
fn mso_relinquish_falls_to_default() {
let mut mso = MultiStateOutputObject::new(1, "MSO-1", 5).unwrap();
mso.write_property_from(
PropertyIdentifier::PRESENT_VALUE,
None,
PropertyValue::Unsigned(4),
Some(16),
&crate::command_source::test_origin(),
)
.unwrap();
assert_eq!(
mso.read_property(PropertyIdentifier::PRESENT_VALUE, None)
.unwrap(),
PropertyValue::Unsigned(4)
);
mso.write_property_from(
PropertyIdentifier::PRESENT_VALUE,
None,
PropertyValue::Null,
Some(16),
&crate::command_source::test_origin(),
)
.unwrap();
assert_eq!(
mso.read_property(PropertyIdentifier::PRESENT_VALUE, None)
.unwrap(),
PropertyValue::Unsigned(1)
); }
#[test]
fn mso_out_of_range_rejected() {
let mut mso = MultiStateOutputObject::new(1, "MSO-1", 5).unwrap();
assert!(mso
.write_property_from(
PropertyIdentifier::PRESENT_VALUE,
None,
PropertyValue::Unsigned(0),
None,
&crate::command_source::test_origin(),
)
.is_err());
assert!(mso
.write_property_from(
PropertyIdentifier::PRESENT_VALUE,
None,
PropertyValue::Unsigned(6),
None,
&crate::command_source::test_origin(),
)
.is_err());
}
#[test]
fn mso_read_reliability_default() {
let mso = MultiStateOutputObject::new(1, "MSO-1", 5).unwrap();
let val = mso
.read_property(PropertyIdentifier::RELIABILITY, None)
.unwrap();
assert_eq!(val, PropertyValue::Enumerated(0)); }
#[test]
fn msv_read_present_value_default() {
let msv = MultiStateValueObject::new(1, "MSV-1", 3).unwrap();
let val = msv
.read_property(PropertyIdentifier::PRESENT_VALUE, None)
.unwrap();
assert_eq!(val, PropertyValue::Unsigned(1));
}
#[test]
fn msv_write_with_priority() {
let mut msv = MultiStateValueObject::new(1, "MSV-1", 3).unwrap();
msv.write_property_from(
PropertyIdentifier::PRESENT_VALUE,
None,
PropertyValue::Unsigned(2),
Some(8),
&crate::command_source::test_origin(),
)
.unwrap();
let val = msv
.read_property(PropertyIdentifier::PRESENT_VALUE, None)
.unwrap();
assert_eq!(val, PropertyValue::Unsigned(2));
let slot = msv
.read_property(PropertyIdentifier::PRIORITY_ARRAY, Some(8))
.unwrap();
assert_eq!(slot, PropertyValue::Unsigned(2));
}
#[test]
fn msv_relinquish_falls_to_default() {
let mut msv = MultiStateValueObject::new(1, "MSV-1", 3).unwrap();
msv.write_property_from(
PropertyIdentifier::PRESENT_VALUE,
None,
PropertyValue::Unsigned(3),
Some(16),
&crate::command_source::test_origin(),
)
.unwrap();
assert_eq!(
msv.read_property(PropertyIdentifier::PRESENT_VALUE, None)
.unwrap(),
PropertyValue::Unsigned(3)
);
msv.write_property_from(
PropertyIdentifier::PRESENT_VALUE,
None,
PropertyValue::Null,
Some(16),
&crate::command_source::test_origin(),
)
.unwrap();
assert_eq!(
msv.read_property(PropertyIdentifier::PRESENT_VALUE, None)
.unwrap(),
PropertyValue::Unsigned(1)
); }
#[test]
fn msv_read_priority_array_all_none() {
let msv = MultiStateValueObject::new(1, "MSV-1", 3).unwrap();
let val = msv
.read_property(PropertyIdentifier::PRIORITY_ARRAY, None)
.unwrap();
if let PropertyValue::List(elements) = val {
assert_eq!(elements.len(), 16);
for elem in &elements {
assert_eq!(elem, &PropertyValue::Null);
}
} else {
panic!("Expected List for priority array without index");
}
}
#[test]
fn msv_read_relinquish_default() {
let msv = MultiStateValueObject::new(1, "MSV-1", 3).unwrap();
let val = msv
.read_property(PropertyIdentifier::RELINQUISH_DEFAULT, None)
.unwrap();
assert_eq!(val, PropertyValue::Unsigned(1));
}
#[test]
fn msv_write_out_of_range_rejected() {
let mut msv = MultiStateValueObject::new(1, "MSV-1", 3).unwrap();
assert!(msv
.write_property_from(
PropertyIdentifier::PRESENT_VALUE,
None,
PropertyValue::Unsigned(0),
None,
&crate::command_source::test_origin(),
)
.is_err());
assert!(msv
.write_property_from(
PropertyIdentifier::PRESENT_VALUE,
None,
PropertyValue::Unsigned(4),
None,
&crate::command_source::test_origin(),
)
.is_err());
}
#[test]
fn msv_write_wrong_type_rejected() {
let mut msv = MultiStateValueObject::new(1, "MSV-1", 3).unwrap();
let result = msv.write_property_from(
PropertyIdentifier::PRESENT_VALUE,
None,
PropertyValue::Real(1.0),
None,
&crate::command_source::test_origin(),
);
assert!(result.is_err());
}
#[test]
fn msv_read_object_type() {
let msv = MultiStateValueObject::new(1, "MSV-1", 3).unwrap();
let val = msv
.read_property(PropertyIdentifier::OBJECT_TYPE, None)
.unwrap();
assert_eq!(
val,
PropertyValue::Enumerated(ObjectType::MULTI_STATE_VALUE.to_raw())
);
}
#[test]
fn msv_read_reliability_default() {
let msv = MultiStateValueObject::new(1, "MSV-1", 3).unwrap();
let val = msv
.read_property(PropertyIdentifier::RELIABILITY, None)
.unwrap();
assert_eq!(val, PropertyValue::Enumerated(0)); }
#[test]
fn msv_present_value_priority_write_value() {
let mut msv = MultiStateValueObject::new(1, "MSV-1", 5).unwrap();
msv.write_property_from(
PropertyIdentifier::PRESENT_VALUE,
None,
PropertyValue::Unsigned(3),
Some(5),
&crate::command_source::test_origin(),
)
.unwrap();
assert_eq!(
msv.read_property(PropertyIdentifier::PRESENT_VALUE, None)
.unwrap(),
PropertyValue::Unsigned(3)
);
assert_eq!(
msv.read_property(PropertyIdentifier::PRIORITY_ARRAY, Some(5))
.unwrap(),
PropertyValue::Unsigned(3)
);
}
#[test]
fn msv_present_value_priority_relinquish() {
let mut msv = MultiStateValueObject::new(1, "MSV-1", 5).unwrap();
msv.write_property_from(
PropertyIdentifier::PRESENT_VALUE,
None,
PropertyValue::Unsigned(3),
Some(5),
&crate::command_source::test_origin(),
)
.unwrap();
msv.write_property_from(
PropertyIdentifier::PRESENT_VALUE,
None,
PropertyValue::Null,
Some(5),
&crate::command_source::test_origin(),
)
.unwrap();
assert_eq!(
msv.read_property(PropertyIdentifier::PRESENT_VALUE, None)
.unwrap(),
PropertyValue::Unsigned(1)
); }
#[test]
fn msv_direct_priority_array_no_index_error() {
let mut msv = MultiStateValueObject::new(1, "MSV-1", 5).unwrap();
let result = msv.write_property(
PropertyIdentifier::PRIORITY_ARRAY,
None,
PropertyValue::Unsigned(3),
None,
);
assert!(result.is_err());
}
#[test]
fn msv_direct_priority_array_index_zero_error() {
let mut msv = MultiStateValueObject::new(1, "MSV-1", 5).unwrap();
let result = msv.write_property(
PropertyIdentifier::PRIORITY_ARRAY,
Some(0),
PropertyValue::Unsigned(3),
None,
);
assert!(result.is_err());
}
#[test]
fn msv_direct_priority_array_index_17_error() {
let mut msv = MultiStateValueObject::new(1, "MSV-1", 5).unwrap();
let result = msv.write_property(
PropertyIdentifier::PRIORITY_ARRAY,
Some(17),
PropertyValue::Unsigned(3),
None,
);
assert!(result.is_err());
}
#[test]
fn msv_present_value_priority_range_validation() {
let mut msv = MultiStateValueObject::new(1, "MSV-1", 5).unwrap();
assert!(msv
.write_property_from(
PropertyIdentifier::PRESENT_VALUE,
None,
PropertyValue::Unsigned(0),
None,
&crate::command_source::test_origin(),
)
.is_err());
assert!(msv
.write_property_from(
PropertyIdentifier::PRESENT_VALUE,
None,
PropertyValue::Unsigned(6),
None,
&crate::command_source::test_origin(),
)
.is_err());
msv.write_property_from(
PropertyIdentifier::PRESENT_VALUE,
None,
PropertyValue::Unsigned(5),
Some(1),
&crate::command_source::test_origin(),
)
.unwrap();
}
#[test]
fn mso_present_value_priority_write_value() {
let mut mso = MultiStateOutputObject::new(1, "MSO-1", 5).unwrap();
mso.write_property_from(
PropertyIdentifier::PRESENT_VALUE,
None,
PropertyValue::Unsigned(3),
Some(5),
&crate::command_source::test_origin(),
)
.unwrap();
assert_eq!(
mso.read_property(PropertyIdentifier::PRESENT_VALUE, None)
.unwrap(),
PropertyValue::Unsigned(3)
);
assert_eq!(
mso.read_property(PropertyIdentifier::PRIORITY_ARRAY, Some(5))
.unwrap(),
PropertyValue::Unsigned(3)
);
}
#[test]
fn mso_present_value_priority_relinquish() {
let mut mso = MultiStateOutputObject::new(1, "MSO-1", 5).unwrap();
mso.write_property_from(
PropertyIdentifier::PRESENT_VALUE,
None,
PropertyValue::Unsigned(3),
Some(5),
&crate::command_source::test_origin(),
)
.unwrap();
mso.write_property_from(
PropertyIdentifier::PRESENT_VALUE,
None,
PropertyValue::Null,
Some(5),
&crate::command_source::test_origin(),
)
.unwrap();
assert_eq!(
mso.read_property(PropertyIdentifier::PRESENT_VALUE, None)
.unwrap(),
PropertyValue::Unsigned(1)
);
}
#[test]
fn mso_direct_priority_array_no_index_error() {
let mut mso = MultiStateOutputObject::new(1, "MSO-1", 5).unwrap();
let result = mso.write_property(
PropertyIdentifier::PRIORITY_ARRAY,
None,
PropertyValue::Unsigned(3),
None,
);
assert!(result.is_err());
}
#[test]
fn mso_direct_priority_array_index_zero_error() {
let mut mso = MultiStateOutputObject::new(1, "MSO-1", 5).unwrap();
let result = mso.write_property(
PropertyIdentifier::PRIORITY_ARRAY,
Some(0),
PropertyValue::Unsigned(3),
None,
);
assert!(result.is_err());
}
#[test]
fn mso_direct_priority_array_index_17_error() {
let mut mso = MultiStateOutputObject::new(1, "MSO-1", 5).unwrap();
let result = mso.write_property(
PropertyIdentifier::PRIORITY_ARRAY,
Some(17),
PropertyValue::Unsigned(3),
None,
);
assert!(result.is_err());
}
#[test]
fn msi_is_createable_and_writable_match_factory() {
use crate::traits::BACnetObject;
let msi = MultiStateInputObject::new(1, "msi-1", 2).unwrap();
assert!(
msi.is_createable(),
"MultiStateInput is factory-constructable"
);
assert!(msi.is_writable_property(PropertyIdentifier::PRESENT_VALUE));
assert!(msi.is_writable_property(PropertyIdentifier::STATE_TEXT));
assert!(msi.is_writable_property(PropertyIdentifier::OUT_OF_SERVICE));
assert!(msi.is_writable_property(PropertyIdentifier::OBJECT_NAME));
assert!(!msi.is_writable_property(PropertyIdentifier::PRIORITY_ARRAY));
assert!(msi.is_writable_property(PropertyIdentifier::EVENT_ENABLE));
}
#[test]
fn mso_is_createable_and_writable_match_factory() {
use crate::traits::BACnetObject;
let mso = MultiStateOutputObject::new(1, "mso-1", 2).unwrap();
assert!(
mso.is_createable(),
"MultiStateOutput is factory-constructable"
);
assert!(!mso.is_writable_property(PropertyIdentifier::PRIORITY_ARRAY));
assert!(mso.is_writable_property(PropertyIdentifier::PRESENT_VALUE));
assert!(mso.is_writable_property(PropertyIdentifier::STATE_TEXT));
assert!(mso.is_writable_property(PropertyIdentifier::OUT_OF_SERVICE));
assert!(mso.is_writable_property(PropertyIdentifier::EVENT_ENABLE));
}
#[test]
fn msv_is_createable_and_writable_match_factory() {
use crate::traits::BACnetObject;
let msv = MultiStateValueObject::new(1, "msv-1", 2).unwrap();
assert!(
msv.is_createable(),
"MultiStateValue is factory-constructable"
);
assert!(!msv.is_writable_property(PropertyIdentifier::PRIORITY_ARRAY));
assert!(msv.is_writable_property(PropertyIdentifier::PRESENT_VALUE));
assert!(msv.is_writable_property(PropertyIdentifier::STATE_TEXT));
assert!(msv.is_writable_property(PropertyIdentifier::OUT_OF_SERVICE));
}
#[test]
fn msi_new_rejects_zero_states() {
let err = MultiStateInputObject::new(1, "MSI-1", 0);
assert!(err.is_err(), "expected an error, got Ok");
if let Err(e) = err {
assert!(matches!(e, Error::OutOfRange(_)), "got {e:?}");
}
}
#[test]
fn mso_new_rejects_zero_states() {
let err = MultiStateOutputObject::new(1, "MSO-1", 0);
assert!(err.is_err(), "expected an error, got Ok");
if let Err(e) = err {
assert!(matches!(e, Error::OutOfRange(_)), "got {e:?}");
}
}
#[test]
fn msv_new_rejects_zero_states() {
let err = MultiStateValueObject::new(1, "MSV-1", 0);
assert!(err.is_err(), "expected an error, got Ok");
if let Err(e) = err {
assert!(matches!(e, Error::OutOfRange(_)), "got {e:?}");
}
}
#[test]
fn msi_one_state_is_valid_initial_value_in_range() {
let msi = MultiStateInputObject::new(1, "MSI-1", 1).unwrap();
assert_eq!(
msi.read_property(PropertyIdentifier::NUMBER_OF_STATES, None)
.unwrap(),
PropertyValue::Unsigned(1)
);
assert_eq!(
msi.read_property(PropertyIdentifier::PRESENT_VALUE, None)
.unwrap(),
PropertyValue::Unsigned(1)
);
assert_eq!(
msi.read_property(PropertyIdentifier::STATE_TEXT, Some(1))
.unwrap(),
PropertyValue::CharacterString("State 1".into())
);
assert!(msi
.read_property(PropertyIdentifier::STATE_TEXT, Some(2))
.is_err());
}
#[test]
fn mso_one_state_initial_and_relinquish_default_in_range() {
let mut mso = MultiStateOutputObject::new(1, "MSO-1", 1).unwrap();
assert_eq!(
mso.read_property(PropertyIdentifier::PRESENT_VALUE, None)
.unwrap(),
PropertyValue::Unsigned(1)
);
assert_eq!(
mso.read_property(PropertyIdentifier::RELINQUISH_DEFAULT, None)
.unwrap(),
PropertyValue::Unsigned(1)
);
mso.write_property_from(
PropertyIdentifier::PRESENT_VALUE,
None,
PropertyValue::Unsigned(1),
Some(8),
&crate::command_source::test_origin(),
)
.unwrap();
assert_eq!(
mso.read_property(PropertyIdentifier::PRESENT_VALUE, None)
.unwrap(),
PropertyValue::Unsigned(1)
);
mso.write_property_from(
PropertyIdentifier::PRESENT_VALUE,
None,
PropertyValue::Null,
Some(8),
&crate::command_source::test_origin(),
)
.unwrap();
assert_eq!(
mso.read_property(PropertyIdentifier::PRESENT_VALUE, None)
.unwrap(),
PropertyValue::Unsigned(1)
);
}
#[test]
fn msv_one_state_initial_and_relinquish_default_in_range() {
let mut msv = MultiStateValueObject::new(1, "MSV-1", 1).unwrap();
assert_eq!(
msv.read_property(PropertyIdentifier::PRESENT_VALUE, None)
.unwrap(),
PropertyValue::Unsigned(1)
);
assert_eq!(
msv.read_property(PropertyIdentifier::RELINQUISH_DEFAULT, None)
.unwrap(),
PropertyValue::Unsigned(1)
);
msv.write_property_from(
PropertyIdentifier::PRESENT_VALUE,
None,
PropertyValue::Unsigned(1),
Some(8),
&crate::command_source::test_origin(),
)
.unwrap();
assert_eq!(
msv.read_property(PropertyIdentifier::PRESENT_VALUE, None)
.unwrap(),
PropertyValue::Unsigned(1)
);
msv.write_property_from(
PropertyIdentifier::PRESENT_VALUE,
None,
PropertyValue::Null,
Some(8),
&crate::command_source::test_origin(),
)
.unwrap();
assert_eq!(
msv.read_property(PropertyIdentifier::PRESENT_VALUE, None)
.unwrap(),
PropertyValue::Unsigned(1)
);
}
#[test]
fn msi_one_state_write_out_of_range_rejected() {
let mut msi = MultiStateInputObject::new(1, "MSI-1", 1).unwrap();
msi.write_property(
PropertyIdentifier::OUT_OF_SERVICE,
None,
PropertyValue::Boolean(true),
None,
)
.unwrap();
assert!(msi
.write_property_from(
PropertyIdentifier::PRESENT_VALUE,
None,
PropertyValue::Unsigned(2),
None,
&crate::command_source::test_origin(),
)
.is_err());
}