Skip to main content

Module testing

Module testing 

Source
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§

AsyncChildTestHarness
Test harness for asynchronous AsyncRunnableChild implementations.
ChildTestHarness
Test harness for Child trait implementations.
ComponentTestHarness
Test harness for Component implementations.
RequestRecord
Record of a request sent to a component.
RunRecord
Record of a run() call on a child.
SignalRecord
Record of a signal sent to a component.
SyncChildTestHarness
Test harness for synchronous RunnableChild implementations.
TimeoutError
Error returned when an async operation times out.

Enums§

RequestResult
Result of a request.
RunResult
Result of a run() call.