169 lines
7.7 KiB
EmacsLisp
169 lines
7.7 KiB
EmacsLisp
// tests/suite/test_state.el — comprehensive tests for runtime/state.el
|
|
//
|
|
// Covers state_set, state_get, state_del, state_keys, state_has, state_get_or.
|
|
// Uses unique key prefixes to avoid interference with the test framework's
|
|
// own state keys (which use _test_ prefix).
|
|
|
|
// ── state_set / state_get roundtrip ───────────────────────────────────────────
|
|
|
|
fn test_state_set_get_basic(_: String) -> String {
|
|
state_set("suite_key1", "hello")
|
|
assert_eq(state_get("suite_key1"), "hello", "get back what was set")
|
|
|
|
state_set("suite_key2", "world")
|
|
assert_eq(state_get("suite_key2"), "world", "second key independent")
|
|
|
|
state_set("suite_num", "42")
|
|
assert_eq(state_get("suite_num"), "42", "numeric string value")
|
|
|
|
state_set("suite_empty", "")
|
|
// empty value and missing key both return "" — that's by design per the docs
|
|
let v: String = state_get("suite_empty")
|
|
assert_true(str_eq(v, "") || str_eq(v, ""), "empty value stored or treated as absent")
|
|
|
|
state_set("suite_long", str_repeat("a", 100))
|
|
assert_int_eq(str_len(state_get("suite_long")), 100, "long value preserved")
|
|
return ""
|
|
}
|
|
|
|
fn test_state_overwrite(_: String) -> String {
|
|
state_set("suite_over", "first")
|
|
assert_eq(state_get("suite_over"), "first", "initial value")
|
|
state_set("suite_over", "second")
|
|
assert_eq(state_get("suite_over"), "second", "value overwritten")
|
|
state_set("suite_over", "third")
|
|
assert_eq(state_get("suite_over"), "third", "value overwritten again")
|
|
return ""
|
|
}
|
|
|
|
fn test_state_multiple_keys(_: String) -> String {
|
|
state_set("suite_mk_a", "alpha")
|
|
state_set("suite_mk_b", "beta")
|
|
state_set("suite_mk_c", "gamma")
|
|
assert_eq(state_get("suite_mk_a"), "alpha", "key a is alpha")
|
|
assert_eq(state_get("suite_mk_b"), "beta", "key b is beta")
|
|
assert_eq(state_get("suite_mk_c"), "gamma", "key c is gamma")
|
|
// Mutate one, others unchanged
|
|
state_set("suite_mk_b", "BETA")
|
|
assert_eq(state_get("suite_mk_a"), "alpha", "a unchanged after b mutated")
|
|
assert_eq(state_get("suite_mk_b"), "BETA", "b updated")
|
|
assert_eq(state_get("suite_mk_c"), "gamma", "c unchanged after b mutated")
|
|
return ""
|
|
}
|
|
|
|
// ── missing keys ──────────────────────────────────────────────────────────────
|
|
|
|
fn test_state_missing_key(_: String) -> String {
|
|
assert_eq(state_get("suite_definitely_not_set_xyz_123"), "", "missing key returns empty string")
|
|
assert_eq(state_get("suite_another_missing_key_abc"), "", "another missing key returns empty string")
|
|
return ""
|
|
}
|
|
|
|
// ── state_del ─────────────────────────────────────────────────────────────────
|
|
|
|
fn test_state_del_basic(_: String) -> String {
|
|
state_set("suite_del1", "value_to_delete")
|
|
assert_eq(state_get("suite_del1"), "value_to_delete", "key present before delete")
|
|
state_del("suite_del1")
|
|
assert_eq(state_get("suite_del1"), "", "key absent after delete")
|
|
|
|
// Delete a non-existent key should not error
|
|
state_del("suite_never_existed_key_xyz")
|
|
assert_eq(state_get("suite_never_existed_key_xyz"), "", "delete non-existent is no-op")
|
|
return ""
|
|
}
|
|
|
|
fn test_state_del_and_reset(_: String) -> String {
|
|
state_set("suite_reuse", "original")
|
|
assert_eq(state_get("suite_reuse"), "original", "original value")
|
|
state_del("suite_reuse")
|
|
assert_eq(state_get("suite_reuse"), "", "deleted")
|
|
state_set("suite_reuse", "new_value")
|
|
assert_eq(state_get("suite_reuse"), "new_value", "key reused after delete")
|
|
return ""
|
|
}
|
|
|
|
// ── state_has ─────────────────────────────────────────────────────────────────
|
|
|
|
fn test_state_has_basic(_: String) -> String {
|
|
state_set("suite_has1", "something")
|
|
assert_true(state_has("suite_has1"), "key with value is present")
|
|
assert_false(state_has("suite_definitely_absent_xyz_999"), "absent key returns false")
|
|
|
|
state_del("suite_has1")
|
|
assert_false(state_has("suite_has1"), "deleted key is not present")
|
|
return ""
|
|
}
|
|
|
|
// ── state_get_or ──────────────────────────────────────────────────────────────
|
|
|
|
fn test_state_get_or_basic(_: String) -> String {
|
|
state_set("suite_gor1", "present")
|
|
assert_eq(state_get_or("suite_gor1", "default"), "present", "returns value when key exists")
|
|
assert_eq(state_get_or("suite_gor_missing_xyz", "fallback"), "fallback", "returns default when key missing")
|
|
assert_eq(state_get_or("suite_gor_missing_xyz", ""), "", "returns empty default when key missing")
|
|
return ""
|
|
}
|
|
|
|
// ── state persists across function calls ──────────────────────────────────────
|
|
|
|
fn _suite_state_helper_write() {
|
|
state_set("suite_persist_test", "written_by_helper")
|
|
}
|
|
|
|
fn _suite_state_helper_increment() {
|
|
let n: Int = str_to_int(state_get("suite_counter"))
|
|
state_set("suite_counter", int_to_str(n + 1))
|
|
}
|
|
|
|
fn test_state_cross_function(_: String) -> String {
|
|
_suite_state_helper_write()
|
|
assert_eq(state_get("suite_persist_test"), "written_by_helper", "value written by helper function is readable")
|
|
|
|
state_set("suite_counter", "0")
|
|
_suite_state_helper_increment()
|
|
assert_eq(state_get("suite_counter"), "1", "counter after 1 increment")
|
|
_suite_state_helper_increment()
|
|
assert_eq(state_get("suite_counter"), "2", "counter after 2 increments")
|
|
_suite_state_helper_increment()
|
|
assert_eq(state_get("suite_counter"), "3", "counter after 3 increments")
|
|
return ""
|
|
}
|
|
|
|
// ── state_keys ────────────────────────────────────────────────────────────────
|
|
|
|
fn test_state_keys_basic(_: String) -> String {
|
|
state_set("suite_sk_x", "1")
|
|
state_set("suite_sk_y", "2")
|
|
let keys: String = state_keys()
|
|
// keys is a JSON array of all state keys — must contain our test keys
|
|
assert_true(str_contains(keys, "suite_sk_x"), "keys includes suite_sk_x")
|
|
assert_true(str_contains(keys, "suite_sk_y"), "keys includes suite_sk_y")
|
|
assert_true(str_starts_with(keys, "["), "keys is a JSON array")
|
|
assert_true(str_ends_with(keys, "]"), "keys is a JSON array")
|
|
assert_true(json_array_len(keys) > 0, "keys array is non-empty")
|
|
return ""
|
|
}
|
|
|
|
// ── value type storage ────────────────────────────────────────────────────────
|
|
|
|
fn test_state_value_types(_: String) -> String {
|
|
// JSON object as value
|
|
let json_val: String = "{\"name\":\"alice\",\"age\":30}"
|
|
state_set("suite_json_val", json_val)
|
|
let retrieved: String = state_get("suite_json_val")
|
|
assert_eq(json_get(retrieved, "name"), "alice", "JSON object stored and retrieved")
|
|
|
|
// JSON array as value
|
|
let arr_val: String = "[1,2,3]"
|
|
state_set("suite_arr_val", arr_val)
|
|
let retrieved_arr: String = state_get("suite_arr_val")
|
|
assert_int_eq(json_array_len(retrieved_arr), 3, "JSON array stored and retrieved")
|
|
|
|
// Large value
|
|
let big: String = str_repeat("x", 500)
|
|
state_set("suite_big_val", big)
|
|
assert_int_eq(str_len(state_get("suite_big_val")), 500, "large value stored correctly")
|
|
return ""
|
|
}
|