# Unit Test Generator

## ⚠️ CRITICAL EXECUTION NOTICE ⚠️

**THIS IS AN EXECUTABLE WORKFLOW - NOT REFERENCE MATERIAL**

When this task is invoked:
1. **CODE ANALYSIS** - Analyze source code structure, dependencies, and logic flows
2. **TEST CASE GENERATION** - Create comprehensive test cases covering all scenarios
3. **FRAMEWORK-SPECIFIC IMPLEMENTATION** - Generate tests using appropriate testing frameworks
4. **QUALITY VALIDATION** - Ensure tests follow best practices and achieve high coverage

## Overview

This workflow analyzes source code and generates high-quality unit tests using the appropriate testing framework for the technology stack. It creates comprehensive test suites covering normal cases, edge cases, and error scenarios.

## Input Parameters

### Required Parameters
- **file_path**: Absolute path to the source file to test
- **test_framework**: "vitest" | "jest" | "nunit" | "auto-detect"

### Optional Parameters
- **coverage_target**: number (default: 90)
- **include_edge_cases**: boolean (default: true)
- **mock_dependencies**: boolean (default: true)
- **generate_integration_helpers**: boolean (default: true)
- **accessibility_tests**: boolean (default: true for components)

## Test Generation Framework

### Phase 1: Source Code Analysis

```yaml
step: analyze_source_code
description: Comprehensive analysis of source code to understand structure and behavior
code_analysis:
  - structure_analysis:
    - function_identification: Extract all functions, methods, and exports
    - dependency_mapping: Map imports, external dependencies, and internal modules
    - type_analysis: Analyze TypeScript types, interfaces, and props
    - complexity_assessment: Evaluate cyclomatic complexity and edge cases
  
  - behavior_analysis:
    - input_output_mapping: Identify function inputs and expected outputs
    - side_effect_detection: Find state mutations, API calls, DOM manipulation
    - error_conditions: Identify potential error scenarios and exceptions
    - async_patterns: Detect promises, async/await, callbacks
  
  - framework_detection:
    - component_analysis: React/Vue component props, state, lifecycle
    - service_analysis: Business logic, data processing, API services
    - utility_analysis: Pure functions, helpers, transformations
    - hook_analysis: Custom hooks, state management patterns
```

### Phase 2: Test Case Design

```yaml
step: design_test_cases
description: Create comprehensive test scenarios covering all code paths
test_case_design:
  - happy_path_scenarios:
    - normal_inputs: Standard use cases with expected inputs
    - typical_workflows: Common user interactions and data flows
    - success_conditions: Verify correct behavior under normal conditions
    - expected_outputs: Validate return values and side effects
  
  - edge_case_scenarios:
    - boundary_conditions: Min/max values, empty/null inputs
    - unusual_inputs: Special characters, extreme values, type mismatches
    - state_transitions: Component lifecycle, state changes
    - timing_conditions: Race conditions, delayed responses
  
  - error_scenarios:
    - invalid_inputs: Malformed data, wrong types, missing parameters
    - network_failures: API errors, timeout conditions
    - permission_errors: Authentication, authorization failures
    - system_errors: Out of memory, file system issues
  
  - integration_scenarios:
    - dependency_interactions: How component interacts with dependencies
    - event_handling: User events, system events, custom events
    - data_flow_testing: Props down, events up patterns
    - context_usage: React Context, global state interactions
```

### Phase 3: Mock Strategy Development

```yaml
step: develop_mocking_strategy
description: Create comprehensive mocking strategy for dependencies and external services
mocking_strategy:
  - dependency_mocking:
    - external_apis: HTTP clients, REST services, GraphQL
    - database_access: ORMs, query builders, direct DB connections
    - file_system: File operations, configuration loading
    - third_party_libraries: Payment gateways, analytics, notifications
  
  - component_mocking:
    - child_components: Mock complex child components
    - custom_hooks: Mock custom hook implementations
    - context_providers: Mock React Context providers
    - higher_order_components: Mock HOC wrapping
  
  - service_mocking:
    - business_services: Core business logic services
    - utility_services: Logging, caching, validation
    - infrastructure_services: Message queues, event buses
    - configuration_services: Environment, feature flags
```

