Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,40 @@ data/**
./extensions/**
venv/**
*.pyc

# Testing
.pytest_cache/
.coverage
htmlcov/
coverage.xml
.tox/
.hypothesis/

# Claude settings
.claude/*

# Build artifacts
build/
dist/
*.egg-info/
__pycache__/
*.py[cod]
*$py.class
*.so

# Virtual environments
env/
ENV/
venv/
.venv/

# IDE
.vscode/
.idea/
*.swp
*.swo
*~
.DS_Store

# OS
Thumbs.db
340 changes: 340 additions & 0 deletions poetry.lock

Large diffs are not rendered by default.

88 changes: 88 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
[tool.poetry]
name = "audio-webui"
version = "0.1.0"
description = "A webui for generating audio with various models"
authors = ["gitmylo"]
readme = "readme.md"
packages = [
{ include = "webui" },
{ include = "hubert" },
{ include = "autodebug" },
{ include = "setup_tools" },
{ include = "simplestyle" },
]

[tool.poetry.dependencies]
python = "^3.10"

[tool.poetry.group.dev.dependencies]
pytest = "^8.0.0"
pytest-cov = "^4.1.0"
pytest-mock = "^3.12.0"

[tool.poetry.scripts]
test = "pytest:main"
tests = "pytest:main"

[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"

[tool.pytest.ini_options]
testpaths = ["tests"]
python_files = ["test_*.py", "*_test.py"]
python_classes = ["Test*"]
python_functions = ["test_*"]
addopts = [
"--verbose",
"--strict-markers",
"--strict-config",
"--cov=webui",
"--cov=hubert",
"--cov=autodebug",
"--cov=setup_tools",
"--cov=simplestyle",
"--cov-report=term-missing",
"--cov-report=html",
"--cov-report=xml",
"--cov-fail-under=80",
]
markers = [
"unit: Unit tests that test individual components in isolation",
"integration: Integration tests that test multiple components together",
"slow: Tests that take a long time to run",
]

[tool.coverage.run]
source = ["webui", "hubert", "autodebug", "setup_tools", "simplestyle"]
omit = [
"*/tests/*",
"*/test_*.py",
"*/__pycache__/*",
"*/venv/*",
"*/data/*",
"*/extensions/*",
"*/assets/*",
"*/scripts/*",
"*/installers/*",
]

[tool.coverage.report]
exclude_lines = [
"pragma: no cover",
"def __repr__",
"raise AssertionError",
"raise NotImplementedError",
"if __name__ == .__main__.:",
"if TYPE_CHECKING:",
"class .*\\bProtocol\\):",
"@(abc\\.)?abstractmethod",
]
precision = 2
show_missing = true

[tool.coverage.html]
directory = "htmlcov"

[tool.coverage.xml]
output = "coverage.xml"
1 change: 1 addition & 0 deletions tests/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"""Test suite for audio-webui project."""
228 changes: 228 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,228 @@
"""Shared pytest fixtures and configuration for audio-webui tests."""

import os
import tempfile
from pathlib import Path
from typing import Generator
from unittest.mock import MagicMock

import pytest


@pytest.fixture
def temp_dir() -> Generator[Path, None, None]:
"""
Provide a temporary directory for test files.

The directory is automatically cleaned up after the test completes.

Yields:
Path: Path object pointing to a temporary directory
"""
with tempfile.TemporaryDirectory() as tmpdir:
yield Path(tmpdir)


@pytest.fixture
def temp_file(temp_dir: Path) -> Generator[Path, None, None]:
"""
Provide a temporary file for testing.

Args:
temp_dir: Temporary directory fixture

Yields:
Path: Path object pointing to a temporary file
"""
tmp_file = temp_dir / "test_file.txt"
tmp_file.touch()
yield tmp_file


@pytest.fixture
def mock_config() -> dict:
"""
Provide a mock configuration dictionary for testing.

Returns:
dict: Mock configuration with common test settings
"""
return {
"no_data_cache": False,
"skip_venv": True,
"skip_install": True,
"gradio_temp_dir": "/tmp/gradio",
"test_mode": True,
}


