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
104 changes: 104 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class

# C extensions
*.so

# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST

# Testing
.pytest_cache/
.coverage
htmlcov/
coverage.xml
*.cover
*.py,cover
.hypothesis/
.tox/
.nox/

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

# IDEs
.vscode/
.idea/
*.swp
*.swo
*~
.project
.pydevproject
.settings/
.DS_Store

# Claude
.claude/*

# Jupyter Notebook
.ipynb_checkpoints

# pyenv
.python-version

# pipenv
Pipfile.lock

# Poetry
# Note: poetry.lock should be committed to version control
# poetry.lock

# PEP 582
__pypackages__/

# Environments
.env
.env.local
.env.*.local

# mypy
.mypy_cache/
.dmypy.json
dmypy.json

# Pyre type checker
.pyre/

# pytype static type analyzer
.pytype/

# Cython debug symbols
cython_debug/

# Local data
data/
logs/
checkpoints/
*.h5
*.pkl
*.json
!package.json
!package-lock.json
1,254 changes: 1,254 additions & 0 deletions poetry.lock

Large diffs are not rendered by default.

80 changes: 80 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
[tool.poetry]
name = "qanet"
version = "0.1.0"
description = "QANet: Combining Local Convolution with Global Self-Attention for Reading Comprehension"
authors = ["Your Name <you@example.com>"]
readme = "README.md"
license = "MIT"

[tool.poetry.dependencies]
python = "^3.8"
numpy = "*"
tqdm = "*"
spacy = "^2.3.0"
bottle = "*"

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


[tool.pytest.ini_options]
minversion = "7.0"
testpaths = ["tests"]
python_files = ["test_*.py", "*_test.py"]
python_classes = ["Test*"]
python_functions = ["test_*"]
addopts = [
"-ra",
"--strict-markers",
"-vv",
"--tb=short"
]
markers = [
"unit: marks tests as unit tests (fast, isolated)",
"integration: marks tests as integration tests (may be slower)",
"slow: marks tests as slow (deselect with '-m \"not slow\"')"
]

[tool.coverage.run]
source = ["tests", "config", "demo", "layers", "main", "model", "prepro", "util"]
omit = [
"*/tests/*",
"*/test_*",
"*/__pycache__/*",
"*/venv/*",
"*/virtualenv/*",
"*.pyc",
"setup.py",
"*/migrations/*",
"*/config/*",
"*/conftest.py"
]

[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__.:",
"if TYPE_CHECKING:",
"class .*\\bProtocol\\):",
"@(abc\\.)?abstractmethod"
]
show_missing = true
precision = 2

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

[tool.coverage.xml]
output = "coverage.xml"

[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"
3 changes: 3 additions & 0 deletions run-tests
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#\!/bin/bash
# Run tests using Poetry
poetry run pytest "$@"
Empty file added tests/__init__.py
Empty file.
77 changes: 77 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
"""Shared pytest fixtures and configuration."""
import os
import tempfile
from pathlib import Path
from typing import Generator

import pytest


@pytest.fixture
def temp_dir() -> Generator[Path, None, None]:
"""Create a temporary directory for test files."""
with tempfile.TemporaryDirectory() as tmp_dir:
yield Path(tmp_dir)


@pytest.fixture
def mock_config():
"""Mock configuration for testing."""
return {
"batch_size": 32,
"hidden_size": 128,
"num_heads": 8,
"num_blocks": 1,
"dropout": 0.1,
"learning_rate": 0.001,
"max_length": 400,
"word_embedding_size": 300,
"char_embedding_size": 200,
}


@pytest.fixture
def sample_data():
"""Sample data for testing."""
return {
"context": "The quick brown fox jumps over the lazy dog.",
"question": "What does the fox do?",
"answer": "jumps over the lazy dog",
"answer_start": 20,
"context_tokens": ["The", "quick", "brown", "fox", "jumps", "over", "the", "lazy", "dog", "."],
"question_tokens": ["What", "does", "the", "fox", "do", "?"],
}


@pytest.fixture
def mock_model_config():
"""Mock model configuration."""
return {
"vocab_size": 10000,
"char_vocab_size": 100,
"max_context_length": 400,
"max_question_length": 50,
"embedding_size": 300,
"model_dim": 128,
"num_heads": 8,
"num_encoder_blocks": 6,
"kernel_size": 7,
"dropout": 0.1,
"layer_dropout": 0.9,
}


@pytest.fixture(autouse=True)
def reset_environment():
"""Reset environment variables before each test."""
original_env = dict(os.environ)
yield
os.environ.clear()
os.environ.update(original_env)


@pytest.fixture
def capture_logs(caplog):
"""Fixture to capture log messages during tests."""
with caplog.at_level("DEBUG"):
yield caplog
Empty file added tests/integration/__init__.py
Empty file.
80 changes: 80 additions & 0 deletions tests/test_setup_validation.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
"""Validation tests to ensure the testing infrastructure is properly set up."""
import sys
from pathlib import Path

import pytest


def test_python_version():
"""Test that we're using a compatible Python version."""
assert sys.version_info >= (3, 8), "Python 3.8 or higher is required"


def test_project_structure():
"""Test that the project structure is correct."""
root = Path(__file__).parent.parent

# Check main project files exist
assert (root / "pyproject.toml").exists()
assert (root / "README.md").exists()

# Check test directories exist
assert (root / "tests").is_dir()
assert (root / "tests" / "unit").is_dir()
assert (root / "tests" / "integration").is_dir()
assert (root / "tests" / "conftest.py").exists()


def test_fixtures_available(temp_dir, mock_config, sample_data, mock_model_config):
"""Test that all fixtures are available and working."""
# Test temp_dir fixture
assert temp_dir.exists()
assert temp_dir.is_dir()

# Test mock_config fixture
assert isinstance(mock_config, dict)
assert "batch_size" in mock_config
assert "hidden_size" in mock_config

# Test sample_data fixture
assert isinstance(sample_data, dict)
assert "context" in sample_data
assert "question" in sample_data

# Test mock_model_config fixture
assert isinstance(mock_model_config, dict)
assert "vocab_size" in mock_model_config


@pytest.mark.unit
def test_unit_marker():
"""Test that the unit marker works."""
assert True


@pytest.mark.integration
def test_integration_marker():
"""Test that the integration marker works."""
assert True


@pytest.mark.slow
def test_slow_marker():
"""Test that the slow marker works."""
assert True


def test_coverage_configured():
"""Test that coverage is properly configured."""
import coverage

# Just check that coverage can be imported
assert coverage.__version__


def test_pytest_mock_available():
"""Test that pytest-mock is available."""
from pytest_mock import MockerFixture

# Just check that we can import it
assert MockerFixture
Empty file added tests/unit/__init__.py
Empty file.