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
97 changes: 97 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
# Testing related
.pytest_cache/
.coverage
htmlcov/
coverage.xml
.tox/
.cache

# Claude settings
.claude/*

# Python
__pycache__/
*.py[cod]
*$py.class
*.so
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST

# PyInstaller
*.manifest
*.spec

# Installer logs
pip-log.txt
pip-delete-this-directory.txt

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

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

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

# OS
.DS_Store
.DS_Store?
._*
.Spotlight-V100
.Trashes
ehthumbs.db
Thumbs.db

# Logs
*.log
logs/
search_app.log

# Temporary files
*.tmp
*.temp
temp/
tmp/

# Application specific
results/
output/
493 changes: 493 additions & 0 deletions poetry.lock

Large diffs are not rendered by default.

78 changes: 78 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
[tool.poetry]
name = "onlinegpt"
version = "0.1.0"
description = "A PyQt5-based search application with multiple search engines"
authors = ["Your Name <your.email@example.com>"]
readme = "README.md"
packages = [{include = "OnlineGPT"}]

[tool.poetry.dependencies]
python = "^3.8"
requests = "^2.31.0"
beautifulsoup4 = "^4.12.0"
charset-normalizer = "^3.3.0"

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


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

[tool.pytest.ini_options]
minversion = "6.0"
addopts = [
"-ra",
"-q",
"--strict-markers",
"--strict-config",
"--cov=OnlineGPT",
"--cov-report=term-missing",
"--cov-report=html:htmlcov",
"--cov-report=xml:coverage.xml",
"--cov-fail-under=80"
]
testpaths = ["tests"]
python_files = ["test_*.py", "*_test.py"]
python_classes = ["Test*"]
python_functions = ["test_*"]
markers = [
"unit: marks tests as unit tests (fast, isolated)",
"integration: marks tests as integration tests (slower, may use external resources)",
"slow: marks tests as slow running"
]

[tool.coverage.run]
source = ["OnlineGPT"]
omit = [
"*/tests/*",
"*/venv/*",
"*/.venv/*",
"*/site-packages/*",
"*/__pycache__/*",
"*/migrations/*",
"*/resources/*"
]

[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__.:"
]
show_missing = true
skip_covered = false

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

[tool.coverage.xml]
output = "coverage.xml"
Empty file added tests/__init__.py
Empty file.
148 changes: 148 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
"""
Shared pytest fixtures for the OnlineGPT testing suite.

This module provides common fixtures that can be used across all test files.
"""

import os
import sys
import tempfile
import pytest
from unittest.mock import Mock, MagicMock, patch
from pathlib import Path

# Add the OnlineGPT directory to the Python path for imports
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', 'OnlineGPT'))


@pytest.fixture
def temp_dir():
"""Create a temporary directory for tests."""
with tempfile.TemporaryDirectory() as tmpdir:
yield Path(tmpdir)


@pytest.fixture
def temp_file(temp_dir):
"""Create a temporary file for tests."""
temp_file_path = temp_dir / "test_file.txt"
temp_file_path.write_text("test content")
yield temp_file_path


@pytest.fixture
def mock_requests():
"""Mock the requests module."""
mock_response = Mock()
mock_response.status_code = 200
mock_response.text = "<html><body>Test content</body></html>"
mock_response.headers = {'content-type': 'text/html'}

with patch('requests.get', return_value=mock_response) as mock_get:
yield mock_get


@pytest.fixture
def mock_beautiful_soup():
"""Mock BeautifulSoup for HTML parsing tests."""
mock_soup = MagicMock()
mock_soup.find_all.return_value = []
mock_soup.get_text.return_value = "Mock text content"

with pytest.mock.patch('bs4.BeautifulSoup', return_value=mock_soup) as mock_bs:
yield mock_bs


@pytest.fixture
def sample_search_results():
"""Provide sample search results for testing."""
return [
{
'title': 'Test Result 1',
'url': 'https://example.com/1',
'snippet': 'This is a test search result snippet',
'source': 'test_engine'
},
{
'title': 'Test Result 2',
'url': 'https://example.com/2',
'snippet': 'Another test search result snippet',
'source': 'test_engine'
}
]


@pytest.fixture
def mock_config():
"""Provide mock configuration settings."""
return {
'max_results': 10,
'timeout': 30,
'user_agent': 'Test Agent/1.0',
'search_engines': ['test_engine1', 'test_engine2'],
'output_format': 'txt'
}


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


@pytest.fixture
def mock_qt_widget():
"""Mock Qt widget for testing GUI components."""
from unittest.mock import MagicMock

mock_widget = MagicMock()
mock_widget.text.return_value = "test text"
mock_widget.isChecked.return_value = False
mock_widget.setEnabled = MagicMock()
mock_widget.setText = MagicMock()

return mock_widget


@pytest.fixture
def sample_html_content():
"""Provide sample HTML content for parsing tests."""
return """
<html>
<head><title>Test Page</title></head>
<body>
<h1>Test Heading</h1>
<p>This is test content for parsing.</p>
<a href="https://example.com">Test Link</a>
</body>
</html>
"""


@pytest.fixture
def mock_file_system(temp_dir):
"""Mock file system operations."""
test_files = {
'test.txt': 'Test file content',
'results.json': '{"results": []}',
'config.ini': '[settings]\nkey=value'
}

for filename, content in test_files.items():
(temp_dir / filename).write_text(content)

yield temp_dir


@pytest.fixture(autouse=True)
def setup_test_environment(monkeypatch):
"""
Automatically set up test environment for all tests.
This fixture runs automatically for every test.
"""
# Set environment variables for testing
monkeypatch.setenv('TESTING', '1')
monkeypatch.setenv('LOG_LEVEL', 'DEBUG')

# Mock any external dependencies that shouldn't run during tests
yield
Empty file added tests/integration/__init__.py
Empty file.
Loading