use std::path::PathBuf;
use calcli::config::Config;
use calcli::domain::evaluator::MevalEvaluator;
use calcli::domain::history::{History, HistoryEntry};
use calcli::domain::quantity::Quantity;
use calcli::domain::variables::VariableStore;
use calcli::services::CalcService;
use calcli::storage::{StateRepository, TomlStateRepository, UiState};
use calcli::tui::App;
fn temp_path() -> PathBuf {
let mut path = std::env::temp_dir();
let unique = format!(
"calcli-it-{}-{:?}.toml",
std::process::id(),
std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.unwrap()
.as_nanos()
);
path.push(unique);
path
}
#[test]
fn a_session_survives_save_and_reload() {
let config = Config::default();
let mut service = CalcService::new(
Box::new(MevalEvaluator::new()),
config.format_settings(),
History::new(config.max_history),
VariableStore::new(),
);
service.submit("6 * 7");
service.submit("=answer");
service.submit("answer + 1");
service.toggle_angle_mode();
let app = App::new(service, &config, &UiState::default());
let snapshot = app.persisted_state();
let path = temp_path();
let repository = TomlStateRepository::new(path.clone());
repository.save(&snapshot).unwrap();
let loaded = repository.load().unwrap();
let _ = std::fs::remove_file(&path);
let settings = loaded.settings.expect("settings were saved");
assert_eq!(settings.angle_mode, calcli::domain::format::AngleMode::Deg);
assert_eq!(loaded.variables.get("answer").unwrap().value, 42.0);
let entries = loaded
.history
.iter()
.map(|entry| HistoryEntry {
input: entry.input.clone(),
value: entry
.value
.map(|v| Quantity::from_persisted(v, entry.unit.as_deref())),
error: None,
})
.collect();
let mut rebuilt = CalcService::new(
Box::new(MevalEvaluator::new()),
config.format_settings(),
History::from_entries(entries, config.max_history),
VariableStore::from_pairs(loaded.variables.iter().map(
|(name, stored)| {
(
name.clone(),
Quantity::from_persisted(
stored.value,
stored.unit.as_deref(),
),
)
},
)),
);
rebuilt.recompute_all();
assert_eq!(
rebuilt.history().entries()[2]
.value
.clone()
.map(|q| q.display_value()),
Some(43.0)
);
assert_eq!(
rebuilt
.variables()
.get("answer")
.map(Quantity::display_value),
Some(42.0)
);
}