#![cfg(feature = "serde")]
#[cfg(feature = "ndarray")]
use ndarray::arr1;
use unitforge::quantities::{Force, ForceUnit};
use unitforge::small_linalg::{Matrix3, Vector3};
use unitforge::PhysicsQuantity;
#[cfg(not(any(feature = "storage-f64", feature = "storage-f32")))]
use unitforge::MAX_ABS_QUANTITY_POWER;
#[test]
fn roundtrip_quantity() {
let original = Force::new(100.0, ForceUnit::kN);
let json = serde_json::to_string(&original).expect("Failed to serialize");
let deserialized: Force = serde_json::from_str(&json).expect("Failed to deserialize");
assert_eq!(deserialized.to(ForceUnit::N), original.to(ForceUnit::N));
}
#[test]
#[cfg(feature = "ndarray")]
fn roundtrip_quantity_ndarray() {
let original = arr1(&[
Force::new(50.0, ForceUnit::kN),
Force::new(75.0, ForceUnit::kN),
]);
let json = serde_json::to_string(&original).expect("Failed to serialize");
let deserialized: ndarray::Array1<Force> =
serde_json::from_str(&json).expect("Failed to deserialize");
assert_eq!(
deserialized[1].to(ForceUnit::N),
original[1].to(ForceUnit::N)
);
}
#[test]
fn roundtrip_vector() {
let original: Vector3<Force> = Vector3::from_f64([1.0, 2.0, 3.0]);
let json = serde_json::to_string(&original).expect("Failed to serialize");
let deserialized: Vector3<Force> = serde_json::from_str(&json).expect("Failed to deserialize");
assert_eq!(deserialized, original);
}
#[test]
fn roundtrip_matrix() {
let mat = Matrix3::new([[3.0_f64; 3]; 3]);
let force = Force::new(1.0, ForceUnit::kN);
let original = mat * force;
let json = serde_json::to_string(&original).expect("Failed to serialize");
let deserialized: Matrix3<Force> = serde_json::from_str(&json).expect("Failed to deserialize");
for i in 0..3 {
for j in 0..3 {
assert_eq!(deserialized[(i, j)], Force::new(3.0, ForceUnit::kN));
}
}
}
#[test]
#[cfg(not(any(feature = "storage-f64", feature = "storage-f32")))]
fn deserialize_canonicalizes_unnormalized_quantity_parts() {
let deserialized: Force =
serde_json::from_str(r#"{"multiplier":1000.0,"power":0}"#).expect("deserialize force");
assert_eq!(deserialized.get_tuple(), (1.0, 3));
assert_eq!(deserialized.to(ForceUnit::N), 1000.0);
}
#[test]
#[cfg(not(any(feature = "storage-f64", feature = "storage-f32")))]
fn deserialize_saturates_large_positive_power_to_infinity() {
let json = format!(r#"{{"multiplier":1.0,"power":{}}}"#, MAX_ABS_QUANTITY_POWER);
let deserialized: Force = serde_json::from_str(&json).expect("deserialize force");
assert!(deserialized.as_f64().is_infinite());
assert!(deserialized.as_f64().is_sign_positive());
assert_eq!(deserialized.get_power(), 0);
}
#[test]
#[cfg(not(any(feature = "storage-f64", feature = "storage-f32")))]
fn deserialize_saturates_large_negative_power_to_zero() {
let json = format!(
r#"{{"multiplier":1.0,"power":{}}}"#,
-MAX_ABS_QUANTITY_POWER
);
let deserialized: Force = serde_json::from_str(&json).expect("deserialize force");
assert_eq!(deserialized.get_tuple(), (0.0, 0));
assert_eq!(deserialized.to(ForceUnit::N), 0.0);
}
#[test]
#[cfg(any(feature = "storage-f64", feature = "storage-f32"))]
fn plain_storage_serializes_value_field() {
let original = Force::new(100.0, ForceUnit::kN);
let json = serde_json::to_value(original).expect("serialize force");
assert_eq!(
json.get("value").and_then(|value| value.as_f64()),
Some(100000.0)
);
assert!(json.get("multiplier").is_none());
assert!(json.get("power").is_none());
}
#[test]
#[cfg(any(feature = "storage-f64", feature = "storage-f32"))]
fn plain_storage_deserializes_value_field() {
let deserialized: Force =
serde_json::from_str(r#"{"value":1000.0}"#).expect("deserialize force");
assert_eq!(deserialized.as_f64(), 1000.0);
assert_eq!(deserialized.to(ForceUnit::N), 1000.0);
}