File: test_exec_.py

package info (click to toggle)
tox 4.49.1-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 2,612 kB
  • sloc: python: 26,672; javascript: 114; sh: 22; makefile: 15
file content (86 lines) | stat: -rw-r--r-- 3,087 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
from __future__ import annotations

import sys
from typing import TYPE_CHECKING

import pytest

from tox.execute.request import ExecuteRequest, StdinSource

if TYPE_CHECKING:
    from unittest.mock import MagicMock

    from tox.pytest import ToxProjectCreator


@pytest.mark.parametrize("trail", [[], ["--"]], ids=["no_posargs", "empty_posargs"])
def test_exec_fail_no_posargs(tox_project: ToxProjectCreator, trail: list[str]) -> None:
    outcome = tox_project({"tox.ini": ""}).run("e", "-e", "py39", *trail)
    outcome.assert_failed()
    msg = "ROOT: HandledError| You must specify a command as positional arguments, use -- <command>\n"
    outcome.assert_out_err(msg, "")


def test_exec_fail_multiple_target(tox_project: ToxProjectCreator) -> None:
    outcome = tox_project({"tox.ini": ""}).run("e", "-e", "py39,py38", "--", "py")
    outcome.assert_failed()
    msg = "ROOT: HandledError| exactly one target environment allowed in exec mode but found py39, py38\n"
    outcome.assert_out_err(msg, "")


@pytest.mark.parametrize("exit_code", [1, 0])
def test_exec(tox_project: ToxProjectCreator, exit_code: int) -> None:
    prj = tox_project({"tox.ini": "[testenv]\npackage=skip"})
    py_cmd = f"import sys; print(sys.version); raise SystemExit({exit_code})"
    outcome = prj.run("e", "-e", "py", "--", "python", "-c", py_cmd)
    if exit_code:
        outcome.assert_failed()
    else:
        outcome.assert_success()
    assert sys.version in outcome.out


def test_exec_help(tox_project: ToxProjectCreator) -> None:
    outcome = tox_project({"tox.ini": ""}).run("e", "-h")
    outcome.assert_success()


def test_exec_always_no_capture(tox_project: ToxProjectCreator) -> None:
    """Verify tox exec always runs with no_capture enabled for interactive mode."""
    ini = "[testenv]\npackage=skip"
    project = tox_project({"tox.ini": ini})

    captured_options: list[MagicMock] = []

    def capture_options(request):  # noqa: ANN001, ANN202
        captured_options.append(request)
        return 0

    execute_calls = project.patch_execute(capture_options)
    result = project.run("e", "-e", "py", "--", "python", "--version")
    result.assert_success()

    assert execute_calls.call_count > 0
    for call in execute_calls.call_args_list:
        _, kwargs = call
        env_instance = kwargs.get("self")
        if env_instance and hasattr(env_instance, "options"):
            assert env_instance.options.no_capture is True


def test_exec_passes_stdin_through(tox_project: ToxProjectCreator, monkeypatch: pytest.MonkeyPatch) -> None:
    project = tox_project({"tox.ini": "[testenv]\npackage=skip"})
    monkeypatch.setattr(sys.stdin, "isatty", lambda: False)

    stdin_sources: list[StdinSource] = []

    def capture_stdin(request: ExecuteRequest) -> int:
        stdin_sources.append(request.stdin)
        return 0

    project.patch_execute(capture_stdin)
    result = project.run("e", "-e", "py", "--", "python", "--version")
    result.assert_success()

    assert stdin_sources
    assert all(source == StdinSource.USER for source in stdin_sources)