@pytest.fixture
def mock_env_vars(monkeypatch) -> dict:
"""
Set up mock environment variables for testing.

Args:
monkeypatch: Pytest monkeypatch fixture

Returns:
dict: Dictionary of mocked environment variables
"""
env_vars = {
"XDG_CACHE_HOME": "/tmp/cache",
"HF_HOME": "/tmp/hf_home",
"MUSICGEN_ROOT": "/tmp/musicgen",
"HF_HUB_CACHE": "/tmp/hf_cache",
"GRADIO_TEMP_DIR": "/tmp/gradio",
}

for key, value in env_vars.items():
monkeypatch.setenv(key, value)

return env_vars


@pytest.fixture
def sample_audio_path(temp_dir: Path) -> Path:
"""
Provide a path for a sample audio file (not created, just the path).

Args:
temp_dir: Temporary directory fixture

Returns:
Path: Path where a sample audio file could be placed
"""
return temp_dir / "sample_audio.wav"


@pytest.fixture
def mock_torch():
"""
Provide a mock torch module for testing without PyTorch dependency.

Returns:
MagicMock: Mock torch module with common attributes
"""
mock = MagicMock()
mock.cuda.is_available.return_value = False
mock.device.return_value = "cpu"
return mock


@pytest.fixture
def mock_gradio():
"""
Provide a mock gradio module for testing without Gradio dependency.

Returns:
MagicMock: Mock gradio module
"""
mock = MagicMock()
mock.Blocks.return_value.__enter__.return_value = mock
return mock


@pytest.fixture
def project_root() -> Path:
"""
Provide the project root directory path.

Returns:
Path: Path to the project root directory
"""
return Path(__file__).parent.parent


@pytest.fixture
def sample_model_config() -> dict:
"""
Provide a sample model configuration for testing.

Returns:
dict: Sample model configuration dictionary
"""
return {
"model_name": "test_model",
"model_type": "text-to-speech",
"parameters": {
"temperature": 0.7,
"top_k": 50,
"top_p": 0.95,
},
"device": "cpu",
}


@pytest.fixture
def mock_file_system(temp_dir: Path):
"""
Create a mock file system structure for testing.

Args:
temp_dir: Temporary directory fixture

Returns:
dict: Dictionary mapping file paths to their locations
"""
# Create directory structure
(temp_dir / "data").mkdir()
(temp_dir / "data" / "models").mkdir()
(temp_dir / "data" / "temp").mkdir()
(temp_dir / "extensions").mkdir()

# Create some sample files
(temp_dir / "data" / "config.json").write_text('{"test": true}')

return {
"root": temp_dir,
"data": temp_dir / "data",
"models": temp_dir / "data" / "models",
"temp": temp_dir / "data" / "temp",
"extensions": temp_dir / "extensions",
"config": temp_dir / "data" / "config.json",
}


@pytest.fixture(autouse=True)
def reset_environment():
"""
Automatically reset certain environment state before each test.

This fixture runs automatically for all tests.
"""
# Store original env vars to restore later
original_env = os.environ.copy()

yield

# Restore original environment
os.environ.clear()
os.environ.update(original_env)


@pytest.fixture
def mock_huggingface_model():
"""
Provide a mock HuggingFace model for testing.

Returns:
MagicMock: Mock HuggingFace model
"""
mock = MagicMock()
mock.generate.return_value = [[1, 2, 3, 4, 5]]
mock.config.return_value = {"model_type": "test"}
return mock


@pytest.fixture
def capture_stdout(capsys):
"""
Provide a convenience fixture for capturing stdout/stderr.

Args:
capsys: Pytest capsys fixture

Returns:
capsys: The capsys fixture for capturing output
"""
return capsys
1 change: 1 addition & 0 deletions tests/integration/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"""Integration tests for audio-webui project."""
Loading