Expand description
Testing harnesses for Component and Child implementations.
Provides test harnesses for testing Component and Child implementations without requiring the full OrcsEngine infrastructure.
§Features
- Engine-independent component/child testing
- Request/Signal/Lifecycle processing
- Event logging for snapshot testing
- Deterministic synchronous execution
- Async child support with timeout
- Automatic time measurement
§Component Testing Example
use orcs_component::testing::{ComponentTestHarness, RequestRecord};
use orcs_component::{Component, ComponentError, Status, EventCategory};
use orcs_event::{Request, Signal, SignalResponse};
use orcs_types::ComponentId;
use serde_json::{json, Value};
struct EchoComponent {
id: ComponentId,
status: Status,
}
impl Component for EchoComponent {
fn id(&self) -> &ComponentId { &self.id }
fn status(&self) -> Status { self.status }
fn on_request(&mut self, req: &Request) -> Result<Value, ComponentError> {
Ok(req.payload.clone())
}
fn on_signal(&mut self, signal: &Signal) -> SignalResponse {
if signal.is_veto() {
self.abort();
SignalResponse::Abort
} else {
SignalResponse::Handled
}
}
fn abort(&mut self) { self.status = Status::Aborted; }
}
let echo = EchoComponent {
id: ComponentId::builtin("echo"),
status: Status::Idle,
};
let mut harness = ComponentTestHarness::new(echo);
// Test request handling
let result = harness.request(EventCategory::Echo, "echo", json!({"msg": "hello"}));
assert!(result.is_ok());
// Test signal handling
let response = harness.veto();
assert_eq!(response, SignalResponse::Abort);§Child Testing Example
use orcs_component::testing::SyncChildTestHarness;
use orcs_component::{Child, RunnableChild, ChildResult, Identifiable, SignalReceiver, Statusable, Status};
use orcs_event::{Signal, SignalResponse};
use serde_json::{json, Value};
struct Worker {
id: String,
status: Status,
}
impl Identifiable for Worker {
fn id(&self) -> &str { &self.id }
}
impl SignalReceiver for Worker {
fn on_signal(&mut self, signal: &Signal) -> SignalResponse {
if signal.is_veto() {
self.abort();
SignalResponse::Abort
} else {
SignalResponse::Handled
}
}
fn abort(&mut self) { self.status = Status::Aborted; }
}
impl Statusable for Worker {
fn status(&self) -> Status { self.status }
}
impl Child for Worker {}
impl RunnableChild for Worker {
fn run(&mut self, input: Value) -> ChildResult {
self.status = Status::Running;
let result = json!({"processed": input});
self.status = Status::Idle;
ChildResult::Ok(result)
}
}
let worker = Worker { id: "worker-1".into(), status: Status::Idle };
let mut harness = SyncChildTestHarness::new(worker);
// Test run
let result = harness.run(json!({"task": "test"}));
assert!(result.is_ok());
// Test signal handling
let response = harness.veto();
assert_eq!(response, SignalResponse::Abort);
// Check logs
assert_eq!(harness.run_log().len(), 1);
assert!(harness.run_log()[0].elapsed_ms.is_some());Structs§
- Async
Child Test Harness - Test harness for asynchronous AsyncRunnableChild implementations.
- Child
Test Harness - Test harness for Child trait implementations.
- Component
Test Harness - Test harness for Component implementations.
- Request
Record - Record of a request sent to a component.
- RunRecord
- Record of a run() call on a child.
- Signal
Record - Record of a signal sent to a component.
- Sync
Child Test Harness - Test harness for synchronous RunnableChild implementations.
- Timeout
Error - Error returned when an async operation times out.
Enums§
- Request
Result - Result of a request.
- RunResult
- Result of a run() call.