Nekmo/pip-rating

View on GitHub
tests/req_files/test_pyproject.py

Summary

Maintainability
A
0 mins
Test Coverage
import unittest
from unittest.mock import MagicMock, patch

from pip_rating.exceptions import RequirementsRatingParseError
from pip_rating.req_files.pyproject import poetry_version, PyprojectReqFile


PROJECT_FILE = """
[project]
dependencies = [
  'PyYAML ~= 5.0',
  'requests[security] < 3',
  'subprocess32; python_version < "3.2"',
]
"""

POETRY_FILE = r"""
[tool.poetry]
name = "test"

[tool.poetry.dependencies]
python = "^3.11"
telegram-upload = "^0.7.0"
dirhunt = ">=0.8.0,<1.0.0"
amazon-dash = "1.4.0"
gkeep = {markers = "python_version < \"3.12\" and platform_system == \"linux\"", version = "^1.0.1"}
proxy-db = {version = "^0.3.1", platform = "linux", python = "^3.11"}
"""

INVALID_FILE = """
[foo]
spam = "eggs"
"""


class TestPoetryVersion(unittest.TestCase):
    """Test poetry_version function."""

    def test_without_version(self):
        """Test poetry_version function without version."""
        self.assertEqual("", poetry_version(None))

    def test_with_dict(self):
        """Test poetry_version function with dict."""
        self.assertEqual(
            "==1.0.0 ; python_version >='3' and python_version <'4.0.0' "
            "and extra == 'dev' and platform_system=='linux'",
            poetry_version(
                {
                    "version": "1.0.0",
                    "python": "^3",
                    "platform": "linux",
                    "markers": "extra == 'dev'",
                }
            ),
        )

    def test_caret(self):
        """Test poetry_version function with caret."""
        with self.subTest("Test major version"):
            self.assertEqual(">=1.0.0,<2.0.0", poetry_version("^1.0.0"))
            self.assertEqual(">=1,<2.0.0", poetry_version("^1"))
            self.assertEqual(">=1.2.0,<2.0.0", poetry_version("^1.2.0"))
            self.assertEqual(">=1.2,<2.0.0", poetry_version("^1.2"))
            self.assertEqual(">=0,<1.0.0", poetry_version("^0"))
        with self.subTest("Test minor version"):
            self.assertEqual(">=0.2.3,<0.3.0", poetry_version("^0.2.3"))
            self.assertEqual(">=0.0,<0.1.0", poetry_version("^0.0"))
        with self.subTest("Test patch version"):
            self.assertEqual(">=0.0.3,<0.0.4", poetry_version("^0.0.3"))

    def test_numeric_wildcard(self):
        """Test poetry_version function with numeric or wildcard."""
        with self.subTest("Test numeric version"):
            self.assertEqual("==1.2.3", poetry_version("1.2.3"))
        with self.subTest("Test wildcard version"):
            self.assertEqual("==*.3", poetry_version("*.3"))

    def test_operators(self):
        """Test poetry_version function with operators."""
        with self.subTest("Test equal operator"):
            self.assertEqual("==1.2.3", poetry_version("==1.2.3"))
        with self.subTest("Test not equal operator"):
            self.assertEqual("!=1.2.3", poetry_version("!=1.2.3"))
        with self.subTest("Test less than operator"):
            self.assertEqual("<1.2.3", poetry_version("<1.2.3"))
        with self.subTest("Test less than or equal operator"):
            self.assertEqual("<=1.2.3", poetry_version("<=1.2.3"))
        with self.subTest("Test greater than operator"):
            self.assertEqual(">1.2.3", poetry_version(">1.2.3"))
        with self.subTest("Test greater than or equal operator"):
            self.assertEqual(">=1.2.3", poetry_version(">=1.2.3"))

    def test_invalid_version(self):
        """Test poetry_version function with invalid version."""
        with self.assertRaises(RequirementsRatingParseError):
            poetry_version("invalid")


class TestPyprojectReqFile(unittest.TestCase):
    """Test PyprojectReqFile class."""

    @patch("pip_rating.req_files.pyproject.PyprojectReqFile.__init__")
    @patch("pip_rating.req_files.pyproject.Path")
    def test_find_in_directory(self, mock_path: MagicMock, mock_init: MagicMock):
        """Test the find_in_directory method in the PyprojectReqFile class."""
        mock_init.return_value = None
        req = PyprojectReqFile.find_in_directory("directory")
        self.assertIsInstance(req, PyprojectReqFile)
        mock_path.return_value.__truediv__.assert_called_once_with("pyproject.toml")
        mock_path.return_value.__truediv__.return_value.exists.assert_called_once_with()
        mock_init.assert_called_once_with(
            mock_path.return_value.__truediv__.return_value
        )

    @patch("pip_rating.req_files.pyproject.Path")
    def test_is_valid(self, mock_path: MagicMock):
        """Test the is_valid method in the PyprojectReqFile class."""
        mock_path.return_value.exists.return_value = True
        mock_path.return_value.name = "pyproject.toml"
        self.assertTrue(PyprojectReqFile.is_valid("path"))
        mock_path.return_value.exists.assert_called_once_with()

    @patch("builtins.open")
    @patch("pip_rating.req_files.pyproject.PyprojectReqFile.__init__")
    def test_get_dependencies(self, mock_init: MagicMock, mock_open: MagicMock):
        """Test the get_dependencies method in the PyprojectReqFile class."""
        mock_init.return_value = None
        pyproject_req_file = PyprojectReqFile("path")
        pyproject_req_file.path = "path"
        with self.subTest("Test with standard project file"):
            mock_open.return_value.__enter__.return_value.read.return_value = (
                PROJECT_FILE.encode("utf-8")
            )
            dependencies = pyproject_req_file.get_dependencies()
            self.assertEqual(
                [
                    "PyYAML ~= 5.0",
                    "requests[security] < 3",
                    'subprocess32; python_version < "3.2"',
                ],
                dependencies,
            )
        with self.subTest("Test with Poetry file"):
            mock_open.return_value.__enter__.return_value.read.return_value = (
                POETRY_FILE.encode("utf-8")
            )
            dependencies = pyproject_req_file.get_dependencies()
            self.assertEqual(
                [
                    "telegram-upload>=0.7.0,<0.8.0",
                    "dirhunt>=0.8.0,<1.0.0",
                    "amazon-dash==1.4.0",
                    'gkeep>=1.0.1,<2.0.0 ; python_version < "3.12" and platform_system == "linux"',
                    "proxy-db>=0.3.1,<0.4.0 ; python_version >='3.11' and python_version <'4.0.0' "
                    "and platform_system=='linux'",
                ],
                dependencies,
            )
        with self.subTest("Invalid file"):
            mock_open.return_value.__enter__.return_value.read.return_value = (
                INVALID_FILE.encode("utf-8")
            )
            with self.assertRaises(RequirementsRatingParseError):
                pyproject_req_file.get_dependencies()