This commit is contained in:
146
tests/conftest.py
Normal file
146
tests/conftest.py
Normal file
@@ -0,0 +1,146 @@
|
||||
# SPDX-FileCopyrightText: 2025 Alexander Kalinovsky <a@k8y.ru>
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
"""Pytest configuration and fixtures for CLI tests."""
|
||||
|
||||
import shutil
|
||||
import sys
|
||||
import tempfile
|
||||
from collections.abc import Generator
|
||||
from pathlib import Path
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
import pytest
|
||||
from typer.testing import CliRunner
|
||||
|
||||
# Add src to path for imports
|
||||
sys.path.insert(0, str(Path(__file__).parent.parent / "src"))
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def cli_runner() -> CliRunner:
|
||||
"""Provide a CLI runner for testing commands."""
|
||||
return CliRunner()
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def temp_dir() -> Generator[Path]:
|
||||
"""Provide a temporary directory for testing."""
|
||||
with tempfile.TemporaryDirectory() as tmp_dir:
|
||||
yield Path(tmp_dir)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_template_dir() -> Generator[Path]:
|
||||
"""Provide a mock template directory structure."""
|
||||
template_dir = Path(__file__).parent / "fixtures" / "mock_template"
|
||||
template_dir.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
# Create template spec
|
||||
spec_file = template_dir / "__template__.yaml"
|
||||
spec_content = """
|
||||
variables:
|
||||
project_name:
|
||||
prompt: "Project name"
|
||||
default: "test_project"
|
||||
description:
|
||||
prompt: "Description"
|
||||
default: "Test description"
|
||||
author:
|
||||
prompt: "Author"
|
||||
default: "Test Author"
|
||||
license:
|
||||
prompt: "License"
|
||||
default: "MIT"
|
||||
include_alembic:
|
||||
prompt: "Include Alembic?"
|
||||
choices: ["yes", "no"]
|
||||
default: "yes"
|
||||
include_i18n:
|
||||
prompt: "Include i18n?"
|
||||
choices: [true, false]
|
||||
default: true
|
||||
post_tasks:
|
||||
- when: "{{ include_alembic == 'yes' }}"
|
||||
run: ["echo", "alembic_init"]
|
||||
- when: "{{ include_i18n == true }}"
|
||||
run: ["echo", "babel_init"]
|
||||
"""
|
||||
spec_file.write_text(spec_content)
|
||||
|
||||
# Create some template files
|
||||
(template_dir / "app").mkdir()
|
||||
(template_dir / "app" / "main.py.j2").write_text(
|
||||
"from fastapi import FastAPI\n\napp = FastAPI(title='{{ project_name }}')\n"
|
||||
)
|
||||
(template_dir / "app" / "config.py.j2").write_text(
|
||||
"PROJECT_NAME = '{{ project_name }}'\nDESCRIPTION = '{{ description }}'\n"
|
||||
)
|
||||
(template_dir / "README.md.j2").write_text(
|
||||
"# {{ project_name }}\n\n{{ description }}\n\nAuthor: {{ author }}\nLicense: {{ license }}"
|
||||
)
|
||||
(template_dir / "pyproject.toml.j2").write_text(
|
||||
"[project]\nname = '{{ project_name }}'\ndescription = '{{ description }}'"
|
||||
)
|
||||
|
||||
# Create optional modules
|
||||
(template_dir / "alembic").mkdir()
|
||||
(template_dir / "alembic" / "alembic.ini.j2").write_text("alembic config for {{ project_name }}")
|
||||
(template_dir / "locales").mkdir()
|
||||
(template_dir / "locales" / "en").mkdir()
|
||||
(template_dir / "locales" / "en" / "LC_MESSAGES").mkdir()
|
||||
|
||||
# Create scripts
|
||||
(template_dir / "scripts").mkdir()
|
||||
(template_dir / "scripts" / "migrations_generate.sh.j2").write_text(
|
||||
"#!/bin/bash\necho 'Generate migrations for {{ project_name }}'"
|
||||
)
|
||||
(template_dir / "scripts" / "migrations_apply.sh.j2").write_text(
|
||||
"#!/bin/bash\necho 'Apply migrations for {{ project_name }}'"
|
||||
)
|
||||
(template_dir / "scripts" / "babel_init.sh.j2").write_text("#!/bin/bash\necho 'Init Babel for {{ project_name }}'")
|
||||
(template_dir / "scripts" / "babel_extract.sh.j2").write_text(
|
||||
"#!/bin/bash\necho 'Extract Babel for {{ project_name }}'"
|
||||
)
|
||||
(template_dir / "scripts" / "babel_update.sh.j2").write_text(
|
||||
"#!/bin/bash\necho 'Update Babel for {{ project_name }}'"
|
||||
)
|
||||
(template_dir / "scripts" / "babel_compile.sh.j2").write_text(
|
||||
"#!/bin/bash\necho 'Compile Babel for {{ project_name }}'"
|
||||
)
|
||||
|
||||
yield template_dir
|
||||
|
||||
# Cleanup
|
||||
shutil.rmtree(template_dir)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_typer_prompt() -> Generator[MagicMock]:
|
||||
"""Mock typer.prompt to avoid interactive input during tests."""
|
||||
with patch("quickbot_cli.cli.typer.prompt") as mock_prompt:
|
||||
mock_prompt.return_value = "test_value"
|
||||
yield mock_prompt
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_typer_secho() -> Generator[MagicMock]:
|
||||
"""Mock typer.secho to capture output during tests."""
|
||||
with patch("quickbot_cli.cli.typer.secho") as mock_secho:
|
||||
yield mock_secho
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_typer_echo() -> Generator[MagicMock]:
|
||||
"""Mock typer.echo to capture output during tests."""
|
||||
with patch("quickbot_cli.cli.typer.echo") as mock_echo:
|
||||
yield mock_echo
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_subprocess_run() -> Generator[MagicMock]:
|
||||
"""Mock subprocess.run to avoid actual command execution during tests."""
|
||||
with patch("quickbot_cli.cli.subprocess.run") as mock_run:
|
||||
mock_run.return_value = MagicMock(returncode=0)
|
||||
yield mock_run
|
||||
Reference in New Issue
Block a user