-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
10 changed files
with
416 additions
and
12 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
from pathlib import Path | ||
from typing import Type | ||
from unittest.mock import Mock | ||
|
||
import pytest | ||
from poetry.core.packages.dependency import Dependency | ||
from poetry.core.packages.dependency_group import DependencyGroup | ||
from poetry.core.packages.directory_dependency import DirectoryDependency | ||
from poetry.poetry import Poetry | ||
|
||
|
||
@pytest.fixture | ||
def mock_event_gen(): | ||
from poetry.console.commands.command import Command | ||
|
||
def _factory(command_cls: Type[Command], disable_cache: bool): | ||
from cleo.events.console_command_event import ConsoleCommandEvent | ||
|
||
main_grp = DependencyGroup("main") | ||
main_grp.add_dependency(DirectoryDependency("packageB", Path("../packageB"), develop=True)) | ||
main_grp.add_dependency(Dependency("numpy", "==1.5.0")) | ||
|
||
mock_command = Mock(spec=command_cls) | ||
mock_command.poetry = Mock(spec=Poetry) | ||
mock_command.poetry.pyproject_path = Path("/monorepo_root/packageA/pyproject.toml") | ||
mock_command.poetry.package = Mock() | ||
mock_command.poetry.package.name = "packageA" | ||
mock_command.poetry.package.dependency_group = Mock() | ||
mock_command.poetry.package.dependency_group.return_value = main_grp | ||
mock_command.poetry.locker = Mock() | ||
mock_command.poetry.pool = Mock() | ||
mock_command.poetry.config = Mock() | ||
mock_command.poetry.disable_cache = disable_cache | ||
mock_command.option = Mock(return_value=False) | ||
|
||
mock_io = Mock() | ||
|
||
mock_event = Mock(spec=ConsoleCommandEvent) | ||
mock_event.command = mock_command | ||
mock_event.io = mock_io | ||
|
||
return mock_event | ||
|
||
return _factory | ||
|
||
|
||
@pytest.fixture | ||
def mock_terminate_event_gen(mock_event_gen): | ||
from poetry.console.commands.command import Command | ||
|
||
def _factory(command_cls: Type[Command], disable_cache: bool): | ||
from cleo.events.console_terminate_event import ConsoleTerminateEvent | ||
|
||
mock_event = mock_event_gen(command_cls, disable_cache) | ||
mock_io = mock_event.io | ||
mock_command = mock_event.command | ||
del mock_event | ||
|
||
mock_terminate_event = Mock(spec=ConsoleTerminateEvent) | ||
mock_terminate_event.command = mock_command | ||
mock_terminate_event.io = mock_io | ||
|
||
return mock_terminate_event | ||
|
||
return _factory |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
from pathlib import Path | ||
from unittest.mock import Mock, patch | ||
|
||
import pytest | ||
from poetry.console.commands.lock import LockCommand | ||
from poetry.installation.installer import Installer | ||
from poetry.poetry import Poetry | ||
|
||
from poetry_monoranger_plugin.config import MonorangerConfig | ||
from poetry_monoranger_plugin.lock_modifier import LockModifier | ||
|
||
|
||
@pytest.mark.parametrize("disable_cache", [True, False]) | ||
def test_executes_modifications_for_lock_command(mock_event_gen, disable_cache: bool): | ||
mock_event = mock_event_gen(LockCommand, disable_cache=disable_cache) | ||
mock_command = mock_event.command | ||
config = MonorangerConfig(enabled=True, monorepo_root="../") | ||
lock_modifier = LockModifier(config) | ||
|
||
with ( | ||
patch("poetry_monoranger_plugin.lock_modifier.Factory.create_poetry", autospec=True) as mock_create_poetry, | ||
patch("poetry_monoranger_plugin.lock_modifier.Installer", autospec=True) as mock_installer_cls, | ||
): | ||
mock_create_poetry.return_value = Mock(spec=Poetry) | ||
mock_installer_cls.return_value = Mock(spec=Installer) | ||
|
||
lock_modifier.execute(mock_event) | ||
|
||
# A new poetry project object at the monorepo root should be created | ||
mock_create_poetry.assert_called_once() | ||
assert mock_create_poetry.call_args[1]["cwd"] == Path("/monorepo_root").resolve() | ||
assert mock_create_poetry.call_args[1]["io"] == mock_event.io | ||
assert mock_create_poetry.call_args[1]["disable_cache"] == disable_cache | ||
|
||
# A new installer should be created with the monorepo root poetry project | ||
mock_installer_cls.assert_called_once() | ||
# Env is remained unchanged as it is the responsibility of venv_modifier.py | ||
assert mock_installer_cls.call_args[0][1] == mock_command.env | ||
assert mock_installer_cls.call_args[0][2] == mock_create_poetry.return_value.package | ||
assert mock_installer_cls.call_args[0][3] == mock_create_poetry.return_value.locker | ||
assert mock_installer_cls.call_args[0][4] == mock_create_poetry.return_value.pool | ||
assert mock_installer_cls.call_args[0][5] == mock_create_poetry.return_value.config | ||
assert mock_installer_cls.call_args[1]["disable_cache"] == mock_create_poetry.return_value.disable_cache | ||
|
||
# The new poetry and installer objects should be set on the command | ||
assert mock_command.set_poetry.call_args[0][0] == mock_create_poetry.return_value | ||
assert mock_command.set_installer.call_args[0][0] == mock_installer_cls.return_value |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
from pathlib import Path | ||
from unittest.mock import Mock, patch | ||
|
||
import pytest | ||
from poetry.console.commands.add import AddCommand | ||
from poetry.installation.installer import Installer | ||
from poetry.poetry import Poetry | ||
|
||
from poetry_monoranger_plugin.config import MonorangerConfig | ||
from poetry_monoranger_plugin.monorepo_adder import DummyInstaller, MonorepoAdderRemover | ||
|
||
|
||
@pytest.mark.parametrize("disable_cache", [True, False]) | ||
def test_executes_modifications_for_addremove_command(mock_event_gen, disable_cache: bool): | ||
mock_event = mock_event_gen(AddCommand, disable_cache=disable_cache) | ||
mock_command = mock_event.command | ||
config = MonorangerConfig(enabled=True, monorepo_root="../") | ||
adder_remover = MonorepoAdderRemover(config) | ||
|
||
with patch("poetry_monoranger_plugin.monorepo_adder.Poetry.__new__", autospec=True) as mock_poetry: | ||
mock_poetry.return_value = Mock(spec=Poetry) | ||
|
||
adder_remover.execute(mock_event) | ||
|
||
mock_poetry.assert_called_once() | ||
assert mock_command.set_poetry.call_args[0][0] == mock_poetry.return_value | ||
assert isinstance(mock_command.set_installer.call_args[0][0], DummyInstaller) | ||
|
||
|
||
@pytest.mark.parametrize("disable_cache", [True, False]) | ||
def test_executes_modifications_post_addremove_command(mock_terminate_event_gen, disable_cache: bool): | ||
# Here we test the .post_execute command | ||
mock_event = mock_terminate_event_gen(AddCommand, disable_cache=disable_cache) | ||
mock_command = mock_event.command | ||
config = MonorangerConfig(enabled=True, monorepo_root="../") | ||
adder_remover = MonorepoAdderRemover(config) | ||
|
||
with ( | ||
patch("poetry_monoranger_plugin.monorepo_adder.Factory.create_poetry", autospec=True) as mock_create_poetry, | ||
patch("poetry_monoranger_plugin.monorepo_adder.Installer", autospec=True) as mock_installer_cls, | ||
): | ||
mock_create_poetry.return_value = Mock(spec=Poetry) | ||
mock_installer_cls.return_value = Mock(spec=Installer) | ||
|
||
adder_remover.post_execute(mock_event) | ||
|
||
# A new poetry project object at the monorepo root should be created | ||
mock_create_poetry.assert_called_once() | ||
assert mock_create_poetry.call_args[1]["cwd"] == Path("/monorepo_root").resolve() | ||
assert mock_create_poetry.call_args[1]["io"] == mock_event.io | ||
assert mock_create_poetry.call_args[1]["disable_cache"] == disable_cache | ||
|
||
# A new installer should be created with the monorepo root poetry project | ||
mock_installer_cls.assert_called_once() | ||
# Env is remained unchanged as it is the responsibility of venv_modifier.py | ||
assert mock_installer_cls.call_args[0][1] == mock_command.env | ||
assert mock_installer_cls.call_args[0][2] == mock_create_poetry.return_value.package | ||
assert mock_installer_cls.call_args[0][3] == mock_create_poetry.return_value.locker | ||
assert mock_installer_cls.call_args[0][4] == mock_create_poetry.return_value.pool | ||
assert mock_installer_cls.call_args[0][5] == mock_create_poetry.return_value.config | ||
assert mock_installer_cls.call_args[1]["disable_cache"] == mock_create_poetry.return_value.disable_cache | ||
|
||
# Check settings of installer | ||
assert mock_installer_cls.return_value.dry_run.call_args[0][0] == mock_command.option("dry-run") | ||
assert mock_installer_cls.return_value.verbose.call_args[0][0] == mock_event.io.is_verbose() | ||
assert mock_installer_cls.return_value.update.call_args[0][0] is True | ||
assert mock_installer_cls.return_value.execute_operations.call_args[0][0] is not mock_command.option("lock") | ||
|
||
# The whitelist should contain the package name | ||
assert mock_installer_cls.return_value.whitelist.call_args[0][0] == [mock_command.poetry.package.name] | ||
|
||
# The installer should be run | ||
assert mock_installer_cls.return_value.run.call_count == 1 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
import copy | ||
from unittest.mock import Mock, patch | ||
|
||
import pytest | ||
from poetry.console.commands.build import BuildCommand | ||
from poetry.core.packages.directory_dependency import DirectoryDependency | ||
from poetry.core.pyproject.toml import PyProjectTOML | ||
|
||
from poetry_monoranger_plugin.config import MonorangerConfig | ||
from poetry_monoranger_plugin.path_rewriter import PathRewriter | ||
|
||
|
||
@pytest.mark.parametrize("disable_cache", [True, False]) | ||
def test_executes_path_rewriting_for_build_command(mock_event_gen, disable_cache: bool): | ||
mock_event = mock_event_gen(BuildCommand, disable_cache=disable_cache) | ||
mock_command = mock_event.command | ||
config = MonorangerConfig(enabled=True, monorepo_root="../", version_rewrite_rule="==") | ||
path_rewriter = PathRewriter(config) | ||
|
||
original_dependencies = copy.deepcopy(mock_command.poetry.package.dependency_group.return_value.dependencies) | ||
|
||
with patch( | ||
"poetry_monoranger_plugin.path_rewriter.PathRewriter._get_dependency_pyproject", autospec=True | ||
) as mock_get_dep: | ||
mock_get_dep.return_value = Mock(spec=PyProjectTOML) | ||
mock_get_dep.return_value.poetry_config = {"version": "0.1.0", "name": "packageB"} | ||
|
||
path_rewriter.execute(mock_event) | ||
|
||
new_dependencies = mock_command.poetry.package.dependency_group.return_value | ||
|
||
assert len(new_dependencies.dependencies) == len(original_dependencies) | ||
# sort the dependencies by name to ensure they are in the same order | ||
original_dependencies = sorted(original_dependencies, key=lambda x: x.name) | ||
new_dependencies = sorted(new_dependencies.dependencies, key=lambda x: x.name) | ||
for i, dep in enumerate(new_dependencies): | ||
assert dep.name == original_dependencies[i].name | ||
if isinstance(original_dependencies[i], DirectoryDependency): | ||
assert dep.pretty_constraint == "0.1.0" | ||
else: | ||
assert dep.pretty_constraint == original_dependencies[i].pretty_constraint |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
from unittest.mock import Mock, patch | ||
|
||
import pytest | ||
from poetry.console.commands.add import AddCommand | ||
from poetry.console.commands.build import BuildCommand | ||
from poetry.console.commands.command import Command | ||
from poetry.console.commands.env_command import EnvCommand | ||
from poetry.console.commands.install import InstallCommand | ||
from poetry.console.commands.lock import LockCommand | ||
from poetry.console.commands.remove import RemoveCommand | ||
from poetry.console.commands.update import UpdateCommand | ||
|
||
from poetry_monoranger_plugin.config import MonorangerConfig | ||
from poetry_monoranger_plugin.plugin import Monoranger | ||
|
||
|
||
def test_activates_plugin_with_valid_config(): | ||
application = Mock() | ||
application.poetry.pyproject.data = { | ||
"tool": {"poetry-monoranger-plugin": {"enabled": True, "monorepo_root": "../"}} | ||
} | ||
application.event_dispatcher = Mock() | ||
plugin = Monoranger() | ||
plugin.activate(application) | ||
|
||
assert plugin.plugin_conf.enabled is True | ||
assert plugin.plugin_conf.monorepo_root == "../" | ||
application.event_dispatcher.add_listener.assert_called() | ||
|
||
|
||
def test_does_not_activate_plugin_with_disabled_config(): | ||
application = Mock() | ||
application.poetry.pyproject.data = {} | ||
application.event_dispatcher = Mock() | ||
plugin = Monoranger() | ||
plugin.activate(application) | ||
|
||
assert plugin.plugin_conf is None | ||
application.event_dispatcher.add_listener.assert_not_called() | ||
|
||
|
||
@pytest.mark.parametrize( | ||
"cmd_type", | ||
[ | ||
AddCommand, | ||
RemoveCommand, | ||
BuildCommand, | ||
EnvCommand, | ||
LockCommand, | ||
InstallCommand, | ||
UpdateCommand, | ||
], | ||
) | ||
def test_handles_all_command_events(mock_event_gen, cmd_type: type[Command]): | ||
cmd_to_patch: dict[type[Command], str] = { | ||
AddCommand: "poetry_monoranger_plugin.monorepo_adder.MonorepoAdderRemover.execute", | ||
RemoveCommand: "poetry_monoranger_plugin.monorepo_adder.MonorepoAdderRemover.execute", | ||
BuildCommand: "poetry_monoranger_plugin.path_rewriter.PathRewriter.execute", | ||
EnvCommand: "poetry_monoranger_plugin.venv_modifier.VenvModifier.execute", | ||
LockCommand: "poetry_monoranger_plugin.lock_modifier.LockModifier.execute", | ||
InstallCommand: "poetry_monoranger_plugin.lock_modifier.LockModifier.execute", | ||
UpdateCommand: "poetry_monoranger_plugin.lock_modifier.LockModifier.execute", | ||
} | ||
event = mock_event_gen(cmd_type, disable_cache=False) | ||
plugin = Monoranger() | ||
plugin.plugin_conf = MonorangerConfig(enabled=True, monorepo_root="../") | ||
with patch(cmd_to_patch[cmd_type]) as mock_execute: | ||
plugin.console_command_event_listener(event, "", Mock()) | ||
mock_execute.assert_called_once_with(event) |
Oops, something went wrong.