610 lines
21 KiB
Python
610 lines
21 KiB
Python
from __future__ import annotations
|
|
|
|
from pathlib import Path
|
|
from typing import TYPE_CHECKING
|
|
from typing import Any
|
|
|
|
import pytest
|
|
|
|
from cleo.io.buffered_io import BufferedIO
|
|
from deepdiff import DeepDiff
|
|
from packaging.utils import canonicalize_name
|
|
from poetry.core.constraints.version import Version
|
|
from poetry.core.constraints.version import parse_constraint
|
|
from poetry.core.packages.package import Package
|
|
from poetry.core.packages.vcs_dependency import VCSDependency
|
|
|
|
from poetry.exceptions import PoetryException
|
|
from poetry.factory import Factory
|
|
from poetry.plugins.plugin import Plugin
|
|
from poetry.repositories.exceptions import InvalidSourceError
|
|
from poetry.repositories.legacy_repository import LegacyRepository
|
|
from poetry.repositories.pypi_repository import PyPiRepository
|
|
from poetry.repositories.repository_pool import Priority
|
|
from poetry.toml.file import TOMLFile
|
|
from tests.helpers import mock_metadata_entry_points
|
|
|
|
|
|
if TYPE_CHECKING:
|
|
from cleo.io.io import IO
|
|
from pytest_mock import MockerFixture
|
|
|
|
from poetry.config.config import Config
|
|
from poetry.poetry import Poetry
|
|
from tests.types import FixtureDirGetter
|
|
|
|
|
|
class MyPlugin(Plugin):
|
|
def activate(self, poetry: Poetry, io: IO) -> None:
|
|
io.write_line("Setting readmes")
|
|
poetry.package.readmes = (Path("README.md"),)
|
|
|
|
|
|
def test_create_poetry(fixture_dir: FixtureDirGetter) -> None:
|
|
poetry = Factory().create_poetry(fixture_dir("sample_project"))
|
|
|
|
package = poetry.package
|
|
|
|
assert package.name == "sample-project"
|
|
assert package.version.text == "1.2.3"
|
|
assert package.description == "Some description."
|
|
assert package.authors == ["Sébastien Eustace <sebastien@eustace.io>"]
|
|
assert package.license is not None
|
|
assert package.license.id == "MIT"
|
|
|
|
for readme in package.readmes:
|
|
assert (
|
|
readme.relative_to(fixture_dir("sample_project")).as_posix() == "README.rst"
|
|
)
|
|
|
|
assert package.homepage == "https://python-poetry.org"
|
|
assert package.repository_url == "https://github.com/python-poetry/poetry"
|
|
assert package.keywords == ["packaging", "dependency", "poetry"]
|
|
|
|
assert package.python_versions == "~2.7 || ^3.6"
|
|
assert str(package.python_constraint) == ">=2.7,<2.8 || >=3.6,<4.0"
|
|
|
|
dependencies = {}
|
|
for dep in package.requires:
|
|
dependencies[dep.name] = dep
|
|
|
|
cleo = dependencies[canonicalize_name("cleo")]
|
|
assert cleo.pretty_constraint == "^0.6"
|
|
assert not cleo.is_optional()
|
|
|
|
pendulum = dependencies[canonicalize_name("pendulum")]
|
|
assert pendulum.pretty_constraint == "branch 2.0"
|
|
assert pendulum.is_vcs()
|
|
assert isinstance(pendulum, VCSDependency)
|
|
assert pendulum.vcs == "git"
|
|
assert pendulum.branch == "2.0"
|
|
assert pendulum.source == "https://github.com/sdispater/pendulum.git"
|
|
assert pendulum.allows_prereleases()
|
|
|
|
requests = dependencies[canonicalize_name("requests")]
|
|
assert requests.pretty_constraint == "^2.18"
|
|
assert not requests.is_vcs()
|
|
assert not requests.allows_prereleases()
|
|
assert requests.is_optional()
|
|
assert requests.extras == frozenset(["security"])
|
|
|
|
pathlib2 = dependencies[canonicalize_name("pathlib2")]
|
|
assert pathlib2.pretty_constraint == "^2.2"
|
|
assert parse_constraint(pathlib2.python_versions) == parse_constraint("~2.7")
|
|
assert not pathlib2.is_optional()
|
|
|
|
demo = dependencies[canonicalize_name("demo")]
|
|
assert demo.is_file()
|
|
assert not demo.is_vcs()
|
|
assert demo.name == "demo"
|
|
assert demo.pretty_constraint == "*"
|
|
|
|
demo = dependencies[canonicalize_name("my-package")]
|
|
assert not demo.is_file()
|
|
assert demo.is_directory()
|
|
assert not demo.is_vcs()
|
|
assert demo.name == "my-package"
|
|
assert demo.pretty_constraint == "*"
|
|
|
|
simple_project = dependencies[canonicalize_name("simple-project")]
|
|
assert not simple_project.is_file()
|
|
assert simple_project.is_directory()
|
|
assert not simple_project.is_vcs()
|
|
assert simple_project.name == "simple-project"
|
|
assert simple_project.pretty_constraint == "*"
|
|
|
|
functools32 = dependencies[canonicalize_name("functools32")]
|
|
assert functools32.name == "functools32"
|
|
assert functools32.pretty_constraint == "^3.2.3"
|
|
assert (
|
|
str(functools32.marker)
|
|
== 'python_version ~= "2.7" and sys_platform == "win32" or python_version in'
|
|
' "3.4 3.5"'
|
|
)
|
|
|
|
assert "db" in package.extras
|
|
|
|
classifiers = package.classifiers
|
|
|
|
assert classifiers == [
|
|
"Topic :: Software Development :: Build Tools",
|
|
"Topic :: Software Development :: Libraries :: Python Modules",
|
|
]
|
|
|
|
assert package.all_classifiers == [
|
|
"License :: OSI Approved :: MIT License",
|
|
*(
|
|
f"Programming Language :: Python :: {version}"
|
|
for version in sorted(
|
|
Package.AVAILABLE_PYTHONS,
|
|
key=lambda x: tuple(map(int, x.split("."))),
|
|
)
|
|
if package.python_constraint.allows_any(
|
|
parse_constraint(version + ".*")
|
|
if len(version) == 1
|
|
else Version.parse(version)
|
|
)
|
|
),
|
|
"Topic :: Software Development :: Build Tools",
|
|
"Topic :: Software Development :: Libraries :: Python Modules",
|
|
]
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
("project",),
|
|
[
|
|
("simple_project",),
|
|
("project_with_extras",),
|
|
],
|
|
)
|
|
def test_create_pyproject_from_package(
|
|
project: str, fixture_dir: FixtureDirGetter
|
|
) -> None:
|
|
poetry = Factory().create_poetry(fixture_dir(project))
|
|
package = poetry.package
|
|
|
|
pyproject: dict[str, Any] = Factory.create_pyproject_from_package(package)
|
|
|
|
result = pyproject["tool"]["poetry"]
|
|
expected = poetry.pyproject.poetry_config
|
|
|
|
# Extras are normalized as they are read.
|
|
extras = expected.pop("extras", None)
|
|
if extras is not None:
|
|
normalized_extras = {
|
|
canonicalize_name(extra): dependencies
|
|
for extra, dependencies in extras.items()
|
|
}
|
|
expected["extras"] = normalized_extras
|
|
|
|
# packages do not support this at present
|
|
expected.pop("scripts", None)
|
|
|
|
# remove any empty sections
|
|
sections = list(expected.keys())
|
|
for section in sections:
|
|
if not expected[section]:
|
|
expected.pop(section)
|
|
|
|
assert not DeepDiff(expected, result)
|
|
|
|
|
|
def test_create_poetry_with_packages_and_includes(
|
|
fixture_dir: FixtureDirGetter,
|
|
) -> None:
|
|
poetry = Factory().create_poetry(fixture_dir("with-include"))
|
|
|
|
package = poetry.package
|
|
|
|
assert package.packages == [
|
|
{"include": "extra_dir/**/*.py"},
|
|
{"include": "extra_dir/**/*.py"},
|
|
{"include": "my_module.py"},
|
|
{"include": "package_with_include"},
|
|
{"include": "tests", "format": "sdist"},
|
|
{"include": "for_wheel_only", "format": ["wheel"]},
|
|
{"include": "src_package", "from": "src"},
|
|
]
|
|
|
|
assert package.include == [
|
|
{"path": "extra_dir/vcs_excluded.txt", "format": []},
|
|
{"path": "notes.txt", "format": []},
|
|
]
|
|
|
|
|
|
def test_create_poetry_with_multi_constraints_dependency(
|
|
fixture_dir: FixtureDirGetter,
|
|
) -> None:
|
|
poetry = Factory().create_poetry(
|
|
fixture_dir("project_with_multi_constraints_dependency")
|
|
)
|
|
|
|
package = poetry.package
|
|
|
|
assert len(package.requires) == 2
|
|
|
|
|
|
def test_create_poetry_non_package_mode(fixture_dir: FixtureDirGetter) -> None:
|
|
poetry = Factory().create_poetry(fixture_dir("non_package_mode"))
|
|
|
|
assert not poetry.is_package_mode
|
|
|
|
|
|
def test_poetry_with_default_source_legacy(
|
|
fixture_dir: FixtureDirGetter, with_simple_keyring: None
|
|
) -> None:
|
|
io = BufferedIO()
|
|
poetry = Factory().create_poetry(fixture_dir("with_default_source_legacy"), io=io)
|
|
|
|
assert len(poetry.pool.repositories) == 1
|
|
assert "Found deprecated key" in io.fetch_error()
|
|
|
|
|
|
def test_poetry_with_default_source(
|
|
fixture_dir: FixtureDirGetter, with_simple_keyring: None
|
|
) -> None:
|
|
io = BufferedIO()
|
|
poetry = Factory().create_poetry(fixture_dir("with_default_source"), io=io)
|
|
|
|
assert len(poetry.pool.repositories) == 1
|
|
assert (
|
|
io.fetch_error().strip()
|
|
== "<warning>Warning: Found deprecated priority 'default' for source 'foo' in"
|
|
" pyproject.toml. You can achieve the same effect by changing the priority"
|
|
" to 'primary' and putting the source first."
|
|
)
|
|
|
|
|
|
def test_poetry_with_default_source_and_pypi(
|
|
fixture_dir: FixtureDirGetter, with_simple_keyring: None
|
|
) -> None:
|
|
io = BufferedIO()
|
|
poetry = Factory().create_poetry(fixture_dir("with_default_source_and_pypi"), io=io)
|
|
|
|
assert len(poetry.pool.repositories) == 2
|
|
assert poetry.pool.has_repository("PyPI")
|
|
assert isinstance(poetry.pool.repository("PyPI"), PyPiRepository)
|
|
assert poetry.pool.get_priority("PyPI") is Priority.PRIMARY
|
|
assert "Warning: Found deprecated key" not in io.fetch_error()
|
|
|
|
|
|
def test_poetry_with_default_source_pypi(
|
|
fixture_dir: FixtureDirGetter, with_simple_keyring: None
|
|
) -> None:
|
|
io = BufferedIO()
|
|
poetry = Factory().create_poetry(fixture_dir("with_default_source_pypi"), io=io)
|
|
|
|
assert len(poetry.pool.repositories) == 1
|
|
assert poetry.pool.has_repository("PyPI")
|
|
assert isinstance(poetry.pool.repository("PyPI"), PyPiRepository)
|
|
assert poetry.pool.get_priority("PyPI") is Priority.DEFAULT
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"project",
|
|
("with_non_default_source_implicit", "with_non_default_source_explicit"),
|
|
)
|
|
def test_poetry_with_non_default_source(
|
|
project: str, fixture_dir: FixtureDirGetter, with_simple_keyring: None
|
|
) -> None:
|
|
io = BufferedIO()
|
|
poetry = Factory().create_poetry(fixture_dir(project), io=io)
|
|
|
|
assert not poetry.pool.has_default()
|
|
assert not poetry.pool.has_repository("PyPI")
|
|
assert poetry.pool.has_repository("foo")
|
|
assert poetry.pool.get_priority("foo") is Priority.PRIMARY
|
|
assert isinstance(poetry.pool.repository("foo"), LegacyRepository)
|
|
assert {repo.name for repo in poetry.pool.repositories} == {"foo"}
|
|
|
|
|
|
def test_poetry_with_non_default_secondary_source_legacy(
|
|
fixture_dir: FixtureDirGetter, with_simple_keyring: None
|
|
) -> None:
|
|
poetry = Factory().create_poetry(
|
|
fixture_dir("with_non_default_secondary_source_legacy")
|
|
)
|
|
|
|
assert poetry.pool.has_repository("PyPI")
|
|
assert isinstance(poetry.pool.repository("PyPI"), PyPiRepository)
|
|
assert poetry.pool.get_priority("PyPI") is Priority.PRIMARY
|
|
assert poetry.pool.has_repository("foo")
|
|
assert isinstance(poetry.pool.repository("foo"), LegacyRepository)
|
|
assert {repo.name for repo in poetry.pool.repositories} == {"PyPI", "foo"}
|
|
|
|
|
|
def test_poetry_with_non_default_secondary_source(
|
|
fixture_dir: FixtureDirGetter, with_simple_keyring: None
|
|
) -> None:
|
|
poetry = Factory().create_poetry(fixture_dir("with_non_default_secondary_source"))
|
|
|
|
assert poetry.pool.has_repository("PyPI")
|
|
assert isinstance(poetry.pool.repository("PyPI"), PyPiRepository)
|
|
assert poetry.pool.get_priority("PyPI") is Priority.PRIMARY
|
|
assert poetry.pool.has_repository("foo")
|
|
assert isinstance(poetry.pool.repository("foo"), LegacyRepository)
|
|
assert {repo.name for repo in poetry.pool.repositories} == {"PyPI", "foo"}
|
|
|
|
|
|
def test_poetry_with_non_default_multiple_secondary_sources_legacy(
|
|
fixture_dir: FixtureDirGetter,
|
|
with_simple_keyring: None,
|
|
) -> None:
|
|
poetry = Factory().create_poetry(
|
|
fixture_dir("with_non_default_multiple_secondary_sources_legacy")
|
|
)
|
|
|
|
assert poetry.pool.has_repository("PyPI")
|
|
assert isinstance(poetry.pool.repository("PyPI"), PyPiRepository)
|
|
assert poetry.pool.get_priority("PyPI") is Priority.PRIMARY
|
|
assert poetry.pool.has_repository("foo")
|
|
assert isinstance(poetry.pool.repository("foo"), LegacyRepository)
|
|
assert poetry.pool.has_repository("bar")
|
|
assert isinstance(poetry.pool.repository("bar"), LegacyRepository)
|
|
assert {repo.name for repo in poetry.pool.repositories} == {"PyPI", "foo", "bar"}
|
|
|
|
|
|
def test_poetry_with_non_default_multiple_secondary_sources(
|
|
fixture_dir: FixtureDirGetter, with_simple_keyring: None
|
|
) -> None:
|
|
poetry = Factory().create_poetry(
|
|
fixture_dir("with_non_default_multiple_secondary_sources")
|
|
)
|
|
|
|
assert poetry.pool.has_repository("PyPI")
|
|
assert isinstance(poetry.pool.repository("PyPI"), PyPiRepository)
|
|
assert poetry.pool.get_priority("PyPI") is Priority.PRIMARY
|
|
assert poetry.pool.has_repository("foo")
|
|
assert isinstance(poetry.pool.repository("foo"), LegacyRepository)
|
|
assert poetry.pool.has_repository("bar")
|
|
assert isinstance(poetry.pool.repository("bar"), LegacyRepository)
|
|
assert {repo.name for repo in poetry.pool.repositories} == {"PyPI", "foo", "bar"}
|
|
|
|
|
|
def test_poetry_with_non_default_multiple_sources_legacy(
|
|
fixture_dir: FixtureDirGetter, with_simple_keyring: None
|
|
) -> None:
|
|
poetry = Factory().create_poetry(
|
|
fixture_dir("with_non_default_multiple_sources_legacy")
|
|
)
|
|
|
|
assert not poetry.pool.has_default()
|
|
assert poetry.pool.has_repository("bar")
|
|
assert isinstance(poetry.pool.repository("bar"), LegacyRepository)
|
|
assert not poetry.pool.has_repository("PyPI")
|
|
assert poetry.pool.has_repository("foo")
|
|
assert isinstance(poetry.pool.repository("foo"), LegacyRepository)
|
|
assert {repo.name for repo in poetry.pool.repositories} == {"bar", "foo"}
|
|
|
|
|
|
def test_poetry_with_non_default_multiple_sources(
|
|
fixture_dir: FixtureDirGetter, with_simple_keyring: None
|
|
) -> None:
|
|
poetry = Factory().create_poetry(fixture_dir("with_non_default_multiple_sources"))
|
|
|
|
assert not poetry.pool.has_default()
|
|
assert not poetry.pool.has_repository("PyPI")
|
|
assert poetry.pool.has_repository("bar")
|
|
assert isinstance(poetry.pool.repository("bar"), LegacyRepository)
|
|
assert poetry.pool.has_repository("foo")
|
|
assert isinstance(poetry.pool.repository("foo"), LegacyRepository)
|
|
assert {repo.name for repo in poetry.pool.repositories} == {"bar", "foo"}
|
|
|
|
|
|
def test_poetry_with_non_default_multiple_sources_pypi(
|
|
fixture_dir: FixtureDirGetter, with_simple_keyring: None
|
|
) -> None:
|
|
io = BufferedIO()
|
|
poetry = Factory().create_poetry(
|
|
fixture_dir("with_non_default_multiple_sources_pypi"), io=io
|
|
)
|
|
|
|
assert len(poetry.pool.repositories) == 4
|
|
assert not poetry.pool.has_default()
|
|
assert poetry.pool.has_repository("PyPI")
|
|
assert isinstance(poetry.pool.repository("PyPI"), PyPiRepository)
|
|
assert poetry.pool.get_priority("PyPI") is Priority.PRIMARY
|
|
# PyPI must be between bar and baz!
|
|
expected = ["bar", "PyPI", "baz", "foo"]
|
|
assert [repo.name for repo in poetry.pool.repositories] == expected
|
|
error = io.fetch_error()
|
|
assert (
|
|
error.strip()
|
|
== "<warning>Warning: Found deprecated priority 'secondary' for source 'foo' in"
|
|
" pyproject.toml. Consider changing the priority to one of the"
|
|
" non-deprecated values: 'default', 'primary', 'supplemental', 'explicit'."
|
|
)
|
|
|
|
|
|
def test_poetry_with_no_default_source(fixture_dir: FixtureDirGetter) -> None:
|
|
poetry = Factory().create_poetry(fixture_dir("sample_project"))
|
|
|
|
assert poetry.pool.has_repository("PyPI")
|
|
assert poetry.pool.get_priority("PyPI") is Priority.PRIMARY
|
|
assert isinstance(poetry.pool.repository("PyPI"), PyPiRepository)
|
|
assert {repo.name for repo in poetry.pool.repositories} == {"PyPI"}
|
|
|
|
|
|
def test_poetry_with_supplemental_source(
|
|
fixture_dir: FixtureDirGetter, with_simple_keyring: None
|
|
) -> None:
|
|
io = BufferedIO()
|
|
poetry = Factory().create_poetry(fixture_dir("with_supplemental_source"), io=io)
|
|
|
|
assert poetry.pool.has_repository("PyPI")
|
|
assert poetry.pool.get_priority("PyPI") is Priority.PRIMARY
|
|
assert isinstance(poetry.pool.repository("PyPI"), PyPiRepository)
|
|
assert poetry.pool.has_repository("supplemental")
|
|
assert poetry.pool.get_priority("supplemental") is Priority.SUPPLEMENTAL
|
|
assert isinstance(poetry.pool.repository("supplemental"), LegacyRepository)
|
|
assert {repo.name for repo in poetry.pool.repositories} == {"PyPI", "supplemental"}
|
|
assert io.fetch_error() == ""
|
|
|
|
|
|
def test_poetry_with_explicit_source(
|
|
fixture_dir: FixtureDirGetter, with_simple_keyring: None
|
|
) -> None:
|
|
io = BufferedIO()
|
|
poetry = Factory().create_poetry(fixture_dir("with_explicit_source"), io=io)
|
|
|
|
assert len(poetry.pool.repositories) == 1
|
|
assert len(poetry.pool.all_repositories) == 2
|
|
assert poetry.pool.has_repository("PyPI")
|
|
assert poetry.pool.get_priority("PyPI") is Priority.PRIMARY
|
|
assert isinstance(poetry.pool.repository("PyPI"), PyPiRepository)
|
|
assert poetry.pool.has_repository("explicit")
|
|
assert isinstance(poetry.pool.repository("explicit"), LegacyRepository)
|
|
assert {repo.name for repo in poetry.pool.repositories} == {"PyPI"}
|
|
assert io.fetch_error() == ""
|
|
|
|
|
|
def test_poetry_with_explicit_pypi_and_other(
|
|
fixture_dir: FixtureDirGetter, with_simple_keyring: None
|
|
) -> None:
|
|
io = BufferedIO()
|
|
poetry = Factory().create_poetry(fixture_dir("with_explicit_pypi_and_other"), io=io)
|
|
|
|
assert len(poetry.pool.repositories) == 1
|
|
assert len(poetry.pool.all_repositories) == 2
|
|
error = io.fetch_error()
|
|
assert error == ""
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"project", ["with_explicit_pypi_no_other", "with_explicit_pypi_and_other_explicit"]
|
|
)
|
|
def test_poetry_with_pypi_explicit_only(
|
|
project: str, fixture_dir: FixtureDirGetter, with_simple_keyring: None
|
|
) -> None:
|
|
with pytest.raises(PoetryException) as e:
|
|
Factory().create_poetry(fixture_dir(project))
|
|
assert str(e.value) == "At least one source must not be configured as 'explicit'."
|
|
|
|
|
|
def test_poetry_with_two_default_sources_legacy(
|
|
fixture_dir: FixtureDirGetter, with_simple_keyring: None
|
|
) -> None:
|
|
with pytest.raises(ValueError) as e:
|
|
Factory().create_poetry(fixture_dir("with_two_default_sources_legacy"))
|
|
|
|
assert str(e.value) == "Only one repository can be the default."
|
|
|
|
|
|
def test_poetry_with_two_default_sources(
|
|
fixture_dir: FixtureDirGetter, with_simple_keyring: None
|
|
) -> None:
|
|
with pytest.raises(ValueError) as e:
|
|
Factory().create_poetry(fixture_dir("with_two_default_sources"))
|
|
|
|
assert str(e.value) == "Only one repository can be the default."
|
|
|
|
|
|
def test_validate(fixture_dir: FixtureDirGetter) -> None:
|
|
complete = TOMLFile(fixture_dir("complete.toml"))
|
|
pyproject: dict[str, Any] = complete.read()
|
|
content = pyproject["tool"]["poetry"]
|
|
|
|
assert Factory.validate(content) == {"errors": [], "warnings": []}
|
|
|
|
|
|
def test_validate_fails(fixture_dir: FixtureDirGetter) -> None:
|
|
complete = TOMLFile(fixture_dir("complete.toml"))
|
|
pyproject: dict[str, Any] = complete.read()
|
|
content = pyproject["tool"]["poetry"]
|
|
content["this key is not in the schema"] = ""
|
|
|
|
expected = (
|
|
"Additional properties are not allowed "
|
|
"('this key is not in the schema' was unexpected)"
|
|
)
|
|
|
|
assert Factory.validate(content) == {"errors": [expected], "warnings": []}
|
|
|
|
|
|
def test_create_poetry_fails_on_invalid_configuration(
|
|
fixture_dir: FixtureDirGetter,
|
|
) -> None:
|
|
with pytest.raises(RuntimeError) as e:
|
|
Factory().create_poetry(fixture_dir("invalid_pyproject"))
|
|
|
|
fastjsonschema_error = "data must contain ['description'] properties"
|
|
custom_error = "The fields ['description'] are required in package mode."
|
|
|
|
expected_template = """\
|
|
The Poetry configuration is invalid:
|
|
- {schema_error}
|
|
- Project name (invalid) is same as one of its dependencies
|
|
"""
|
|
expected = {
|
|
expected_template.format(schema_error=schema_error)
|
|
for schema_error in (fastjsonschema_error, custom_error)
|
|
}
|
|
|
|
assert str(e.value) in expected
|
|
|
|
|
|
def test_create_poetry_fails_on_nameless_project(
|
|
fixture_dir: FixtureDirGetter,
|
|
) -> None:
|
|
with pytest.raises(RuntimeError) as e:
|
|
Factory().create_poetry(fixture_dir("nameless_pyproject"))
|
|
|
|
fastjsonschema_error = "data must contain ['name'] properties"
|
|
custom_error = "The fields ['name'] are required in package mode."
|
|
|
|
expected_template = """\
|
|
The Poetry configuration is invalid:
|
|
- {schema_error}
|
|
"""
|
|
expected = {
|
|
expected_template.format(schema_error=schema_error)
|
|
for schema_error in (fastjsonschema_error, custom_error)
|
|
}
|
|
|
|
assert str(e.value) in expected
|
|
|
|
|
|
def test_create_poetry_with_local_config(fixture_dir: FixtureDirGetter) -> None:
|
|
poetry = Factory().create_poetry(fixture_dir("with_local_config"))
|
|
|
|
assert not poetry.config.get("virtualenvs.in-project")
|
|
assert not poetry.config.get("virtualenvs.create")
|
|
assert not poetry.config.get("virtualenvs.options.always-copy")
|
|
assert not poetry.config.get("virtualenvs.options.no-pip")
|
|
assert not poetry.config.get("virtualenvs.options.no-setuptools")
|
|
assert not poetry.config.get("virtualenvs.options.system-site-packages")
|
|
|
|
|
|
def test_create_poetry_with_plugins(
|
|
mocker: MockerFixture, fixture_dir: FixtureDirGetter
|
|
) -> None:
|
|
mock_metadata_entry_points(mocker, MyPlugin)
|
|
|
|
poetry = Factory().create_poetry(fixture_dir("sample_project"))
|
|
|
|
assert poetry.package.readmes == (Path("README.md"),)
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
("source", "expected"),
|
|
[
|
|
({}, "Missing [name] in source."),
|
|
({"name": "foo"}, "Missing [url] in source 'foo'."),
|
|
(
|
|
{"name": "PyPI", "url": "https://example.com"},
|
|
"The PyPI repository cannot be configured with a custom url.",
|
|
),
|
|
],
|
|
)
|
|
def test_create_package_source_invalid(
|
|
source: dict[str, str],
|
|
expected: str,
|
|
config: Config,
|
|
fixture_dir: FixtureDirGetter,
|
|
) -> None:
|
|
with pytest.raises(InvalidSourceError) as e:
|
|
Factory.create_package_source(source, config=config)
|
|
Factory().create_poetry(fixture_dir("with_source_pypi_url"))
|
|
|
|
assert str(e.value) == expected
|