From 38fa7068cab89eb4393ab6629613857f9e3660c8 Mon Sep 17 00:00:00 2001 From: Oliver Bristow Date: Fri, 4 Apr 2025 01:13:25 +0100 Subject: [PATCH 1/3] Add test for coupling of AVAILABLE_CLI_OPTIONS and ARGS_* --- freqtrade/commands/arguments.py | 4 +++- tests/test_arguments.py | 28 ++++++++++++++++++++++++++-- 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/freqtrade/commands/arguments.py b/freqtrade/commands/arguments.py index e166b0903..a639d1f87 100755 --- a/freqtrade/commands/arguments.py +++ b/freqtrade/commands/arguments.py @@ -21,6 +21,8 @@ ARGS_COMMON = [ "user_data_dir", ] +ARGS_MAIN = ["version_main"] + ARGS_STRATEGY = [ "strategy", "strategy_path", @@ -347,7 +349,7 @@ class Arguments: self.parser = ArgumentParser( prog="freqtrade", description="Free, open source crypto trading bot" ) - self._build_args(optionlist=["version_main"], parser=self.parser) + self._build_args(optionlist=ARGS_MAIN, parser=self.parser) from freqtrade.commands import ( start_analysis_entries_exits, diff --git a/tests/test_arguments.py b/tests/test_arguments.py index 1d48acb96..dbd0bd5f7 100644 --- a/tests/test_arguments.py +++ b/tests/test_arguments.py @@ -5,11 +5,35 @@ from unittest.mock import MagicMock import pytest -from freqtrade.commands import Arguments -from freqtrade.commands.cli_options import check_int_nonzero, check_int_positive +from freqtrade.commands import Arguments, arguments +from freqtrade.commands.cli_options import ( + check_int_nonzero, + check_int_positive, + AVAILABLE_CLI_OPTIONS, +) from tests.conftest import CURRENT_TEST_STRATEGY +def test_available_cli_options(): + """AVAILABLE_CLI_OPTIONS has keys that are the union of the values in all ARGS_* - required by CLI""" + # each of the ARGS_* lists has a list of members which is assumed to also be in AVAILABLE_CLI_OPTIONS + args_union = { + arg + for variable, value in vars(arguments).items() + if variable.startswith("ARGS_") + for arg in value + } + expected_options = set(AVAILABLE_CLI_OPTIONS) + only_in_command_args = expected_options.difference(args_union) + only_in_all_args = args_union.difference(expected_options) + if only_in_all_args or only_in_command_args: + pytest.fail( + "variables around command line arguments not kept in sync:\n" + f" * args only in some ARGS_* list but not AVAILABLE_CLI_OPTIONS: {only_in_all_args}\n" + f" * args only in AVAILABLE_CLI_OPTIONS but not some ARGS_* list: {only_in_command_args}" + ) + + # Parse common command-line-arguments. Used for all tools def test_parse_args_none() -> None: arguments = Arguments(["trade"]) From 55be046933a1d0028b500be70ac6d2c7d1071cef Mon Sep 17 00:00:00 2001 From: Oliver Bristow Date: Fri, 4 Apr 2025 01:47:01 +0100 Subject: [PATCH 2/3] Add test for coupling of AVAILABLE_CLI_OPTIONS and Arguments --- tests/test_arguments.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/tests/test_arguments.py b/tests/test_arguments.py index dbd0bd5f7..88915a96c 100644 --- a/tests/test_arguments.py +++ b/tests/test_arguments.py @@ -34,6 +34,21 @@ def test_available_cli_options(): ) +def test_arguments_match_available_cli_options(monkeypatch): + """All entries in AVAILABLE_CLI_OPTIONS are used in argument parsing.""" + parsed_options = set() + actual_build_args = Arguments._build_args + + def build_args_monitor(self, optionlist, parser): + parsed_options.update(optionlist) + return actual_build_args(self, optionlist=optionlist, parser=parser) + + monkeypatch.setattr(Arguments, "_build_args", build_args_monitor) + # this will result in a parser being built so we can check the arguments used + Arguments([]).get_parsed_arg() + assert parsed_options == set(AVAILABLE_CLI_OPTIONS) + + # Parse common command-line-arguments. Used for all tools def test_parse_args_none() -> None: arguments = Arguments(["trade"]) From f817b21d17cbc6854260088601fb6efdfa5976a8 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 5 Apr 2025 18:14:20 +0200 Subject: [PATCH 3/3] chore: fix ruff --- tests/test_arguments.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/tests/test_arguments.py b/tests/test_arguments.py index 88915a96c..913f4759d 100644 --- a/tests/test_arguments.py +++ b/tests/test_arguments.py @@ -7,16 +7,19 @@ import pytest from freqtrade.commands import Arguments, arguments from freqtrade.commands.cli_options import ( + AVAILABLE_CLI_OPTIONS, check_int_nonzero, check_int_positive, - AVAILABLE_CLI_OPTIONS, ) from tests.conftest import CURRENT_TEST_STRATEGY def test_available_cli_options(): - """AVAILABLE_CLI_OPTIONS has keys that are the union of the values in all ARGS_* - required by CLI""" - # each of the ARGS_* lists has a list of members which is assumed to also be in AVAILABLE_CLI_OPTIONS + """ + AVAILABLE_CLI_OPTIONS has keys that are the union of the values in all ARGS_* - required by CLI + each of the ARGS_* lists has a list of members which is assumed to also + be in AVAILABLE_CLI_OPTIONS + """ args_union = { arg for variable, value in vars(arguments).items() @@ -30,7 +33,8 @@ def test_available_cli_options(): pytest.fail( "variables around command line arguments not kept in sync:\n" f" * args only in some ARGS_* list but not AVAILABLE_CLI_OPTIONS: {only_in_all_args}\n" - f" * args only in AVAILABLE_CLI_OPTIONS but not some ARGS_* list: {only_in_command_args}" + " * args only in AVAILABLE_CLI_OPTIONS but not some ARGS_* list: " + f"{only_in_command_args}" )