//! 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, }; struct MockComponent { name: &'static str, n_eqs: usize, } impl Component for MockComponent { fn compute_residuals( &self, _state: &[f64], _residuals: &mut ResidualVector, ) -> Result<(), ComponentError> { Ok(()) } fn jacobian_entries( &self, _state: &[f64], _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() } }