From 0ca8d48a34c48981bb9bc663ec59987737e2faa8 Mon Sep 17 00:00:00 2001 From: 7000pctAUTO Date: Mon, 2 Feb 2026 18:27:19 +0000 Subject: [PATCH] Initial upload with CI/CD workflow --- tests/test_exporter.py | 240 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 240 insertions(+) create mode 100644 tests/test_exporter.py diff --git a/tests/test_exporter.py b/tests/test_exporter.py new file mode 100644 index 0000000..a195de2 --- /dev/null +++ b/tests/test_exporter.py @@ -0,0 +1,240 @@ +"""Tests for the exporter module.""" + +import json +import tempfile +from pathlib import Path + +import pytest +from src.exporter import Exporter +from src.models import SearchResult, MatchLocation + + +class TestExporter: + """Tests for Exporter class.""" + + @pytest.fixture + def sample_results(self): + """Create sample search results.""" + matches = [ + MatchLocation( + file_path="src/main.py", + line_number=10, + line_content="def hello():" , + match_start=0, + match_end=11, + ), + MatchLocation( + file_path="src/main.py", + line_number=20, + line_content="def world():" , + match_start=0, + match_end=11, + ), + ] + + return [ + SearchResult( + repo_name="test/repo1", + repo_url="https://github.com/test/repo1", + stars=100, + description="Test repository 1", + language="Python", + matches=matches, + total_matches=2, + score=50.5, + ), + SearchResult( + repo_name="test/repo2", + repo_url="https://github.com/test/repo2", + stars=200, + description="Test repository 2", + language="Python", + matches=[], + total_matches=0, + score=0.0, + ), + ] + + def test_export_to_json(self, sample_results): + """Test exporting results to JSON.""" + with tempfile.NamedTemporaryFile(suffix=".json", delete=False) as f: + output_path = Path(f.name) + + try: + Exporter.export_to_json(sample_results, output_path) + + with open(output_path, "r") as f: + data = json.load(f) + + assert "total_repositories" in data + assert "total_matches" in data + assert "results" in data + assert data["total_repositories"] == 2 + assert data["total_matches"] == 2 + + finally: + output_path.unlink() + + def test_export_to_json_with_metadata(self, sample_results): + """Test exporting with metadata.""" + with tempfile.NamedTemporaryFile(suffix=".json", delete=False) as f: + output_path = Path(f.name) + + try: + Exporter.export_to_json( + sample_results, + output_path, + include_metadata=True, + ) + + with open(output_path, "r") as f: + data = json.load(f) + + assert "metadata" in data + assert "exported_at" in data["metadata"] + assert "version" in data["metadata"] + + finally: + output_path.unlink() + + def test_export_results_json_format(self, sample_results): + """Test export results with JSON format.""" + with tempfile.NamedTemporaryFile(suffix=".json", delete=False) as f: + output_path = Path(f.name) + + try: + Exporter.export_results(sample_results, output_path, format="json") + + assert output_path.exists() + + finally: + output_path.unlink() + + def test_export_raises_on_unsupported_format(self, sample_results): + """Test that unsupported format raises error.""" + with tempfile.NamedTemporaryFile(suffix=".txt", delete=False) as f: + output_path = Path(f.name) + + try: + with pytest.raises(ValueError): + Exporter.export_results( + sample_results, + output_path, + format="unsupported", + ) + + finally: + output_path.unlink() + + def test_format_summary(self, sample_results): + """Test formatting results as summary.""" + summary = Exporter.format_summary(sample_results) + + assert "test/repo1" in summary + assert "test/repo2" in summary + assert "2 matches" in summary + assert "100 stars" in summary + + def test_prepare_export_data(self, sample_results): + """Test preparing export data structure.""" + data = Exporter._prepare_export_data(sample_results, include_metadata=False) + + assert data["total_repositories"] == 2 + assert data["total_matches"] == 2 + assert len(data["results"]) == 2 + assert "metadata" not in data + + def test_prepare_export_data_with_metadata(self, sample_results): + """Test preparing export data with metadata.""" + data = Exporter._prepare_export_data(sample_results, include_metadata=True) + + assert "metadata" in data + + def test_get_timestamp_format(self): + """Test timestamp format.""" + timestamp = Exporter._get_timestamp() + + assert "Z" in timestamp + assert "-" in timestamp + + +class TestSearchResultToDict: + """Tests for SearchResult.to_dict().""" + + def test_to_dict_basic(self): + """Test converting SearchResult to dictionary.""" + result = SearchResult( + repo_name="test/repo", + repo_url="https://github.com/test/repo", + stars=50, + ) + + data = result.to_dict() + + assert data["repo_name"] == "test/repo" + assert data["repo_url"] == "https://github.com/test/repo" + assert data["stars"] == 50 + + def test_to_dict_with_matches(self): + """Test converting SearchResult with matches.""" + matches = [ + MatchLocation( + file_path="test.py", + line_number=1, + line_content="test", + match_start=0, + match_end=4, + ), + ] + + result = SearchResult( + repo_name="test/repo", + repo_url="https://github.com/test/repo", + stars=50, + matches=matches, + total_matches=1, + ) + + data = result.to_dict() + + assert len(data["matches"]) == 1 + assert data["matches"][0]["file_path"] == "test.py" + + def test_get_match_summary(self): + """Test getting match summary by file.""" + matches = [ + MatchLocation( + file_path="main.py", + line_number=1, + line_content="test", + match_start=0, + match_end=4, + ), + MatchLocation( + file_path="main.py", + line_number=2, + line_content="test", + match_start=0, + match_end=4, + ), + MatchLocation( + file_path="utils.py", + line_number=1, + line_content="test", + match_start=0, + match_end=4, + ), + ] + + result = SearchResult( + repo_name="test/repo", + repo_url="https://github.com/test/repo", + stars=50, + matches=matches, + total_matches=3, + ) + + summary = result.get_match_summary() + + assert summary["main.py"] == 2 + assert summary["utils.py"] == 1