feat(python): implement python bindings for all components and solvers
This commit is contained in:
158
crates/entropyk/tests/api_usage.rs
Normal file
158
crates/entropyk/tests/api_usage.rs
Normal file
@@ -0,0 +1,158 @@
|
||||
//! 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()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user