use std::{collections::HashMap, sync::Arc};
use crate::api::v1::{
Buffer, BufferError, BufferId, BufferManager, EventBus, KernelContext, MarkBank, ModeId,
ModuleId, MotionEngine, OptionRegistry, RwLock, ServiceRegistry, TextObjectEngine,
};
pub struct TestBufferManager {
buffers: RwLock<HashMap<BufferId, Arc<RwLock<Buffer>>>>,
}
impl TestBufferManager {
#[must_use]
pub fn new() -> Self {
Self {
buffers: RwLock::new(HashMap::new()),
}
}
}
impl Default for TestBufferManager {
fn default() -> Self {
Self::new()
}
}
#[cfg_attr(coverage_nightly, coverage(off))]
impl BufferManager for TestBufferManager {
fn get(&self, id: BufferId) -> Option<Arc<RwLock<Buffer>>> {
self.buffers.read().get(&id).cloned()
}
fn create(&self) -> BufferId {
let id = BufferId::new();
let buffer = Arc::new(RwLock::new(Buffer::new()));
self.buffers.write().insert(id, buffer);
id
}
fn register(&self, buffer: Buffer) -> BufferId {
let id = BufferId::new();
let buffer = Arc::new(RwLock::new(buffer));
self.buffers.write().insert(id, buffer);
id
}
fn unregister(&self, id: BufferId) -> Result<Buffer, BufferError> {
self.buffers
.write()
.remove(&id)
.map_or(Err(BufferError::NotFound(id)), |arc_buffer| {
Arc::try_unwrap(arc_buffer)
.map_or_else(|arc| Ok(arc.read().clone()), |rwlock| Ok(rwlock.into_inner()))
})
}
fn list(&self) -> Vec<BufferId> {
self.buffers.read().keys().copied().collect()
}
fn count(&self) -> usize {
self.buffers.read().len()
}
}
#[must_use]
pub fn create_test_context() -> KernelContext {
KernelContext::new(
Arc::new(EventBus::new()),
Arc::new(TestBufferManager::new()),
Arc::new(MotionEngine),
Arc::new(TextObjectEngine),
Arc::new(RwLock::new(MarkBank::new())),
Arc::new(OptionRegistry::new()),
Arc::new(ServiceRegistry::new()),
)
}
#[must_use]
pub const fn test_mode() -> ModeId {
ModeId::new(ModuleId::new("test"), "normal")
}
#[must_use]
pub fn setup_buffer(ctx: &KernelContext, content: &str) -> BufferId {
let buffer = Buffer::from_string(content);
ctx.buffers.register(buffer)
}