unitdc-rs/tests/interpreter_test.rs
2024-07-29 12:13:53 -05:00

130 lines
3.9 KiB
Rust

use std::sync::Mutex;
use num_traits::ToPrimitive;
use unitdc::{
interpreter::Interpreter,
quantity::units::{BaseUnit, UnitCombo, UnitExponent},
};
#[test]
fn test_interpreter() {
let outputs = Mutex::new(Vec::new());
let output_fn = |output| outputs.lock().unwrap().push(output);
let mut interpreter = Interpreter::new(Box::new(output_fn));
interpreter
.run_str("@base(m)")
.expect("command should succeed");
interpreter
.run_str("0 (m) 1e3 @derived(km)")
.expect("command should succeed");
interpreter
.run_str("2 (km) p")
.expect("command should succeed");
let output = outputs.lock().unwrap().pop().expect("output should exist");
match output {
unitdc::interpreter::Output::Quantity(q) => {
assert_eq!(q.number.to_f64().unwrap(), 2000.0);
assert_eq!(
q.unit,
UnitCombo(vec![UnitExponent {
unit: BaseUnit {
symbol: "m".to_string(),
},
exponent: 1,
},])
);
}
_ => panic!("output should be a quantity"),
}
interpreter
.run_str("2 (km) 1 (m) + p")
.expect("command should succeed");
let output = outputs.lock().unwrap().pop().expect("output should exist");
match output {
unitdc::interpreter::Output::Quantity(q) => {
assert_eq!(q.number.to_f64().unwrap(), 2001.0);
assert_eq!(
q.unit,
UnitCombo(vec![UnitExponent {
unit: BaseUnit {
symbol: "m".to_string(),
},
exponent: 1,
},])
);
}
_ => panic!("output should be a quantity"),
}
}
#[test]
fn test_warn_confusing_units() {
let outputs = Mutex::new(Vec::new());
let output_fn = |output| outputs.lock().unwrap().push(output);
let mut interpreter = Interpreter::new(Box::new(output_fn));
interpreter
.run_str("@base(K)")
.expect("command should succeed");
interpreter
.run_str("273.15 (K) 1 @derived(degC)")
.expect("command should succeed");
interpreter
.run_str("0 (degC) 0 (degC) + p")
.expect("command should succeed");
let output = outputs.lock().unwrap().pop().expect("output should exist");
let msg = outputs.lock().unwrap().pop().expect("output should exist");
match msg {
unitdc::interpreter::Output::Message(e) => {
assert_eq!(
e.to_ascii_lowercase().contains("warning"),
true,
"output should contain 'warning'"
);
}
_ => panic!("output should be a message"),
}
match output {
unitdc::interpreter::Output::Quantity(q) => {
assert_eq!(q.number.to_f64().unwrap(), 273.15 * 2.);
assert_eq!(
q.unit,
UnitCombo(vec![UnitExponent {
unit: BaseUnit {
symbol: "K".to_string(),
},
exponent: 1,
},])
);
}
_ => panic!("output should be a quantity"),
}
interpreter
.run_str("@base(m)")
.expect("command should succeed");
interpreter
.run_str("0 (degC) 1 (m) * 0 (degC) 1 (m) * + p")
.expect("command should succeed");
let _ = outputs.lock().unwrap().pop().expect("output should exist");
let msg = outputs.lock().unwrap().pop().expect("output should exist");
match msg {
unitdc::interpreter::Output::Message(e) => {
assert_eq!(
e.to_ascii_lowercase().contains("warning"),
true,
"output should contain 'warning'"
);
}
_ => panic!("output should be a message"),
}
}