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
26 changes: 25 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,28 @@
.vscode

# θΏθ‘ŒηΌ“ε­˜
__pycache__
__pycache__

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

# Claude Code settings
.claude/

# Build artifacts
dist/
build/
*.egg-info/

# Environment files
.env
.env.local
.env.*.local

# OS files
.DS_Store
Thumbs.db
525 changes: 525 additions & 0 deletions poetry.lock

Large diffs are not rendered by default.

83 changes: 83 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
[tool.poetry]
name = "video-converter"
version = "0.1.0"
description = "A Python video converter with audio processing capabilities"
authors = ["Your Name <[email protected]>"]
readme = "README.md"
packages = [{include = "video_converter"}]

[tool.poetry.dependencies]
python = "^3.8"
certifi = "2022.12.7"
charset-normalizer = "3.0.1"
colorama = "0.4.6"
colorlog = "6.7.0"
idna = "3.4"
numpy = "1.24.2"
pydub = "0.25.1"
requests = "2.28.2"
SpeechRecognition = "3.9.0"
urllib3 = "1.26.14"

[tool.poetry.group.test.dependencies]
pytest = "^7.4.0"
pytest-cov = "^4.1.0"
pytest-mock = "^3.11.1"


[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 = [
"--strict-markers",
"--strict-config",
"--verbose",
"--cov=video_converter",
"--cov-report=html:htmlcov",
"--cov-report=xml:coverage.xml",
"--cov-report=term-missing",
"--cov-fail-under=80"
]
markers = [
"unit: Unit tests",
"integration: Integration tests",
"slow: Slow tests"
]

[tool.coverage.run]
source = ["video_converter"]
branch = true
omit = [
"*/tests/*",
"*/test_*",
"*/__pycache__/*",
"*/venv/*",
"*/virtualenv/*",
"*/.pytest_cache/*"
]

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

[tool.coverage.html]
directory = "htmlcov"
Empty file added tests/__init__.py
Empty file.
85 changes: 85 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import pytest
import tempfile
import shutil
from pathlib import Path
from unittest.mock import Mock, MagicMock


@pytest.fixture
def temp_dir():
"""Create a temporary directory for test files."""
temp_path = Path(tempfile.mkdtemp())
yield temp_path
shutil.rmtree(temp_path)


@pytest.fixture
def sample_audio_file(temp_dir):
"""Create a mock audio file for testing."""
audio_file = temp_dir / "sample.wav"
audio_file.touch()
return audio_file


@pytest.fixture
def sample_video_file(temp_dir):
"""Create a mock video file for testing."""
video_file = temp_dir / "sample.mp4"
video_file.touch()
return video_file


@pytest.fixture
def mock_logger():
"""Mock logger for testing logging functionality."""
return Mock()


@pytest.fixture
def mock_config():
"""Mock configuration for testing."""
return {
'output_dir': '/tmp/output',
'log_level': 'INFO',
'supported_formats': ['.wav', '.mp3', '.m4a', '.mp4']
}


@pytest.fixture
def mock_pydub_audio():
"""Mock pydub AudioSegment for testing."""
mock_audio = MagicMock()
mock_audio.duration_seconds = 10.0
mock_audio.frame_rate = 44100
mock_audio.channels = 2
return mock_audio


@pytest.fixture
def mock_speech_recognition():
"""Mock speech recognition for testing."""
mock_recognizer = MagicMock()
mock_recognizer.recognize_google.return_value = "test transcription"
return mock_recognizer


@pytest.fixture
def sample_file_paths(temp_dir):
"""Create sample file paths for testing."""
files = {
'audio': temp_dir / "audio.wav",
'video': temp_dir / "video.mp4",
'text': temp_dir / "text.txt",
'log': temp_dir / "test.log"
}

for file_path in files.values():
file_path.touch()

return files


@pytest.fixture(autouse=True)
def reset_mocks():
"""Reset all mocks before each test."""
yield
Empty file added tests/integration/__init__.py
Empty file.
74 changes: 74 additions & 0 deletions tests/test_setup_validation.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
"""
Validation tests to ensure testing infrastructure is properly set up.
These tests verify that the testing environment works correctly.
"""
import pytest
from pathlib import Path
import video_converter


class TestSetupValidation:
"""Tests to validate the testing setup is working correctly."""

def test_pytest_is_working(self):
"""Test that pytest is functioning."""
assert True

def test_can_import_package(self):
"""Test that the main package can be imported."""
assert video_converter is not None

def test_coverage_is_enabled(self, pytestconfig):
"""Test that coverage reporting is enabled."""
plugins = [plugin.__class__.__name__ for plugin in pytestconfig.pluginmanager.get_plugins()]
# Coverage plugin should be loaded
assert any('cov' in plugin.lower() for plugin in plugins)

def test_temp_dir_fixture(self, temp_dir):
"""Test that temp_dir fixture works."""
assert temp_dir.exists()
assert temp_dir.is_dir()

def test_mock_logger_fixture(self, mock_logger):
"""Test that mock_logger fixture works."""
mock_logger.info("test message")
mock_logger.info.assert_called_once_with("test message")

def test_sample_file_fixtures(self, sample_audio_file, sample_video_file):
"""Test that sample file fixtures work."""
assert sample_audio_file.exists()
assert sample_video_file.exists()
assert sample_audio_file.suffix == '.wav'
assert sample_video_file.suffix == '.mp4'

def test_project_structure_exists(self):
"""Test that expected project structure exists."""
project_root = Path(__file__).parent.parent

expected_files = [
'main.py',
'requirements.txt',
'pyproject.toml',
'video_converter/__init__.py',
'video_converter/file_utils.py',
'video_converter/log_utils.py',
'video_converter/voice_utils.py'
]

for file_path in expected_files:
assert (project_root / file_path).exists(), f"Missing: {file_path}"

@pytest.mark.unit
def test_unit_marker_works(self):
"""Test that unit test marker works."""
assert True

@pytest.mark.integration
def test_integration_marker_works(self):
"""Test that integration test marker works."""
assert True

@pytest.mark.slow
def test_slow_marker_works(self):
"""Test that slow test marker works."""
assert True
Empty file added tests/unit/__init__.py
Empty file.