255 lines
8.5 KiB
Python
255 lines
8.5 KiB
Python
"""Unit tests for the parsers module."""
|
|
|
|
from unittest.mock import patch
|
|
|
|
from scaffoldforge.parsers import ChecklistItem, IssueData, IssueParser
|
|
|
|
|
|
class TestChecklistItem:
|
|
"""Tests for ChecklistItem dataclass."""
|
|
|
|
def test_checklist_item_creation(self):
|
|
"""Test creating a checklist item."""
|
|
item = ChecklistItem(
|
|
text="Implement feature",
|
|
completed=False,
|
|
line_number=5,
|
|
category="Implementation"
|
|
)
|
|
assert item.text == "Implement feature"
|
|
assert item.completed is False
|
|
assert item.line_number == 5
|
|
assert item.category == "Implementation"
|
|
|
|
def test_checklist_item_completed(self):
|
|
"""Test completed checklist item."""
|
|
item = ChecklistItem(
|
|
text="Completed task",
|
|
completed=True,
|
|
line_number=10
|
|
)
|
|
assert item.completed is True
|
|
|
|
|
|
class TestIssueData:
|
|
"""Tests for IssueData dataclass."""
|
|
|
|
def test_issue_data_creation(self):
|
|
"""Test creating issue data."""
|
|
data = IssueData(
|
|
number=123,
|
|
title="Test Issue",
|
|
body="Test body",
|
|
body_html="<p>Test body</p>",
|
|
labels=["bug", "priority"],
|
|
state="open",
|
|
url="https://github.com/user/repo/issues/123",
|
|
repository="user/repo",
|
|
author="testuser",
|
|
created_at="2024-01-01T00:00:00",
|
|
updated_at="2024-01-02T00:00:00"
|
|
)
|
|
assert data.number == 123
|
|
assert data.title == "Test Issue"
|
|
assert data.labels == ["bug", "priority"]
|
|
|
|
def test_get_todo_items(self):
|
|
"""Test getting incomplete todo items."""
|
|
checklist = [
|
|
ChecklistItem(text="Task 1", completed=False),
|
|
ChecklistItem(text="Task 2", completed=True),
|
|
ChecklistItem(text="Task 3", completed=False),
|
|
]
|
|
data = IssueData(
|
|
number=1, title="Test", body="", body_html="",
|
|
labels=[], state="open", url="", repository="", author="",
|
|
created_at="", updated_at="", checklist=checklist
|
|
)
|
|
todos = data.get_todo_items()
|
|
assert len(todos) == 2
|
|
assert "Task 1" in todos
|
|
assert "Task 3" in todos
|
|
assert "Task 2" not in todos
|
|
|
|
def test_get_completed_items(self):
|
|
"""Test getting completed items."""
|
|
checklist = [
|
|
ChecklistItem(text="Task 1", completed=False),
|
|
ChecklistItem(text="Task 2", completed=True),
|
|
]
|
|
data = IssueData(
|
|
number=1, title="Test", body="", body_html="",
|
|
labels=[], state="open", url="", repository="", author="",
|
|
created_at="", updated_at="", checklist=checklist
|
|
)
|
|
completed = data.get_completed_items()
|
|
assert len(completed) == 1
|
|
assert "Task 2" in completed
|
|
|
|
def test_generate_todo_comments(self):
|
|
"""Test generating TODO comments."""
|
|
checklist = [
|
|
ChecklistItem(text="Implement feature", completed=False),
|
|
ChecklistItem(text="Write tests", completed=False),
|
|
]
|
|
data = IssueData(
|
|
number=42, title="Test", body="", body_html="",
|
|
labels=[], state="open", url="", repository="", author="",
|
|
created_at="", updated_at="", checklist=checklist
|
|
)
|
|
comments = data.generate_todo_comments()
|
|
assert "TODO #1: Implement feature" in comments
|
|
assert "TODO #2: Write tests" in comments
|
|
|
|
|
|
class TestIssueParser:
|
|
"""Tests for IssueParser class."""
|
|
|
|
@patch('scaffoldforge.parsers.issue_parser.Github')
|
|
def test_parser_initialization_without_token(self, mock_github):
|
|
"""Test parser initialization without token."""
|
|
IssueParser()
|
|
mock_github.assert_called_once()
|
|
|
|
@patch('scaffoldforge.parsers.issue_parser.Github')
|
|
def test_parser_initialization_with_token(self, mock_github):
|
|
"""Test parser initialization with token."""
|
|
IssueParser(token="test_token")
|
|
mock_github.assert_called_once_with("test_token")
|
|
|
|
def test_parse_checklist_simple(self):
|
|
"""Test parsing simple checklist items."""
|
|
parser = IssueParser()
|
|
body = """
|
|
## Tasks
|
|
- [x] Completed task
|
|
- [ ] Pending task
|
|
- [X] Also completed
|
|
"""
|
|
checklist = parser._parse_checklist(body)
|
|
assert len(checklist) == 3
|
|
assert checklist[0].text == "Completed task"
|
|
assert checklist[0].completed is True
|
|
assert checklist[1].text == "Pending task"
|
|
assert checklist[1].completed is False
|
|
|
|
def test_parse_checklist_with_categories(self):
|
|
"""Test parsing checklist with category headers."""
|
|
parser = IssueParser()
|
|
body = """
|
|
## Implementation
|
|
- [ ] Task 1
|
|
- [ ] Task 2
|
|
|
|
## Testing
|
|
- [ ] Test 1
|
|
"""
|
|
checklist = parser._parse_checklist(body)
|
|
assert len(checklist) == 3
|
|
assert checklist[0].category == "Implementation"
|
|
assert checklist[2].category == "Testing"
|
|
|
|
def test_parse_requirements(self):
|
|
"""Test parsing requirements section."""
|
|
parser = IssueParser()
|
|
body = """
|
|
## Requirements
|
|
- Must work
|
|
- Must be fast
|
|
- Must be secure
|
|
"""
|
|
requirements = parser._parse_requirements(body)
|
|
assert len(requirements) == 3
|
|
assert "Must work" in requirements
|
|
|
|
def test_parse_acceptance_criteria(self):
|
|
"""Test parsing acceptance criteria."""
|
|
parser = IssueParser()
|
|
body = """
|
|
## Acceptance Criteria
|
|
- [x] Feature works
|
|
- [ ] Tests pass
|
|
"""
|
|
criteria = parser._parse_acceptance_criteria(body)
|
|
assert len(criteria) == 2
|
|
assert "Feature works" in criteria
|
|
|
|
def test_parse_file_paths(self):
|
|
"""Test parsing file paths from body."""
|
|
parser = IssueParser()
|
|
body = """
|
|
Create a new file `src/main.py`
|
|
Also need `utils.py`
|
|
"""
|
|
files = parser._parse_file_paths(body)
|
|
assert len(files) >= 2
|
|
|
|
def test_detect_language_from_labels(self):
|
|
"""Test language detection from labels."""
|
|
parser = IssueParser()
|
|
issue_data = IssueData(
|
|
number=1, title="Test", body="", body_html="",
|
|
labels=["python", "enhancement"], state="open", url="",
|
|
repository="", author="", created_at="", updated_at=""
|
|
)
|
|
lang = parser.detect_language(issue_data)
|
|
assert lang == "python"
|
|
|
|
def test_detect_language_from_body(self):
|
|
"""Test language detection from body content."""
|
|
parser = IssueParser()
|
|
issue_data = IssueData(
|
|
number=1, title="Test", body="This is a Go project",
|
|
body_html="", labels=[], state="open", url="",
|
|
repository="", author="", created_at="", updated_at=""
|
|
)
|
|
lang = parser.detect_language(issue_data)
|
|
assert lang == "go"
|
|
|
|
def test_detect_language_unknown(self):
|
|
"""Test language detection when unknown."""
|
|
parser = IssueParser()
|
|
issue_data = IssueData(
|
|
number=1, title="Test", body="No language mentioned",
|
|
body_html="", labels=[], state="open", url="",
|
|
repository="", author="", created_at="", updated_at=""
|
|
)
|
|
lang = parser.detect_language(issue_data)
|
|
assert lang is None
|
|
|
|
def test_detect_project_type_cli(self):
|
|
"""Test CLI project type detection."""
|
|
parser = IssueParser()
|
|
issue_data = IssueData(
|
|
number=1, title="Create a CLI tool",
|
|
body="Need to build a command line interface",
|
|
body_html="", labels=[], state="open", url="",
|
|
repository="", author="", created_at="", updated_at=""
|
|
)
|
|
proj_type = parser.detect_project_type(issue_data)
|
|
assert proj_type == "cli"
|
|
|
|
def test_detect_project_type_api(self):
|
|
"""Test API project type detection."""
|
|
parser = IssueParser()
|
|
issue_data = IssueData(
|
|
number=1, title="Create REST API",
|
|
body="Build an API endpoint",
|
|
body_html="", labels=[], state="open", url="",
|
|
repository="", author="", created_at="", updated_at=""
|
|
)
|
|
proj_type = parser.detect_project_type(issue_data)
|
|
assert proj_type == "api"
|
|
|
|
def test_empty_body_handling(self):
|
|
"""Test handling of empty body."""
|
|
parser = IssueParser()
|
|
checklist = parser._parse_checklist("")
|
|
assert len(checklist) == 0
|
|
|
|
requirements = parser._parse_requirements("")
|
|
assert len(requirements) == 0
|
|
|
|
files = parser._parse_file_paths("")
|
|
assert len(files) == 0
|