import { useState } from 'react' import { UnitTest, TestCase } from '@/types/project' import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card' import { Button } from '@/components/ui/button' import { Input } from '@/components/ui/input' import { Label } from '@/components/ui/label' import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select' import { ScrollArea } from '@/components/ui/scroll-area' import { Textarea } from '@/components/ui/textarea' import { Plus, Trash, Flask, Sparkle } from '@phosphor-icons/react' import { toast } from 'sonner' import { Badge } from '@/components/ui/badge' interface UnitTestDesignerProps { tests: UnitTest[] onTestsChange: (tests: UnitTest[]) => void } export function UnitTestDesigner({ tests, onTestsChange }: UnitTestDesignerProps) { const [selectedTestId, setSelectedTestId] = useState(tests[0]?.id || null) const selectedTest = tests.find(t => t.id === selectedTestId) const handleAddTest = () => { const newTest: UnitTest = { id: `unit-test-${Date.now()}`, name: 'New Test Suite', description: '', testType: 'component', targetFile: '', testCases: [] } onTestsChange([...tests, newTest]) setSelectedTestId(newTest.id) } const handleDeleteTest = (testId: string) => { onTestsChange(tests.filter(t => t.id !== testId)) if (selectedTestId === testId) { const remaining = tests.filter(t => t.id !== testId) setSelectedTestId(remaining[0]?.id || null) } } const handleUpdateTest = (testId: string, updates: Partial) => { onTestsChange( tests.map(t => t.id === testId ? { ...t, ...updates } : t) ) } const handleAddTestCase = () => { if (!selectedTest) return const newCase: TestCase = { id: `case-${Date.now()}`, description: 'should work correctly', assertions: ['expect(...).toBe(...)'], setup: '', teardown: '' } handleUpdateTest(selectedTest.id, { testCases: [...selectedTest.testCases, newCase] }) } const handleUpdateTestCase = (caseId: string, updates: Partial) => { if (!selectedTest) return handleUpdateTest(selectedTest.id, { testCases: selectedTest.testCases.map(c => c.id === caseId ? { ...c, ...updates } : c) }) } const handleDeleteTestCase = (caseId: string) => { if (!selectedTest) return handleUpdateTest(selectedTest.id, { testCases: selectedTest.testCases.filter(c => c.id !== caseId) }) } const handleAddAssertion = (caseId: string) => { if (!selectedTest) return const testCase = selectedTest.testCases.find(c => c.id === caseId) if (!testCase) return handleUpdateTestCase(caseId, { assertions: [...testCase.assertions, 'expect(...).toBe(...)'] }) } const handleUpdateAssertion = (caseId: string, index: number, value: string) => { if (!selectedTest) return const testCase = selectedTest.testCases.find(c => c.id === caseId) if (!testCase) return const newAssertions = [...testCase.assertions] newAssertions[index] = value handleUpdateTestCase(caseId, { assertions: newAssertions }) } const handleDeleteAssertion = (caseId: string, index: number) => { if (!selectedTest) return const testCase = selectedTest.testCases.find(c => c.id === caseId) if (!testCase) return handleUpdateTestCase(caseId, { assertions: testCase.assertions.filter((_, i) => i !== index) }) } const handleGenerateWithAI = async () => { const description = prompt('Describe the component/function you want to test:') if (!description) return try { toast.info('Generating test with AI...') const promptText = `You are a unit test generator. Create tests based on: "${description}" Return a valid JSON object with a single property "test": { "test": { "id": "unique-id", "name": "ComponentName/FunctionName Tests", "description": "Test suite description", "testType": "component" | "function" | "hook" | "integration", "targetFile": "/path/to/file.tsx", "testCases": [ { "id": "case-id", "description": "should render correctly", "assertions": [ "expect(screen.getByText('Hello')).toBeInTheDocument()", "expect(result).toBe(true)" ], "setup": "const { getByText } = render()", "teardown": "cleanup()" } ] } } Create comprehensive test cases with appropriate assertions for React Testing Library or Vitest.` const response = await window.spark.llm(promptText, 'gpt-4o', true) const parsed = JSON.parse(response) onTestsChange([...tests, parsed.test]) setSelectedTestId(parsed.test.id) toast.success('Test suite generated successfully!') } catch (error) { console.error(error) toast.error('Failed to generate test') } } const getTestTypeColor = (type: string) => { const colors: Record = { component: 'bg-blue-500', function: 'bg-green-500', hook: 'bg-purple-500', integration: 'bg-orange-500' } return colors[type] || 'bg-gray-500' } return (

Test Suites

{tests.map(test => (
setSelectedTestId(test.id)} >
{test.name}
{test.targetFile || 'No file'}
{test.testCases.length} cases
))} {tests.length === 0 && (
No test suites yet. Click + to create one.
)}
{selectedTest ? (

Test Suite Configuration

Test Suite Details
handleUpdateTest(selectedTest.id, { name: e.target.value })} />