From b4a9f80038e91e3b8cda9d1c5ff1f69bb8785608 Mon Sep 17 00:00:00 2001 From: Nikita Date: Sun, 4 Dec 2022 12:17:49 +0400 Subject: [PATCH] fix orderer (#44) --- tests/core/scenario_orderer/_utils.py | 13 +++++ .../test_plain_scenario_orderer.py | 52 +++++++++++++++++++ .../test_stable_scenario_orderer.py | 2 +- vedro/_config.py | 4 +- vedro/core/scenario_orderer/__init__.py | 3 +- .../_plain_scenario_orderer.py | 1 + .../_stable_scenario_orderer.py | 16 ++++++ vedro/plugins/orderer/orderer_plugin.py | 12 +++-- vedro/plugins/orderer/reversed_orderer.py | 3 +- vedro/plugins/orderer/stable_orderer.py | 15 +----- 10 files changed, 98 insertions(+), 23 deletions(-) create mode 100644 tests/core/scenario_orderer/_utils.py create mode 100644 tests/core/scenario_orderer/test_plain_scenario_orderer.py rename tests/{plugins/orderer => core/scenario_orderer}/test_stable_scenario_orderer.py (95%) create mode 100644 vedro/core/scenario_orderer/_stable_scenario_orderer.py diff --git a/tests/core/scenario_orderer/_utils.py b/tests/core/scenario_orderer/_utils.py new file mode 100644 index 00000000..46625442 --- /dev/null +++ b/tests/core/scenario_orderer/_utils.py @@ -0,0 +1,13 @@ +from pathlib import Path + +from vedro import Scenario +from vedro.core import VirtualScenario + +__all__ = ("make_vscenario",) + + +def make_vscenario(path: str) -> VirtualScenario: + class _Scenario(Scenario): + __file__ = Path(path).absolute() + + return VirtualScenario(_Scenario, steps=[]) diff --git a/tests/core/scenario_orderer/test_plain_scenario_orderer.py b/tests/core/scenario_orderer/test_plain_scenario_orderer.py new file mode 100644 index 00000000..78a110b7 --- /dev/null +++ b/tests/core/scenario_orderer/test_plain_scenario_orderer.py @@ -0,0 +1,52 @@ +import pytest +from baby_steps import given, then, when + +from vedro.core.scenario_orderer import PlainScenarioOrderer + +from ._utils import make_vscenario + + +@pytest.fixture() +def orderer() -> PlainScenarioOrderer: + return PlainScenarioOrderer() + + +@pytest.mark.asyncio +async def test_sort_no_scenarios(*, orderer: PlainScenarioOrderer): + with given: + scenarios = [] + + with when: + res = await orderer.sort(scenarios) + + with then: + assert res == [] + assert scenarios == [] + + +@pytest.mark.asyncio +async def test_sort_scenarios(*, orderer: PlainScenarioOrderer): + with given: + orig_scenarios = {path: make_vscenario(path) for path in [ + "scenarios/directory/scn.py", + "scenarios/dir1/scn1.py", + "scenarios/dir1/scn2.py", + "scenarios/dir2/scn2.py", + "scenarios/scn2.py", + "scenarios/scn10.py", + ]} + scenarios = list(orig_scenarios.values()) + + with when: + res = await orderer.sort(scenarios) + + with then: + assert res == [ + orig_scenarios["scenarios/directory/scn.py"], + orig_scenarios["scenarios/dir1/scn1.py"], + orig_scenarios["scenarios/dir1/scn2.py"], + orig_scenarios["scenarios/dir2/scn2.py"], + orig_scenarios["scenarios/scn2.py"], + orig_scenarios["scenarios/scn10.py"], + ] + assert scenarios == list(orig_scenarios.values()) diff --git a/tests/plugins/orderer/test_stable_scenario_orderer.py b/tests/core/scenario_orderer/test_stable_scenario_orderer.py similarity index 95% rename from tests/plugins/orderer/test_stable_scenario_orderer.py rename to tests/core/scenario_orderer/test_stable_scenario_orderer.py index 4b47ff7b..31b2590e 100644 --- a/tests/plugins/orderer/test_stable_scenario_orderer.py +++ b/tests/core/scenario_orderer/test_stable_scenario_orderer.py @@ -1,7 +1,7 @@ import pytest from baby_steps import given, then, when -from vedro.plugins.orderer import StableScenarioOrderer +from vedro.core.scenario_orderer import StableScenarioOrderer from ._utils import make_vscenario diff --git a/vedro/_config.py b/vedro/_config.py index eb3dba3e..373babd4 100644 --- a/vedro/_config.py +++ b/vedro/_config.py @@ -37,7 +37,7 @@ ExtFilter, HiddenFilter, ) -from vedro.core.scenario_orderer import PlainScenarioOrderer +from vedro.core.scenario_orderer import StableScenarioOrderer __all__ = ("Config",) @@ -54,7 +54,7 @@ class Registry(core.Config.Registry): ScenarioLoader = Factory[ScenarioLoader](ScenarioFileLoader) - ScenarioOrderer = Factory[ScenarioOrderer](PlainScenarioOrderer) + ScenarioOrderer = Factory[ScenarioOrderer](StableScenarioOrderer) ScenarioDiscoverer = Factory[ScenarioDiscoverer](lambda: MultiScenarioDiscoverer( finder=Config.Registry.ScenarioFinder(), diff --git a/vedro/core/scenario_orderer/__init__.py b/vedro/core/scenario_orderer/__init__.py index e7af521a..f130bd83 100644 --- a/vedro/core/scenario_orderer/__init__.py +++ b/vedro/core/scenario_orderer/__init__.py @@ -1,4 +1,5 @@ from ._plain_scenario_orderer import PlainScenarioOrderer from ._scenario_orderer import ScenarioOrderer +from ._stable_scenario_orderer import StableScenarioOrderer -__all__ = ("ScenarioOrderer", "PlainScenarioOrderer",) +__all__ = ("ScenarioOrderer", "PlainScenarioOrderer", "StableScenarioOrderer",) diff --git a/vedro/core/scenario_orderer/_plain_scenario_orderer.py b/vedro/core/scenario_orderer/_plain_scenario_orderer.py index c80b9d67..8684f10c 100644 --- a/vedro/core/scenario_orderer/_plain_scenario_orderer.py +++ b/vedro/core/scenario_orderer/_plain_scenario_orderer.py @@ -6,6 +6,7 @@ __all__ = ("PlainScenarioOrderer",) +# deprecated class PlainScenarioOrderer(ScenarioOrderer): async def sort(self, scenarios: List[VirtualScenario]) -> List[VirtualScenario]: return scenarios diff --git a/vedro/core/scenario_orderer/_stable_scenario_orderer.py b/vedro/core/scenario_orderer/_stable_scenario_orderer.py new file mode 100644 index 00000000..006955c1 --- /dev/null +++ b/vedro/core/scenario_orderer/_stable_scenario_orderer.py @@ -0,0 +1,16 @@ +from pathlib import Path +from typing import Any, List, Tuple + +from .._virtual_scenario import VirtualScenario +from ._scenario_orderer import ScenarioOrderer + +__all__ = ("StableScenarioOrderer",) + + +class StableScenarioOrderer(ScenarioOrderer): + def _cmp(self, scn: VirtualScenario) -> Tuple[Any, ...]: + path = Path(scn.path) + return (len(path.parts),) + tuple((len(x), x) for x in path.parts) + + async def sort(self, scenarios: List[VirtualScenario]) -> List[VirtualScenario]: + return list(sorted(scenarios, key=self._cmp)) diff --git a/vedro/plugins/orderer/orderer_plugin.py b/vedro/plugins/orderer/orderer_plugin.py index 19058844..c89a8399 100644 --- a/vedro/plugins/orderer/orderer_plugin.py +++ b/vedro/plugins/orderer/orderer_plugin.py @@ -1,9 +1,9 @@ from vedro.core import ConfigType, Dispatcher, Plugin, PluginConfig +from vedro.core.scenario_orderer import StableScenarioOrderer from vedro.events import ArgParsedEvent, ArgParseEvent, ConfigLoadedEvent from .random_orderer import RandomOrderer from .reversed_orderer import ReversedOrderer -from .stable_orderer import StableScenarioOrderer __all__ = ("Orderer", "OrdererPlugin") @@ -29,11 +29,15 @@ def on_arg_parse(self, event: ArgParseEvent) -> None: help="Set random scenario order") def on_arg_parsed(self, event: ArgParsedEvent) -> None: + if event.args.order_random: + self._global_config.Registry.ScenarioOrderer.register(RandomOrderer, self) + return + if event.args.order_reversed: self._global_config.Registry.ScenarioOrderer.register(ReversedOrderer, self) - elif event.args.order_random: - self._global_config.Registry.ScenarioOrderer.register(RandomOrderer, self) - else: + return + + if event.args.order_stable: self._global_config.Registry.ScenarioOrderer.register(StableScenarioOrderer, self) diff --git a/vedro/plugins/orderer/reversed_orderer.py b/vedro/plugins/orderer/reversed_orderer.py index f1bb0fbc..e4e4968a 100644 --- a/vedro/plugins/orderer/reversed_orderer.py +++ b/vedro/plugins/orderer/reversed_orderer.py @@ -1,8 +1,7 @@ from typing import List from vedro.core import VirtualScenario - -from .stable_orderer import StableScenarioOrderer +from vedro.core.scenario_orderer import StableScenarioOrderer __all__ = ("ReversedOrderer",) diff --git a/vedro/plugins/orderer/stable_orderer.py b/vedro/plugins/orderer/stable_orderer.py index 554d30f1..b9d57979 100644 --- a/vedro/plugins/orderer/stable_orderer.py +++ b/vedro/plugins/orderer/stable_orderer.py @@ -1,15 +1,4 @@ -from pathlib import Path -from typing import Any, List, Tuple - -from vedro.core import ScenarioOrderer, VirtualScenario +# backward compatibility +from vedro.core.scenario_orderer import StableScenarioOrderer __all__ = ("StableScenarioOrderer",) - - -class StableScenarioOrderer(ScenarioOrderer): - def _cmp(self, scn: VirtualScenario) -> Tuple[Any, ...]: - path = Path(scn.path) - return (len(path.parts),) + tuple((len(x), x) for x in path.parts) - - async def sort(self, scenarios: List[VirtualScenario]) -> List[VirtualScenario]: - return list(sorted(scenarios, key=self._cmp))