extern crate alloc;
use crate::{EventEmitter, EventError, EventHandler, EventPayload, Listener};
use alloc::{
string::{String, ToString},
sync::Arc,
};
use core::sync::atomic::{AtomicU64, Ordering};
#[test]
fn add_listeners_variety() {
let mut emitter = EventEmitter::<String>::default();
let cb: Arc<dyn Fn(&EventPayload<String>) + Send + Sync> = Arc::new(|_| {});
let l1 = emitter
.add("event", Some("tag1".to_string()), cb.clone())
.unwrap();
assert_eq!(l1.tag(), Some(&"tag1".to_string()));
assert_eq!(l1.lifetime(), None);
let l2 = emitter
.add_limited("event", Some("tag2".to_string()), cb.clone(), 2)
.unwrap();
assert_eq!(l2.tag(), Some(&"tag2".to_string()));
assert_eq!(l2.lifetime(), Some(2));
let l3 = emitter
.add_once("event", Some("tag3".to_string()), cb.clone())
.unwrap();
assert_eq!(l3.tag(), Some(&"tag3".to_string()));
assert_eq!(l3.lifetime(), Some(1));
assert_eq!(emitter.listener_count("event").unwrap(), 3);
}
#[test]
fn listener_at_limit_and_removal() {
let mut emitter = EventEmitter::<String>::default();
let called = Arc::new(AtomicU64::new(0));
let called_clone = called.clone();
let cb: Arc<dyn Fn(&EventPayload<String>) + Send + Sync> = Arc::new(move |_| {
called_clone.fetch_add(1, Ordering::SeqCst);
});
emitter.add_once("event", None, cb.clone()).unwrap();
emitter.add_limited("event", None, cb.clone(), 3).unwrap();
let _ = emitter.emit("event", Arc::new("payload".to_string()));
assert_eq!(called.load(Ordering::SeqCst), 2);
assert_eq!(emitter.listener_count("event").unwrap_or(0), 1);
for _ in 0..2 {
let _ = emitter.emit("event", Arc::new("payload".to_string()));
}
assert_eq!(called.load(Ordering::SeqCst), 4);
assert_eq!(emitter.listener_count("event").unwrap_or(0), 0);
}
#[test]
fn event_overload() {
let mut emitter = EventEmitter::<String>::new(2);
let cb: Arc<dyn Fn(&EventPayload<String>) + Send + Sync> = Arc::new(|_| {});
emitter.add("event", None, cb.clone()).unwrap();
emitter.add("event", None, cb.clone()).unwrap();
let res = emitter.add("event", None, cb.clone());
assert_eq!(res, Err(EventError::OverloadedEvent));
}
mod removing_listeners {
use super::*;
#[test]
fn remove_single_listener() {
let cb: Arc<dyn Fn(&EventPayload<String>) + Send + Sync> = Arc::new(|_| {});
let mut emitter = EventEmitter::<String>::default();
let listener = emitter.add("test", None, cb.clone()).unwrap();
assert_eq!(emitter.listener_count("test").unwrap(), 1);
assert!(emitter.remove_listener("test", &listener).is_ok());
assert_eq!(emitter.listener_count("test").unwrap_or(0), 0);
let listener = emitter.add_limited("test", None, cb.clone(), 5).unwrap();
assert_eq!(emitter.listener_count("test").unwrap(), 1);
assert!(emitter.remove_listener("test", &listener).is_ok());
assert_eq!(emitter.listener_count("test").unwrap_or(0), 0);
let listener = emitter.add_once("test", None, cb.clone()).unwrap();
assert_eq!(emitter.listener_count("test").unwrap(), 1);
assert!(emitter.remove_listener("test", &listener).is_ok());
assert_eq!(emitter.listener_count("test").unwrap_or(0), 0);
}
#[test]
fn remove_all_listeners() {
let cb: Arc<dyn Fn(&EventPayload<String>) + Send + Sync> = Arc::new(|_| {});
let mut emitter = EventEmitter::<String>::default();
for i in 0..10 {
match i % 3 {
0 => emitter.add("test", None, cb.clone()).unwrap(),
1 => emitter.add_limited("test", None, cb.clone(), 5).unwrap(),
_ => emitter.add_once("test", None, cb.clone()).unwrap(),
};
}
assert_eq!(emitter.listener_count("test").unwrap(), 10);
let returned = emitter.remove_all_listeners("test");
assert!(returned.is_ok());
assert_eq!(emitter.listener_count("test").unwrap_or(0), 0);
assert_eq!(returned.unwrap().len(), 10);
}
#[test]
fn remove_invalid_listener_throws_error() {
let cb: Arc<dyn Fn(&EventPayload<String>) + Send + Sync> = Arc::new(|_| {});
let mut emitter = EventEmitter::<String>::default();
emitter.add("test", None, cb.clone()).unwrap();
let fake = Listener::new(None, Arc::new(|_| {}), None);
assert_eq!(
emitter.remove_listener("test", &fake),
Err(EventError::ListenerNotFound)
);
}
#[test]
fn remove_from_invalid_event_throws_error() {
let cb: Arc<dyn Fn(&EventPayload<String>) + Send + Sync> = Arc::new(|_| {});
let mut emitter = EventEmitter::<String>::default();
emitter.add("test", None, cb.clone()).unwrap();
let fake = Listener::new(None, Arc::new(|_| {}), None);
assert_eq!(
emitter.remove_listener("not_test", &fake),
Err(EventError::EventNotFound)
);
}
}
mod emitting_events {
use super::*;
#[test]
fn emit_successful() {
let called = Arc::new(AtomicU64::new(0));
let called_clone = called.clone();
let cb: Arc<dyn Fn(&EventPayload<String>) + Send + Sync> = Arc::new(move |payload| {
assert_eq!(payload.as_ref(), "Test");
called_clone.fetch_add(1, Ordering::SeqCst);
});
let mut emitter = EventEmitter::<String>::default();
emitter.add("count", None, cb.clone()).unwrap();
for _ in 0..10 {
assert!(emitter.emit("count", Arc::new("Test".to_string())).is_ok());
}
assert_eq!(
called.load(Ordering::SeqCst),
10,
"Event callbacks unsuccessful"
);
}
#[test]
fn emit_multiple_successful() {
let called = Arc::new(AtomicU64::new(0));
let called_clone = called.clone();
let cb: Arc<dyn Fn(&EventPayload<String>) + Send + Sync> = Arc::new(move |payload| {
assert_eq!(payload.as_ref(), "Test");
called_clone.fetch_add(1, Ordering::SeqCst);
});
let mut emitter = EventEmitter::<String>::default();
for _ in 0..10 {
emitter.add("count", None, cb.clone()).unwrap();
}
assert!(emitter.emit("count", Arc::new("Test".to_string())).is_ok());
assert_eq!(
called.load(Ordering::SeqCst),
10,
"Event callbacks unsuccessful"
);
}
#[test]
fn once_listener_emission_drop_off_successful() {
let called = Arc::new(AtomicU64::new(0));
let called_clone = called.clone();
let cb: Arc<dyn Fn(&EventPayload<String>) + Send + Sync> = Arc::new(move |_| {
called_clone.fetch_add(1, Ordering::SeqCst);
});
let mut emitter = EventEmitter::<String>::default();
emitter
.add_once("count", Some("tag1".to_string()), cb.clone())
.unwrap();
let falloff = emitter.emit("count", Arc::new("Increment".to_string()));
assert!(falloff.is_ok(), "Emit failed");
assert_eq!(
called.load(Ordering::SeqCst),
1,
"Event callbacks unsuccessful"
);
let falloff = falloff.unwrap();
assert_eq!(falloff.len(), 1, "Expected 1 event to falloff");
assert_eq!(
falloff[0].tag(),
Some("tag1".to_string()).as_ref(),
"Unexpected event payload"
);
assert_eq!(emitter.listener_count("count").unwrap_or(0), 0);
}
#[test]
fn limited_listener_emission_drop_off_successful() {
let called = Arc::new(AtomicU64::new(0));
let called_clone = called.clone();
let cb: Arc<dyn Fn(&EventPayload<String>) + Send + Sync> = Arc::new(move |_| {
called_clone.fetch_add(1, Ordering::SeqCst);
});
let mut emitter = EventEmitter::<String>::default();
emitter
.add_limited("count", Some("tag1".to_string()), cb.clone(), 5)
.unwrap();
for _ in 0..4 {
assert!(emitter.emit("count", Arc::new("Test".to_string())).is_ok());
}
let falloff = emitter.emit("count", Arc::new("Test".to_string()));
assert!(falloff.is_ok(), "Emit failed");
assert_eq!(
called.load(Ordering::SeqCst),
5,
"Event callbacks unsuccessful"
);
let falloff = falloff.unwrap();
assert_eq!(falloff.len(), 1, "Expected 1 event to falloff");
assert_eq!(
falloff[0].tag(),
Some("tag1".to_string()).as_ref(),
"Unexpected event payload"
);
assert_eq!(emitter.listener_count("count").unwrap_or(0), 0);
}
}
mod emitting_final_events {
use super::*;
#[test]
fn emit_final_drops_infinite_listener() {
let called = Arc::new(AtomicU64::new(0));
let called_clone = called.clone();
let cb: Arc<dyn Fn(&EventPayload<String>) + Send + Sync> = Arc::new(move |_| {
called_clone.fetch_add(1, Ordering::SeqCst);
});
let mut emitter = EventEmitter::<String>::default();
emitter
.add("count_final", Some("tag1".to_string()), cb.clone())
.unwrap();
assert!(
emitter
.emit("count_final", Arc::new("Test".to_string()))
.is_ok(),
"Regular emit failed"
);
let falloff = emitter.emit_final("count_final", Arc::new("Test".to_string()));
assert!(falloff.is_ok());
assert_eq!(
called.load(Ordering::SeqCst),
2,
"Event callbacks unsuccessful"
);
let falloff = falloff.unwrap();
assert_eq!(falloff.len(), 1, "Expected 1 event to falloff");
assert_eq!(
falloff[0].tag(),
Some("tag1".to_string()).as_ref(),
"Unexpected event payload"
);
assert_eq!(
emitter.emit_final("count_final", Arc::new("Test".to_string())),
Err(EventError::EventNotFound)
);
}
#[test]
fn emit_final_drops_limited_listener() {
let called = Arc::new(AtomicU64::new(0));
let called_clone = called.clone();
let cb: Arc<dyn Fn(&EventPayload<String>) + Send + Sync> = Arc::new(move |_| {
called_clone.fetch_add(1, Ordering::SeqCst);
});
let mut emitter = EventEmitter::<String>::default();
emitter
.add_limited("count_final", Some("tag1".to_string()), cb.clone(), 5)
.unwrap();
assert!(
emitter
.emit("count_final", Arc::new("Test".to_string()))
.is_ok(),
"Regular emit failed"
);
let falloff = emitter.emit_final("count_final", Arc::new("Test".to_string()));
assert!(falloff.is_ok());
assert_eq!(
called.load(Ordering::SeqCst),
2,
"Event callbacks unsuccessful"
);
let falloff = falloff.unwrap();
assert_eq!(falloff.len(), 1, "Expected 1 event to falloff");
assert_eq!(
falloff[0].tag(),
Some("tag1".to_string()).as_ref(),
"Unexpected event payload"
);
assert_eq!(falloff[0].lifetime(), Some(3), "Unexpected event lifetime");
assert_eq!(
emitter.emit_final("count_final", Arc::new("Test".to_string())),
Err(EventError::EventNotFound)
);
}
}