Files
Entropyk/crates/entropyk/tests/port_validated_edges.rs
Sepehr ab5dc7e568 chore: remove BMAD framework files and IDE configuration artifacts
Clean up unused BMAD workflow, agent, and command files across all IDE
configurations (.agent, .clinerules, .cursor, .gemini, .github, .kilocode,
.opencode) and internal module files (_bmad/bmb, _bmad/bmm).

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-04-25 15:01:09 +02:00

203 lines
5.5 KiB
Rust

//! Integration tests for SystemBuilder::edge_with_ports()
use entropyk::SystemBuilder;
use entropyk_components::{ComponentError, ConnectedPort, JacobianBuilder, ResidualVector};
/// A minimal mock component with configurable ports for testing.
struct MockComponentWithPorts {
n_eqs: usize,
ports: Vec<ConnectedPort>,
}
impl MockComponentWithPorts {
fn new(n_eqs: usize) -> Self {
Self {
n_eqs,
ports: Vec::new(),
}
}
#[allow(dead_code)]
fn with_ports(n_eqs: usize, ports: Vec<ConnectedPort>) -> Self {
Self { n_eqs, ports }
}
}
impl entropyk_components::Component for MockComponentWithPorts {
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) -> &[ConnectedPort] {
&self.ports
}
}
#[test]
fn test_edge_with_ports_component_not_found() {
let result = SystemBuilder::new()
.component("a", Box::new(MockComponentWithPorts::new(1)))
.unwrap()
.edge_with_ports("missing", "outlet", "a", "inlet");
assert!(result.is_err());
if let Err(ref err) = result {
assert!(
err.to_string().contains("not found"),
"Expected ComponentNotFound error, got: {}",
err
);
}
}
#[test]
fn test_edge_with_ports_target_not_found() {
let result = SystemBuilder::new()
.component("a", Box::new(MockComponentWithPorts::new(1)))
.unwrap()
.edge_with_ports("a", "outlet", "missing", "inlet");
assert!(result.is_err());
if let Err(ref err) = result {
assert!(
err.to_string().contains("not found"),
"Expected ComponentNotFound error, got: {}",
err
);
}
}
#[test]
fn test_edge_with_ports_cross_circuit_rejected() {
use entropyk_core::CircuitId;
let result = SystemBuilder::new()
.component_in_circuit(
"a",
Box::new(MockComponentWithPorts::new(1)),
CircuitId::ZERO,
)
.unwrap()
.component_in_circuit("b", Box::new(MockComponentWithPorts::new(1)), CircuitId(1))
.unwrap()
.edge_with_ports("a", "outlet", "b", "inlet");
assert!(result.is_err());
if let Err(ref err) = result {
assert!(
err.to_string().contains("different circuits"),
"Expected CrossCircuitEdge error, got: {}",
err
);
}
}
#[test]
fn test_edge_with_ports_convention_based_names() {
let builder = SystemBuilder::new()
.component("a", Box::new(MockComponentWithPorts::new(2)))
.unwrap()
.component("b", Box::new(MockComponentWithPorts::new(2)))
.unwrap()
.edge_with_ports("a", "outlet", "b", "inlet")
.expect("edge_with_ports should resolve convention-based port names");
assert_eq!(builder.edge_count(), 1);
}
#[test]
fn test_edge_with_ports_suction_discharge_names() {
let builder = SystemBuilder::new()
.component("comp", Box::new(MockComponentWithPorts::new(2)))
.unwrap()
.component("pipe", Box::new(MockComponentWithPorts::new(2)))
.unwrap()
.edge_with_ports("comp", "discharge", "pipe", "inlet")
.expect("edge_with_ports should resolve suction/discharge convention names");
assert_eq!(builder.edge_count(), 1);
}
#[test]
fn test_edge_with_ports_unknown_port_name_error() {
use entropyk::SystemBuilderError;
let result = SystemBuilder::new()
.component("a", Box::new(MockComponentWithPorts::new(2)))
.unwrap()
.component("b", Box::new(MockComponentWithPorts::new(2)))
.unwrap()
.edge_with_ports("a", "bogus_port", "b", "inlet");
assert!(result.is_err());
if let Err(SystemBuilderError::PortNotFound {
component,
port_name,
}) = result
{
assert_eq!(component, "a");
assert!(port_name.starts_with("bogus_port"), "port_name should start with the port name, got: {port_name}");
} else {
panic!("Expected PortNotFound error");
}
}
#[test]
fn test_edge_with_ports_same_circuit_succeeds() {
use entropyk_core::CircuitId;
let builder = SystemBuilder::new()
.component_in_circuit(
"a",
Box::new(MockComponentWithPorts::new(2)),
CircuitId::ZERO,
)
.unwrap()
.component_in_circuit(
"b",
Box::new(MockComponentWithPorts::new(2)),
CircuitId::ZERO,
)
.unwrap()
.edge_with_ports("a", "outlet", "b", "inlet")
.expect("edge_with_ports should succeed for same-circuit components");
assert_eq!(builder.edge_count(), 1);
}
#[test]
fn test_build_system_with_port_validated_edges() {
let system = SystemBuilder::new()
.component("a", Box::new(MockComponentWithPorts::new(2)))
.unwrap()
.component("b", Box::new(MockComponentWithPorts::new(2)))
.unwrap()
.component("c", Box::new(MockComponentWithPorts::new(2)))
.unwrap()
.edge_with_ports("a", "outlet", "b", "inlet")
.unwrap()
.edge_with_ports("b", "outlet", "c", "inlet")
.unwrap()
.build()
.expect("build should succeed");
assert_eq!(system.node_count(), 3);
assert_eq!(system.edge_count(), 2);
}