code-crawler / tests /test_github.py
juliaturc's picture
Add official documentation instead of README (#93)
efee316
"""
Unit tests for the classes under github.py.
These tests ensure the functionality of GitHub issue management,
issue chunking, and issue comments, including happy-path scenarios.
Dependencies:
pip install pytest
pip install pytest-mock
"""
from unittest.mock import MagicMock, patch
import pytest
import requests
from sage.github import (
GitHubIssue,
GitHubIssueComment,
GitHubIssuesChunker,
GitHubIssuesManager,
IssueChunk,
)
class TestGitHubIssuesManager:
@pytest.fixture(autouse=True)
def setup_method(self):
"""Fixture to create a GitHubIssuesManager instance for each test."""
self.github_manager = GitHubIssuesManager(repo_id="random/random-repo", access_token="fake_token")
@staticmethod
def mock_issue_response():
"""A mock response for GitHub issues."""
return MagicMock(
json=lambda: [
{
"url": "https://api.github.com/repos/random/random-repo/issues/1",
"html_url": "https://github.com/random/random-repo/issues/1",
"title": "Found a bug",
"body": "I'm having a problem with this.",
"comments_url": "https://api.github.com/repos/random/random-repo/issues/1/comments",
"comments": 2,
}
]
)
@staticmethod
def mock_comment_response():
"""Create a mock response for GitHub issue comments."""
return MagicMock(
json=lambda: [
{
"url": "https://api.github.com/repos/random/random-repo/issues/comments/1",
"html_url": "https://github.com/random/random-repo/issues/comments/1",
"body": "This is a comment.",
}
]
)
@patch("github.requests.get")
def test_download_issues(self, mock_get):
"""Test the download of issues from GitHub."""
mock_get.side_effect = [self.mock_issue_response(), self.mock_comment_response()]
self.github_manager.download()
assert len(self.github_manager.issues) == 1
assert self.github_manager.issues[0].title == "Found a bug"
assert self.github_manager.issues[0].body == "I'm having a problem with this."
assert self.github_manager.issues[0].url == "https://api.github.com/repos/random/random-repo/issues/1"
@patch("github.requests.get")
def test_walk_issues(self, mock_get):
"""Test the walking through downloaded issues."""
self.github_manager.issues = [
GitHubIssue(url="issue_url", html_url="html_issue_url", title="Test Issue", body="Test Body", comments=[]),
GitHubIssue(
url="issue_url_2",
html_url="html_issue_url_2",
title="Another Test Issue",
body="Another Test Body",
comments=[],
),
]
issues = list(self.github_manager.walk())
assert len(issues) == 2
assert issues[0][0].title == "Test Issue"
assert issues[1][0].title == "Another Test Issue"
@patch("github.requests.get")
def test_get_page_of_issues(self, mock_get):
"""Test fetching a page of issues."""
mock_response = MagicMock()
mock_response.json.return_value = [
{
"url": "https://api.github.com/repos/random/random-repo/issues/1",
"html_url": "https://github.com/random/random-repo/issues/1",
"title": "Found a bug",
"body": "I'm having a problem with this.",
"comments_url": "https://api.github.com/repos/random/random-repo/issues/1/comments",
"comments": 2,
}
]
mock_get.return_value = mock_response
issues = self.github_manager._get_page_of_issues(
"https://api.github.com/repos/random/random-repo/issues?page=1"
).json()
assert len(issues) == 1
@patch("github.requests.get")
def test_get_comments(self, mock_get):
"""Test retrieving comments for an issue."""
mock_get.return_value.json.return_value = self.mock_comment_response().json()
comments = self.github_manager._get_comments("comments_url")
assert len(comments) == 1
assert comments[0].body == "This is a comment."
def test_chunker(self):
"""Test chunking of an issue into smaller parts."""
issue = GitHubIssue(
url="issue_url",
html_url="html_issue_url",
title="Test Issue",
body="This is a long body of the issue that needs to be chunked.",
comments=[
GitHubIssueComment(url="comment_url_1", html_url="html_comment_url_1", body="First comment."),
GitHubIssueComment(url="comment_url_2", html_url="html_comment_url_2", body="Second comment."),
],
)
chunker = GitHubIssuesChunker(max_tokens=50)
chunks = chunker.chunk(content=issue, metadata={})
assert len(chunks) > 0
assert all(isinstance(chunk, IssueChunk) for chunk in chunks)
assert chunks[0].issue.title == "Test Issue"
assert chunks[0].start_comment == 0
class TestGitHubIssueComment:
def test_initialization(self):
"""Test the initialization of the GitHubIssueComment class."""
comment = GitHubIssueComment(url="comment_url", html_url="html_comment_url", body="Sample comment")
assert comment.url == "comment_url"
assert comment.html_url == "html_comment_url"
assert comment.body == "Sample comment"
def test_pretty_property(self):
"""Test the pretty property of the GitHubIssueComment class."""
comment = GitHubIssueComment(url="comment_url", html_url="html_comment_url", body="Sample comment")
assert comment.pretty == "## Comment: Sample comment"
class TestGitHubIssue:
def test_initialization(self):
"""Test the initialization of the GitHubIssue class."""
issue = GitHubIssue(
url="issue_url", html_url="html_issue_url", title="Test Issue", body="Test Body", comments=[]
)
assert issue.url == "issue_url"
assert issue.html_url == "html_issue_url"
assert issue.title == "Test Issue"
assert issue.body == "Test Body"
assert issue.comments == []
def test_pretty_property(self):
"""Test the pretty property of the GitHubIssue class."""
issue = GitHubIssue(
url="issue_url", html_url="html_issue_url", title="Test Issue", body="Test Body", comments=[]
)
assert issue.pretty == "# Issue: Test Issue\nTest Body"
class TestIssueChunk:
def test_initialization(self):
"""Test the initialization of the IssueChunk class."""
issue = GitHubIssue(
url="issue_url", html_url="html_issue_url", title="Test Issue", body="Test Body", comments=[]
)
chunk = IssueChunk(issue=issue, start_comment=0, end_comment=1)
assert chunk.issue == issue
assert chunk.start_comment == 0
assert chunk.end_comment == 1
def test_content_property(self):
"""Test the content property of the IssueChunk class."""
issue = GitHubIssue(
url="issue_url", html_url="html_issue_url", title="Test Issue", body="Test Body", comments=[]
)
chunk = IssueChunk(issue=issue, start_comment=0, end_comment=1)
assert chunk.content == "# Issue: Test Issue\nTest Body\n\n"
def test_metadata_property(self):
"""Test the metadata property of the IssueChunk class."""
issue = GitHubIssue(
url="issue_url", html_url="html_issue_url", title="Test Issue", body="Test Body", comments=[]
)
chunk = IssueChunk(issue=issue, start_comment=0, end_comment=1)
expected_metadata = {
"id": "html_issue_url_0_1",
"url": "html_issue_url",
"start_comment": 0,
"end_comment": 1,
"text": "# Issue: Test Issue\nTest Body\n\n",
}
assert chunk.metadata == expected_metadata
def test_num_tokens_property(self):
"""Test the num_tokens property of the IssueChunk class."""
issue = GitHubIssue(
url="issue_url", html_url="html_issue_url", title="Test Issue", body="This is a test body.", comments=[]
)
chunk = IssueChunk(issue=issue, start_comment=0, end_comment=1)
assert chunk.num_tokens == 12
class TestGitHubIssuesChunker:
def test_initialization(self):
"""Test the initialization of the GitHubIssuesChunker class."""
chunker = GitHubIssuesChunker(max_tokens=50)
assert chunker.max_tokens == 50
def test_chunk_method(self):
"""Test the chunk method of the GitHubIssuesChunker class."""
issue = GitHubIssue(
url="issue_url",
html_url="html_issue_url",
title="Test Issue",
body="This is a long body of the issue that needs to be chunked.",
comments=[],
)
chunker = GitHubIssuesChunker(max_tokens=50)
chunks = chunker.chunk(content=issue, metadata={})
assert len(chunks) > 0
assert all(isinstance(chunk, IssueChunk) for chunk in chunks)
if __name__ == "__main__":
pytest.main()