Entropyk/crates/cli/tests/config_parsing.rs

171 lines
4.5 KiB
Rust

//! Tests for configuration parsing.
use entropyk_cli::config::{ComponentConfig, ScenarioConfig, SolverConfig};
use entropyk_cli::error::CliError;
use std::path::PathBuf;
use tempfile::tempdir;
#[test]
fn test_parse_minimal_config() {
let json = r#"{ "fluid": "R134a" }"#;
let config = ScenarioConfig::from_json(json).unwrap();
assert_eq!(config.fluid, "R134a");
assert!(config.circuits.is_empty());
assert_eq!(config.solver.strategy, "fallback");
}
#[test]
fn test_parse_full_config() {
let json = r#"
{
"fluid": "R410A",
"circuits": [{
"id": 0,
"components": [
{ "type": "Condenser", "name": "cond1", "ua": 5000.0 },
{ "type": "Evaporator", "name": "evap1", "ua": 4000.0 }
],
"edges": [
{ "from": "cond1:outlet", "to": "evap1:inlet" }
]
}],
"solver": {
"strategy": "newton",
"max_iterations": 50,
"tolerance": 1e-8
}
}"#;
let config = ScenarioConfig::from_json(json).unwrap();
assert_eq!(config.fluid, "R410A");
assert_eq!(config.circuits.len(), 1);
assert_eq!(config.circuits[0].components.len(), 2);
assert_eq!(config.solver.strategy, "newton");
assert_eq!(config.solver.max_iterations, 50);
}
#[test]
fn test_validate_missing_fluid() {
let json = r#"{ "fluid": "" }"#;
let result = ScenarioConfig::from_json(json);
assert!(result.is_err());
if let Err(CliError::Config(msg)) = result {
assert!(msg.contains("fluid"));
}
}
#[test]
fn test_validate_empty_circuit() {
let json = r#"
{
"fluid": "R134a",
"circuits": [{
"id": 0,
"components": []
}]
}"#;
let result = ScenarioConfig::from_json(json);
assert!(result.is_err());
}
#[test]
fn test_validate_invalid_edge_format() {
let json = r#"
{
"fluid": "R134a",
"circuits": [{
"id": 0,
"components": [{ "type": "Condenser", "name": "cond1", "ua": 5000.0 }],
"edges": [{ "from": "invalid", "to": "also_invalid" }]
}]
}"#;
let result = ScenarioConfig::from_json(json);
assert!(result.is_err());
if let Err(CliError::Config(msg)) = result {
assert!(msg.contains("edge format"));
}
}
#[test]
fn test_load_config_from_file() {
let dir = tempdir().unwrap();
let config_path = dir.path().join("test.json");
let json = r#"{ "fluid": "R744" }"#;
std::fs::write(&config_path, json).unwrap();
let config = ScenarioConfig::from_file(&config_path).unwrap();
assert_eq!(config.fluid, "R744");
}
#[test]
fn test_load_config_file_not_found() {
let result = ScenarioConfig::from_file(PathBuf::from("/nonexistent/path.json").as_path());
assert!(result.is_err());
if let Err(CliError::ConfigNotFound(path)) = result {
assert!(path.to_str().unwrap().contains("nonexistent"));
}
}
#[test]
fn test_solver_config_defaults() {
let config = SolverConfig::default();
assert_eq!(config.strategy, "fallback");
assert_eq!(config.max_iterations, 100);
assert_eq!(config.tolerance, 1e-6);
assert_eq!(config.timeout_ms, 0);
assert!(!config.verbose);
}
#[test]
fn test_component_config_params() {
let json = r#"
{
"type": "Evaporator",
"name": "evap1",
"ua": 4000.0,
"t_sat_k": 278.15,
"superheat_k": 5.0
}"#;
let component: ComponentConfig = serde_json::from_str(json).unwrap();
assert_eq!(component.component_type, "Evaporator");
assert_eq!(component.name, "evap1");
assert_eq!(
component.params.get("ua").unwrap().as_f64().unwrap(),
4000.0
);
assert_eq!(
component.params.get("t_sat_k").unwrap().as_f64().unwrap(),
278.15
);
assert_eq!(
component
.params
.get("superheat_k")
.unwrap()
.as_f64()
.unwrap(),
5.0
);
}
#[test]
fn test_validate_edge_unknown_component() {
let json = r#"
{
"fluid": "R134a",
"circuits": [{
"id": 0,
"components": [{ "type": "Condenser", "name": "cond1", "ua": 5000.0 }],
"edges": [{ "from": "cond1:outlet", "to": "nonexistent:inlet" }]
}]
}"#;
let result = ScenarioConfig::from_json(json);
assert!(result.is_err());
if let Err(CliError::Config(msg)) = result {
assert!(msg.contains("unknown component"));
assert!(msg.contains("nonexistent"));
}
}