From a979dabe96b6baff5ff07e2f016777181881d337 Mon Sep 17 00:00:00 2001 From: Arun Babu Neelicattu Date: Thu, 10 Sep 2020 19:18:05 +0200 Subject: [PATCH] tests: clean up fixtures and console tests This change cleans up a few of the fixtures used in the test suite to be more consistent and also renames ambiguous helper classes. --- tests/conftest.py | 141 ++++++++++++++++ tests/console/commands/debug/test_resolve.py | 20 +-- tests/console/commands/env/conftest.py | 51 ++++++ tests/console/commands/env/helpers.py | 21 +++ tests/console/commands/env/test_info.py | 17 +- tests/console/commands/env/test_list.py | 80 +++------- tests/console/commands/env/test_remove.py | 50 ++---- tests/console/commands/env/test_use.py | 125 +++++---------- tests/console/commands/self/test_update.py | 12 +- tests/console/commands/test_about.py | 11 +- tests/console/commands/test_add.py | 24 +-- tests/console/commands/test_cache.py | 15 +- tests/console/commands/test_check.py | 15 +- tests/console/commands/test_config.py | 51 ++---- tests/console/commands/test_export.py | 142 +++------------- tests/console/commands/test_init.py | 160 +++---------------- tests/console/commands/test_run.py | 14 +- tests/console/commands/test_search.py | 17 +- tests/console/commands/test_show.py | 94 +++-------- tests/console/commands/test_version.py | 15 +- tests/console/conftest.py | 153 +----------------- tests/helpers.py | 117 ++++++++++++++ 22 files changed, 571 insertions(+), 774 deletions(-) create mode 100644 tests/console/commands/env/conftest.py create mode 100644 tests/console/commands/env/helpers.py diff --git a/tests/conftest.py b/tests/conftest.py index 2d5f502b0e3..15f7b56e567 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,5 +1,7 @@ import os +import re import shutil +import sys import tempfile from typing import Any @@ -8,13 +10,25 @@ import httpretty import pytest +from cleo import CommandTester + from poetry.config.config import Config as BaseConfig from poetry.config.dict_config_source import DictConfigSource +from poetry.factory import Factory from poetry.inspection.info import PackageInfo from poetry.inspection.info import PackageInfoError +from poetry.installation import Installer +from poetry.layouts import layout +from poetry.repositories import Pool +from poetry.repositories import Repository from poetry.utils._compat import Path from poetry.utils.env import EnvManager +from poetry.utils.env import SystemEnv from poetry.utils.env import VirtualEnv +from tests.helpers import TestExecutor +from tests.helpers import TestLocker +from tests.helpers import TestRepository +from tests.helpers import get_package from tests.helpers import mock_clone from tests.helpers import mock_download @@ -168,3 +182,130 @@ def tmp_venv(tmp_dir): yield venv shutil.rmtree(str(venv.path)) + + +@pytest.fixture +def installed(): + return Repository() + + +@pytest.fixture(scope="session") +def current_env(): + return SystemEnv(Path(sys.executable)) + + +@pytest.fixture(scope="session") +def current_python(current_env): + return current_env.version_info[:3] + + +@pytest.fixture(scope="session") +def default_python(current_python): + return "^{}".format(".".join(str(v) for v in current_python[:2])) + + +@pytest.fixture +def repo(http): + http.register_uri( + http.GET, re.compile("^https?://foo.bar/(.+?)$"), + ) + return TestRepository(name="foo") + + +@pytest.fixture +def project_factory(tmp_dir, config, repo, installed, default_python): + workspace = Path(tmp_dir) + + def _factory( + name=None, + dependencies=None, + dev_dependencies=None, + pyproject_content=None, + install_deps=True, + ): + project_dir = workspace / "poetry-fixture-{}".format(name) + dependencies = dependencies or {} + dev_dependencies = dev_dependencies or {} + + if pyproject_content: + project_dir.mkdir(parents=True, exist_ok=True) + with project_dir.joinpath("pyproject.toml").open( + "w", encoding="utf-8" + ) as f: + f.write(pyproject_content) + else: + layout("src")( + name, + "0.1.0", + author="PyTest Tester ", + readme_format="md", + python=default_python, + dependencies=dependencies, + dev_dependencies=dev_dependencies, + ).create(project_dir, with_tests=False) + + poetry = Factory().create_poetry(project_dir) + + locker = TestLocker( + poetry.locker.lock.path, poetry.locker._local_config + ) # noqa + locker.write() + + poetry.set_locker(locker) + poetry.set_config(config) + + pool = Pool() + pool.add_repository(repo) + + poetry.set_pool(pool) + + if install_deps: + for deps in [dependencies, dev_dependencies]: + for name, version in deps.items(): + pkg = get_package(name, version) + repo.add_package(pkg) + installed.add_package(pkg) + + return poetry + + return _factory + + +@pytest.fixture +def command_tester_factory(app, env): + def _tester(command, poetry=None, installer=None, executor=None, environment=None): + command = app.find(command) + tester = CommandTester(command) + + if poetry: + app._poetry = poetry + + poetry = app.poetry + command._pool = poetry.pool + + if hasattr(command, "set_env"): + command.set_env(environment or env) + + if hasattr(command, "set_installer"): + installer = installer or Installer( + tester.io, + env, + poetry.package, + poetry.locker, + poetry.pool, + poetry.config, + executor=executor + or TestExecutor(env, poetry.pool, poetry.config, tester.io), + ) + installer.use_executor(True) + command.set_installer(installer) + + return tester + + return _tester + + +@pytest.fixture +def do_lock(command_tester_factory, poetry): + command_tester_factory("lock").execute() + assert poetry.locker.lock.exists() diff --git a/tests/console/commands/debug/test_resolve.py b/tests/console/commands/debug/test_resolve.py index f96c36fc062..ad7e94321d2 100644 --- a/tests/console/commands/debug/test_resolve.py +++ b/tests/console/commands/debug/test_resolve.py @@ -1,13 +1,15 @@ -from cleo.testers import CommandTester +import pytest from poetry.factory import Factory from tests.helpers import get_package -def test_debug_resolve_gives_resolution_results(app, repo): - command = app.find("debug resolve") - tester = CommandTester(command) +@pytest.fixture() +def tester(command_tester_factory): + return command_tester_factory("debug resolve") + +def test_debug_resolve_gives_resolution_results(tester, repo): cachy2 = get_package("cachy", "0.2.0") cachy2.add_dependency(Factory.create_dependency("msgpack-python", ">=0.5 <0.6")) @@ -29,10 +31,7 @@ def test_debug_resolve_gives_resolution_results(app, repo): assert expected == tester.io.fetch_output() -def test_debug_resolve_tree_option_gives_the_dependency_tree(app, repo): - command = app.find("debug resolve") - tester = CommandTester(command) - +def test_debug_resolve_tree_option_gives_the_dependency_tree(tester, repo): cachy2 = get_package("cachy", "0.2.0") cachy2.add_dependency(Factory.create_dependency("msgpack-python", ">=0.5 <0.6")) @@ -54,13 +53,10 @@ def test_debug_resolve_tree_option_gives_the_dependency_tree(app, repo): assert expected == tester.io.fetch_output() -def test_debug_resolve_git_dependency(app, repo): +def test_debug_resolve_git_dependency(tester, repo): repo.add_package(get_package("pendulum", "2.0.3")) repo.add_package(get_package("cleo", "0.6.5")) - command = app.find("debug resolve") - tester = CommandTester(command) - tester.execute("git+https://github.com/demo/demo.git") expected = """\ diff --git a/tests/console/commands/env/conftest.py b/tests/console/commands/env/conftest.py new file mode 100644 index 00000000000..5fbddf1aa6f --- /dev/null +++ b/tests/console/commands/env/conftest.py @@ -0,0 +1,51 @@ +import os + +import pytest + +from poetry.utils._compat import Path +from poetry.utils.env import EnvManager + + +@pytest.fixture +def venv_name(app): + return EnvManager.generate_env_name("simple-project", str(app.poetry.file.parent)) + + +@pytest.fixture +def venv_cache(tmp_dir): + return Path(tmp_dir) + + +@pytest.fixture(scope="module") +def python_versions(): + return ["3.6", "3.7"] + + +@pytest.fixture +def venvs_in_cache_config(app, venv_cache): + app.poetry.config.merge({"virtualenvs": {"path": str(venv_cache)}}) + + +@pytest.fixture +def venvs_in_cache_dirs( + app, venvs_in_cache_config, venv_name, venv_cache, python_versions +): + directories = [] + for version in python_versions: + directory = venv_cache.joinpath("{}-py{}".format(venv_name, version)) + directory.mkdir(parents=True, exist_ok=True) + directories.append(directory.name) + return directories + + +@pytest.fixture +def venvs_in_project_dir(app): + os.environ.pop("VIRTUAL_ENV", None) + venv_dir = app.poetry.file.parent.joinpath(".venv") + venv_dir.mkdir(exist_ok=True) + app.poetry.config.merge({"virtualenvs": {"in-project": True}}) + + try: + yield venv_dir + finally: + venv_dir.rmdir() diff --git a/tests/console/commands/env/helpers.py b/tests/console/commands/env/helpers.py new file mode 100644 index 00000000000..17d4c2ac274 --- /dev/null +++ b/tests/console/commands/env/helpers.py @@ -0,0 +1,21 @@ +from typing import Optional +from typing import Union + +from poetry.core.semver import Version +from poetry.utils._compat import Path + + +def build_venv(path, executable=None): # type: (Union[Path,str], Optional[str]) -> () + Path(path).mkdir(parents=True, exist_ok=True) + + +def check_output_wrapper(version=Version.parse("3.7.1")): + def check_output(cmd, *args, **kwargs): + if "sys.version_info[:3]" in cmd: + return version.text + elif "sys.version_info[:2]" in cmd: + return "{}.{}".format(version.major, version.minor) + else: + return str(Path("/prefix")) + + return check_output diff --git a/tests/console/commands/env/test_info.py b/tests/console/commands/env/test_info.py index 775680f13dc..9d1a0c8426a 100644 --- a/tests/console/commands/env/test_info.py +++ b/tests/console/commands/env/test_info.py @@ -1,7 +1,5 @@ import pytest -from cleo.testers import CommandTester - from poetry.utils._compat import Path from poetry.utils.env import MockEnv @@ -16,10 +14,12 @@ def setup(mocker): ) -def test_env_info_displays_complete_info(app): - command = app.find("env info") - tester = CommandTester(command) +@pytest.fixture +def tester(command_tester_factory): + return command_tester_factory("env info") + +def test_env_info_displays_complete_info(tester): tester.execute() expected = """ @@ -40,12 +40,7 @@ def test_env_info_displays_complete_info(app): assert expected == tester.io.fetch_output() -def test_env_info_displays_path_only(app): - command = app.find("env info") - tester = CommandTester(command) - +def test_env_info_displays_path_only(tester): tester.execute("--path") - expected = str(Path("/prefix")) - assert expected + "\n" == tester.io.fetch_output() diff --git a/tests/console/commands/env/test_list.py b/tests/console/commands/env/test_list.py index e2946373b6a..12c3b432236 100644 --- a/tests/console/commands/env/test_list.py +++ b/tests/console/commands/env/test_list.py @@ -1,78 +1,38 @@ -import os - +import pytest import tomlkit -from cleo.testers import CommandTester - -from poetry.utils._compat import Path -from poetry.utils.env import EnvManager from poetry.utils.toml_file import TomlFile -def test_none_activated(app, tmp_dir, mocker, env): - mocker.patch("poetry.utils.env.EnvManager.get", return_value=env) - - app.poetry.config.merge({"virtualenvs": {"path": str(tmp_dir)}}) - - venv_name = EnvManager.generate_env_name( - "simple-project", str(app.poetry.file.parent) - ) - (Path(tmp_dir) / "{}-py3.7".format(venv_name)).mkdir() - (Path(tmp_dir) / "{}-py3.6".format(venv_name)).mkdir() - - command = app.find("env list") - tester = CommandTester(command) - tester.execute() - - expected = """\ -{}-py3.6 -{}-py3.7 -""".format( - venv_name, venv_name - ) - - assert expected == tester.io.fetch_output() - - -def test_activated(app, tmp_dir): - app.poetry.config.merge({"virtualenvs": {"path": str(tmp_dir)}}) - - venv_name = EnvManager.generate_env_name( - "simple-project", str(app.poetry.file.parent) - ) - (Path(tmp_dir) / "{}-py3.7".format(venv_name)).mkdir() - (Path(tmp_dir) / "{}-py3.6".format(venv_name)).mkdir() - - envs_file = TomlFile(Path(tmp_dir) / "envs.toml") +@pytest.fixture +def venv_activate_37(venv_cache, venv_name): + envs_file = TomlFile(venv_cache / "envs.toml") doc = tomlkit.document() doc[venv_name] = {"minor": "3.7", "patch": "3.7.0"} envs_file.write(doc) - command = app.find("env list") - tester = CommandTester(command) - tester.execute() - expected = """\ -{}-py3.6 -{}-py3.7 (Activated) -""".format( - venv_name, venv_name - ) - - assert expected == tester.io.fetch_output() +@pytest.fixture +def tester(command_tester_factory): + return command_tester_factory("env list") -def test_in_project_venv(app, tmpdir): - os.environ.pop("VIRTUAL_ENV", None) - app.poetry.config.merge({"virtualenvs": {"in-project": True}}) +def test_none_activated(tester, venvs_in_cache_dirs, mocker, env): + mocker.patch("poetry.utils.env.EnvManager.get", return_value=env) + tester.execute() + expected = "\n".join(venvs_in_cache_dirs).strip() + assert expected == tester.io.fetch_output().strip() - (app.poetry.file.parent / ".venv").mkdir(exist_ok=True) - command = app.find("env list") - tester = CommandTester(command) +def test_activated(tester, venvs_in_cache_dirs, venv_cache, venv_activate_37): tester.execute() + expected = ( + "\n".join(venvs_in_cache_dirs).strip().replace("py3.7", "py3.7 (Activated)") + ) + assert expected == tester.io.fetch_output().strip() - expected = ".venv (Activated)\n" +def test_in_project_venv(tester, venvs_in_project_dir): + tester.execute() + expected = ".venv (Activated)\n" assert expected == tester.io.fetch_output() - (app.poetry.file.parent / ".venv").rmdir() diff --git a/tests/console/commands/env/test_remove.py b/tests/console/commands/env/test_remove.py index bf3c3a6c4fb..2b4f3ae775c 100644 --- a/tests/console/commands/env/test_remove.py +++ b/tests/console/commands/env/test_remove.py @@ -1,57 +1,41 @@ -from cleo.testers import CommandTester +import pytest -from poetry.utils._compat import Path -from poetry.utils.env import EnvManager +from poetry.core.semver.version import Version +from tests.console.commands.env.helpers import check_output_wrapper -from .test_use import Version -from .test_use import check_output_wrapper +@pytest.fixture +def tester(command_tester_factory): + return command_tester_factory("env remove") -def test_remove_by_python_version(app, tmp_dir, mocker): - app.poetry.config.merge({"virtualenvs": {"path": str(tmp_dir)}}) - - venv_name = EnvManager.generate_env_name( - "simple-project", str(app.poetry.file.parent) - ) - (Path(tmp_dir) / "{}-py3.7".format(venv_name)).mkdir() - (Path(tmp_dir) / "{}-py3.6".format(venv_name)).mkdir() +def test_remove_by_python_version( + mocker, tester, venvs_in_cache_dirs, venv_name, venv_cache +): check_output = mocker.patch( "poetry.utils._compat.subprocess.check_output", side_effect=check_output_wrapper(Version.parse("3.6.6")), ) - command = app.find("env remove") - tester = CommandTester(command) tester.execute("3.6") assert check_output.called - assert not (Path(tmp_dir) / "{}-py3.6".format(venv_name)).exists() + assert not (venv_cache / "{}-py3.6".format(venv_name)).exists() expected = "Deleted virtualenv: {}\n".format( - (Path(tmp_dir) / "{}-py3.6".format(venv_name)) + (venv_cache / "{}-py3.6".format(venv_name)) ) - assert expected == tester.io.fetch_output() -def test_remove_by_name(app, tmp_dir): - app.poetry.config.merge({"virtualenvs": {"path": str(tmp_dir)}}) +def test_remove_by_name(tester, venvs_in_cache_dirs, venv_name, venv_cache): + expected = "" - venv_name = EnvManager.generate_env_name( - "simple-project", str(app.poetry.file.parent) - ) - (Path(tmp_dir) / "{}-py3.7".format(venv_name)).mkdir() - (Path(tmp_dir) / "{}-py3.6".format(venv_name)).mkdir() + for name in venvs_in_cache_dirs: + tester.execute(name) - command = app.find("env remove") - tester = CommandTester(command) - tester.execute("{}-py3.6".format(venv_name)) + assert not (venv_cache / name).exists() - assert not (Path(tmp_dir) / "{}-py3.6".format(venv_name)).exists() - - expected = "Deleted virtualenv: {}\n".format( - (Path(tmp_dir) / "{}-py3.6".format(venv_name)) - ) + expected += "Deleted virtualenv: {}\n".format((venv_cache / name)) assert expected == tester.io.fetch_output() diff --git a/tests/console/commands/env/test_use.py b/tests/console/commands/env/test_use.py index 777c011d40e..aeb67a94264 100644 --- a/tests/console/commands/env/test_use.py +++ b/tests/console/commands/env/test_use.py @@ -1,69 +1,58 @@ import os -import sys - -from typing import Optional -from typing import Union +import pytest import tomlkit -from cleo.testers import CommandTester - from poetry.core.semver import Version from poetry.utils._compat import Path -from poetry.utils.env import EnvManager from poetry.utils.env import MockEnv from poetry.utils.toml_file import TomlFile +from tests.console.commands.env.helpers import build_venv +from tests.console.commands.env.helpers import check_output_wrapper -CWD = Path(__file__).parent.parent / "fixtures" / "simple_project" - - -def build_venv(path, executable=None): # type: (Union[Path,str], Optional[str]) -> () - os.mkdir(str(path)) - - -def check_output_wrapper(version=Version.parse("3.7.1")): - def check_output(cmd, *args, **kwargs): - if "sys.version_info[:3]" in cmd: - return version.text - elif "sys.version_info[:2]" in cmd: - return "{}.{}".format(version.major, version.minor) - else: - return str(Path("/prefix")) - - return check_output - - -def test_activate_activates_non_existing_virtualenv_no_envs_file(app, tmp_dir, mocker): +@pytest.fixture(autouse=True) +def setup(mocker): mocker.stopall() if "VIRTUAL_ENV" in os.environ: del os.environ["VIRTUAL_ENV"] - app.poetry.config.merge({"virtualenvs": {"path": str(tmp_dir)}}) +@pytest.fixture(autouse=True) +def mock_subprocess_calls(setup, current_python, mocker): mocker.patch( "poetry.utils._compat.subprocess.check_output", - side_effect=check_output_wrapper(), + side_effect=check_output_wrapper(Version(*current_python)), ) mocker.patch( "poetry.utils._compat.subprocess.Popen.communicate", - side_effect=[("/prefix", None), ("/prefix", None)], + side_effect=[("/prefix", None), ("/prefix", None), ("/prefix", None)], ) - m = mocker.patch("poetry.utils.env.EnvManager.build_venv", side_effect=build_venv) - command = app.find("env use") - tester = CommandTester(command) - tester.execute("3.7") - venv_name = EnvManager.generate_env_name( - "simple-project", str(app.poetry.file.parent) +@pytest.fixture +def tester(command_tester_factory): + return command_tester_factory("env use") + + +def test_activate_activates_non_existing_virtualenv_no_envs_file( + mocker, tester, venv_cache, venv_name, venvs_in_cache_config +): + mocker.patch( + "poetry.utils._compat.subprocess.check_output", + side_effect=check_output_wrapper(), ) - m.assert_called_with( - Path(tmp_dir) / "{}-py3.7".format(venv_name), executable="python3.7" + mock_build_env = mocker.patch( + "poetry.utils.env.EnvManager.build_venv", side_effect=build_venv ) - envs_file = TomlFile(Path(tmp_dir) / "envs.toml") + tester.execute("3.7") + + venv_py37 = venv_cache / "{}-py3.7".format(venv_name) + mock_build_env.assert_called_with(venv_py37, executable="python3.7") + + envs_file = TomlFile(venv_cache / "envs.toml") assert envs_file.exists() envs = envs_file.read() assert envs[venv_name]["minor"] == "3.7" @@ -73,70 +62,45 @@ def test_activate_activates_non_existing_virtualenv_no_envs_file(app, tmp_dir, m Creating virtualenv {} in {} Using virtualenv: {} """.format( - "{}-py3.7".format(venv_name), - tmp_dir, - os.path.join(tmp_dir, "{}-py3.7".format(venv_name)), + venv_py37.name, venv_py37.parent, venv_py37, ) assert expected == tester.io.fetch_output() def test_get_prefers_explicitly_activated_virtualenvs_over_env_var( - app, tmp_dir, mocker + tester, current_python, venv_cache, venv_name, venvs_in_cache_config ): - mocker.stopall() os.environ["VIRTUAL_ENV"] = "/environment/prefix" - venv_name = EnvManager.generate_env_name( - "simple-project", str(app.poetry.file.parent) - ) - current_python = sys.version_info[:3] python_minor = ".".join(str(v) for v in current_python[:2]) - python_patch = ".".join(str(v) for v in current_python) - - app.poetry.config.merge({"virtualenvs": {"path": str(tmp_dir)}}) - (Path(tmp_dir) / "{}-py{}".format(venv_name, python_minor)).mkdir() + python_patch = ".".join(str(v) for v in current_python[:3]) + venv_dir = venv_cache / "{}-py{}".format(venv_name, python_minor) + venv_dir.mkdir(parents=True, exist_ok=True) - envs_file = TomlFile(Path(tmp_dir) / "envs.toml") + envs_file = TomlFile(venv_cache / "envs.toml") doc = tomlkit.document() doc[venv_name] = {"minor": python_minor, "patch": python_patch} envs_file.write(doc) - mocker.patch( - "poetry.utils._compat.subprocess.check_output", - side_effect=check_output_wrapper(Version(*current_python)), - ) - mocker.patch( - "poetry.utils._compat.subprocess.Popen.communicate", - side_effect=[("/prefix", None), ("/prefix", None), ("/prefix", None)], - ) - - command = app.find("env use") - tester = CommandTester(command) tester.execute(python_minor) expected = """\ Using virtualenv: {} """.format( - os.path.join(tmp_dir, "{}-py{}".format(venv_name, python_minor)) + venv_dir ) assert expected == tester.io.fetch_output() def test_get_prefers_explicitly_activated_non_existing_virtualenvs_over_env_var( - app, tmp_dir, mocker + mocker, tester, current_python, venv_cache, venv_name, venvs_in_cache_config ): - mocker.stopall() os.environ["VIRTUAL_ENV"] = "/environment/prefix" - venv_name = EnvManager.generate_env_name( - "simple-project", str(app.poetry.file.parent) - ) - current_python = sys.version_info[:3] python_minor = ".".join(str(v) for v in current_python[:2]) - - app.poetry.config.merge({"virtualenvs": {"path": str(tmp_dir)}}) + venv_dir = venv_cache / "{}-py{}".format(venv_name, python_minor) mocker.patch( "poetry.utils.env.EnvManager._env", @@ -148,28 +112,15 @@ def test_get_prefers_explicitly_activated_non_existing_virtualenvs_over_env_var( is_venv=True, ), ) - - mocker.patch( - "poetry.utils._compat.subprocess.check_output", - side_effect=check_output_wrapper(Version(*current_python)), - ) - mocker.patch( - "poetry.utils._compat.subprocess.Popen.communicate", - side_effect=[("/prefix", None), ("/prefix", None), ("/prefix", None)], - ) mocker.patch("poetry.utils.env.EnvManager.build_venv", side_effect=build_venv) - command = app.find("env use") - tester = CommandTester(command) tester.execute(python_minor) expected = """\ Creating virtualenv {} in {} Using virtualenv: {} """.format( - "{}-py{}".format(venv_name, python_minor), - tmp_dir, - os.path.join(tmp_dir, "{}-py{}".format(venv_name, python_minor)), + venv_dir.name, venv_dir.parent, venv_dir, ) assert expected == tester.io.fetch_output() diff --git a/tests/console/commands/self/test_update.py b/tests/console/commands/self/test_update.py index 54fc88635df..6e094111ad0 100644 --- a/tests/console/commands/self/test_update.py +++ b/tests/console/commands/self/test_update.py @@ -1,6 +1,6 @@ import os -from cleo.testers import CommandTester +import pytest from poetry.__version__ import __version__ from poetry.core.packages.package import Package @@ -12,12 +12,17 @@ FIXTURES = Path(__file__).parent.joinpath("fixtures") +@pytest.fixture() +def tester(command_tester_factory): + return command_tester_factory("self update") + + def test_self_update_should_install_all_necessary_elements( - app, http, mocker, environ, tmp_dir + tester, http, mocker, environ, tmp_dir ): os.environ["POETRY_HOME"] = tmp_dir - command = app.find("self update") + command = tester._command version = Version.parse(__version__).next_minor.text mocker.patch( @@ -41,7 +46,6 @@ def test_self_update_should_install_all_necessary_elements( body=FIXTURES.joinpath("poetry-1.0.5-darwin.tar.gz").read_bytes(), ) - tester = CommandTester(command) tester.execute() bin_ = Path(tmp_dir).joinpath("bin") diff --git a/tests/console/commands/test_about.py b/tests/console/commands/test_about.py index 768cf6b33e1..d61308abfdc 100644 --- a/tests/console/commands/test_about.py +++ b/tests/console/commands/test_about.py @@ -1,12 +1,13 @@ -from cleo.testers import CommandTester +import pytest -def test_about(app): - command = app.find("about") - tester = CommandTester(command) +@pytest.fixture() +def tester(command_tester_factory): + return command_tester_factory("about") - tester.execute() +def test_about(tester): + tester.execute() expected = """\ Poetry - Package Management for Python diff --git a/tests/console/commands/test_add.py b/tests/console/commands/test_add.py index af2e093cd04..09fae525aec 100644 --- a/tests/console/commands/test_add.py +++ b/tests/console/commands/test_add.py @@ -5,10 +5,7 @@ import pytest -from cleo.testers import CommandTester - from poetry.core.semver import Version -from poetry.installation.installer import Installer from poetry.repositories.legacy_repository import LegacyRepository from poetry.utils._compat import Path from tests.helpers import get_dependency @@ -16,25 +13,8 @@ @pytest.fixture() -def tester(app, poetry, config, executor, env): - tester = CommandTester(app.find("add")) - - executor._io = tester.io - - installer = Installer( - tester.io, - env, - poetry.package, - poetry.locker, - poetry.pool, - config, - executor=executor, - ) - installer.use_executor(True) - tester._command.set_installer(installer) - tester._command.set_env(env) - - return tester +def tester(command_tester_factory): + return command_tester_factory("add") @pytest.fixture() diff --git a/tests/console/commands/test_cache.py b/tests/console/commands/test_cache.py index 9d70f2890b9..a8d47842d1e 100644 --- a/tests/console/commands/test_cache.py +++ b/tests/console/commands/test_cache.py @@ -2,8 +2,6 @@ import pytest -from cleo.testers import CommandTester - @pytest.fixture def repository_cache_dir(monkeypatch, tmpdir): @@ -32,10 +30,12 @@ def mock_caches(repository_cache_dir, repository_one, repository_two): (repository_cache_dir / repository_two).mkdir() -def test_cache_list(app, mock_caches, repository_one, repository_two): - command = app.find("cache list") - tester = CommandTester(command) +@pytest.fixture +def tester(command_tester_factory): + return command_tester_factory("cache list") + +def test_cache_list(tester, mock_caches, repository_one, repository_two): tester.execute() expected = """\ @@ -48,10 +48,7 @@ def test_cache_list(app, mock_caches, repository_one, repository_two): assert expected == tester.io.fetch_output() -def test_cache_list_empty(app, repository_cache_dir): - command = app.find("cache list") - tester = CommandTester(command) - +def test_cache_list_empty(tester, repository_cache_dir): tester.execute() expected = """\ diff --git a/tests/console/commands/test_check.py b/tests/console/commands/test_check.py index 8f8b94a5c9b..caa5485154f 100644 --- a/tests/console/commands/test_check.py +++ b/tests/console/commands/test_check.py @@ -1,13 +1,15 @@ -from cleo.testers import CommandTester +import pytest from poetry.utils._compat import PY2 from poetry.utils._compat import Path -def test_check_valid(app): - command = app.find("check") - tester = CommandTester(command) +@pytest.fixture() +def tester(command_tester_factory): + return command_tester_factory("check") + +def test_check_valid(tester): tester.execute() expected = """\ @@ -17,7 +19,7 @@ def test_check_valid(app): assert expected == tester.io.fetch_output() -def test_check_invalid(app, mocker): +def test_check_invalid(mocker, tester): mocker.patch( "poetry.factory.Factory.locate", return_value=Path(__file__).parent.parent.parent @@ -26,9 +28,6 @@ def test_check_invalid(app, mocker): / "pyproject.toml", ) - command = app.find("check") - tester = CommandTester(command) - tester.execute() if PY2: diff --git a/tests/console/commands/test_config.py b/tests/console/commands/test_config.py index 534e4de2fc6..4bf102073d5 100644 --- a/tests/console/commands/test_config.py +++ b/tests/console/commands/test_config.py @@ -1,15 +1,18 @@ import json import os -from cleo.testers import CommandTester +import pytest from poetry.config.config_source import ConfigSource from poetry.factory import Factory -def test_list_displays_default_value_if_not_set(app, config): - command = app.find("config") - tester = CommandTester(command) +@pytest.fixture() +def tester(command_tester_factory): + return command_tester_factory("config") + + +def test_list_displays_default_value_if_not_set(tester, config): tester.execute("--list") expected = """cache-dir = "/foo" @@ -24,10 +27,7 @@ def test_list_displays_default_value_if_not_set(app, config): assert expected == tester.io.fetch_output() -def test_list_displays_set_get_setting(app, config): - command = app.find("config") - tester = CommandTester(command) - +def test_list_displays_set_get_setting(tester, config): tester.execute("virtualenvs.create false") tester.execute("--list") @@ -45,10 +45,7 @@ def test_list_displays_set_get_setting(app, config): assert expected == tester.io.fetch_output() -def test_display_single_setting(app, config): - command = app.find("config") - tester = CommandTester(command) - +def test_display_single_setting(tester, config): tester.execute("virtualenvs.create") expected = """true @@ -57,13 +54,10 @@ def test_display_single_setting(app, config): assert expected == tester.io.fetch_output() -def test_display_single_local_setting(app, config, fixture_dir): - poetry = Factory().create_poetry(fixture_dir("with_local_config")) - app._poetry = poetry - - command = app.find("config") - tester = CommandTester(command) - +def test_display_single_local_setting(command_tester_factory, fixture_dir): + tester = command_tester_factory( + "config", poetry=Factory().create_poetry(fixture_dir("with_local_config")) + ) tester.execute("virtualenvs.create") expected = """false @@ -72,10 +66,7 @@ def test_display_single_local_setting(app, config, fixture_dir): assert expected == tester.io.fetch_output() -def test_list_displays_set_get_local_setting(app, config): - command = app.find("config") - tester = CommandTester(command) - +def test_list_displays_set_get_local_setting(tester, config): tester.execute("virtualenvs.create false --local") tester.execute("--list") @@ -93,21 +84,15 @@ def test_list_displays_set_get_local_setting(app, config): assert expected == tester.io.fetch_output() -def test_set_pypi_token(app, config, config_source, auth_config_source): - command = app.find("config") - tester = CommandTester(command) - +def test_set_pypi_token(tester, auth_config_source): tester.execute("pypi-token.pypi mytoken") - tester.execute("--list") assert "mytoken" == auth_config_source.config["pypi-token"]["pypi"] -def test_set_client_cert(app, config_source, auth_config_source, mocker): +def test_set_client_cert(tester, auth_config_source, mocker): mocker.spy(ConfigSource, "__init__") - command = app.find("config") - tester = CommandTester(command) tester.execute("certificates.foo.client-cert path/to/cert.pem") @@ -117,10 +102,8 @@ def test_set_client_cert(app, config_source, auth_config_source, mocker): ) -def test_set_cert(app, config_source, auth_config_source, mocker): +def test_set_cert(tester, auth_config_source, mocker): mocker.spy(ConfigSource, "__init__") - command = app.find("config") - tester = CommandTester(command) tester.execute("certificates.foo.cert path/to/ca.pem") diff --git a/tests/console/commands/test_export.py b/tests/console/commands/test_export.py index 65d4927916d..f5b9fba4a7d 100644 --- a/tests/console/commands/test_export.py +++ b/tests/console/commands/test_export.py @@ -3,16 +3,8 @@ import pytest -from cleo.testers import CommandTester - -from poetry.factory import Factory -from poetry.repositories.pool import Pool from tests.helpers import get_package -from ..conftest import Application -from ..conftest import Locker -from ..conftest import Path - PYPROJECT_CONTENT = """\ [tool.poetry] @@ -48,166 +40,76 @@ """ -@pytest.fixture -def poetry(repo, tmp_dir): - with (Path(tmp_dir) / "pyproject.toml").open("w", encoding="utf-8") as f: - f.write(PYPROJECT_CONTENT) - - p = Factory().create_poetry(Path(tmp_dir)) - - locker = Locker(p.locker.lock.path, p.locker._local_config) - locker.write() - p.set_locker(locker) - - pool = Pool() - pool.add_repository(repo) - p.set_pool(pool) - - yield p - - -@pytest.fixture -def app(poetry): - return Application(poetry) - - -def test_export_exports_requirements_txt_file_locks_if_no_lock_file(app, repo): - command = app.find("export") - tester = CommandTester(command) - - assert not app.poetry.locker.lock.exists() - +@pytest.fixture(autouse=True) +def setup(repo): repo.add_package(get_package("foo", "1.0.0")) repo.add_package(get_package("bar", "1.1.0")) - tester.execute("--format requirements.txt --output requirements.txt") - - requirements = app.poetry.file.parent / "requirements.txt" - assert requirements.exists() - - with requirements.open(encoding="utf-8") as f: - content = f.read() - assert app.poetry.locker.lock.exists() - - expected = """\ -foo==1.0.0 -""" - - assert expected == content - assert "The lock file does not exist. Locking." in tester.io.fetch_output() - - -def test_export_exports_requirements_txt_uses_lock_file(app, repo): - repo.add_package(get_package("foo", "1.0.0")) - repo.add_package(get_package("bar", "1.1.0")) +@pytest.fixture +def poetry(project_factory): + return project_factory(name="export", pyproject_content=PYPROJECT_CONTENT) - command = app.find("lock") - tester = CommandTester(command) - tester.execute() - assert app.poetry.locker.lock.exists() +@pytest.fixture +def tester(command_tester_factory, poetry): + return command_tester_factory("export", poetry=poetry) - command = app.find("export") - tester = CommandTester(command) +def _export_requirements(tester, poetry): tester.execute("--format requirements.txt --output requirements.txt") - requirements = app.poetry.file.parent / "requirements.txt" + requirements = poetry.file.parent / "requirements.txt" assert requirements.exists() with requirements.open(encoding="utf-8") as f: content = f.read() - assert app.poetry.locker.lock.exists() + assert poetry.locker.lock.exists() expected = """\ foo==1.0.0 """ assert expected == content - assert "The lock file does not exist. Locking." not in tester.io.fetch_output() -def test_export_fails_on_invalid_format(app, repo): - repo.add_package(get_package("foo", "1.0.0")) - repo.add_package(get_package("bar", "1.1.0")) +def test_export_exports_requirements_txt_file_locks_if_no_lock_file(tester, poetry): + assert not poetry.locker.lock.exists() + _export_requirements(tester, poetry) + assert "The lock file does not exist. Locking." in tester.io.fetch_output() - command = app.find("lock") - tester = CommandTester(command) - tester.execute() - assert app.poetry.locker.lock.exists() +def test_export_exports_requirements_txt_uses_lock_file(tester, poetry, do_lock): + _export_requirements(tester, poetry) + assert "The lock file does not exist. Locking." not in tester.io.fetch_output() - command = app.find("export") - tester = CommandTester(command) +def test_export_fails_on_invalid_format(tester, do_lock): with pytest.raises(ValueError): tester.execute("--format invalid") -def test_export_prints_to_stdout_by_default(app, repo): - repo.add_package(get_package("foo", "1.0.0")) - repo.add_package(get_package("bar", "1.1.0")) - - command = app.find("lock") - tester = CommandTester(command) - tester.execute() - - assert app.poetry.locker.lock.exists() - - command = app.find("export") - tester = CommandTester(command) - +def test_export_prints_to_stdout_by_default(tester, do_lock): tester.execute("--format requirements.txt") - expected = """\ foo==1.0.0 """ - assert expected == tester.io.fetch_output() -def test_export_uses_requirements_txt_format_by_default(app, repo): - repo.add_package(get_package("foo", "1.0.0")) - repo.add_package(get_package("bar", "1.1.0")) - - command = app.find("lock") - tester = CommandTester(command) - tester.execute() - - assert app.poetry.locker.lock.exists() - - command = app.find("export") - tester = CommandTester(command) - +def test_export_uses_requirements_txt_format_by_default(tester, do_lock): tester.execute() - expected = """\ foo==1.0.0 """ - assert expected == tester.io.fetch_output() -def test_export_includes_extras_by_flag(app, repo): - repo.add_package(get_package("foo", "1.0.0")) - repo.add_package(get_package("bar", "1.1.0")) - - command = app.find("lock") - tester = CommandTester(command) - tester.execute() - - assert app.poetry.locker.lock.exists() - - command = app.find("export") - tester = CommandTester(command) - +def test_export_includes_extras_by_flag(tester, do_lock): tester.execute("--format requirements.txt --extras feature_bar") - expected = """\ bar==1.1.0 foo==1.0.0 """ - assert expected == tester.io.fetch_output() diff --git a/tests/console/commands/test_init.py b/tests/console/commands/test_init.py index 59c263d91ae..20f992327e7 100644 --- a/tests/console/commands/test_init.py +++ b/tests/console/commands/test_init.py @@ -1,20 +1,24 @@ import sys -from cleo.testers import CommandTester +import pytest from poetry.utils._compat import Path from tests.helpers import get_package -def test_basic_interactive(app, mocker, poetry): - command = app.find("init") - command._pool = poetry.pool +@pytest.fixture(autouse=True) +def patches(mocker, mocked_open_files): + mocked_open_files.append("pyproject.toml") + patch = mocker.patch("poetry.utils._compat.Path.cwd") + patch.return_value = Path(__file__).parent + + +@pytest.fixture +def tester(command_tester_factory): + return command_tester_factory("init") - mocker.patch("poetry.utils._compat.Path.open") - p = mocker.patch("poetry.utils._compat.Path.cwd") - p.return_value = Path(__file__) - tester = CommandTester(command) +def test_basic_interactive(tester): inputs = [ "my-package", # Package name "1.2.3", # Version @@ -45,19 +49,11 @@ def test_basic_interactive(app, mocker, poetry): assert expected in tester.io.fetch_output() -def test_interactive_with_dependencies(app, repo, mocker, poetry): +def test_interactive_with_dependencies(tester, repo): repo.add_package(get_package("django-pendulum", "0.1.6-pre4")) repo.add_package(get_package("pendulum", "2.0.0")) repo.add_package(get_package("pytest", "3.6.0")) - command = app.find("init") - command._pool = poetry.pool - - mocker.patch("poetry.utils._compat.Path.open") - p = mocker.patch("poetry.utils._compat.Path.cwd") - p.return_value = Path(__file__).parent - - tester = CommandTester(command) inputs = [ "my-package", # Package name "1.2.3", # Version @@ -98,15 +94,7 @@ def test_interactive_with_dependencies(app, repo, mocker, poetry): assert expected in tester.io.fetch_output() -def test_empty_license(app, mocker, poetry): - command = app.find("init") - command._pool = poetry.pool - - mocker.patch("poetry.utils._compat.Path.open") - p = mocker.patch("poetry.utils._compat.Path.cwd") - p.return_value = Path(__file__) - - tester = CommandTester(command) +def test_empty_license(tester): inputs = [ "my-package", # Package name "1.2.3", # Version @@ -138,20 +126,10 @@ def test_empty_license(app, mocker, poetry): assert expected in tester.io.fetch_output() -def test_interactive_with_git_dependencies( - app, repo, mocker, poetry, mocked_open_files -): +def test_interactive_with_git_dependencies(tester, repo): repo.add_package(get_package("pendulum", "2.0.0")) repo.add_package(get_package("pytest", "3.6.0")) - command = app.find("init") - command._pool = poetry.pool - - mocked_open_files.append("pyproject.toml") - p = mocker.patch("poetry.utils._compat.Path.cwd") - p.return_value = Path(__file__).parent - - tester = CommandTester(command) inputs = [ "my-package", # Package name "1.2.3", # Version @@ -190,20 +168,10 @@ def test_interactive_with_git_dependencies( assert expected in tester.io.fetch_output() -def test_interactive_with_git_dependencies_with_reference( - app, repo, mocker, poetry, mocked_open_files -): +def test_interactive_with_git_dependencies_with_reference(tester, repo): repo.add_package(get_package("pendulum", "2.0.0")) repo.add_package(get_package("pytest", "3.6.0")) - command = app.find("init") - command._pool = poetry.pool - - mocked_open_files.append("pyproject.toml") - p = mocker.patch("poetry.utils._compat.Path.cwd") - p.return_value = Path(__file__).parent - - tester = CommandTester(command) inputs = [ "my-package", # Package name "1.2.3", # Version @@ -242,20 +210,10 @@ def test_interactive_with_git_dependencies_with_reference( assert expected in tester.io.fetch_output() -def test_interactive_with_git_dependencies_and_other_name( - app, repo, mocker, poetry, mocked_open_files -): +def test_interactive_with_git_dependencies_and_other_name(tester, repo): repo.add_package(get_package("pendulum", "2.0.0")) repo.add_package(get_package("pytest", "3.6.0")) - command = app.find("init") - command._pool = poetry.pool - - mocked_open_files.append("pyproject.toml") - p = mocker.patch("poetry.utils._compat.Path.cwd") - p.return_value = Path(__file__).parent - - tester = CommandTester(command) inputs = [ "my-package", # Package name "1.2.3", # Version @@ -294,20 +252,10 @@ def test_interactive_with_git_dependencies_and_other_name( assert expected in tester.io.fetch_output() -def test_interactive_with_directory_dependency( - app, repo, mocker, poetry, mocked_open_files -): +def test_interactive_with_directory_dependency(tester, repo): repo.add_package(get_package("pendulum", "2.0.0")) repo.add_package(get_package("pytest", "3.6.0")) - command = app.find("init") - command._pool = poetry.pool - - mocked_open_files.append("pyproject.toml") - p = mocker.patch("poetry.utils._compat.Path.cwd") - p.return_value = Path(__file__).parent - - tester = CommandTester(command) inputs = [ "my-package", # Package name "1.2.3", # Version @@ -346,20 +294,10 @@ def test_interactive_with_directory_dependency( assert expected in tester.io.fetch_output() -def test_interactive_with_directory_dependency_and_other_name( - app, repo, mocker, poetry -): +def test_interactive_with_directory_dependency_and_other_name(tester, repo): repo.add_package(get_package("pendulum", "2.0.0")) repo.add_package(get_package("pytest", "3.6.0")) - command = app.find("init") - command._pool = poetry.pool - - mocker.patch("poetry.utils._compat.Path.open") - p = mocker.patch("poetry.utils._compat.Path.cwd") - p.return_value = Path(__file__).parent - - tester = CommandTester(command) inputs = [ "my-package", # Package name "1.2.3", # Version @@ -398,18 +336,10 @@ def test_interactive_with_directory_dependency_and_other_name( assert expected in tester.io.fetch_output() -def test_interactive_with_file_dependency(app, repo, mocker, poetry): +def test_interactive_with_file_dependency(tester, repo): repo.add_package(get_package("pendulum", "2.0.0")) repo.add_package(get_package("pytest", "3.6.0")) - command = app.find("init") - command._pool = poetry.pool - - mocker.patch("poetry.utils._compat.Path.open") - p = mocker.patch("poetry.utils._compat.Path.cwd") - p.return_value = Path(__file__).parent - - tester = CommandTester(command) inputs = [ "my-package", # Package name "1.2.3", # Version @@ -448,15 +378,7 @@ def test_interactive_with_file_dependency(app, repo, mocker, poetry): assert expected in tester.io.fetch_output() -def test_python_option(app, mocker, poetry): - command = app.find("init") - command._pool = poetry.pool - - mocker.patch("poetry.utils._compat.Path.open") - p = mocker.patch("poetry.utils._compat.Path.cwd") - p.return_value = Path(__file__) - - tester = CommandTester(command) +def test_python_option(tester): inputs = [ "my-package", # Package name "1.2.3", # Version @@ -486,17 +408,9 @@ def test_python_option(app, mocker, poetry): assert expected in tester.io.fetch_output() -def test_predefined_dependency(app, repo, mocker, poetry): +def test_predefined_dependency(tester, repo): repo.add_package(get_package("pendulum", "2.0.0")) - command = app.find("init") - command._pool = poetry.pool - - mocker.patch("poetry.utils._compat.Path.open") - p = mocker.patch("poetry.utils._compat.Path.cwd") - p.return_value = Path(__file__) - - tester = CommandTester(command) inputs = [ "my-package", # Package name "1.2.3", # Version @@ -528,18 +442,10 @@ def test_predefined_dependency(app, repo, mocker, poetry): assert expected in tester.io.fetch_output() -def test_predefined_and_interactive_dependencies(app, repo, mocker, poetry): +def test_predefined_and_interactive_dependencies(tester, repo): repo.add_package(get_package("pendulum", "2.0.0")) repo.add_package(get_package("pyramid", "1.10")) - command = app.find("init") - command._pool = poetry.pool - - mocker.patch("poetry.utils._compat.Path.open") - p = mocker.patch("poetry.utils._compat.Path.cwd") - p.return_value = Path(__file__) - - tester = CommandTester(command) inputs = [ "my-package", # Package name "1.2.3", # Version @@ -575,17 +481,9 @@ def test_predefined_and_interactive_dependencies(app, repo, mocker, poetry): assert 'pyramid = "^1.10"' in output -def test_predefined_dev_dependency(app, repo, mocker, poetry): +def test_predefined_dev_dependency(tester, repo): repo.add_package(get_package("pytest", "3.6.0")) - command = app.find("init") - command._pool = poetry.pool - - mocker.patch("poetry.utils._compat.Path.open") - p = mocker.patch("poetry.utils._compat.Path.cwd") - p.return_value = Path(__file__) - - tester = CommandTester(command) inputs = [ "my-package", # Package name "1.2.3", # Version @@ -618,18 +516,10 @@ def test_predefined_dev_dependency(app, repo, mocker, poetry): assert expected in tester.io.fetch_output() -def test_predefined_and_interactive_dev_dependencies(app, repo, mocker, poetry): +def test_predefined_and_interactive_dev_dependencies(tester, repo): repo.add_package(get_package("pytest", "3.6.0")) repo.add_package(get_package("pytest-requests", "0.2.0")) - command = app.find("init") - command._pool = poetry.pool - - mocker.patch("poetry.utils._compat.Path.open") - p = mocker.patch("poetry.utils._compat.Path.cwd") - p.return_value = Path(__file__) - - tester = CommandTester(command) inputs = [ "my-package", # Package name "1.2.3", # Version diff --git a/tests/console/commands/test_run.py b/tests/console/commands/test_run.py index e8ae40aa606..351d869d1a9 100644 --- a/tests/console/commands/test_run.py +++ b/tests/console/commands/test_run.py @@ -1,12 +1,16 @@ -from cleo.testers import CommandTester +import pytest -def test_run_passes_all_args(app, mocker, env): +@pytest.fixture +def tester(command_tester_factory): + return command_tester_factory("run") + + +@pytest.fixture(autouse=True) +def patches(mocker, env): mocker.patch("poetry.utils.env.EnvManager.get", return_value=env) - command = app.find("run") - tester = CommandTester(command) +def test_run_passes_all_args(tester, env): tester.execute("python -V") - assert [["python", "-V"]] == env.executed diff --git a/tests/console/commands/test_search.py b/tests/console/commands/test_search.py index 57891e93b2f..9b61476c0b5 100644 --- a/tests/console/commands/test_search.py +++ b/tests/console/commands/test_search.py @@ -1,4 +1,4 @@ -from cleo.testers import CommandTester +import pytest from poetry.utils._compat import Path @@ -9,15 +9,20 @@ ) -def test_search(app, http): +@pytest.fixture(autouse=True) +def mock_search_http_response(http): with FIXTURES_DIRECTORY.joinpath("search.html").open(encoding="utf-8") as f: - search_results = f.read() + http.register_uri("GET", "https://pypi.org/search", f.read()) - http.register_uri("GET", "https://pypi.org/search", search_results) - command = app.find("search") - tester = CommandTester(command) +@pytest.fixture +def tester(command_tester_factory): + return command_tester_factory("search") + +def test_search( + tester, http, +): tester.execute("sqlalchemy") expected = """ diff --git a/tests/console/commands/test_show.py b/tests/console/commands/test_show.py index 7dc8d502883..cf4dffcacc4 100644 --- a/tests/console/commands/test_show.py +++ b/tests/console/commands/test_show.py @@ -1,20 +1,22 @@ import pytest -from cleo.testers import CommandTester from clikit.formatter.ansi_formatter import AnsiFormatter from poetry.factory import Factory from tests.helpers import get_package -def test_show_basic_with_installed_packages(app, poetry, installed): +@pytest.fixture +def tester(command_tester_factory): + return command_tester_factory("show") + + +def test_show_basic_with_installed_packages(tester, poetry, installed): poetry.package.add_dependency(Factory.create_dependency("cachy", "^0.1.0")) poetry.package.add_dependency(Factory.create_dependency("pendulum", "^2.0.0")) poetry.package.add_dependency( Factory.create_dependency("pytest", "^3.7.3", category="dev") ) - command = app.find("show") - tester = CommandTester(command) cachy_010 = get_package("cachy", "0.1.0") cachy_010.description = "Cachy package" @@ -84,13 +86,12 @@ def test_show_basic_with_installed_packages(app, poetry, installed): assert expected == tester.io.fetch_output() -def test_show_basic_with_not_installed_packages_non_decorated(app, poetry, installed): +def test_show_basic_with_not_installed_packages_non_decorated( + tester, poetry, installed +): poetry.package.add_dependency(Factory.create_dependency("cachy", "^0.1.0")) poetry.package.add_dependency(Factory.create_dependency("pendulum", "^2.0.0")) - command = app.find("show") - tester = CommandTester(command) - cachy_010 = get_package("cachy", "0.1.0") cachy_010.description = "Cachy package" @@ -141,13 +142,10 @@ def test_show_basic_with_not_installed_packages_non_decorated(app, poetry, insta assert expected == tester.io.fetch_output() -def test_show_basic_with_not_installed_packages_decorated(app, poetry, installed): +def test_show_basic_with_not_installed_packages_decorated(tester, poetry, installed): poetry.package.add_dependency(Factory.create_dependency("cachy", "^0.1.0")) poetry.package.add_dependency(Factory.create_dependency("pendulum", "^2.0.0")) - command = app.find("show") - tester = CommandTester(command) - cachy_010 = get_package("cachy", "0.1.0") cachy_010.description = "Cachy package" @@ -199,13 +197,10 @@ def test_show_basic_with_not_installed_packages_decorated(app, poetry, installed assert expected == tester.io.fetch_output() -def test_show_latest_non_decorated(app, poetry, installed, repo): +def test_show_latest_non_decorated(tester, poetry, installed, repo): poetry.package.add_dependency(Factory.create_dependency("cachy", "^0.1.0")) poetry.package.add_dependency(Factory.create_dependency("pendulum", "^2.0.0")) - command = app.find("show") - tester = CommandTester(command) - cachy_010 = get_package("cachy", "0.1.0") cachy_010.description = "Cachy package" cachy_020 = get_package("cachy", "0.2.0") @@ -267,13 +262,10 @@ def test_show_latest_non_decorated(app, poetry, installed, repo): assert expected == tester.io.fetch_output() -def test_show_latest_decorated(app, poetry, installed, repo): +def test_show_latest_decorated(tester, poetry, installed, repo): poetry.package.add_dependency(Factory.create_dependency("cachy", "^0.1.0")) poetry.package.add_dependency(Factory.create_dependency("pendulum", "^2.0.0")) - command = app.find("show") - tester = CommandTester(command) - cachy_010 = get_package("cachy", "0.1.0") cachy_010.description = "Cachy package" cachy_020 = get_package("cachy", "0.2.0") @@ -336,13 +328,10 @@ def test_show_latest_decorated(app, poetry, installed, repo): assert expected == tester.io.fetch_output() -def test_show_outdated(app, poetry, installed, repo): +def test_show_outdated(tester, poetry, installed, repo): poetry.package.add_dependency(Factory.create_dependency("cachy", "^0.1.0")) poetry.package.add_dependency(Factory.create_dependency("pendulum", "^2.0.0")) - command = app.find("show") - tester = CommandTester(command) - cachy_010 = get_package("cachy", "0.1.0") cachy_010.description = "Cachy package" cachy_020 = get_package("cachy", "0.2.0") @@ -400,10 +389,7 @@ def test_show_outdated(app, poetry, installed, repo): assert expected == tester.io.fetch_output() -def test_show_outdated_with_only_up_to_date_packages(app, poetry, installed, repo): - command = app.find("show") - tester = CommandTester(command) - +def test_show_outdated_with_only_up_to_date_packages(tester, poetry, installed, repo): cachy_020 = get_package("cachy", "0.2.0") cachy_020.description = "Cachy package" @@ -440,13 +426,10 @@ def test_show_outdated_with_only_up_to_date_packages(app, poetry, installed, rep assert expected == tester.io.fetch_output() -def test_show_outdated_has_prerelease_but_not_allowed(app, poetry, installed, repo): +def test_show_outdated_has_prerelease_but_not_allowed(tester, poetry, installed, repo): poetry.package.add_dependency(Factory.create_dependency("cachy", "^0.1.0")) poetry.package.add_dependency(Factory.create_dependency("pendulum", "^2.0.0")) - command = app.find("show") - tester = CommandTester(command) - cachy_010 = get_package("cachy", "0.1.0") cachy_010.description = "Cachy package" cachy_020 = get_package("cachy", "0.2.0") @@ -509,7 +492,7 @@ def test_show_outdated_has_prerelease_but_not_allowed(app, poetry, installed, re assert expected == tester.io.fetch_output() -def test_show_outdated_has_prerelease_and_allowed(app, poetry, installed, repo): +def test_show_outdated_has_prerelease_and_allowed(tester, poetry, installed, repo): poetry.package.add_dependency( Factory.create_dependency( "cachy", {"version": "^0.1.0", "allow-prereleases": True} @@ -517,9 +500,6 @@ def test_show_outdated_has_prerelease_and_allowed(app, poetry, installed, repo): ) poetry.package.add_dependency(Factory.create_dependency("pendulum", "^2.0.0")) - command = app.find("show") - tester = CommandTester(command) - cachy_010dev = get_package("cachy", "0.1.0.dev1") cachy_010dev.description = "Cachy package" cachy_020 = get_package("cachy", "0.2.0") @@ -582,13 +562,10 @@ def test_show_outdated_has_prerelease_and_allowed(app, poetry, installed, repo): assert expected == tester.io.fetch_output() -def test_show_outdated_formatting(app, poetry, installed, repo): +def test_show_outdated_formatting(tester, poetry, installed, repo): poetry.package.add_dependency(Factory.create_dependency("cachy", "^0.1.0")) poetry.package.add_dependency(Factory.create_dependency("pendulum", "^2.0.0")) - command = app.find("show") - tester = CommandTester(command) - cachy_010 = get_package("cachy", "0.1.0") cachy_010.description = "Cachy package" cachy_020 = get_package("cachy", "0.2.0") @@ -651,10 +628,9 @@ def test_show_outdated_formatting(app, poetry, installed, repo): @pytest.mark.parametrize("project_directory", ["project_with_local_dependencies"]) -def test_show_outdated_local_dependencies(app, poetry, installed, repo): - command = app.find("show") - tester = CommandTester(command) - +def test_show_outdated_local_dependencies(tester, poetry, installed, repo): + cachy_010 = get_package("cachy", "0.1.0") + cachy_010.description = "Cachy package" cachy_020 = get_package("cachy", "0.2.0") cachy_020.description = "Cachy package" cachy_030 = get_package("cachy", "0.3.0") @@ -762,11 +738,7 @@ def test_show_outdated_local_dependencies(app, poetry, installed, repo): @pytest.mark.parametrize("project_directory", ["project_with_git_dev_dependency"]) -def test_show_outdated_git_dev_dependency(app, poetry, installed, repo): - command = app.find("show") - tester = CommandTester(command) - print(poetry.package.all_requires) - +def test_show_outdated_git_dev_dependency(tester, poetry, installed, repo): cachy_010 = get_package("cachy", "0.1.0") cachy_010.description = "Cachy package" cachy_020 = get_package("cachy", "0.2.0") @@ -861,10 +833,7 @@ def test_show_outdated_git_dev_dependency(app, poetry, installed, repo): @pytest.mark.parametrize("project_directory", ["project_with_git_dev_dependency"]) -def test_show_outdated_no_dev_git_dev_dependency(app, poetry, installed, repo): - command = app.find("show") - tester = CommandTester(command) - +def test_show_outdated_no_dev_git_dev_dependency(tester, poetry, installed, repo): cachy_010 = get_package("cachy", "0.1.0") cachy_010.description = "Cachy package" cachy_020 = get_package("cachy", "0.2.0") @@ -956,13 +925,11 @@ def test_show_outdated_no_dev_git_dev_dependency(app, poetry, installed, repo): assert expected == tester.io.fetch_output() -def test_show_hides_incompatible_package(app, poetry, installed, repo): +def test_show_hides_incompatible_package(tester, poetry, installed, repo): poetry.package.add_dependency( Factory.create_dependency("cachy", {"version": "^0.1.0", "python": "< 2.0"}) ) poetry.package.add_dependency(Factory.create_dependency("pendulum", "^2.0.0")) - command = app.find("show") - tester = CommandTester(command) cachy_010 = get_package("cachy", "0.1.0") cachy_010.description = "Cachy package" @@ -1014,10 +981,7 @@ def test_show_hides_incompatible_package(app, poetry, installed, repo): assert expected == tester.io.fetch_output() -def test_show_all_shows_incompatible_package(app, poetry, installed, repo): - command = app.find("show") - tester = CommandTester(command) - +def test_show_all_shows_incompatible_package(tester, poetry, installed, repo): cachy_010 = get_package("cachy", "0.1.0") cachy_010.description = "Cachy package" @@ -1070,10 +1034,7 @@ def test_show_all_shows_incompatible_package(app, poetry, installed, repo): assert expected == tester.io.fetch_output() -def test_show_non_dev_with_basic_installed_packages(app, poetry, installed): - command = app.find("show") - tester = CommandTester(command) - +def test_show_non_dev_with_basic_installed_packages(tester, poetry, installed): cachy_010 = get_package("cachy", "0.1.0") cachy_010.description = "Cachy package" @@ -1141,10 +1102,7 @@ def test_show_non_dev_with_basic_installed_packages(app, poetry, installed): assert expected == tester.io.fetch_output() -def test_show_tree(app, poetry, installed): - command = app.find("show") - tester = CommandTester(command) - +def test_show_tree(tester, poetry, installed): poetry.package.add_dependency(Factory.create_dependency("cachy", "^0.2.0")) cachy2 = get_package("cachy", "0.2.0") diff --git a/tests/console/commands/test_version.py b/tests/console/commands/test_version.py index 42c4d297d44..77f6d8aa41e 100644 --- a/tests/console/commands/test_version.py +++ b/tests/console/commands/test_version.py @@ -1,7 +1,5 @@ import pytest -from cleo import CommandTester - from poetry.console.commands import VersionCommand @@ -10,6 +8,11 @@ def command(): return VersionCommand() +@pytest.fixture +def tester(command_tester_factory): + return command_tester_factory("version") + + @pytest.mark.parametrize( "version, rule, expected", [ @@ -40,15 +43,11 @@ def test_increment_version(version, rule, expected, command): assert expected == command.increment_version(version, rule).text -def test_version_show(app): - command = app.find("version") - tester = CommandTester(command) +def test_version_show(tester): tester.execute() assert "simple-project 1.2.3\n" == tester.io.fetch_output() -def test_short_version_show(app): - command = app.find("version") - tester = CommandTester(command) +def test_short_version_show(tester): tester.execute("--short") assert "1.2.3\n" == tester.io.fetch_output() diff --git a/tests/console/conftest.py b/tests/console/conftest.py index 76417e382ab..8a3a5cba8ae 100644 --- a/tests/console/conftest.py +++ b/tests/console/conftest.py @@ -1,75 +1,26 @@ import os -import re import pytest from cleo import ApplicationTester -from poetry.console import Application as BaseApplication -from poetry.core.masonry.utils.helpers import escape_name -from poetry.core.masonry.utils.helpers import escape_version -from poetry.core.packages.utils.link import Link from poetry.factory import Factory -from poetry.installation.executor import Executor as BaseExecutor from poetry.installation.noop_installer import NoopInstaller from poetry.io.null_io import NullIO -from poetry.packages import Locker as BaseLocker -from poetry.poetry import Poetry as BasePoetry from poetry.repositories import Pool -from poetry.repositories import Repository as BaseRepository -from poetry.repositories.exceptions import PackageNotFound from poetry.utils._compat import Path from poetry.utils.env import MockEnv -from poetry.utils.toml_file import TomlFile +from tests.helpers import TestApplication +from tests.helpers import TestExecutor +from tests.helpers import TestLocker from tests.helpers import mock_clone -class Executor(BaseExecutor): - def __init__(self, *args, **kwargs): - super(Executor, self).__init__(*args, **kwargs) - - self._installs = [] - self._updates = [] - self._uninstalls = [] - - @property - def installations(self): - return self._installs - - @property - def updates(self): - return self._updates - - @property - def removals(self): - return self._uninstalls - - def _do_execute_operation(self, operation): - super(Executor, self)._do_execute_operation(operation) - - if not operation.skipped: - getattr(self, "_{}s".format(operation.job_type)).append(operation.package) - - def _execute_install(self, operation): - return 0 - - def _execute_update(self, operation): - return 0 - - def _execute_remove(self, operation): - return 0 - - @pytest.fixture() def installer(): return NoopInstaller() -@pytest.fixture -def installed(): - return BaseRepository() - - @pytest.fixture def env(): return MockEnv(path=Path("/prefix"), base=Path("/base/prefix"), is_venv=True) @@ -114,98 +65,6 @@ def setup(mocker, installer, installed, config, env): os.environ.update(environ) -class Application(BaseApplication): - def __init__(self, poetry): - super(Application, self).__init__() - - self._poetry = poetry - - def reset_poetry(self): - poetry = self._poetry - self._poetry = Factory().create_poetry(self._poetry.file.path.parent) - self._poetry.set_pool(poetry.pool) - self._poetry.set_config(poetry.config) - self._poetry.set_locker( - Locker(poetry.locker.lock.path, self._poetry.local_config) - ) - - -class Locker(BaseLocker): - def __init__(self, lock, local_config): - self._lock = TomlFile(lock) - self._local_config = local_config - self._lock_data = None - self._content_hash = self._get_content_hash() - self._locked = False - self._lock_data = None - self._write = False - - def write(self, write=True): - self._write = write - - def is_locked(self): - return self._locked - - def locked(self, is_locked=True): - self._locked = is_locked - - return self - - def mock_lock_data(self, data): - self.locked() - - self._lock_data = data - - def is_fresh(self): - return True - - def _write_lock_data(self, data): - if self._write: - super(Locker, self)._write_lock_data(data) - self._locked = True - return - - self._lock_data = data - - -class Poetry(BasePoetry): - def __init__(self, file, local_config, package, locker, config): - self._file = TomlFile(file) - self._package = package - self._local_config = local_config - self._locker = Locker(locker.lock.path, locker._local_config) - self._config = config - - # Configure sources - self._pool = Pool() - - -class Repository(BaseRepository): - def find_packages(self, dependency): - packages = super(Repository, self).find_packages(dependency) - if len(packages) == 0: - raise PackageNotFound("Package [{}] not found.".format(dependency.name)) - - return packages - - def find_links_for_package(self, package): - return [ - Link( - "https://foo.bar/files/{}-{}-py2.py3-none-any.whl".format( - escape_name(package.name), escape_version(package.version.text) - ) - ) - ] - - -@pytest.fixture -def repo(http): - http.register_uri( - http.GET, re.compile("^https?://foo.bar/(.+?)$"), - ) - return Repository(name="foo") - - @pytest.fixture def project_directory(): return "simple_project" @@ -216,7 +75,7 @@ def poetry(repo, project_directory, config): p = Factory().create_poetry( Path(__file__).parent.parent / "fixtures" / project_directory ) - p.set_locker(Locker(p.locker.lock.path, p.locker._local_config)) + p.set_locker(TestLocker(p.locker.lock.path, p.locker._local_config)) with p.file.path.open(encoding="utf-8") as f: content = f.read() @@ -235,7 +94,7 @@ def poetry(repo, project_directory, config): @pytest.fixture def app(poetry): - app_ = Application(poetry) + app_ = TestApplication(poetry) app_.config.set_terminate_after_run(False) return app_ @@ -253,4 +112,4 @@ def new_installer_disabled(config): @pytest.fixture() def executor(poetry, config, env): - return Executor(env, poetry.pool, config, NullIO()) + return TestExecutor(env, poetry.pool, config, NullIO()) diff --git a/tests/helpers.py b/tests/helpers.py index 0dd7ce312e5..095fed16e1a 100644 --- a/tests/helpers.py +++ b/tests/helpers.py @@ -1,13 +1,23 @@ import os import shutil +from poetry.console import Application +from poetry.core.masonry.utils.helpers import escape_name +from poetry.core.masonry.utils.helpers import escape_version from poetry.core.packages import Dependency +from poetry.core.packages import Link from poetry.core.packages import Package from poetry.core.vcs.git import ParsedUrl +from poetry.factory import Factory +from poetry.installation.executor import Executor +from poetry.packages import Locker +from poetry.repositories import Repository +from poetry.repositories.exceptions import PackageNotFound from poetry.utils._compat import PY2 from poetry.utils._compat import WINDOWS from poetry.utils._compat import Path from poetry.utils._compat import urlparse +from poetry.utils.toml_file import TomlFile FIXTURE_PATH = Path(__file__).parent / "fixtures" @@ -88,3 +98,110 @@ def mock_download(url, dest, **__): fixture = fixtures / parts.path.lstrip("/") copy_or_symlink(fixture, Path(dest)) + + +class TestExecutor(Executor): + def __init__(self, *args, **kwargs): + super(TestExecutor, self).__init__(*args, **kwargs) + + self._installs = [] + self._updates = [] + self._uninstalls = [] + + @property + def installations(self): + return self._installs + + @property + def updates(self): + return self._updates + + @property + def removals(self): + return self._uninstalls + + def _do_execute_operation(self, operation): + super(TestExecutor, self)._do_execute_operation(operation) + + if not operation.skipped: + getattr(self, "_{}s".format(operation.job_type)).append(operation.package) + + def _execute_install(self, operation): + return 0 + + def _execute_update(self, operation): + return 0 + + def _execute_remove(self, operation): + return 0 + + +class TestApplication(Application): + def __init__(self, poetry): + super(TestApplication, self).__init__() + self._poetry = poetry + + def reset_poetry(self): + poetry = self._poetry + self._poetry = Factory().create_poetry(self._poetry.file.path.parent) + self._poetry.set_pool(poetry.pool) + self._poetry.set_config(poetry.config) + self._poetry.set_locker( + TestLocker(poetry.locker.lock.path, self._poetry.local_config) + ) + + +class TestLocker(Locker): + def __init__(self, lock, local_config): # noqa + self._lock = TomlFile(lock) + self._local_config = local_config + self._lock_data = None + self._content_hash = self._get_content_hash() + self._locked = False + self._lock_data = None + self._write = False + + def write(self, write=True): + self._write = write + + def is_locked(self): + return self._locked + + def locked(self, is_locked=True): + self._locked = is_locked + + return self + + def mock_lock_data(self, data): + self.locked() + + self._lock_data = data + + def is_fresh(self): + return True + + def _write_lock_data(self, data): + if self._write: + super(TestLocker, self)._write_lock_data(data) + self._locked = True + return + + self._lock_data = data + + +class TestRepository(Repository): + def find_packages(self, dependency): + packages = super(TestRepository, self).find_packages(dependency) + if len(packages) == 0: + raise PackageNotFound("Package [{}] not found.".format(dependency.name)) + + return packages + + def find_links_for_package(self, package): + return [ + Link( + "https://foo.bar/files/{}-{}-py2.py3-none-any.whl".format( + escape_name(package.name), escape_version(package.version.text) + ) + ) + ]