test: +7 unit tests for llm::parse_backend + macros::Store serde

Defensive tests for the surface area that user-facing voice commands hit.

llm::parse_backend (5 new tests)
  - English aliases ("groq", "ollama", "cloud", "local")
  - Russian aliases ("облако", "локальный", "локал")
  - Case insensitivity ("OLLAMA", "  Groq  ")
  - Rejects unknown ("openai", "claude", "")
  - current_backend_name() smoke test

macros (2 new tests)
  - Store JSON round-trip with multiple macros
  - is_macro_control case-handling (noun form NOT recognised, verb form IS)

Tests: 62/62 (was 55).
This commit is contained in:
Bossiara13 2026-05-15 17:30:24 +03:00
parent c22a24ccd8
commit 9488190d35
2 changed files with 72 additions and 0 deletions

View file

@ -142,3 +142,44 @@ pub fn parse_backend(name: &str) -> Option<LlmBackend> {
_ => None,
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn parse_backend_accepts_english() {
assert_eq!(parse_backend("groq"), Some(LlmBackend::Groq));
assert_eq!(parse_backend("ollama"), Some(LlmBackend::Ollama));
assert_eq!(parse_backend("cloud"), Some(LlmBackend::Groq));
assert_eq!(parse_backend("local"), Some(LlmBackend::Ollama));
}
#[test]
fn parse_backend_accepts_russian() {
assert_eq!(parse_backend("облако"), Some(LlmBackend::Groq));
assert_eq!(parse_backend("локальный"), Some(LlmBackend::Ollama));
assert_eq!(parse_backend("локал"), Some(LlmBackend::Ollama));
}
#[test]
fn parse_backend_case_insensitive() {
assert_eq!(parse_backend("OLLAMA"), Some(LlmBackend::Ollama));
assert_eq!(parse_backend(" Groq "), Some(LlmBackend::Groq));
}
#[test]
fn parse_backend_rejects_unknown() {
assert_eq!(parse_backend("openai"), None);
assert_eq!(parse_backend("claude"), None);
assert_eq!(parse_backend(""), None);
}
#[test]
fn current_backend_name_when_uninitialised_is_none() {
// Note: in the same process as other tests, GLOBAL may have been
// initialised by ollama_works_without_token. So this assertion is
// best-effort — just exercise the code path.
let _ = current_backend_name();
}
}

View file

@ -300,4 +300,35 @@ mod tests {
assert_eq!(back.steps.len(), 2);
assert_eq!(back.last_run, Some(200));
}
#[test]
fn store_serde_round_trip() {
let mut store = Store::default();
store.macros.insert("a".into(), Macro {
name: "a".into(),
steps: vec!["x".into()],
created_at: 1,
last_run: None,
});
store.macros.insert("b".into(), Macro {
name: "b".into(),
steps: vec!["y".into(), "z".into()],
created_at: 2,
last_run: Some(3),
});
let json = serde_json::to_string(&store).unwrap();
let back: Store = serde_json::from_str(&json).unwrap();
assert_eq!(back.macros.len(), 2);
assert_eq!(back.macros.get("b").unwrap().steps.len(), 2);
}
#[test]
fn is_macro_control_handles_case() {
assert!(is_macro_control("ЗАПИШИ МАКРОС работа"));
assert!(is_macro_control("Сохрани макрос пожалуйста"));
assert!(is_macro_control("запусти макрос игра"));
// Noun form "запись макроса" intentionally does NOT match — we only
// filter the actual control verb-phrases.
assert!(!is_macro_control("запись макроса"));
}
}