use super::PluginContext;
use std::time::Duration;
pub trait Plugin: Send {
fn name(&self) -> &str;
fn on_init(&mut self, _ctx: &mut PluginContext) -> crate::Result<()> {
Ok(())
}
fn on_mount(&mut self, _ctx: &mut PluginContext) -> crate::Result<()> {
Ok(())
}
fn on_tick(&mut self, _ctx: &mut PluginContext, _delta: Duration) -> crate::Result<()> {
Ok(())
}
fn on_unmount(&mut self, _ctx: &mut PluginContext) -> crate::Result<()> {
Ok(())
}
fn styles(&self) -> Option<&str> {
None
}
fn priority(&self) -> i32 {
0
}
}
#[cfg(test)]
mod tests {
use super::*;
struct TestPlugin {
init_called: bool,
mount_called: bool,
tick_count: usize,
}
impl Plugin for TestPlugin {
fn name(&self) -> &str {
"test"
}
fn on_init(&mut self, _ctx: &mut PluginContext) -> crate::Result<()> {
self.init_called = true;
Ok(())
}
fn on_mount(&mut self, _ctx: &mut PluginContext) -> crate::Result<()> {
self.mount_called = true;
Ok(())
}
fn on_tick(&mut self, _ctx: &mut PluginContext, _delta: Duration) -> crate::Result<()> {
self.tick_count += 1;
Ok(())
}
}
#[test]
fn test_plugin_default_implementations() {
struct MinimalPlugin;
impl Plugin for MinimalPlugin {
fn name(&self) -> &str {
"minimal"
}
}
let plugin = MinimalPlugin;
assert_eq!(plugin.name(), "minimal");
assert_eq!(plugin.priority(), 0);
assert!(plugin.styles().is_none());
}
#[test]
fn test_plugin_lifecycle_on_init() {
let mut plugin = TestPlugin {
init_called: false,
mount_called: false,
tick_count: 0,
};
let mut ctx = PluginContext::new();
ctx.set_current_plugin("test");
assert!(!plugin.init_called);
plugin.on_init(&mut ctx).unwrap();
assert!(plugin.init_called);
}
#[test]
fn test_plugin_lifecycle_on_mount() {
let mut plugin = TestPlugin {
init_called: false,
mount_called: false,
tick_count: 0,
};
let mut ctx = PluginContext::new();
ctx.set_current_plugin("test");
assert!(!plugin.mount_called);
plugin.on_mount(&mut ctx).unwrap();
assert!(plugin.mount_called);
}
#[test]
fn test_plugin_lifecycle_on_tick() {
let mut plugin = TestPlugin {
init_called: false,
mount_called: false,
tick_count: 0,
};
let mut ctx = PluginContext::new();
ctx.set_current_plugin("test");
assert_eq!(plugin.tick_count, 0);
plugin.on_tick(&mut ctx, Duration::from_millis(16)).unwrap();
assert_eq!(plugin.tick_count, 1);
plugin.on_tick(&mut ctx, Duration::from_millis(16)).unwrap();
assert_eq!(plugin.tick_count, 2);
}
#[test]
fn test_plugin_default_on_unmount() {
struct UnmountPlugin;
impl Plugin for UnmountPlugin {
fn name(&self) -> &str {
"unmount"
}
}
let mut plugin = UnmountPlugin;
let mut ctx = PluginContext::new();
assert!(plugin.on_unmount(&mut ctx).is_ok());
}
#[test]
fn test_plugin_with_styles() {
struct StyledPlugin;
impl Plugin for StyledPlugin {
fn name(&self) -> &str {
"styled"
}
fn styles(&self) -> Option<&str> {
Some(".button { color: red; }")
}
}
let plugin = StyledPlugin;
assert_eq!(plugin.styles(), Some(".button { color: red; }"));
}
#[test]
fn test_plugin_with_priority() {
struct HighPriorityPlugin;
impl Plugin for HighPriorityPlugin {
fn name(&self) -> &str {
"high"
}
fn priority(&self) -> i32 {
100
}
}
assert_eq!(HighPriorityPlugin.priority(), 100);
}
#[test]
fn test_test_plugin_name() {
let plugin = TestPlugin {
init_called: false,
mount_called: false,
tick_count: 0,
};
assert_eq!(plugin.name(), "test");
}
#[test]
fn test_default_on_init() {
struct DefaultPlugin;
impl Plugin for DefaultPlugin {
fn name(&self) -> &str {
"default"
}
}
let mut plugin = DefaultPlugin;
let mut ctx = PluginContext::new();
assert!(plugin.on_init(&mut ctx).is_ok());
}
#[test]
fn test_default_on_mount() {
struct DefaultPlugin;
impl Plugin for DefaultPlugin {
fn name(&self) -> &str {
"default"
}
}
let mut plugin = DefaultPlugin;
let mut ctx = PluginContext::new();
assert!(plugin.on_mount(&mut ctx).is_ok());
}
#[test]
fn test_default_on_tick() {
struct DefaultPlugin;
impl Plugin for DefaultPlugin {
fn name(&self) -> &str {
"default"
}
}
let mut plugin = DefaultPlugin;
let mut ctx = PluginContext::new();
assert!(plugin.on_tick(&mut ctx, Duration::from_millis(16)).is_ok());
}
}