use crate::{field_types::*, modele, FieldListener, Hit, ObjectValue, Reference};
use std::{cell::RefCell, rc::Rc};
use crate::{HitError, Kernel, Model, Plugins};
pub struct TestEventsKernel {
model: Rc<Model>,
}
impl Kernel for TestEventsKernel {
fn get_model(&self, _name: &str) -> Result<Rc<Model>, HitError> {
return Ok(self.model.clone());
}
fn get_instantiable_models(&self) -> Vec<&Model> {
return vec![&self.model];
}
fn get_plugins(&self) -> Plugins {
Plugins::new()
}
fn get_models(&self) -> Vec<String> {
vec!["test/test".to_string()]
}
}
fn create_test_events_model() -> Rc<Model> {
modele!("test/test", "Filesystem" =>
"name": FieldTypeString {
required: true
},
"subitems": FieldTypeSubobjectArray {
authorized_models: vec!["test/test".to_string()]
},
"references": FieldTypeReferenceArray {
authorized_models: vec!["test/test".to_string()]
},
"reference": FieldTypeReference {
authorized_models: vec!["test/test".to_string()]
}
)
}
fn create_test_events_kernel() -> TestEventsKernel {
TestEventsKernel {
model: create_test_events_model(),
}
}
struct TestPropertyListener {
event_count: i32,
id: String,
}
impl FieldListener<ObjectValue> for TestPropertyListener {
fn on_update(&mut self, _value: &ObjectValue) {
self.event_count += 1;
}
fn get_unique_id(&self) -> &str {
&self.id
}
}
#[test]
fn it_should_send_an_event_when_property_is_set() {
let listener = Rc::new(RefCell::new(TestPropertyListener {
event_count: 0,
id: "a".into(),
}));
let listener2 = Rc::new(RefCell::new(TestPropertyListener {
event_count: 0,
id: "b".into(),
}));
let mut hit = Hit::new(
"id".into(),
"test/test".into(),
Rc::new(create_test_events_kernel()),
)
.expect("Error creating instance");
hit.subscribe_field("id", "name", listener.clone())
.expect("Error");
hit.subscribe_field("id", "reference", listener2.clone())
.expect("Error");
hit.set("id", "name", ObjectValue::String("test".into()))
.expect("Error");
hit.set("id", "name", ObjectValue::String("test2".into()))
.expect("Error");
hit.set(
"id",
"reference",
ObjectValue::Reference(Reference { id: "id".into() }),
)
.expect("Error");
hit.set("id", "reference", ObjectValue::Null)
.expect("Error");
let listener = listener.borrow();
let listener2 = listener2.borrow();
assert_eq!(listener.event_count, 2);
assert_eq!(listener2.event_count, 2);
}
#[test]
fn it_should_not_send_an_event_when_a_listener_is_unsubscribed() {
let listener = Rc::new(RefCell::new(TestPropertyListener {
event_count: 0,
id: "a".into(),
}));
let mut hit = Hit::new(
"id".into(),
"test/test".into(),
Rc::new(create_test_events_kernel()),
)
.expect("Error creating instance");
hit.subscribe_field("id", "name", listener.clone())
.expect("Error");
hit.set("id", "name", ObjectValue::String("test".into()))
.expect("Error");
let listener = listener.borrow();
assert_eq!(listener.event_count, 1);
hit.unsubscribe_field("id", "name", "a").expect("Error");
hit.set("id", "name", ObjectValue::String("test2".into()))
.expect("Error");
assert_eq!(listener.event_count, 1);
}
#[test]
fn it_should_return_an_error_when_a_non_existing_listener_is_unsubscribed() {
let hit = Hit::new(
"id".into(),
"test/test".into(),
Rc::new(create_test_events_kernel()),
)
.expect("Error creating instance");
let error = hit.unsubscribe_field("id", "name", "a");
assert_eq!(error.err().unwrap(), HitError::ListenerNotFound("a".into()));
}