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
102 changes: 102 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
# 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/
pip-wheel-metadata/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST

# PyInstaller
*.manifest
*.spec

# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/

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

# IDEs
.idea/
.vscode/
*.swp
*.swo
*~
.project
.pydevproject
.settings/
*.sublime-project
*.sublime-workspace

# OS
.DS_Store
Thumbs.db

# Claude
.claude/*

# Project specific
*.sqlite
*.db
.mypy_cache/
.dmypy.json
dmypy.json

# Jupyter Notebook
.ipynb_checkpoints

# pyenv
.python-version

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

# Logs
logs/
*.log

# Temporary files
tmp/
temp/
*.tmp
*.temp
282 changes: 282 additions & 0 deletions poetry.lock

Large diffs are not rendered by default.

73 changes: 73 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
[tool.poetry]
name = "text-to-sql-models"
version = "0.1.0"
description = "Multi-model text-to-SQL conversion system with SQLova, ValueNet, and IRNet"
authors = ["Your Name <you@example.com>"]
readme = "README.md"
package-mode = false

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

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

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

[tool.pytest.ini_options]
minversion = "7.0"
testpaths = ["tests"]
python_files = ["test_*.py", "*_test.py"]
python_classes = ["Test*"]
python_functions = ["test_*"]
addopts = [
"--strict-markers",
"-v",
"--tb=short",
"--maxfail=1"
]
markers = [
"unit: Unit tests",
"integration: Integration tests",
"slow: Slow running tests"
]

[tool.coverage.run]
source = ["irnet", "valuenet"]
omit = [
"*/tests/*",
"*/__pycache__/*",
"*/venv/*",
"*/virtualenv/*",
"*/.venv/*",
"*/site-packages/*",
"*/setup.py",
"*/conftest.py"
]

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

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

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

[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"
Empty file added tests/__init__.py
Empty file.
166 changes: 166 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
import os
import tempfile
import shutil
from pathlib import Path
import pytest
import json


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


@pytest.fixture
def sample_csv_content():
"""Sample CSV content for testing."""
return """name,age,city
John Doe,30,New York
Jane Smith,25,Los Angeles
Bob Johnson,35,Chicago"""


@pytest.fixture
def sample_csv_file(temp_dir, sample_csv_content):
"""Create a sample CSV file in temp directory."""
csv_path = temp_dir / "sample.csv"
csv_path.write_text(sample_csv_content)
return csv_path


@pytest.fixture
def mock_config():
"""Mock configuration dictionary."""
return {
"host": "0.0.0.0",
"port": 5050,
"debug": False,
"models": ["sqlova", "valuenet", "irnet"],
"database_path": "/tmp/test_dbs"
}


@pytest.fixture
def mock_api_request():
"""Mock API request payload."""
return {
"csv": "name,age,city\\nJohn,30,NYC",
"question": "What is the average age?",
"model": "valuenet"
}


@pytest.fixture
def mock_sql_response():
"""Mock SQL response."""
return {
"sql": "SELECT AVG(age) FROM table",
"confidence": 0.95,
"model": "valuenet"
}


@pytest.fixture
def sample_sqlite_db(temp_dir):
"""Create a sample SQLite database."""
import sqlite3

db_path = temp_dir / "test.db"
conn = sqlite3.connect(str(db_path))
cursor = conn.cursor()

cursor.execute('''
CREATE TABLE users (
id INTEGER PRIMARY KEY,
name TEXT,
age INTEGER,
city TEXT
)
''')

users = [
(1, 'John Doe', 30, 'New York'),
(2, 'Jane Smith', 25, 'Los Angeles'),
(3, 'Bob Johnson', 35, 'Chicago')
]

cursor.executemany('INSERT INTO users VALUES (?, ?, ?, ?)', users)
conn.commit()
conn.close()

return db_path


@pytest.fixture
def flask_test_client(monkeypatch):
"""Create a Flask test client (placeholder for actual implementation)."""
monkeypatch.setenv("FLASK_ENV", "testing")
return None


@pytest.fixture
def mock_model_predictions():
"""Mock model prediction results."""
return {
"sqlova": {
"sql": "SELECT * FROM table WHERE age > 25",
"confidence": 0.89
},
"valuenet": {
"sql": "SELECT AVG(age) FROM table WHERE city = 'NYC'",
"confidence": 0.92
},
"irnet": {
"sql": "SELECT name, age FROM table ORDER BY age DESC",
"confidence": 0.87
}
}


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


@pytest.fixture
def captured_logs():
"""Capture log messages during tests."""
import logging
from io import StringIO

log_capture = StringIO()
handler = logging.StreamHandler(log_capture)
handler.setLevel(logging.DEBUG)

root_logger = logging.getLogger()
root_logger.addHandler(handler)

yield log_capture

root_logger.removeHandler(handler)


@pytest.fixture
def mock_http_response():
"""Mock HTTP response object."""
class MockResponse:
def __init__(self, json_data, status_code=200):
self.json_data = json_data
self.status_code = status_code
self.text = json.dumps(json_data)

def json(self):
return self.json_data

def raise_for_status(self):
if self.status_code >= 400:
raise Exception(f"HTTP {self.status_code}")

return MockResponse
Empty file added tests/integration/__init__.py
Empty file.
Loading