Skip to content

Commit

Permalink
test: add Poetry PEP 621 unit and functional tests
Browse files Browse the repository at this point in the history
  • Loading branch information
mkniewallner committed Jan 9, 2025
1 parent b9ace6d commit befb7d1
Show file tree
Hide file tree
Showing 7 changed files with 271 additions and 3 deletions.
2 changes: 2 additions & 0 deletions tests/fixtures/project_with_poetry_pep_621/poetry.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[virtualenvs]
in-project = true
34 changes: 34 additions & 0 deletions tests/fixtures/project_with_poetry_pep_621/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
[project]
name = "foo"
version = "0.0.1"
description = ""
authors = []
requires-python = ">=3.9"
dependencies = [
"arrow==1.3.0",
"pkginfo==1.11.2",
"requests",
]

[tool.poetry.dependencies]
requests = { git = "https://github.com/psf/requests", tag = "v2.32.3" }

[project.optional-dependencies]
foo = [
"click==8.1.7",
"isort==5.13.2",
]
bar = ["urllib3==2.2.3"]

[tool.poetry.dev-dependencies]
black = "24.10.0"

[tool.poetry.group.lint.dependencies]
mypy = "1.13.0"

[tool.poetry.group.test.dependencies]
pytest = "8.3.3"
pytest-cov = "5.0.0"

[tool.deptry.per_rule_ignores]
DEP002 = ["pkginfo"]
10 changes: 10 additions & 0 deletions tests/fixtures/project_with_poetry_pep_621/src/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
from os import chdir, walk
from pathlib import Path

