From 57e204fe44743e1c6a11c4dc6e8240cd888dc641 Mon Sep 17 00:00:00 2001 From: 7000pctAUTO Date: Tue, 3 Feb 2026 01:25:57 +0000 Subject: [PATCH] Add test files --- tests/test_integration.py | 214 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 214 insertions(+) create mode 100644 tests/test_integration.py diff --git a/tests/test_integration.py b/tests/test_integration.py new file mode 100644 index 0000000..b8e4495 --- /dev/null +++ b/tests/test_integration.py @@ -0,0 +1,214 @@ +"""Integration tests for the complete workflow.""" + +import pytest +from pathlib import Path +from unittest.mock import Mock, patch + +from src.cli.commands import cli +from src.search.searcher import Searcher +from src.models.document import Document, SourceType, SearchResult + + +class TestIntegration: + """Integration tests for the complete workflow.""" + + @pytest.fixture + def runner(self): + """Create a CLI runner.""" + from click.testing import CliRunner + return CliRunner() + + def test_index_then_search_workflow(self, runner, tmp_path): + """Test complete workflow: index then search.""" + openapi_file = tmp_path / "api.yaml" + openapi_file.write_text(""" +openapi: "3.0.0" +info: + title: Test API + version: "1.0.0" +paths: + /users: + get: + summary: Get users + operationId: getUsers + responses: + '200': + description: OK +""") + + readme_file = tmp_path / "README.md" + readme_file.write_text(""" +# Test API + +This is a test API. + +## Endpoints + +- GET /users - List users +""") + + with patch("src.cli.commands.Searcher") as MockSearcher: + mock_searcher = Mock() + mock_searcher.index.return_value = 2 + mock_doc = Document( + id="test", + content="test content", + source_type=SourceType.OPENAPI, + title="Test", + ) + mock_result = SearchResult(document=mock_doc, score=0.9) + mock_searcher.hybrid_search.return_value = [mock_result] + MockSearcher.return_value = mock_searcher + + index_result = runner.invoke(cli, ["index", str(tmp_path)]) + assert index_result.exit_code == 0 + + search_result = runner.invoke(cli, ["search", "users"]) + assert search_result.exit_code == 0 + + def test_search_with_no_index(self, runner): + """Test search behavior when index is empty.""" + with patch("src.cli.commands.Searcher") as MockSearcher: + mock_searcher = Mock() + mock_searcher.hybrid_search.return_value = [] + MockSearcher.return_value = mock_searcher + + result = runner.invoke(cli, ["search", "test query"]) + + assert result.exit_code == 0 + mock_searcher.hybrid_search.assert_called_once() + + def test_multiple_index_types(self, runner, tmp_path): + """Test indexing multiple document types.""" + (tmp_path / "api.yaml").write_text(""" +openapi: "3.0.0" +info: + title: API + version: "1.0.0" +paths: {} +""") + + (tmp_path / "README.md").write_text("# Test\n") + (tmp_path / "code.py").write_text('"""Test."""\ndef foo(): pass\n') + + with patch("src.cli.commands.Searcher") as MockSearcher: + mock_searcher = Mock() + mock_searcher.index.return_value = 3 + MockSearcher.return_value = mock_searcher + + result = runner.invoke(cli, ["index", str(tmp_path), "--type", "all"]) + + assert result.exit_code == 0 + mock_searcher.index.assert_called_once() + + def test_list_with_stats(self, runner): + """Test list command shows correct stats.""" + from src.models.document import IndexStats + + with patch("src.cli.commands.Searcher") as MockSearcher: + mock_searcher = Mock() + mock_searcher.get_stats.return_value = IndexStats( + total_documents=25, + openapi_count=10, + readme_count=8, + code_count=7, + ) + MockSearcher.return_value = mock_searcher + + result = runner.invoke(cli, ["list"]) + + assert result.exit_code == 0 + assert "25" in result.output or "total" in result.output.lower() + + def test_clear_index(self, runner): + """Test clearing the index.""" + with patch("src.cli.commands.Searcher") as MockSearcher: + mock_searcher = Mock() + mock_searcher._vector_store.count.return_value = 10 + mock_searcher.clear_index.return_value = True + MockSearcher.return_value = mock_searcher + + result = runner.invoke(cli, ["clear", "--force"]) + + assert result.exit_code == 0 + + def test_config_management(self, runner, tmp_path): + """Test configuration show and reset.""" + with patch("src.cli.commands.get_config") as mock_get_config: + mock_config = Mock() + mock_config.to_dict.return_value = { + "index_path": "./docs", + "model_name": "test-model", + "embedding_device": "cpu", + } + mock_get_config.return_value = mock_config + + show_result = runner.invoke(cli, ["config", "--show"]) + assert show_result.exit_code == 0 + + mock_get_config.return_value = mock_config + reset_result = runner.invoke(cli, ["config", "--reset"]) + assert reset_result.exit_code == 0 + mock_config.reset.assert_called_once() + + +class TestEdgeCases: + """Edge case tests.""" + + @pytest.fixture + def runner(self): + """Create a CLI runner.""" + from click.testing import CliRunner + return CliRunner() + + def test_search_empty_query(self, runner): + """Test search with empty query.""" + with patch("src.cli.commands.Searcher") as MockSearcher: + mock_searcher = Mock() + mock_searcher.hybrid_search.return_value = [] + MockSearcher.return_value = mock_searcher + + result = runner.invoke(cli, ["search", ""]) + + assert result.exit_code == 0 + + def test_search_very_long_query(self, runner): + """Test search with very long query.""" + with patch("src.cli.commands.Searcher") as MockSearcher: + mock_searcher = Mock() + mock_searcher.hybrid_search.return_value = [] + MockSearcher.return_value = mock_searcher + + long_query = "test " * 1000 + result = runner.invoke(cli, ["search", long_query]) + + assert result.exit_code == 0 + + def test_index_empty_directory(self, runner, tmp_path): + """Test indexing an empty directory.""" + with patch("src.cli.commands.Searcher") as MockSearcher: + mock_searcher = Mock() + mock_searcher.index.return_value = 0 + MockSearcher.return_value = mock_searcher + + result = runner.invoke(cli, ["index", str(tmp_path)]) + + assert result.exit_code == 0 + + def test_list_json_output(self, runner): + """Test list with JSON output.""" + from src.models.document import IndexStats + + with patch("src.cli.commands.Searcher") as MockSearcher: + mock_searcher = Mock() + mock_searcher.get_stats.return_value = IndexStats( + total_documents=5, + openapi_count=2, + readme_count=2, + code_count=1, + ) + MockSearcher.return_value = mock_searcher + + result = runner.invoke(cli, ["list", "--json"]) + + assert result.exit_code == 0