Skip to content

Commit

Permalink
Test cli help (#391)
Browse files Browse the repository at this point in the history
* test if showing --help of CLI commands runs without trouble

Signed-off-by: Nicolas Höning <nicolas@seita.nl>

* add name attribute to QuantityField which was causing --help of create schedule CLI to fail

Signed-off-by: Nicolas Höning <nicolas@seita.nl>

* Allow MarshmallowClickMixin to be used for custom fields that define their own __init__

Signed-off-by: F.N. Claessen <felix@seita.nl>

* black

Signed-off-by: F.N. Claessen <felix@seita.nl>

* more generic way to list the click commands per module

Signed-off-by: Nicolas Höning <nicolas@seita.nl>

Co-authored-by: F.N. Claessen <felix@seita.nl>
  • Loading branch information
nhoening and Flix6x committed Mar 10, 2022
1 parent 8fe7e8b commit bbc1e6e
Show file tree
Hide file tree
Showing 10 changed files with 60 additions and 5 deletions.
1 change: 1 addition & 0 deletions flexmeasures/cli/data_add.py
Original file line number Diff line number Diff line change
Expand Up @@ -848,6 +848,7 @@ def create_schedule(
"""Create a new schedule for a given power sensor.
Current limitations:
- only supports battery assets and Charge Points
- only supports datetimes on the hour or a multiple of the sensor resolution thereafter
"""
Expand Down
12 changes: 12 additions & 0 deletions flexmeasures/cli/tests/test_data_add.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
AccountAnnotationRelationship,
)
from flexmeasures.data.models.data_sources import DataSource
from flexmeasures.cli.tests.utils import get_click_commands


@pytest.mark.skip_github
Expand Down Expand Up @@ -75,3 +76,14 @@ def test_add_holidays(app, db, setup_roles_users):
.count()
== 11
)


def test_cli_help(app):
"""Test that showing help does not throw an error."""
from flexmeasures.cli import data_add

runner = app.test_cli_runner()
for cmd in get_click_commands(data_add):
result = runner.invoke(cmd, ["--help"])
assert result.exit_code == 0
assert "Usage" in result.output
12 changes: 12 additions & 0 deletions flexmeasures/cli/tests/test_data_edit.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

from flexmeasures.cli.tests.utils import to_flags
from flexmeasures.data.models.time_series import Sensor, TimedBelief
from flexmeasures.cli.tests.utils import get_click_commands


@pytest.mark.skip
Expand Down Expand Up @@ -101,3 +102,14 @@ def test_resample_sensor_data(
resample_sensor_data, to_flags(cli_input) + ["--skip-integrity-check"]
)
assert "Successfully resampled" in result.output


def test_cli_help(app):
"""Test that showing help does not throw an error."""
from flexmeasures.cli import data_edit

runner = app.test_cli_runner()
for cmd in get_click_commands(data_edit):
result = runner.invoke(cmd, ["--help"])
assert result.exit_code == 0
assert "Usage" in result.output
13 changes: 13 additions & 0 deletions flexmeasures/cli/tests/test_data_show.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import pytest

from flexmeasures.data.models.time_series import Sensor
from flexmeasures.cli.tests.utils import get_click_commands


@pytest.mark.skip_github
Expand Down Expand Up @@ -110,3 +111,15 @@ def test_plot_beliefs(app, fresh_db, setup_beliefs_fresh_db):
assert "Data spans an hour" in result.output

assert result.exit_code == 0


def test_cli_help(app):
"""Test that showing help does not throw an error."""
from flexmeasures.cli import data_show

runner = app.test_cli_runner()
for cmd in get_click_commands(data_show):
result = runner.invoke(cmd, ["--help"])
assert "Usage" in result.output
assert cmd.__doc__.strip() in result.output
assert result.exit_code == 0
13 changes: 13 additions & 0 deletions flexmeasures/cli/tests/utils.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
from typing import List, Callable

from click.core import Command as ClickCommand


def to_flags(cli_input: dict) -> list:
"""Turn dictionary of CLI input into a list of CLI flags ready for use in FlaskCliRunner.invoke().
Expand All @@ -18,3 +23,11 @@ def to_flags(cli_input: dict) -> list:
)
for item in sublist
]


def get_click_commands(module) -> List[Callable]:
return [
getattr(module, attr)
for attr in dir(module)
if type(getattr(module, attr)) == ClickCommand
]
2 changes: 1 addition & 1 deletion flexmeasures/data/schemas/generic_assets.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ class Meta:
model = GenericAssetType


class GenericAssetIdField(fields.Int, MarshmallowClickMixin):
class GenericAssetIdField(MarshmallowClickMixin, fields.Int):
"""Field that deserializes to a GenericAsset and serializes back to an integer."""

@with_appcontext
Expand Down
2 changes: 1 addition & 1 deletion flexmeasures/data/schemas/sensors.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ class Meta:
model = Sensor


class SensorIdField(fields.Int, MarshmallowClickMixin):
class SensorIdField(MarshmallowClickMixin, fields.Int):
"""Field that deserializes to a Sensor and serializes back to an integer."""

@with_appcontext
Expand Down
4 changes: 2 additions & 2 deletions flexmeasures/data/schemas/times.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class DurationValidationError(FMValidationError):
status = "INVALID_PERIOD" # USEF error status


class DurationField(fields.Str, MarshmallowClickMixin):
class DurationField(MarshmallowClickMixin, fields.Str):
"""Field that deserializes to a ISO8601 Duration
and serializes back to a string."""

Expand Down Expand Up @@ -64,7 +64,7 @@ def ground_from(
return duration


class AwareDateTimeField(fields.AwareDateTime, MarshmallowClickMixin):
class AwareDateTimeField(MarshmallowClickMixin, fields.AwareDateTime):
"""Field that de-serializes to a timezone aware datetime
and serializes back to a string."""

Expand Down
2 changes: 1 addition & 1 deletion flexmeasures/data/schemas/units.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ def __call__(self, value):
return value


class QuantityField(fields.Str, MarshmallowClickMixin):
class QuantityField(MarshmallowClickMixin, fields.Str):
"""Marshmallow/Click field for validating quantities against a unit registry.
The FlexMeasures unit registry is based on the pint library.
Expand Down
4 changes: 4 additions & 0 deletions flexmeasures/data/schemas/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@


class MarshmallowClickMixin(click.ParamType):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.name = self.__class__.__name__

def get_metavar(self, param):
return self.__class__.__name__

Expand Down

0 comments on commit bbc1e6e

Please sign in to comment.