159 lines
3.4 KiB
Rust
159 lines
3.4 KiB
Rust
//! Integration tests for the Entropyk public API.
|
|
//!
|
|
//! These tests verify the builder pattern, error propagation, and overall
|
|
//! API ergonomics using real component types.
|
|
|
|
use entropyk::{System, SystemBuilder, ThermoError};
|
|
use entropyk_components::{
|
|
Component, ComponentError, JacobianBuilder, ResidualVector, SystemState,
|
|
};
|
|
|
|
struct MockComponent {
|
|
name: &'static str,
|
|
n_eqs: usize,
|
|
}
|
|
|
|
impl Component for MockComponent {
|
|
fn compute_residuals(
|
|
&self,
|
|
_state: &SystemState,
|
|
_residuals: &mut ResidualVector,
|
|
) -> Result<(), ComponentError> {
|
|
Ok(())
|
|
}
|
|
|
|
fn jacobian_entries(
|
|
&self,
|
|
_state: &SystemState,
|
|
_jacobian: &mut JacobianBuilder,
|
|
) -> Result<(), ComponentError> {
|
|
Ok(())
|
|
}
|
|
|
|
fn n_equations(&self) -> usize {
|
|
self.n_eqs
|
|
}
|
|
|
|
fn get_ports(&self) -> &[entropyk_components::ConnectedPort] {
|
|
&[]
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn test_builder_creates_empty_system() {
|
|
let builder = SystemBuilder::new();
|
|
assert_eq!(builder.component_count(), 0);
|
|
assert_eq!(builder.edge_count(), 0);
|
|
}
|
|
|
|
#[test]
|
|
fn test_builder_adds_components() {
|
|
let builder = SystemBuilder::new()
|
|
.component(
|
|
"comp1",
|
|
Box::new(MockComponent {
|
|
name: "comp1",
|
|
n_eqs: 2,
|
|
}),
|
|
)
|
|
.expect("should add component");
|
|
|
|
assert_eq!(builder.component_count(), 1);
|
|
}
|
|
|
|
#[test]
|
|
fn test_builder_rejects_duplicate_names() {
|
|
let result = SystemBuilder::new()
|
|
.component(
|
|
"dup",
|
|
Box::new(MockComponent {
|
|
name: "dup",
|
|
n_eqs: 1,
|
|
}),
|
|
)
|
|
.expect("first add should succeed")
|
|
.component(
|
|
"dup",
|
|
Box::new(MockComponent {
|
|
name: "dup",
|
|
n_eqs: 1,
|
|
}),
|
|
);
|
|
|
|
assert!(result.is_err());
|
|
}
|
|
|
|
#[test]
|
|
fn test_builder_creates_edges() {
|
|
let builder = SystemBuilder::new()
|
|
.component(
|
|
"a",
|
|
Box::new(MockComponent {
|
|
name: "a",
|
|
n_eqs: 1,
|
|
}),
|
|
)
|
|
.expect("add a")
|
|
.component(
|
|
"b",
|
|
Box::new(MockComponent {
|
|
name: "b",
|
|
n_eqs: 1,
|
|
}),
|
|
)
|
|
.expect("add b")
|
|
.edge("a", "b")
|
|
.expect("edge a->b");
|
|
|
|
assert_eq!(builder.edge_count(), 1);
|
|
}
|
|
|
|
#[test]
|
|
fn test_builder_rejects_missing_edge_component() {
|
|
let result = SystemBuilder::new()
|
|
.component(
|
|
"a",
|
|
Box::new(MockComponent {
|
|
name: "a",
|
|
n_eqs: 1,
|
|
}),
|
|
)
|
|
.expect("add a")
|
|
.edge("a", "nonexistent");
|
|
|
|
assert!(result.is_err());
|
|
}
|
|
|
|
#[test]
|
|
fn test_builder_into_inner() {
|
|
let system = SystemBuilder::new()
|
|
.component(
|
|
"c",
|
|
Box::new(MockComponent {
|
|
name: "c",
|
|
n_eqs: 1,
|
|
}),
|
|
)
|
|
.expect("add c")
|
|
.into_inner();
|
|
|
|
assert_eq!(system.node_count(), 1);
|
|
}
|
|
|
|
#[test]
|
|
fn test_direct_system_api() {
|
|
let mut system = System::new();
|
|
let idx = system.add_component(Box::new(MockComponent {
|
|
name: "test",
|
|
n_eqs: 2,
|
|
}));
|
|
assert_eq!(system.node_count(), 1);
|
|
}
|
|
|
|
#[test]
|
|
fn test_error_types_are_compatible() {
|
|
fn _assert_thermo_error_from_component(e: ComponentError) -> ThermoError {
|
|
e.into()
|
|
}
|
|
}
|