### Phase 4: Test Implementation Generation

```yaml
step: generate_test_implementation
description: Generate framework-specific test implementations with best practices
implementation_generation:
  - test_structure:
    - describe_blocks: Logical grouping of related tests
    - test_organization: Clear naming and categorization
    - setup_teardown: Proper before/after hooks
    - test_isolation: Independent test execution
  
  - assertion_patterns:
    - behavior_assertions: Verify actual behavior vs expected
    - state_assertions: Check component/service state changes
    - interaction_assertions: Verify function calls and parameters
    - output_assertions: Validate return values and side effects
  
  - framework_specific:
    - vitest_patterns: Vitest-specific utilities and matchers
    - testing_library: Component testing with user events
    - nunit_patterns: .NET testing patterns and attributes
    - async_testing: Promise/async handling patterns
```

## Framework-Specific Implementation

### Vitest/React Component Tests

```typescript
// Generated test for React component
import { render, screen, fireEvent, waitFor } from '@testing-library/react'
import { vi, describe, it, expect, beforeEach } from 'vitest'
import { UserDashboard } from '../UserDashboard'
import { useAuth } from '../hooks/useAuth'
import { fetchUserData } from '../services/userService'

// Mock dependencies
vi.mock('../hooks/useAuth')
vi.mock('../services/userService')

const mockUseAuth = vi.mocked(useAuth)
const mockFetchUserData = vi.mocked(fetchUserData)

describe('UserDashboard', () => {
  const defaultProps = {
    userId: 'user123',
    onUserUpdate: vi.fn(),
    theme: 'light'
  }

  beforeEach(() => {
    vi.clearAllMocks()
    mockUseAuth.mockReturnValue({
      user: { id: 'user123', name: 'John Doe', role: 'user' },
      isAuthenticated: true,
      loading: false
    })
  })

  describe('Rendering', () => {
    it('should render user dashboard with user information', () => {
      render(<UserDashboard {...defaultProps} />)
      
      expect(screen.getByText('Welcome, John Doe')).toBeInTheDocument()
      expect(screen.getByRole('main')).toHaveAttribute('aria-label', 'User Dashboard')
    })

    it('should show loading state when user data is loading', () => {
      mockUseAuth.mockReturnValue({
        user: null,
        isAuthenticated: true,
        loading: true
      })

      render(<UserDashboard {...defaultProps} />)
      
      expect(screen.getByRole('progressbar')).toBeInTheDocument()
      expect(screen.getByText('Loading dashboard...')).toBeInTheDocument()
    })

    it('should handle unauthenticated state', () => {
      mockUseAuth.mockReturnValue({
        user: null,
        isAuthenticated: false,
        loading: false
      })

      render(<UserDashboard {...defaultProps} />)
      
      expect(screen.getByText('Please log in to access your dashboard')).toBeInTheDocument()
    })
  })

  describe('User Interactions', () => {
    it('should call onUserUpdate when profile is edited', async () => {
      render(<UserDashboard {...defaultProps} />)
      
      const editButton = screen.getByRole('button', { name: /edit profile/i })
      fireEvent.click(editButton)
      
      const nameInput = screen.getByLabelText(/name/i)
      fireEvent.change(nameInput, { target: { value: 'Jane Doe' } })
      
      const saveButton = screen.getByRole('button', { name: /save/i })
      fireEvent.click(saveButton)
      
      await waitFor(() => {
        expect(defaultProps.onUserUpdate).toHaveBeenCalledWith({
          id: 'user123',
          name: 'Jane Doe',
          role: 'user'
        })
      })
    })

    it('should handle keyboard navigation', () => {
      render(<UserDashboard {...defaultProps} />)
      
      const dashboard = screen.getByRole('main')
      fireEvent.keyDown(dashboard, { key: 'Tab' })
      
      expect(screen.getByRole('button', { name: /edit profile/i })).toHaveFocus()
    })
  })

  describe('Data Fetching', () => {
    it('should fetch user data on mount', async () => {
      mockFetchUserData.mockResolvedValue({
        profile: { avatar: 'avatar.jpg', preferences: {} },
        stats: { loginCount: 42 }
      })

      render(<UserDashboard {...defaultProps} />)
      
      expect(mockFetchUserData).toHaveBeenCalledWith('user123')
      
      await waitFor(() => {
        expect(screen.getByText('Login Count: 42')).toBeInTheDocument()
      })
    })

    it('should handle fetch errors gracefully', async () => {
      mockFetchUserData.mockRejectedValue(new Error('Network error'))

      render(<UserDashboard {...defaultProps} />)
      
      await waitFor(() => {
        expect(screen.getByText('Unable to load dashboard data')).toBeInTheDocument()
      })
    })
  })

  describe('Accessibility', () => {
    it('should have proper ARIA labels and roles', () => {
      render(<UserDashboard {...defaultProps} />)
      
      expect(screen.getByRole('main')).toHaveAttribute('aria-label', 'User Dashboard')
      expect(screen.getByRole('button', { name: /edit profile/i })).toBeInTheDocument()
      expect(screen.getByLabelText(/user statistics/i)).toBeInTheDocument()
    })

    it('should announce loading state to screen readers', () => {
      mockUseAuth.mockReturnValue({
        user: null,
        isAuthenticated: true,
        loading: true
      })

      render(<UserDashboard {...defaultProps} />)
      
      expect(screen.getByRole('progressbar')).toHaveAttribute('aria-label', 'Loading dashboard')
    })
  })

  describe('Error Boundaries', () => {
    it('should handle component errors gracefully', () => {
      const ThrowingComponent = () => {
        throw new Error('Test error')
      }

      const consoleSpy = vi.spyOn(console, 'error').mockImplementation(() => {})
      
      expect(() => {
        render(
          <UserDashboard {...defaultProps}>
            <ThrowingComponent />
          </UserDashboard>
        )
      }).not.toThrow()
      
      consoleSpy.mockRestore()
    })
  })
})
```

