#[cfg(any(debug_assertions, test))]
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
enum Termination {
Error,
Panic,
}
pub(super) fn matrix_enabled() -> bool {
cfg!(debug_assertions)
&& std::env::var_os("RHO_TUI_TEST_MODE").as_deref() == Some(std::ffi::OsStr::new("matrix"))
}
pub(super) fn display_version() -> String {
resolve_display_version(
matrix_enabled(),
std::env::var("RHO_TUI_DISPLAY_VERSION").ok().as_deref(),
env!("CARGO_PKG_VERSION"),
)
}
fn resolve_display_version(matrix: bool, override_version: Option<&str>, package: &str) -> String {
if matrix {
if let Some(value) = override_version
.map(str::trim)
.filter(|value| !value.is_empty())
{
return value.to_owned();
}
}
package.to_owned()
}
#[cfg(debug_assertions)]
pub(super) fn seed_matrix_model_cache() {
if matrix_enabled() {
use rho_providers::model::provider_models::{
replace_cached_provider_models_for_tests, ProviderModel,
};
let models = [ProviderModel {
provider: "openai".into(),
model: "gpt-5.5".into(),
display_name: "gpt-5.5".into(),
context_window: Some(400_000),
max_output_tokens: Some(128_000),
reasoning_capabilities: Default::default(),
}];
let _ = replace_cached_provider_models_for_tests("openai", &models);
}
}
pub(super) fn after_terminal_init() -> anyhow::Result<()> {
#[cfg(debug_assertions)]
{
let herdr = std::env::var_os("HERDR_ENV").is_some();
let matrix = matrix_enabled();
if !herdr && !matrix {
return Ok(());
}
let Some(value) = std::env::var_os("RHO_TUI_TEST_TERMINATION") else {
return Ok(());
};
let value = value
.into_string()
.map_err(|_| anyhow::anyhow!("RHO_TUI_TEST_TERMINATION must be valid UTF-8"))?;
match parse_termination(&value)? {
Termination::Error => anyhow::bail!("deterministic injected TUI application error"),
Termination::Panic => panic!("deterministic injected TUI panic"),
}
}
#[cfg(not(debug_assertions))]
Ok(())
}
#[cfg(any(debug_assertions, test))]
fn parse_termination(value: &str) -> anyhow::Result<Termination> {
match value {
"error" => Ok(Termination::Error),
"panic" => Ok(Termination::Panic),
_ => anyhow::bail!("unknown RHO_TUI_TEST_TERMINATION value '{value}'"),
}
}
#[cfg(test)]
mod tests {
use super::*;
use pretty_assertions::assert_eq;
#[test]
fn parses_only_explicit_error_and_panic_modes() {
assert_eq!(parse_termination("error").unwrap(), Termination::Error);
assert_eq!(parse_termination("panic").unwrap(), Termination::Panic);
assert_eq!(
parse_termination("other").unwrap_err().to_string(),
"unknown RHO_TUI_TEST_TERMINATION value 'other'"
);
}
#[test]
fn display_version_override_only_applies_in_matrix_mode() {
let cases = [
(false, None, "1.2.3", "1.2.3"),
(false, Some("9.9.9"), "1.2.3", "1.2.3"),
(true, None, "1.2.3", "1.2.3"),
(true, Some(""), "1.2.3", "1.2.3"),
(true, Some(" "), "1.2.3", "1.2.3"),
(true, Some("1.0.0"), "1.2.3", "1.0.0"),
(true, Some(" 1.0.0 "), "1.2.3", "1.0.0"),
];
for (matrix, override_version, package, expected) in cases {
assert_eq!(
resolve_display_version(matrix, override_version, package),
expected,
"matrix={matrix:?} override={override_version:?}"
);
}
}
}