mirror of
https://github.com/copier-org/copier.git
synced 2025-05-05 15:32:54 +00:00
95 lines
3.1 KiB
Python
95 lines
3.1 KiB
Python
from __future__ import annotations
|
|
|
|
import platform
|
|
import sys
|
|
from pathlib import Path
|
|
from typing import Any, Iterator
|
|
from unittest.mock import patch
|
|
|
|
import pytest
|
|
from coverage.tracer import CTracer
|
|
from pexpect.popen_spawn import PopenSpawn
|
|
from plumbum import local
|
|
from pytest_gitconfig.plugin import DELETE, GitConfig
|
|
|
|
from .helpers import Spawn
|
|
|
|
|
|
@pytest.fixture
|
|
def spawn() -> Spawn:
|
|
"""Spawn a copier process TUI to interact with."""
|
|
if platform.system() == "Windows":
|
|
# HACK https://github.com/prompt-toolkit/python-prompt-toolkit/issues/1243#issuecomment-706668723
|
|
# FIXME Use pexpect or wexpect somehow to fix this
|
|
pytest.xfail(
|
|
"pexpect fails on Windows",
|
|
)
|
|
|
|
def _spawn(cmd: tuple[str, ...], *, timeout: int | None = None) -> PopenSpawn:
|
|
# Disable subprocess timeout if debugging (except coverage), for commodity
|
|
# See https://stackoverflow.com/a/67065084/1468388
|
|
tracer = getattr(sys, "gettrace", lambda: None)()
|
|
if not isinstance(tracer, (CTracer, type(None))):
|
|
timeout = None
|
|
# Using PopenSpawn, although probably it would be best to use pexpect.spawn
|
|
# instead. However, it's working fine and it seems easier to fix in the
|
|
# future to work on Windows (where, this way, spawning actually works; it's just
|
|
# python-prompt-toolkit that rejects displaying a TUI)
|
|
return PopenSpawn(cmd, timeout, logfile=sys.stderr.buffer)
|
|
|
|
return _spawn
|
|
|
|
|
|
@pytest.fixture(scope="session")
|
|
def default_git_user_name() -> Any:
|
|
"""Unset the default Git user name."""
|
|
return DELETE
|
|
|
|
|
|
@pytest.fixture(scope="session")
|
|
def default_git_user_email() -> Any:
|
|
"""Unset the default Git user email."""
|
|
return DELETE
|
|
|
|
|
|
@pytest.fixture(scope="session", autouse=True)
|
|
def default_gitconfig(default_gitconfig: GitConfig) -> GitConfig:
|
|
"""
|
|
Use a clean and isolated default gitconfig avoiding user settings to break some tests.
|
|
|
|
Add plumbum support to the original session-scoped fixture.
|
|
"""
|
|
# local.env is a snapshot frozen at Python startup requiring its own monkeypatching
|
|
for var in list(local.env.keys()):
|
|
if var.startswith("GIT_"):
|
|
del local.env[var]
|
|
local.env["GIT_CONFIG_GLOBAL"] = str(default_gitconfig)
|
|
default_gitconfig.set({"core.autocrlf": "input"})
|
|
return default_gitconfig
|
|
|
|
|
|
@pytest.fixture
|
|
def gitconfig(gitconfig: GitConfig) -> Iterator[GitConfig]:
|
|
"""
|
|
Use a clean and isolated gitconfig to test some specific user settings.
|
|
|
|
Add plumbum support to the original function-scoped fixture.
|
|
"""
|
|
with local.env(GIT_CONFIG_GLOBAL=str(gitconfig)):
|
|
yield gitconfig
|
|
|
|
|
|
@pytest.fixture
|
|
def config_path(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> Iterator[Path]:
|
|
config_path = tmp_path / "config"
|
|
monkeypatch.delenv("COPIER_SETTINGS_PATH", raising=False)
|
|
with patch("copier.settings.user_config_path", return_value=config_path):
|
|
yield config_path
|
|
|
|
|
|
@pytest.fixture
|
|
def settings_path(config_path: Path) -> Path:
|
|
config_path.mkdir()
|
|
settings_path = config_path / "settings.yml"
|
|
return settings_path
|