diff options
author | Diogo Sousa <montezdesousa@gmail.com> | 2024-06-07 11:41:02 +0100 |
---|---|---|
committer | Diogo Sousa <montezdesousa@gmail.com> | 2024-06-07 11:41:02 +0100 |
commit | 9e3d30a439fd8853915d44bccd5c817b1cd4fc8b (patch) | |
tree | cbd9a34118fb99dd847e18a92668a05a411351d7 | |
parent | a839c228cc133ee6a744b27e5df5c4e2a5f33159 (diff) |
fix tests
-rw-r--r-- | cli/openbb_cli/controllers/settings_controller.py | 39 | ||||
-rw-r--r-- | cli/openbb_cli/controllers/utils.py | 2 | ||||
-rw-r--r-- | cli/openbb_cli/models/settings.py | 48 | ||||
-rw-r--r-- | cli/tests/test_controllers_settings_controller.py | 48 | ||||
-rw-r--r-- | cli/tests/test_controllers_utils.py | 14 |
5 files changed, 81 insertions, 70 deletions
diff --git a/cli/openbb_cli/controllers/settings_controller.py b/cli/openbb_cli/controllers/settings_controller.py index 4dacfb76d1e..da8add50b52 100644 --- a/cli/openbb_cli/controllers/settings_controller.py +++ b/cli/openbb_cli/controllers/settings_controller.py @@ -7,6 +7,7 @@ from typing import List, Literal, Optional, get_origin from openbb_cli.config.menu_text import MenuText from openbb_cli.controllers.base_controller import BaseController +from openbb_cli.models.settings import SettingGroups from openbb_cli.session import Session session = Session() @@ -21,7 +22,7 @@ class SettingsController(BaseController): "group": (v.json_schema_extra or {}).get("group"), "description": v.description, "annotation": v.annotation, - "name": k, + "field_name": k, } for k, v in sorted( session.settings.model_fields.items(), @@ -38,9 +39,9 @@ class SettingsController(BaseController): super().__init__(queue) for cmd, field in self._COMMANDS.items(): group = field.get("group") - if group == "feature-flags": + if group == SettingGroups.feature_flags: self._generate_command(cmd, field, "toggle") - elif group == "preferences": + elif group == SettingGroups.preferences: self._generate_command(cmd, field, "set") self.update_completer(self.choices_default) @@ -49,16 +50,16 @@ class SettingsController(BaseController): mt = MenuText("settings/") mt.add_info("Feature Flags") for k, f in self._COMMANDS.items(): - if f.get("group") == "feature-flags": + if f.get("group") == SettingGroups.feature_flags: mt.add_setting( name=k, - status=getattr(session.settings, f["name"]), + status=getattr(session.settings, f["field_name"]), description=f["description"], ) mt.add_raw("\n") mt.add_info("Preferences") for k, f in self._COMMANDS.items(): - if f.get("group") == "preferences": + if f.get("group") == SettingGroups.preferences: mt.add_cmd( name=k, description=f["description"], @@ -66,13 +67,13 @@ class SettingsController(BaseController): session.console.print(text=mt.menu_text, menu="Settings") def _generate_command( - self, name: str, field: dict, action_type: Literal["toggle", "set"] + self, cmd_name: str, field: dict, action_type: Literal["toggle", "set"] ): """Generate command call.""" def _toggle(self, other_args: List[str], field=field) -> None: """Toggle setting value.""" - name = field["name"] + field_name = field["field_name"] parser = argparse.ArgumentParser( formatter_class=argparse.ArgumentDefaultsHelpFormatter, prog=field["command"], @@ -81,17 +82,21 @@ class SettingsController(BaseController): ) ns_parser = self.parse_simple_args(parser, other_args) if ns_parser: - session.settings.set_item(name, not getattr(session.settings, name)) + session.settings.set_item( + field_name, not getattr(session.settings, field_name) + ) def _set(self, other_args: List[str], field=field) -> None: """Set preference value.""" - name = field["name"] + field_name = field["field_name"] annotation = field["annotation"] command = field["command"] + type_ = str if get_origin(annotation) is Literal else annotation choices = None if get_origin(annotation) is Literal: choices = annotation.__args__ elif command == "console_style": + # To have updated choices for console style choices = session.style.available_styles parser = argparse.ArgumentParser( formatter_class=argparse.ArgumentDefaultsHelpFormatter, @@ -105,18 +110,22 @@ class SettingsController(BaseController): dest="value", action="store", required=False, - type=None if get_origin(annotation) is Literal else annotation, # type: ignore[arg-type] + type=type_, # type: ignore[arg-type] choices=choices, ) ns_parser = self.parse_simple_args(parser, other_args) if ns_parser: if ns_parser.value: + # Console style is applied immediately if command == "console_style": session.style.apply(ns_parser.value) - session.settings.set_item(name, ns_parser.value) + session.settings.set_item(field_name, ns_parser.value) + session.console.print( + f"[info]Current value:[/info] {getattr(session.settings, field_name)}" + ) elif not other_args: session.console.print( - f"Current value: {getattr(session.settings, name)}" + f"[info]Current value:[/info] {getattr(session.settings, field_name)}" ) action = None @@ -128,6 +137,6 @@ class SettingsController(BaseController): raise ValueError(f"Action type '{action_type}' not allowed.") bound_method = update_wrapper( - partial(MethodType(action, self), field=field), action + wrapper=partial(MethodType(action, self), field=field), wrapped=action ) - setattr(self, f"call_{name}", bound_method) + setattr(self, f"call_{cmd_name}", bound_method) diff --git a/cli/openbb_cli/controllers/utils.py b/cli/openbb_cli/controllers/utils.py index b0f7b220f0d..c85bf236c5d 100644 --- a/cli/openbb_cli/controllers/utils.py +++ b/cli/openbb_cli/controllers/utils.py @@ -258,7 +258,7 @@ def parse_and_split_input(an_input: str, custom_filters: List) -> List[str]: else: filter_input = False - commands = an_input.split("/") if "-t" not in an_input else [an_input] + commands = an_input.split("/") if "timezone" not in an_input else [an_input] for command_num, command in enumerate(commands): if command == commands[command_num] == commands[-1] == "": diff --git a/cli/openbb_cli/models/settings.py b/cli/openbb_cli/models/settings.py index 84af3eb7a2a..645488a7a7a 100644 --- a/cli/openbb_cli/models/settings.py +++ b/cli/openbb_cli/models/settings.py @@ -1,5 +1,6 @@ """Settings model.""" +from enum import Enum from typing import Any, Literal from dotenv import dotenv_values, set_key @@ -11,6 +12,13 @@ from pytz import all_timezones VERSION = get_package_version("openbb-cli") +class SettingGroups(Enum): + """Setting types.""" + + feature_flags = "feature_flag" + preferences = "preference" + + class Settings(BaseModel): """Settings model.""" @@ -34,67 +42,67 @@ class Settings(BaseModel): default=False, description="whether to overwrite Excel files if they already exists", command="overwrite", - group="feature-flags", + group=SettingGroups.feature_flags, ) SHOW_VERSION: bool = Field( default=True, description="whether to show the version in the bottom right corner", command="version", - group="feature-flags", + group=SettingGroups.feature_flags, ) USE_INTERACTIVE_DF: bool = Field( default=True, description="display tables in interactive window", command="interactive", - group="feature-flags", + group=SettingGroups.feature_flags, ) USE_CLEAR_AFTER_CMD: bool = Field( default=False, description="clear console after each command", command="cls", - group="feature-flags", + group=SettingGroups.feature_flags, ) USE_DATETIME: bool = Field( default=True, description="whether to show the date and time before the flair", command="datetime", - group="feature-flags", + group=SettingGroups.feature_flags, ) USE_PROMPT_TOOLKIT: bool = Field( default=True, description="enable prompt toolkit (autocomplete and history)", command="promptkit", - group="feature-flags", + group=SettingGroups.feature_flags, ) ENABLE_EXIT_AUTO_HELP: bool = Field( default=True, description="automatically print help when quitting menu", command="exithelp", - group="feature-flags", + group=SettingGroups.feature_flags, ) REMEMBER_CONTEXTS: bool = Field( default=True, description="remember contexts between menus", command="rcontext", - group="feature-flags", + group=SettingGroups.feature_flags, ) ENABLE_RICH_PANEL: bool = Field( default=True, description="enable colorful rich CLI panel", command="richpanel", - group="feature-flags", + group=SettingGroups.feature_flags, ) TOOLBAR_HINT: bool = Field( default=True, description="displays usage hints in the bottom toolbar", command="tbhint", - group="feature-flags", + group=SettingGroups.feature_flags, ) SHOW_MSG_OBBJECT_REGISTRY: bool = Field( default=False, description="show obbject registry message after a new result is added", command="obbject_msg", - group="feature-flags", + group=SettingGroups.feature_flags, ) # PREFERENCES @@ -102,43 +110,43 @@ class Settings(BaseModel): default="America/New_York", description="pick timezone", command="timezone", - group="preferences", + group=SettingGroups.preferences, ) FLAIR: Literal[tuple(AVAILABLE_FLAIRS)] = Field( # type: ignore[valid-type] default=":openbb", description="choose flair icon", command="flair", - group="preferences", + group=SettingGroups.preferences, ) N_TO_KEEP_OBBJECT_REGISTRY: int = Field( default=10, description="define the maximum number of obbjects allowed in the registry", command="obbject_res", - group="preferences", + group=SettingGroups.preferences, ) N_TO_DISPLAY_OBBJECT_REGISTRY: int = Field( default=5, description="define the maximum number of cached results to display on the help menu", command="obbject_display", - group="preferences", + group=SettingGroups.preferences, ) RICH_STYLE: str = Field( default="dark", description="apply a custom rich style to the CLI", command="console_style", - group="preferences", + group=SettingGroups.preferences, ) ALLOWED_NUMBER_OF_ROWS: int = Field( default=20, - description="Number of rows to show (when not using interactive tables).", + description="number of rows to show (when not using interactive tables).", command="n_rows", - group="preferences", + group=SettingGroups.preferences, ) ALLOWED_NUMBER_OF_COLUMNS: int = Field( default=5, - description="Number of columns to show (when not using interactive tables).", + description="number of columns to show (when not using interactive tables).", command="n_cols", - group="preferences", + group=SettingGroups.preferences, ) model_config = ConfigDict(validate_assignment=True) diff --git a/cli/tests/test_controllers_settings_controller.py b/cli/tests/test_controllers_settings_controller.py index 7540b3bea4f..6b2389d491f 100644 --- a/cli/tests/test_controllers_settings_controller.py +++ b/cli/tests/test_controllers_settings_controller.py @@ -5,7 +5,7 @@ from unittest.mock import MagicMock, patch import pytest from openbb_cli.controllers.settings_controller import SettingsController -# pylint: disable=redefined-outer-name, unused-argument +# pylint: disable=redefined-outer-name, unused-argument, no-member @pytest.fixture @@ -14,7 +14,7 @@ def mock_session(): mock.settings.USE_INTERACTIVE_DF = False mock.settings.ALLOWED_NUMBER_OF_ROWS = 20 mock.settings.TIMEZONE = "UTC" - + mock.style.available_styles = ["dark"] mock.settings.set_item = MagicMock() yield mock @@ -35,7 +35,7 @@ def test_call_interactive(mock_session): ) def test_call_n_rows(input_rows, expected, mock_session): controller = SettingsController() - args = ["--rows", str(input_rows)] + args = ["--value", str(input_rows)] controller.call_n_rows(args) mock_session.settings.set_item.assert_called_with( "ALLOWED_NUMBER_OF_ROWS", expected @@ -45,7 +45,7 @@ def test_call_n_rows(input_rows, expected, mock_session): def test_call_n_rows_no_args_provided(mock_session): controller = SettingsController() controller.call_n_rows([]) - mock_session.console.print.assert_called_with("Current number of rows: 20") + mock_session.console.print.assert_called_with("[info]Current value:[/info] 20") @pytest.mark.parametrize( @@ -56,22 +56,18 @@ def test_call_n_rows_no_args_provided(mock_session): ], ) def test_call_timezone(timezone, valid, mock_session): - with patch( - "openbb_cli.controllers.settings_controller.is_timezone_valid", - return_value=valid, - ): - controller = SettingsController() - args = ["--timezone", timezone] - controller.call_timezone(args) - if valid: - mock_session.settings.set_item.assert_called_with("TIMEZONE", timezone) - else: - mock_session.settings.set_item.assert_not_called() + controller = SettingsController() + args = ["--value", timezone] + controller.call_timezone(args) + if valid: + mock_session.settings.set_item.assert_called_with("TIMEZONE", timezone) + else: + mock_session.settings.set_item.assert_not_called() def test_call_console_style(mock_session): controller = SettingsController() - args = ["--style", "dark"] + args = ["--value", "dark"] controller.call_console_style(args) mock_session.console.print.assert_called() @@ -80,25 +76,25 @@ def test_call_console_style_no_args(mock_session): mock_session.settings.RICH_STYLE = "default" controller = SettingsController() controller.call_console_style([]) - mock_session.console.print.assert_called_with("Current console style: default") + mock_session.console.print.assert_called_with("[info]Current value:[/info] default") def test_call_flair(mock_session): controller = SettingsController() - args = ["--flair", "rocket"] + args = ["--value", "rocket"] controller.call_flair(args) def test_call_flair_no_args(mock_session): - mock_session.settings.FLAIR = "star" + mock_session.settings.FLAIR = "bug" controller = SettingsController() controller.call_flair([]) - mock_session.console.print.assert_called_with("Current flair: star") + mock_session.console.print.assert_called_with("[info]Current value:[/info] bug") def test_call_obbject_display(mock_session): controller = SettingsController() - args = ["--number", "5"] + args = ["--value", "5"] controller.call_obbject_display(args) mock_session.settings.set_item.assert_called_once_with( "N_TO_DISPLAY_OBBJECT_REGISTRY", 5 @@ -109,16 +105,14 @@ def test_call_obbject_display_no_args(mock_session): mock_session.settings.N_TO_DISPLAY_OBBJECT_REGISTRY = 10 controller = SettingsController() controller.call_obbject_display([]) - mock_session.console.print.assert_called_with( - "Current number of results to display from the OBBject registry: 10" - ) + mock_session.console.print.assert_called_with("[info]Current value:[/info] 10") @pytest.mark.parametrize( "args, expected", [ - (["--rows", "50"], 50), - (["--rows", "100"], 100), + (["--value", "50"], 50), + (["--value", "100"], 100), ([], 20), ], ) @@ -131,4 +125,4 @@ def test_call_n_rows_v2(args, expected, mock_session): "ALLOWED_NUMBER_OF_ROWS", expected ) else: - mock_session.console.print.assert_called_with("Current number of rows: 20") + mock_session.console.print.assert_called_with("[info]Current value:[/info] 20") diff --git a/cli/tests/test_controllers_utils.py b/cli/tests/test_controllers_utils.py index 68a8597b2f9..b3a622fc91e 100644 --- a/cli/tests/test_controllers_utils.py +++ b/cli/tests/test_controllers_utils.py @@ -23,13 +23,13 @@ from openbb_cli.controllers.utils import ( @pytest.fixture def mock_session(): """Mock the session and its dependencies.""" - with patch("openbb_cli.controllers.utils.Session", autospec=True) as mock: - mock.return_value.console.print = MagicMock() - mock.return_value.is_local = MagicMock(return_value=True) - mock.return_value.settings.VERSION = "1.0" - mock.return_value.user.profile.hub_session.username = "testuser" - mock.return_value.settings.FLAIR = "rocket" - yield mock + with patch("openbb_cli.controllers.utils.session") as mock_session: + mock_session.console.print = MagicMock() + mock_session.is_local = MagicMock(return_value=True) + mock_session.settings.VERSION = "1.0" + mock_session.user.profile.hub_session.username = "testuser" + mock_session.settings.FLAIR = "rocket" + yield mock_session def test_remove_file_existing_file(): |