import black
import click
import mypy
import pytest
import pytest_cov
import white as w
from urllib3 import contrib
37 changes: 37 additions & 0 deletions tests/fixtures/project_with_poetry_pep_621/src/notebook.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": 2,
"id": "9f4924ec-2200-4801-9d49-d4833651cbc4",
"metadata": {},
"outputs": [],
"source": [
"import click\n",
"from urllib3 import contrib\n",
"import arrow"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.9.11"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
108 changes: 108 additions & 0 deletions tests/functional/cli/test_cli_poetry_pep_621.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
from __future__ import annotations

import uuid
from pathlib import Path
from typing import TYPE_CHECKING

import pytest

from tests.functional.utils import Project
from tests.utils import get_issues_report

if TYPE_CHECKING:
from tests.utils import PoetryVenvFactory


@pytest.mark.xdist_group(name=Project.POETRY_PEP_621)
def test_cli_with_poetry_pep_621(poetry_venv_factory: PoetryVenvFactory) -> None:
with poetry_venv_factory(Project.POETRY_PEP_621) as virtual_env:
issue_report = f"{uuid.uuid4()}.json"
result = virtual_env.run(f"deptry . -o {issue_report}")

assert result.returncode == 1
assert get_issues_report(Path(issue_report)) == [
{
"error": {
"code": "DEP002",
"message": "'requests' defined as a dependency but not used in the codebase",
},
"module": "requests",
"location": {
"file": str(Path("pyproject.toml")),
"line": None,
"column": None,
},
},
{
"error": {
"code": "DEP002",
"message": "'isort' defined as a dependency but not used in the codebase",
},
"module": "isort",
"location": {
"file": str(Path("pyproject.toml")),
"line": None,
"column": None,
},
},
{
"error": {
"code": "DEP004",
"message": "'black' imported but declared as a dev dependency",
},
"module": "black",
"location": {
"file": str(Path("src/main.py")),
"line": 4,
"column": 8,
},
},
{
"error": {
"code": "DEP004",
"message": "'mypy' imported but declared as a dev dependency",
},
"module": "mypy",
"location": {
"file": str(Path("src/main.py")),
"line": 6,
"column": 8,
},
},
{
"error": {
"code": "DEP004",
"message": "'pytest' imported but declared as a dev dependency",
},
"module": "pytest",
"location": {
"file": str(Path("src/main.py")),
"line": 7,
"column": 8,
},
},
{
"error": {
"code": "DEP004",
"message": "'pytest_cov' imported but declared as a dev dependency",
},
"module": "pytest_cov",
"location": {
"file": str(Path("src/main.py")),
"line": 8,
"column": 8,
},
},
{
"error": {
"code": "DEP001",
"message": "'white' imported but missing from the dependency definitions",
},
"module": "white",
"location": {
"file": str(Path("src/main.py")),
"line": 9,
"column": 8,
},
},
]
1 change: 1 addition & 0 deletions tests/functional/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ class Project(str, Enum):
NAMESPACE = "project_using_namespace"
PDM = "project_with_pdm"
POETRY = "project_with_poetry"
POETRY_PEP_621 = "project_with_poetry_pep_621"
PYPROJECT_DIFFERENT_DIRECTORY = "project_with_pyproject_different_directory"
REQUIREMENTS_TXT = "project_with_requirements_txt"
REQUIREMENTS_IN = "project_with_requirements_in"
Expand Down
82 changes: 79 additions & 3 deletions tests/unit/dependency_getter/test_poetry.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@ def test_dependency_getter(tmp_path: Path) -> None:
[tool.poetry.dependencies]
python = ">=3.7,<4.0"
bar = { version = ">=2.5.1,<4.0.0", python = ">3.7" }
foo-bar = { version = ">=2.5.1,<4.0.0", optional = true, python = ">3.7" }
bar = { version = ">=2.5.1,<4.0.0", python = ">3.7" }
foo-bar = { version = ">=2.5.1,<4.0.0", optional = true, python = ">3.7" }
fox-python = "*" # top level module is called "fox"
[tool.poetry.dev-dependencies]
toml = "^0.10.2"
qux = { version = ">=2.5.1,<4.0.0", optional = true }
qux = { version = ">=2.5.1,<4.0.0", optional = true }
[tool.poetry.group.lint.dependencies]
black = "^22.6.0"
Expand Down Expand Up @@ -73,6 +73,82 @@ def test_dependency_getter(tmp_path: Path) -> None:
assert "pytest_cov" in dev_dependencies[5].top_levels


def test_dependency_getter_pep_621(tmp_path: Path) -> None:
fake_pyproject_toml = """
[project]
name = "foo"
requires-python = ">=3.7,<4.0"
dependencies = [
"bar>=2.5.1,<4.0.0",
"fox-python",
]
[project.optional-dependencies]
an-extra = ["foobar>=2.5.1,<4.0.0"]
[tool.poetry.dependencies]
fox-python = { git = "https://example.com/foo/bar.git", tag = "v1.2.3" }
# This dependency will not be used by Poetry nor extracted by deptry, as `[project.dependencies]` defines at least once
# dependency, and in this case, dependencies in `[tool.poetry.dependencies]` only enrich existing dependencies from
# `[project.dependencies]`, so deptry will completely skip `[tool.poetry.dependencies]`.
skipped-dependency = "1.2.3"
[tool.poetry.dev-dependencies]
toml = "^0.10.2"
qux = { version = ">=2.5.1,<4.0.0", optional = true }
[tool.poetry.group.lint.dependencies]
black = "^22.6.0"
mypy = "^1.3.0"
[tool.poetry.group.test.dependencies]
pytest = "^7.3.0"
pytest-cov = "^4.0.0"
"""

with run_within_dir(tmp_path):
with Path("pyproject.toml").open("w") as f:
f.write(fake_pyproject_toml)

getter = PoetryDependencyGetter(
config=Path("pyproject.toml"),
package_module_name_map={"fox-python": ("fox",)},
)
dependencies_extract = getter.get()
dependencies = dependencies_extract.dependencies
dev_dependencies = dependencies_extract.dev_dependencies

assert len(dependencies) == 3
assert len(dev_dependencies) == 6

assert dependencies[0].name == "bar"
assert "bar" in dependencies[0].top_levels

assert dependencies[1].name == "fox-python"
assert "fox" in dependencies[1].top_levels

assert dependencies[2].name == "foobar"
assert "foobar" in dependencies[2].top_levels

assert dev_dependencies[0].name == "toml"
assert "toml" in dev_dependencies[0].top_levels

assert dev_dependencies[1].name == "qux"
assert "qux" in dev_dependencies[1].top_levels

assert dev_dependencies[2].name == "black"
assert "black" in dev_dependencies[2].top_levels

assert dev_dependencies[3].name == "mypy"
assert "mypy" in dev_dependencies[3].top_levels

assert dev_dependencies[4].name == "pytest"
assert "pytest" in dev_dependencies[4].top_levels

assert dev_dependencies[5].name == "pytest-cov"
assert "pytest_cov" in dev_dependencies[5].top_levels


def test_dependency_getter_empty_dependencies(tmp_path: Path) -> None:
fake_pyproject_toml = """
[tool.poetry]
Expand Down

0 comments on commit befb7d1

Please sign in to comment.