Skip to content
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
31 changes: 31 additions & 0 deletions rocketpy/rocket/rocket.py
Original file line number Diff line number Diff line change
Expand Up @@ -384,6 +384,37 @@ 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."""
Expand Down
38 changes: 37 additions & 1 deletion tests/unit/rocket/test_rocket.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import numpy as np
import pytest
import warnings

from rocketpy import Function, NoseCone, Rocket, SolidMotor
from rocketpy.mathutils.vector_matrix import Vector
Expand All @@ -10,7 +11,9 @@


@patch("matplotlib.pyplot.show")
def test_elliptical_fins(mock_show, calisto_robust, calisto_trapezoidal_fins): # pylint: disable=unused-argument
def test_elliptical_fins(
mock_show, calisto_robust, calisto_trapezoidal_fins
): # pylint: disable=unused-argument
test_rocket = calisto_robust
calisto_robust.aerodynamic_surfaces.remove(calisto_trapezoidal_fins)
test_rocket.add_elliptical_fins(4, span=0.100, root_chord=0.120, position=-1.168)
Expand Down Expand Up @@ -370,6 +373,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
Expand Down
Loading