137 lines
5.3 KiB
Python
137 lines
5.3 KiB
Python
from __future__ import annotations
|
|
|
|
import unittest
|
|
|
|
from PythonModels.components.cylinder import Cylinder
|
|
from PythonModels.components.orifice import Orifice
|
|
from PythonModels.components.pipe import Pipe
|
|
from PythonModels.components.resistive_pipe import ResistivePipe
|
|
from PythonModels.components.tank import Tank
|
|
from PythonModels.components.tee import Tee
|
|
from PythonModels.core.medium import IdealGasMedium
|
|
from PythonModels.core.ports import PortVariableDefinition
|
|
from PythonModels.registry import COMPONENT_MODEL_REGISTRY
|
|
|
|
|
|
class ComponentMetadataTests(unittest.TestCase):
|
|
def setUp(self) -> None:
|
|
self.medium = IdealGasMedium()
|
|
|
|
def component_instances(self):
|
|
return (
|
|
Cylinder("cylinder_1", self.medium),
|
|
Tank("tank_1", self.medium),
|
|
Pipe("pipe_dynamic_1", self.medium),
|
|
ResistivePipe("pipe_1", self.medium),
|
|
Orifice("orifice_1"),
|
|
Tee("tee_1"),
|
|
)
|
|
|
|
def test_every_component_declares_a_complete_model_contract(self) -> None:
|
|
for component in self.component_instances():
|
|
with self.subTest(component=component.name):
|
|
for attribute in (
|
|
"MODEL_TYPE",
|
|
"PORTS",
|
|
"PARAMETERS",
|
|
"RESULT_VARIABLES",
|
|
):
|
|
self.assertIn(attribute, type(component).__dict__)
|
|
self.assertTrue(component.MODEL_TYPE)
|
|
self.assertEqual(component.model_type, component.MODEL_TYPE)
|
|
self.assertEqual(component.port_definitions, component.PORTS)
|
|
self.assertEqual(
|
|
set(component.parameter_values),
|
|
{definition.name for definition in component.PARAMETERS},
|
|
)
|
|
self.assertTrue(
|
|
all(definition.label for definition in component.PARAMETERS)
|
|
)
|
|
self.assertTrue(
|
|
all(definition.quantity for definition in component.PARAMETERS)
|
|
)
|
|
|
|
def test_registry_reuses_component_parameter_and_port_declarations(self) -> None:
|
|
registered_classes = {
|
|
"cylinder": Cylinder,
|
|
"tank": Tank,
|
|
"pipe": ResistivePipe,
|
|
"orifice": Orifice,
|
|
"tee": Tee,
|
|
}
|
|
for model_type, component_class in registered_classes.items():
|
|
with self.subTest(model_type=model_type):
|
|
spec = COMPONENT_MODEL_REGISTRY[model_type]
|
|
self.assertEqual(spec.model_type, component_class.MODEL_TYPE)
|
|
self.assertEqual(spec.ports, component_class.PORTS)
|
|
self.assertEqual(spec.parameters, component_class.PARAMETERS)
|
|
component = spec.create(f"{model_type}_1", self.medium, {})
|
|
self.assertEqual(
|
|
component.parameter_values,
|
|
{
|
|
definition.name: definition.default
|
|
for definition in component_class.PARAMETERS
|
|
},
|
|
)
|
|
|
|
def test_result_metadata_exactly_describes_each_exposed_value(self) -> None:
|
|
for component in self.component_instances():
|
|
with self.subTest(component=component.name):
|
|
values = component.result_values()
|
|
metadata = component.result_variable_metadata()
|
|
keys = [variable.key for variable in metadata]
|
|
self.assertEqual(len(keys), len(set(keys)))
|
|
self.assertEqual(
|
|
set(values),
|
|
{
|
|
variable.key.removeprefix(f"{component.name}.")
|
|
for variable in metadata
|
|
},
|
|
)
|
|
self.assertTrue(all(variable.label for variable in metadata))
|
|
self.assertTrue(all(variable.quantity for variable in metadata))
|
|
|
|
def test_storage_and_port_variables_include_display_metadata(self) -> None:
|
|
cylinder = Cylinder("cylinder_1", self.medium)
|
|
metadata = {
|
|
variable.key: variable
|
|
for variable in cylinder.result_variable_metadata()
|
|
}
|
|
|
|
pressure = metadata["cylinder_1.p"]
|
|
self.assertEqual(pressure.scope, "component")
|
|
self.assertEqual(pressure.label, "压力")
|
|
self.assertEqual(pressure.quantity, "pressure")
|
|
self.assertEqual(pressure.unit, "Pa")
|
|
|
|
mass_flow = metadata["cylinder_1.port_b.m_flow"]
|
|
self.assertEqual(mass_flow.scope, "port")
|
|
self.assertEqual(mass_flow.port_name, "port_b")
|
|
self.assertEqual(mass_flow.label, "质量流量")
|
|
self.assertEqual(mass_flow.quantity, "mass_flow")
|
|
self.assertEqual(mass_flow.unit, "kg/s")
|
|
|
|
def test_port_display_metadata_is_not_part_of_the_physical_contract(self) -> None:
|
|
first = PortVariableDefinition(
|
|
"p",
|
|
"effort",
|
|
"equal",
|
|
label="压力",
|
|
quantity="pressure",
|
|
unit="Pa",
|
|
)
|
|
second = PortVariableDefinition(
|
|
"p",
|
|
"effort",
|
|
"equal",
|
|
label="Pressure",
|
|
quantity="absolute_pressure",
|
|
unit="kPa",
|
|
)
|
|
|
|
self.assertEqual(first, second)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|