blob: c184c5e5da63b1de768dcbe9796027bc2a242f37 [file] [edit]
import runpy
import subprocess
import sys
from pathlib import Path
from unittest.mock import MagicMock
import pytest
ACTION_MAIN = Path(__file__).resolve().parents[1] / "action" / "main.py"
pytestmark = pytest.mark.skipif(
sys.version_info < (3, 11), reason="use_pyproject requires Python 3.11 or later"
)
@pytest.fixture
def action_run(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> MagicMock:
monkeypatch.chdir(tmp_path)
monkeypatch.setenv("GITHUB_ACTION_PATH", str(tmp_path))
for name, value in {
"INPUT_USE_PYPROJECT": "true",
"INPUT_VERSION": "",
"INPUT_BLACK_ARGS": "",
"INPUT_OPTIONS": "--check",
"INPUT_SRC": ".",
"INPUT_JUPYTER": "false",
"OUTPUT_FILE": "",
}.items():
monkeypatch.setenv(name, value)
runner = MagicMock(return_value=subprocess.CompletedProcess([], 0, stdout=""))
monkeypatch.setattr(subprocess, "run", runner)
return runner
@pytest.mark.parametrize(
("config", "specifier"),
[
pytest.param(
'[dependency-groups]\ndev = [{include-group = "base"}, "black==26.5.1"]\n'
'base = ["pytest"]\n',
"==26.5.1",
id="include-before-pin",
),
pytest.param(
'[dependency-groups]\ndev = ["black==26.5.1", {include-group = "base"}]\n'
'base = ["pytest"]\n',
"==26.5.1",
id="include-after-pin",
),
pytest.param(
'[dependency-groups]\ndev = [{include-group = "lint"}]\n'
'lint = ["black==26.5.1"]\n',
"==26.5.1",
id="pin-in-included-group",
),
pytest.param(
'[dependency-groups]\ndev = [{include-group = "base"}]\n'
'base = ["pytest"]\n[project]\ndependencies = ["black==26.5.1"]\n',
"==26.5.1",
id="unrelated-include-before-project-pin",
),
pytest.param(
'[project]\ndependencies = ["black==26.5.1"]\n',
"==26.5.1",
id="project-pin",
),
pytest.param(
'[dependency-groups]\nlint = ["black[jupyter]>=26; python_version >= '
"'3.11'\"]\n",
">=26",
id="extras-and-marker",
),
],
)
def test_action_use_pyproject(
tmp_path: Path, action_run: MagicMock, config: str, specifier: str
) -> None:
(tmp_path / "pyproject.toml").write_text(config, encoding="utf-8")
with pytest.raises(SystemExit) as exc:
runpy.run_path(str(ACTION_MAIN), run_name="__main__")
assert exc.value.code == 0
assert action_run.call_count == 3
assert action_run.call_args_list[1].args[0][-1] == f"black[colorama]{specifier}"
assert action_run.call_args_list[2].args[0][1:] == ["--check", "."]
@pytest.mark.parametrize(
("config", "message"),
[
pytest.param(
'[dependency-groups]\nlint = ["black"]\n',
"Version specifier missing for 'black' dependency",
id="unpinned-black",
),
pytest.param(
'[dependency-groups]\ndev = [{include-group = "base"}]\n'
'base = ["pytest"]\n',
"'black' dependency missing from pyproject.toml",
id="include-without-black",
),
],
)
def test_action_use_pyproject_missing_pin(
tmp_path: Path,
action_run: MagicMock,
capsys: pytest.CaptureFixture[str],
config: str,
message: str,
) -> None:
(tmp_path / "pyproject.toml").write_text(config, encoding="utf-8")
with pytest.raises(SystemExit) as exc:
runpy.run_path(str(ACTION_MAIN), run_name="__main__")
assert exc.value.code == 1
assert message in capsys.readouterr().err
assert action_run.call_count == 1