use crate::binding::ResolvedBindings;
use crate::event::EventLog;
use crate::runtime::TaskExecutor;
use crate::store::DataStore;
use serde_json::{json, Value};
pub fn mock_executor() -> TaskExecutor {
let event_log = EventLog::new();
TaskExecutor::new("mock", None, None, event_log)
}
pub fn mock_executor_with_events() -> (TaskExecutor, EventLog) {
let event_log = EventLog::new();
let executor = TaskExecutor::new("mock", None, None, event_log.clone());
(executor, event_log)
}
#[cfg(test)]
pub fn mock_executor_with_mcp(servers: &[&str]) -> TaskExecutor {
let executor = mock_executor();
for server in servers {
executor.inject_mock_mcp_client(server);
}
executor
}
#[cfg(test)]
pub fn mock_executor_with_mcp_and_events(servers: &[&str]) -> (TaskExecutor, EventLog) {
let event_log = EventLog::new();
let executor = TaskExecutor::new("mock", None, None, event_log.clone());
for server in servers {
executor.inject_mock_mcp_client(server);
}
(executor, event_log)
}
pub fn test_context() -> (ResolvedBindings, DataStore) {
(ResolvedBindings::new(), DataStore::new())
}
pub fn bindings_with(entries: &[(&str, Value)]) -> ResolvedBindings {
let mut bindings = ResolvedBindings::new();
for &(key, ref value) in entries {
bindings.set(key, value.clone());
}
bindings
}
pub fn test_context_with(entries: &[(&str, Value)]) -> (ResolvedBindings, DataStore) {
(bindings_with(entries), DataStore::new())
}
pub fn weather_data() -> Value {
json!({
"temp": 25,
"humidity": 60,
"summary": "Sunny"
})
}
pub fn entity_context() -> Value {
json!({
"entity": "qr-code",
"locale": "fr-FR",
"title": "QR Code"
})
}
pub fn user_profile() -> Value {
json!({
"id": "user-123",
"name": "Test User",
"email": "test@example.com",
"role": "admin"
})
}
pub fn api_response() -> Value {
json!({
"status": "ok",
"data": {
"items": [
{ "id": 1, "name": "Item 1" },
{ "id": 2, "name": "Item 2" }
],
"total": 2
},
"timestamp": "2026-02-21T10:00:00Z"
})
}
pub fn mcp_tool_result() -> Value {
json!({
"entity": "qr-code",
"locale": "fr-FR",
"content": {
"title": "Code QR",
"description": "Un code-barres bidimensionnel"
}
})
}
pub fn empty_result() -> Value {
json!({})
}
pub fn nested_data() -> Value {
json!({
"level1": {
"level2": {
"level3": {
"value": "deep-value"
}
},
"array": [
{ "id": "a" },
{ "id": "b" },
{ "id": "c" }
]
}
})
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_mock_executor_creates_valid_executor() {
let executor = mock_executor();
let _cloned = executor.clone();
}
#[test]
fn test_mock_executor_with_events_returns_shared_log() {
let (executor, event_log) = mock_executor_with_events();
let _exec_clone = executor.clone();
let _log_clone = event_log.clone();
assert!(event_log.events().is_empty());
}
#[test]
fn test_mock_executor_with_mcp_injects_clients() {
let executor = mock_executor_with_mcp(&["novanet", "perplexity"]);
let _cloned = executor.clone();
}
#[test]
fn test_mock_executor_with_mcp_and_events() {
let (executor, event_log) = mock_executor_with_mcp_and_events(&["novanet"]);
let _exec_clone = executor.clone();
assert!(event_log.events().is_empty());
}
#[test]
fn test_test_context_returns_empty_bindings_and_store() {
let (bindings, store) = test_context();
assert!(bindings.get("nonexistent").is_none());
assert!(store.get("nonexistent").is_none());
}
#[test]
fn test_bindings_with_populates_entries() {
let bindings = bindings_with(&[("name", json!("Alice")), ("age", json!(30))]);
assert_eq!(bindings.get("name").unwrap(), &json!("Alice"));
assert_eq!(bindings.get("age").unwrap(), &json!(30));
}
#[test]
fn test_bindings_with_empty_returns_empty() {
let bindings = bindings_with(&[]);
assert!(bindings.get("anything").is_none());
}
#[test]
fn test_test_context_with_populates_bindings() {
let (bindings, store) = test_context_with(&[("key", json!("value"))]);
assert_eq!(bindings.get("key").unwrap(), &json!("value"));
assert!(store.get("nonexistent").is_none());
}
#[test]
fn test_weather_data_has_expected_fields() {
let data = weather_data();
assert_eq!(data["temp"], 25);
assert_eq!(data["humidity"], 60);
assert_eq!(data["summary"], "Sunny");
}
#[test]
fn test_entity_context_has_expected_fields() {
let ctx = entity_context();
assert_eq!(ctx["entity"], "qr-code");
assert_eq!(ctx["locale"], "fr-FR");
assert_eq!(ctx["title"], "QR Code");
}
#[test]
fn test_user_profile_has_expected_fields() {
let user = user_profile();
assert_eq!(user["id"], "user-123");
assert_eq!(user["name"], "Test User");
assert_eq!(user["email"], "test@example.com");
assert_eq!(user["role"], "admin");
}
#[test]
fn test_api_response_has_expected_structure() {
let resp = api_response();
assert_eq!(resp["status"], "ok");
assert!(resp["data"]["items"].is_array());
assert_eq!(resp["data"]["total"], 2);
}
#[test]
fn test_mcp_tool_result_has_expected_fields() {
let result = mcp_tool_result();
assert_eq!(result["entity"], "qr-code");
assert_eq!(result["locale"], "fr-FR");
assert!(result["content"].is_object());
}
#[test]
fn test_empty_result_is_empty_object() {
let result = empty_result();
assert!(result.is_object());
assert!(result.as_object().unwrap().is_empty());
}
#[test]
fn test_nested_data_supports_deep_access() {
let data = nested_data();
assert_eq!(data["level1"]["level2"]["level3"]["value"], "deep-value");
assert!(data["level1"]["array"].is_array());
assert_eq!(data["level1"]["array"][0]["id"], "a");
}
}