File: conftest.py

package info (click to toggle)
python-invoke 2.2.0-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 1,856 kB
  • sloc: python: 15,986; makefile: 24
file content (92 lines) | stat: -rw-r--r-- 2,895 bytes parent folder | download | duplicates (2)
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
87
88
89
90
91
92
import logging
import os
import sys
import termios

import pytest
from unittest.mock import patch

from _util import support

# Set up icecream globally for convenience.
from icecream import install

install()


# pytest seems to tweak logging such that Invoke's debug logs go to stderr,
# which is then hella spammy if one is using --capture=no (which one must in
# order to test low level terminal IO stuff, as we do!)
# So, we explicitly turn default logging back down.
# NOTE: no real better place to put this than here
# TODO: see if we can use modern pytest's logging functionality to remove the
# need for this, now that pytest-relaxed was modernized
logging.basicConfig(level=logging.INFO)


@pytest.fixture(autouse=True)
def fake_user_home():
    # Ignore any real user homedir for purpose of testing.
    # This allows, for example, a user who has real Invoke configs in their
    # homedir to still run the test suite safely.
    # TODO: this is still a bit of a kludge & doesn't solve systemwide configs
    with patch("invoke.config.expanduser", side_effect=lambda x: x):
        yield


@pytest.fixture
def reset_environ():
    """
    Resets `os.environ` to its prior state after the fixtured test finishes.
    """
    old_environ = os.environ.copy()
    yield
    os.environ.clear()
    os.environ.update(old_environ)


@pytest.fixture
def chdir_support():
    # Always do things relative to tests/_support
    os.chdir(support)
    yield
    # Chdir back to project root to avoid problems
    os.chdir(os.path.join(os.path.dirname(__file__), ".."))


@pytest.fixture
def clean_sys_modules():
    """
    Attempt to nix any imports incurred by the test, to prevent state bleed.

    In some cases this prevents outright errors (eg a test accidentally relying
    on another's import of a task tree in the support folder) and in others
    it's required because we're literally testing runtime imports.
    """
    snapshot = sys.modules.copy()
    yield
    # Iterate over another copy to avoid ye olde mutate-during-iterate problem
    # NOTE: cannot simply 'sys.modules = snapshot' as that is warned against
    for name, module in sys.modules.copy().items():
        # Delete anything newly added (imported)
        if name not in snapshot:
            del sys.modules[name]
        # Overwrite anything that was modified (the easy version...)
        sys.modules.update(snapshot)


@pytest.fixture
def integration(reset_environ, chdir_support, clean_sys_modules):
    yield


@pytest.fixture
def mock_termios():
    with patch("invoke.terminals.termios") as mocked:
        # Ensure mocked termios has 'real' values for constants...otherwise
        # doing bit arithmetic on Mocks kinda defeats the point.
        mocked.ECHO = termios.ECHO
        mocked.ICANON = termios.ICANON
        mocked.VMIN = termios.VMIN
        mocked.VTIME = termios.VTIME
        yield mocked