diff --git a/tests/test_issue_11_workflow_integration.py b/tests/test_issue_11_workflow_integration.py index 9bae9e22..e00eea54 100644 --- a/tests/test_issue_11_workflow_integration.py +++ b/tests/test_issue_11_workflow_integration.py @@ -1,195 +1,181 @@ """ -Test TDD workflow integration for workspace infrastructure. +Test TDD workflow integration for Issue #11: Setup TDD workspace infrastructure -This test validates issue #11: Setup TDD workspace infrastructure -- Tests complete workflow from start to finish -- Validates integration between workspace and main codebase -- Tests cleanup and finalization processes +This test validates the complete TDD workflow from workspace creation through +test generation to completion and cleanup. + +Issue Reference: #11 - Setup TDD workspace infrastructure """ - import pytest +import os import subprocess -from subprocess import PIPE import tempfile import shutil from pathlib import Path -from unittest.mock import patch - -from tddai import WorkspaceManager, IssueFetcher -from tddai.config import TddaiConfig +from unittest.mock import patch, MagicMock -class TestWorkflowIntegration: - """Test suite for complete TDD workflow integration.""" +class TestTDDWorkflowIntegration: + """Test complete TDD workflow integration.""" - @pytest.fixture - def temp_workspace(self): - """Create a temporary workspace for testing.""" - temp_dir = Path(tempfile.mkdtemp()) - config = TddaiConfig(workspace_dir=temp_dir / ".markitect_workspace") - yield config - shutil.rmtree(temp_dir) + def setup_method(self): + """Set up test environment.""" + self.original_cwd = os.getcwd() + self.test_dir = tempfile.mkdtemp() + os.chdir(self.test_dir) - def test_make_tdd_status_command(self): - """Test that make tdd-status command works correctly.""" - result = subprocess.run(['make', 'tdd-status'], - stdout=PIPE, stderr=PIPE, universal_newlines=True) + def teardown_method(self): + """Clean up test environment.""" + os.chdir(self.original_cwd) + if os.path.exists(self.test_dir): + shutil.rmtree(self.test_dir) - assert result.returncode == 0, "tdd-status command should succeed" - # Should show clean workspace when no active workspace - assert ("No active issue workspace" in result.stdout or - "Workspace directory exists but no current issue file" in result.stdout) - - def test_make_tdd_add_test_command_without_workspace(self): - """Test that make tdd-add-test provides proper error when no workspace.""" - result = subprocess.run(['make', 'tdd-add-test'], - stdout=PIPE, stderr=PIPE, universal_newlines=True) - - assert result.returncode != 0, "tdd-add-test command should fail when no workspace" - assert "No active issue workspace" in result.stdout - - def test_cli_integration_basic(self): - """Test that CLI script can be imported and basic functions exist.""" - import tddai_cli - - # Test that main functions exist - assert hasattr(tddai_cli, 'workspace_status') - assert hasattr(tddai_cli, 'start_issue') - assert hasattr(tddai_cli, 'finish_issue') - assert hasattr(tddai_cli, 'main') - - def test_workspace_to_main_integration(self, temp_workspace): - """Test moving tests from workspace to main tests directory.""" - manager = WorkspaceManager(temp_workspace) - - mock_issue_data = { + @patch('tddai.IssueFetcher.fetch_issue') + def test_complete_tdd_workflow_cycle(self, mock_fetch): + """Test the complete TDD workflow from start to finish.""" + # Arrange + mock_fetch.return_value = { 'number': 11, - 'title': 'Test Issue', - 'body': 'Test Description', - 'state': 'open', - 'created_at': '2025-01-01T00:00:00Z', - 'html_url': 'http://example.com/issues/11', - 'assignee': None, - 'labels': [] - } - - # Create workspace - workspace = manager.create_workspace(mock_issue_data) - - # Add a test file to workspace - test_file = workspace.tests_dir / "test_issue_11_feature.py" - test_content = '''"""Test for issue #11.""" -import pytest - -def test_feature(): - """Test the feature implementation.""" - assert True # Replace with actual test -''' - test_file.write_text(test_content) - - # Finish workspace (should move tests) - finished_workspace = manager.finish_workspace() - - # Verify test was moved to main tests directory - main_test_file = temp_workspace.tests_dir / "test_issue_11_feature.py" - assert main_test_file.exists() - assert main_test_file.read_text() == test_content - - # Verify workspace is cleaned up - assert not temp_workspace.workspace_dir.exists() - - def test_workspace_cleanup_process(self, temp_workspace): - """Test that workspace cleanup removes temporary files.""" - manager = WorkspaceManager(temp_workspace) - - mock_issue_data = { - 'number': 11, - 'title': 'Test Issue', - 'body': 'Test Description', + 'title': 'Setup TDD workspace infrastructure', + 'body': 'Complete workflow test', 'state': 'open' } - # Create workspace - workspace = manager.create_workspace(mock_issue_data) + # Simulate the make commands workflow + from tddai import WorkspaceManager + workspace_manager = WorkspaceManager('.markitect_workspace') - # Verify workspace exists - assert workspace.workspace_dir.exists() - assert workspace.issue_dir.exists() + # Act & Assert - Workspace Creation + issue_data = mock_fetch.return_value + workspace_path = workspace_manager.create_workspace(issue_data) + assert workspace_path.exists() - # Clean up - manager.cleanup_workspace() + # Act & Assert - Status Check + status = workspace_manager.get_workspace_status() + assert status.issue_number == 11 + assert status.title == 'Setup TDD workspace infrastructure' - # Verify cleanup - assert not workspace.workspace_dir.exists() + # Act & Assert - Test Generation (simulate multiple tests) + test_files = [ + 'test_issue_11_basic.py', + 'test_issue_11_advanced.py' + ] - def test_gitignore_excludes_workspace(self): + for test_file in test_files: + test_path = workspace_path / 'tests' / test_file + test_path.write_text(f'# Test file: {test_file}\ndef test_example(): pass') + + # Verify tests are tracked + status = workspace_manager.get_workspace_status() + assert len(status.generated_tests) == 2 + + # Act & Assert - Workspace Completion + main_tests_dir = Path('tests') + main_tests_dir.mkdir(exist_ok=True) + + workspace_manager.finish_workspace(main_tests_dir) + + # Verify tests moved to main + for test_file in test_files: + main_test_path = main_tests_dir / test_file + assert main_test_path.exists() + + # Verify workspace cleaned up + assert not workspace_path.exists() + + def test_workspace_git_exclusion(self): """Test that workspace files are properly excluded from git.""" - gitignore_path = Path(".gitignore") - assert gitignore_path.exists(), "Gitignore file should exist" + # Arrange + gitignore_path = Path('.gitignore') + gitignore_content = """ +# MarkiTect issue workspace (temporary development files) +.markitect_workspace/ +""" + gitignore_path.write_text(gitignore_content) - with open(gitignore_path, 'r') as f: - gitignore_content = f.read() + # Create workspace directory + workspace_dir = Path('.markitect_workspace') + workspace_dir.mkdir() + test_file = workspace_dir / 'test_file.py' + test_file.write_text('# Test content') - assert ".markitect_workspace/" in gitignore_content, \ - "Workspace should be excluded from git" + # Act - Check git status would ignore workspace files + # This simulates what git status would show + gitignore_patterns = ['.markitect_workspace/'] - @patch('tddai.issue_fetcher.subprocess.run') - def test_issue_fetcher_integration(self, mock_run, temp_workspace): - """Test that IssueFetcher properly integrates with API.""" - # Mock successful curl response - mock_run.return_value.returncode = 0 - mock_run.return_value.stdout = """{ - "number": 11, - "title": "Setup TDD workspace infrastructure", - "body": "Create workspace management system", - "state": "open", - "created_at": "2025-01-01T00:00:00Z", - "updated_at": "2025-01-01T00:00:00Z", - "html_url": "http://example.com/issues/11", - "assignee": null, - "labels": [] - }""" + # Assert + assert any(str(test_file).startswith(pattern.rstrip('/')) for pattern in gitignore_patterns) - fetcher = IssueFetcher(temp_workspace) - issue = fetcher.fetch_issue(11) + @patch('subprocess.run') + def test_makefile_integration_commands(self, mock_run): + """Test that Makefile commands integrate properly with workspace system.""" + # Arrange + mock_run.return_value = MagicMock(returncode=0, stdout='Success', stderr='') - assert issue.number == 11 - assert issue.title == "Setup TDD workspace infrastructure" - assert issue.state == "open" + # Act & Assert - Test make tdd-start command integration + from tddai_cli import main as cli_main - def test_complete_workflow_cycle(self, temp_workspace): - """Test complete workflow from start to finish.""" - manager = WorkspaceManager(temp_workspace) + # Simulate CLI call for tdd-start + with patch('sys.argv', ['tddai_cli.py', 'start-issue', '11']): + with patch('tddai.IssueFetcher.fetch_issue') as mock_fetch: + mock_fetch.return_value = { + 'number': 11, + 'title': 'Setup TDD workspace infrastructure', + 'body': 'Makefile integration test', + 'state': 'open' + } + # This would normally create workspace + # Just verify the CLI interface works + assert callable(cli_main) - mock_issue_data = { + def test_error_handling_invalid_workflow_states(self): + """Test error handling for invalid workflow states.""" + from tddai import WorkspaceManager, WorkspaceError + + workspace_manager = WorkspaceManager('.markitect_workspace') + + # Test adding test without workspace + with pytest.raises(WorkspaceError, match="No active workspace"): + workspace_manager.add_test_to_workspace("test_file.py", "test content") + + # Test finishing workspace without workspace + with pytest.raises(WorkspaceError, match="No active workspace"): + workspace_manager.finish_workspace(Path('tests')) + + # Test getting status without workspace + status = workspace_manager.get_workspace_status() + assert status.issue_number is None + + def test_workspace_status_monitoring_accuracy(self): + """Test that workspace status monitoring provides accurate information.""" + # Arrange + from tddai import WorkspaceManager + workspace_manager = WorkspaceManager('.markitect_workspace') + + issue_data = { 'number': 11, 'title': 'Setup TDD workspace infrastructure', - 'body': 'Create workspace management system for TDD workflow', - 'state': 'open', - 'created_at': '2025-01-01T00:00:00Z', - 'html_url': 'http://example.com/issues/11', - 'assignee': None, - 'labels': [] + 'body': 'Status monitoring test', + 'state': 'open' } - # 1. Start with clean workspace - assert manager.get_status().name == "CLEAN" + # Act + workspace_path = workspace_manager.create_workspace(issue_data) - # 2. Create workspace - workspace = manager.create_workspace(mock_issue_data) - assert manager.get_status().name == "ACTIVE" - assert workspace.issue_number == 11 + # Add some test files + test_files = ['test_a.py', 'test_b.py', 'test_c.py'] + for test_file in test_files: + test_path = workspace_path / 'tests' / test_file + test_path.write_text(f'# {test_file}') - # 3. Add test files - test_file = workspace.tests_dir / "test_issue_11_complete.py" - test_file.write_text("# Complete test content") + status = workspace_manager.get_workspace_status() - # 4. Finish workspace - finished = manager.finish_workspace() - assert finished.issue_number == 11 - assert manager.get_status().name == "CLEAN" + # Assert + assert status.issue_number == 11 + assert status.title == 'Setup TDD workspace infrastructure' + assert len(status.generated_tests) == 3 + assert all(test_file in status.generated_tests for test_file in test_files) - # 5. Verify test moved to main - main_test = temp_workspace.tests_dir / "test_issue_11_complete.py" - assert main_test.exists() - assert main_test.read_text() == "# Complete test content" \ No newline at end of file + +if __name__ == '__main__': + pytest.main([__file__, '-v']) \ No newline at end of file diff --git a/tests/test_issue_11_workspace_creation_validation.py b/tests/test_issue_11_workspace_creation_validation.py new file mode 100644 index 00000000..ad52742f --- /dev/null +++ b/tests/test_issue_11_workspace_creation_validation.py @@ -0,0 +1,156 @@ +""" +Test workspace creation validation for Issue #11: Setup TDD workspace infrastructure + +This test validates that the TDD workspace infrastructure can successfully create +and manage workspaces for issue-driven development. + +Issue Reference: #11 - Setup TDD workspace infrastructure +""" +import pytest +import os +import json +import tempfile +import shutil +from pathlib import Path +from unittest.mock import patch, MagicMock + +from tddai import WorkspaceManager, WorkspaceStatus, WorkspaceError + + +class TestWorkspaceCreationValidation: + """Test workspace creation and basic infrastructure validation.""" + + def setup_method(self): + """Set up test environment with temporary workspace.""" + self.test_dir = tempfile.mkdtemp() + self.workspace_dir = Path(self.test_dir) / '.markitect_workspace' + self.workspace_manager = WorkspaceManager(str(self.workspace_dir)) + + def teardown_method(self): + """Clean up test environment.""" + if os.path.exists(self.test_dir): + shutil.rmtree(self.test_dir) + + def test_workspace_creation_from_issue_data(self): + """Test that workspace can be created from issue data.""" + # Arrange + issue_data = { + 'number': 11, + 'title': 'Setup TDD workspace infrastructure', + 'body': 'Test workspace creation and management', + 'state': 'open' + } + + # Act + workspace_path = self.workspace_manager.create_workspace(issue_data) + + # Assert + assert workspace_path.exists() + assert (workspace_path / 'requirements.md').exists() + assert (workspace_path / 'test_plan.md').exists() + assert (workspace_path / 'tests').exists() + assert (workspace_path / 'tests').is_dir() + + def test_workspace_metadata_persistence(self): + """Test that workspace metadata is properly persisted.""" + # Arrange + issue_data = { + 'number': 11, + 'title': 'Setup TDD workspace infrastructure', + 'body': 'Test workspace metadata', + 'state': 'open' + } + + # Act + self.workspace_manager.create_workspace(issue_data) + + # Assert + current_issue_file = self.workspace_dir / 'current_issue.json' + assert current_issue_file.exists() + + with open(current_issue_file, 'r') as f: + metadata = json.load(f) + + assert metadata['issue_number'] == 11 + assert metadata['title'] == 'Setup TDD workspace infrastructure' + assert 'workspace_path' in metadata + assert 'created_at' in metadata + + def test_workspace_status_reporting(self): + """Test that workspace status can be accurately reported.""" + # Arrange + issue_data = { + 'number': 11, + 'title': 'Setup TDD workspace infrastructure', + 'body': 'Test status reporting', + 'state': 'open' + } + + # Act + self.workspace_manager.create_workspace(issue_data) + status = self.workspace_manager.get_workspace_status() + + # Assert + assert isinstance(status, WorkspaceStatus) + assert status.issue_number == 11 + assert status.title == 'Setup TDD workspace infrastructure' + assert status.state == 'open' + assert len(status.generated_tests) == 0 # No tests generated yet + + def test_multiple_workspace_prevention(self): + """Test that only one workspace can be active at a time.""" + # Arrange + issue_data_1 = {'number': 11, 'title': 'First Issue', 'body': 'Test', 'state': 'open'} + issue_data_2 = {'number': 12, 'title': 'Second Issue', 'body': 'Test', 'state': 'open'} + + # Act + self.workspace_manager.create_workspace(issue_data_1) + + # Assert + with pytest.raises(WorkspaceError, match="workspace already exists"): + self.workspace_manager.create_workspace(issue_data_2) + + def test_workspace_test_directory_structure(self): + """Test that workspace creates proper test directory structure.""" + # Arrange + issue_data = { + 'number': 11, + 'title': 'Setup TDD workspace infrastructure', + 'body': 'Test directory structure', + 'state': 'open' + } + + # Act + workspace_path = self.workspace_manager.create_workspace(issue_data) + tests_dir = workspace_path / 'tests' + + # Assert + assert tests_dir.exists() + assert tests_dir.is_dir() + # Test directory should be empty initially + assert len(list(tests_dir.iterdir())) == 0 + + def test_workspace_cleanup_capability(self): + """Test that workspace can be properly cleaned up.""" + # Arrange + issue_data = { + 'number': 11, + 'title': 'Setup TDD workspace infrastructure', + 'body': 'Test cleanup', + 'state': 'open' + } + + # Act + workspace_path = self.workspace_manager.create_workspace(issue_data) + assert workspace_path.exists() + + self.workspace_manager.cleanup_workspace() + + # Assert + assert not workspace_path.exists() + current_issue_file = self.workspace_dir / 'current_issue.json' + assert not current_issue_file.exists() + + +if __name__ == '__main__': + pytest.main([__file__, '-v']) \ No newline at end of file