### NUnit/.NET Service Tests

```csharp
// Generated test for .NET service
using NUnit.Framework;
using Moq;
using FluentAssertions;
using Microsoft.Extensions.Logging;
using Hubtel.Services;
using Hubtel.Models;
using Hubtel.Exceptions;

namespace Hubtel.Tests.Services
{
    [TestFixture]
    public class PaymentServiceTests
    {
        private Mock<IPaymentGateway> _mockPaymentGateway;
        private Mock<IUserRepository> _mockUserRepository;
        private Mock<ILogger<PaymentService>> _mockLogger;
        private PaymentService _paymentService;

        [SetUp]
        public void Setup()
        {
            _mockPaymentGateway = new Mock<IPaymentGateway>();
            _mockUserRepository = new Mock<IUserRepository>();
            _mockLogger = new Mock<ILogger<PaymentService>>();
            
            _paymentService = new PaymentService(
                _mockPaymentGateway.Object,
                _mockUserRepository.Object,
                _mockLogger.Object
            );
        }

        [TearDown]
        public void TearDown()
        {
            _paymentService?.Dispose();
        }

        [TestFixture]
        public class ProcessPaymentMethod : PaymentServiceTests
        {
            private PaymentRequest _validPaymentRequest;
            private User _validUser;

            [SetUp]
            public void ProcessPaymentSetup()
            {
                _validPaymentRequest = new PaymentRequest
                {
                    UserId = "user123",
                    Amount = 100.00m,
                    Currency = "USD",
                    PaymentMethod = "credit_card",
                    Description = "Test payment"
                };

                _validUser = new User
                {
                    Id = "user123",
                    Email = "test@example.com",
                    IsActive = true,
                    PaymentMethodsEnabled = true
                };
            }

            [Test]
            public async Task ProcessPayment_WithValidRequest_ShouldReturnSuccessResult()
            {
                // Arrange
                _mockUserRepository
                    .Setup(x => x.GetByIdAsync("user123"))
                    .ReturnsAsync(_validUser);

                _mockPaymentGateway
                    .Setup(x => x.ProcessPaymentAsync(It.IsAny<PaymentRequest>()))
                    .ReturnsAsync(new PaymentResult
                    {
                        Success = true,
                        TransactionId = "txn123",
                        Status = PaymentStatus.Completed
                    });

                // Act
                var result = await _paymentService.ProcessPaymentAsync(_validPaymentRequest);

                // Assert
                result.Should().NotBeNull();
                result.Success.Should().BeTrue();
                result.TransactionId.Should().NotBeNullOrEmpty();
                result.Status.Should().Be(PaymentStatus.Completed);
            }

            [Test]
            public async Task ProcessPayment_WithInvalidUser_ShouldThrowUserNotFoundException()
            {
                // Arrange
                _mockUserRepository
                    .Setup(x => x.GetByIdAsync("invalid_user"))
                    .ReturnsAsync((User)null);

                var invalidRequest = _validPaymentRequest with { UserId = "invalid_user" };

                // Act & Assert
                var exception = await Assert.ThrowsAsync<UserNotFoundException>(
                    () => _paymentService.ProcessPaymentAsync(invalidRequest)
                );

                exception.UserId.Should().Be("invalid_user");
                exception.Message.Should().Contain("User not found");
            }

            [TestCase(0)]
            [TestCase(-10)]
            [TestCase(-100.50)]
            public async Task ProcessPayment_WithInvalidAmount_ShouldThrowInvalidPaymentException(decimal invalidAmount)
            {
                // Arrange
                var invalidRequest = _validPaymentRequest with { Amount = invalidAmount };
                
                _mockUserRepository
                    .Setup(x => x.GetByIdAsync("user123"))
                    .ReturnsAsync(_validUser);

                // Act & Assert
                var exception = await Assert.ThrowsAsync<InvalidPaymentException>(
                    () => _paymentService.ProcessPaymentAsync(invalidRequest)
                );

                exception.Message.Should().Contain("Amount must be greater than zero");
            }

            [Test]
            public async Task ProcessPayment_WithInactiveUser_ShouldThrowUserNotActiveException()
            {
                // Arrange
                var inactiveUser = _validUser with { IsActive = false };
                
                _mockUserRepository
                    .Setup(x => x.GetByIdAsync("user123"))
                    .ReturnsAsync(inactiveUser);

                // Act & Assert
                var exception = await Assert.ThrowsAsync<UserNotActiveException>(
                    () => _paymentService.ProcessPaymentAsync(_validPaymentRequest)
                );

                exception.UserId.Should().Be("user123");
            }

            [Test]
            public async Task ProcessPayment_WhenGatewayFails_ShouldReturnFailureResult()
            {
                // Arrange
                _mockUserRepository
                    .Setup(x => x.GetByIdAsync("user123"))
                    .ReturnsAsync(_validUser);

                _mockPaymentGateway
                    .Setup(x => x.ProcessPaymentAsync(It.IsAny<PaymentRequest>()))
                    .ReturnsAsync(new PaymentResult
                    {
                        Success = false,
                        ErrorCode = "GATEWAY_ERROR",
                        ErrorMessage = "Payment gateway unavailable"
                    });

                // Act
                var result = await _paymentService.ProcessPaymentAsync(_validPaymentRequest);

                // Assert
                result.Should().NotBeNull();
                result.Success.Should().BeFalse();
                result.ErrorCode.Should().Be("GATEWAY_ERROR");
                result.ErrorMessage.Should().Contain("gateway unavailable");
            }

            [Test]
            public async Task ProcessPayment_ShouldLogPaymentAttempt()
            {
                // Arrange
                _mockUserRepository
                    .Setup(x => x.GetByIdAsync("user123"))
                    .ReturnsAsync(_validUser);

                _mockPaymentGateway
                    .Setup(x => x.ProcessPaymentAsync(It.IsAny<PaymentRequest>()))
                    .ReturnsAsync(new PaymentResult { Success = true, TransactionId = "txn123" });

                // Act
                await _paymentService.ProcessPaymentAsync(_validPaymentRequest);

                // Assert
                _mockLogger.Verify(
                    x => x.Log(
                        LogLevel.Information,
                        It.IsAny<EventId>(),
                        It.Is<It.IsAnyType>((v, t) => v.ToString().Contains("Processing payment for user")),
                        It.IsAny<Exception>(),
                        It.IsAny<Func<It.IsAnyType, Exception, string>>()
                    ),
                    Times.Once
                );
            }
        }

        [TestFixture]
        public class ValidatePaymentRequestMethod : PaymentServiceTests
        {
            [Test]
            public void ValidatePaymentRequest_WithValidRequest_ShouldNotThrow()
            {
                // Arrange
                var validRequest = new PaymentRequest
                {
                    UserId = "user123",
                    Amount = 50.00m,
                    Currency = "USD",
                    PaymentMethod = "credit_card"
                };

                // Act & Assert
                Assert.DoesNotThrow(() => _paymentService.ValidatePaymentRequest(validRequest));
            }

            [TestCase(null)]
            [TestCase("")]
            [TestCase("   ")]
            public void ValidatePaymentRequest_WithInvalidUserId_ShouldThrowArgumentException(string invalidUserId)
            {
                // Arrange
                var invalidRequest = new PaymentRequest
                {
                    UserId = invalidUserId,
                    Amount = 50.00m,
                    Currency = "USD",
                    PaymentMethod = "credit_card"
                };

                // Act & Assert
                var exception = Assert.Throws<ArgumentException>(
                    () => _paymentService.ValidatePaymentRequest(invalidRequest)
                );

                exception.Message.Should().Contain("UserId cannot be null or empty");
            }

            [TestCase("INVALID")]
            [TestCase("123")]
            [TestCase("")]
            public void ValidatePaymentRequest_WithInvalidCurrency_ShouldThrowArgumentException(string invalidCurrency)
            {
                // Arrange
                var invalidRequest = new PaymentRequest
                {
                    UserId = "user123",
                    Amount = 50.00m,
                    Currency = invalidCurrency,
                    PaymentMethod = "credit_card"
                };

                // Act & Assert
                var exception = Assert.Throws<ArgumentException>(
                    () => _paymentService.ValidatePaymentRequest(invalidRequest)
                );

                exception.Message.Should().Contain("Invalid currency code");
            }
        }
    }
}
```

## Quality Validation

### Test Quality Checklist
- ✅ **AAA Pattern**: Arrange, Act, Assert structure
- ✅ **Descriptive Names**: Clear test method and describe block names  
- ✅ **Single Responsibility**: Each test validates one specific behavior
- ✅ **Test Isolation**: Tests can run independently in any order
- ✅ **Proper Mocking**: Dependencies are properly mocked and verified
- ✅ **Edge Cases**: Boundary conditions and error scenarios covered
- ✅ **Accessibility**: Components tested for a11y compliance
- ✅ **Async Handling**: Promises and async operations properly tested

### Coverage Validation
- **Line Coverage**: Target 90%+ for generated tests
- **Branch Coverage**: All conditional paths tested
- **Function Coverage**: All exported functions tested
- **Statement Coverage**: All executable statements covered

This comprehensive unit test generator creates high-quality, maintainable tests that follow best practices and achieve excellent coverage across different testing frameworks.