use hypen_engine::lifecycle::{Module, ModuleInstance};
use serde_json::json;
#[test]
fn test_module_new() {
let module = Module::new("UserProfile");
assert_eq!(module.name, "UserProfile");
assert_eq!(module.actions.len(), 0);
assert_eq!(module.state_keys.len(), 0);
assert!(!module.persist);
assert_eq!(module.version, None);
}
#[test]
fn test_module_builder_pattern() {
let module = Module::new("Counter")
.with_actions(vec!["increment".to_string(), "decrement".to_string()])
.with_state_keys(vec!["count".to_string()])
.with_persist(true)
.with_version(1);
assert_eq!(module.name, "Counter");
assert_eq!(module.actions, vec!["increment", "decrement"]);
assert_eq!(module.state_keys, vec!["count"]);
assert!(module.persist);
assert_eq!(module.version, Some(1));
}
#[test]
fn test_module_instance_new() {
let module = Module::new("User");
let state = json!({
"name": "Alice",
"email": "alice@example.com"
});
let instance = ModuleInstance::new(module, state.clone());
assert_eq!(instance.module.name, "User");
assert_eq!(instance.get_state(), &state);
assert!(!instance.mounted);
}
#[test]
fn test_module_instance_with_empty_state() {
let module = Module::new("Empty");
let state = json!({});
let instance = ModuleInstance::new(module, state);
assert_eq!(instance.get_state(), &json!({}));
assert!(!instance.mounted);
}
#[test]
fn test_update_state_simple_merge() {
let module = Module::new("User");
let mut instance = ModuleInstance::new(
module,
json!({
"name": "Alice",
"age": 30
}),
);
instance.update_state(json!({
"age": 31
}));
assert_eq!(instance.get_state()["name"], "Alice");
assert_eq!(instance.get_state()["age"], 31);
}
#[test]
fn test_update_state_nested_merge() {
let module = Module::new("User");
let mut instance = ModuleInstance::new(
module,
json!({
"user": {
"profile": {
"name": "Alice",
"bio": "Developer"
},
"email": "alice@example.com"
}
}),
);
instance.update_state(json!({
"user": {
"profile": {
"bio": "Senior Developer"
}
}
}));
assert_eq!(instance.get_state()["user"]["profile"]["name"], "Alice");
assert_eq!(
instance.get_state()["user"]["profile"]["bio"],
"Senior Developer"
);
assert_eq!(instance.get_state()["user"]["email"], "alice@example.com");
}
#[test]
fn test_update_state_add_new_keys() {
let module = Module::new("User");
let mut instance = ModuleInstance::new(
module,
json!({
"name": "Alice"
}),
);
instance.update_state(json!({
"age": 30,
"email": "alice@example.com"
}));
assert_eq!(instance.get_state()["name"], "Alice");
assert_eq!(instance.get_state()["age"], 30);
assert_eq!(instance.get_state()["email"], "alice@example.com");
}
#[test]
fn test_update_state_replace_non_object_value() {
let module = Module::new("Counter");
let mut instance = ModuleInstance::new(
module,
json!({
"count": 10
}),
);
instance.update_state(json!({
"count": 15
}));
assert_eq!(instance.get_state()["count"], 15);
}
#[test]
fn test_update_state_replace_object_with_primitive() {
let module = Module::new("Data");
let mut instance = ModuleInstance::new(
module,
json!({
"user": {
"name": "Alice",
"age": 30
}
}),
);
instance.update_state(json!({
"user": "Alice"
}));
assert_eq!(instance.get_state()["user"], "Alice");
}
#[test]
fn test_update_state_deep_nesting() {
let module = Module::new("Deep");
let mut instance = ModuleInstance::new(
module,
json!({
"a": {
"b": {
"c": {
"d": {
"value": 1
}
}
}
}
}),
);
instance.update_state(json!({
"a": {
"b": {
"c": {
"d": {
"value": 2
}
}
}
}
}));
assert_eq!(instance.get_state()["a"]["b"]["c"]["d"]["value"], 2);
}
#[test]
fn test_mount_changes_mounted_flag() {
let module = Module::new("User");
let mut instance = ModuleInstance::new(module, json!({}));
assert!(!instance.mounted);
instance.mount();
assert!(instance.mounted);
}
#[test]
fn test_unmount_changes_mounted_flag() {
let module = Module::new("User");
let mut instance = ModuleInstance::new(module, json!({}));
instance.mount();
assert!(instance.mounted);
instance.unmount();
assert!(!instance.mounted);
}
#[test]
fn test_mount_twice_is_idempotent() {
let module = Module::new("User");
let mut instance = ModuleInstance::new(module, json!({}));
instance.mount();
instance.mount();
assert!(instance.mounted);
}
#[test]
fn test_unmount_twice_is_idempotent() {
let module = Module::new("User");
let mut instance = ModuleInstance::new(module, json!({}));
instance.mount();
instance.unmount();
instance.unmount();
assert!(!instance.mounted);
}
#[test]
fn test_get_state_returns_current_state() {
let module = Module::new("User");
let initial_state = json!({
"name": "Alice",
"age": 30
});
let instance = ModuleInstance::new(module, initial_state.clone());
let state = instance.get_state();
assert_eq!(state, &initial_state);
}
#[test]
fn test_module_serialization() {
let module = Module::new("Counter")
.with_actions(vec!["increment".to_string()])
.with_state_keys(vec!["count".to_string()])
.with_persist(true)
.with_version(2);
let json = serde_json::to_value(&module).unwrap();
assert_eq!(json["name"], "Counter");
assert_eq!(json["actions"], json!(["increment"]));
assert_eq!(json["state_keys"], json!(["count"]));
assert_eq!(json["persist"], true);
assert_eq!(json["version"], 2);
}
#[test]
fn test_module_deserialization() {
let json = json!({
"name": "UserProfile",
"actions": ["updateName", "updateEmail"],
"state_keys": ["user"],
"persist": false,
"version": null
});
let module: Module = serde_json::from_value(json).unwrap();
assert_eq!(module.name, "UserProfile");
assert_eq!(module.actions, vec!["updateName", "updateEmail"]);
assert_eq!(module.state_keys, vec!["user"]);
assert!(!module.persist);
assert_eq!(module.version, None);
}
#[test]
fn test_update_state_preserves_reference() {
let module = Module::new("User");
let mut instance = ModuleInstance::new(
module,
json!({
"count": 0
}),
);
instance.update_state(json!({"count": 1}));
instance.update_state(json!({"count": 2}));
instance.update_state(json!({"count": 3}));
assert_eq!(instance.get_state()["count"], 3);
}