diff --git a/CHANGELOG.md b/CHANGELOG.md index db6bd8a73..6774e4e10 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -32,6 +32,8 @@ Attention: The newest changes should be on top --> ### Added +- ENH: Custom Exception errors and messages [#285](https://github.com/RocketPy-Team/RocketPy/issues/285) + ### Changed ### Fixed diff --git a/rocketpy/rocket/rocket.py b/rocketpy/rocket/rocket.py index 1112a98f3..63853a399 100644 --- a/rocketpy/rocket/rocket.py +++ b/rocketpy/rocket/rocket.py @@ -384,6 +384,35 @@ def __init__( # pylint: disable=too-many-statements self.prints = _RocketPrints(self) self.plots = _RocketPlots(self) + def _check_missing_components(self): + """Check if the rocket is missing any essential components and issue a warning. + + This method verifies whether the rocket has the following key components: + - motor + - aerodynamic surface(s) + + If any of these components are missing, a single warning message is issued + listing all missing components. This helps users quickly identify potential + issues before running simulations or analyses. + + Notes + ----- + - The warning uses Python's built-in `warnings.warn` function. + + Returns + ------- + None + """ + missing_components = [] + if isinstance(self.motor, EmptyMotor): + missing_components.append("motor") + if not self.aerodynamic_surfaces: + missing_components.append("aerodynamic surfaces") + + if missing_components: + component_list = ", ".join(missing_components) + warnings.warn(f"Rocket has no {component_list} defined.", UserWarning) + @property def nosecones(self): """A list containing all the nose cones currently added to the rocket.""" diff --git a/tests/unit/rocket/test_rocket.py b/tests/unit/rocket/test_rocket.py index 3c1e7168d..5c3fed359 100644 --- a/tests/unit/rocket/test_rocket.py +++ b/tests/unit/rocket/test_rocket.py @@ -1,3 +1,4 @@ +import warnings from unittest.mock import patch import numpy as np @@ -370,6 +371,39 @@ def test_add_motor(calisto_motorless, cesaroni_m1670): assert center_of_mass_motorless is not center_of_mass_with_motor +def test_check_missing_all_components(calisto_motorless): + """Tests the _check_missing_components method for a Rocket with no components.""" + with pytest.warns(UserWarning) as record: + calisto_motorless._check_missing_components() + + assert len(record) == 1 + msg = str(record[0].message) + assert "motor" in msg + assert "aerodynamic surfaces" in msg + + +def test_check_missing_some_components(calisto): + """Tests the _check_missing_components method for a Rocket missing some components.""" + calisto.aerodynamic_surfaces = [] + + with pytest.warns(UserWarning) as record: + calisto._check_missing_components() + + assert len(record) == 1 + msg = str(record[0].message) + assert "aerodynamic surfaces" in msg + + +def test_check_missing_no_components_missing(calisto_robust): + """Tests the _check_missing_components method for a complete Rocket.""" + # Catch all warnings that occur inside this 'with' block. + with warnings.catch_warnings(record=True) as w: + warnings.simplefilter("always") + calisto_robust._check_missing_components() + # For a complete rocket, this method should NOT issue any warnings. + assert len(w) == 0 + + def test_set_rail_button(calisto): rail_buttons = calisto.set_rail_buttons(0.2, -0.5, 30) # assert buttons_distance