import React from 'react' import { describe, it, expect } from 'vitest' import { render, screen } from '@testing-library/react' import Tag from './tag' import type { TagVariant } from './tag.types' describe('Tag Component', () => { describe('Rendering', () => { it('should render with default props', () => { render(Default Tag) const tag = screen.getByText('Default Tag') expect(tag).toBeInTheDocument() expect(tag.tagName).toBe('SPAN') }) it('should render children correctly', () => { render(Test Content) expect(screen.getByText('Test Content')).toBeInTheDocument() }) it('should render as span element by default', () => { render(Span Tag) const tag = screen.getByText('Span Tag') expect(tag.tagName).toBe('SPAN') }) it('should render as p element when elm prop is "p"', () => { render(Paragraph Tag) const tag = screen.getByText('Paragraph Tag') expect(tag.tagName).toBe('P') }) }) describe('Accessibility (ARIA Roles)', () => { it('should have role="note" by default', () => { render(Note Tag) const tag = screen.getByRole('note') expect(tag).toBeInTheDocument() }) it('should apply role="status" when specified', () => { render(Status Tag) const tag = screen.getByRole('status') expect(tag).toBeInTheDocument() }) it('should support aria-label for additional context', () => { render(Beta) const tag = screen.getByLabelText('Beta version indicator') expect(tag).toBeInTheDocument() }) it('should support aria-describedby for extended descriptions', () => { render( <>
This is a beta feature
Beta ) const tag = screen.getByRole('note') expect(tag).toHaveAttribute('aria-describedby', 'beta-desc') }) }) describe('Variants', () => { const variants: TagVariant[] = ['alpha', 'beta', 'stable', 'production'] variants.forEach((variant) => { it(`should apply data-tag="${variant}" attribute for ${variant} variant`, () => { render({variant}) const tag = screen.getByText(variant) expect(tag).toHaveAttribute('data-tag', variant) }) }) it('should not apply data-tag attribute when variant is undefined', () => { render(No Variant) const tag = screen.getByText('No Variant') expect(tag).not.toHaveAttribute('data-tag') }) }) describe('Custom Styling', () => { it('should apply custom inline styles via styles prop', () => { render( Styled Tag ) const tag = screen.getByText('Styled Tag') expect(tag).toHaveStyle({ fontSize: '1rem' }) expect(tag.style.backgroundColor).toBeTruthy() expect(tag.style.color).toBeTruthy() }) it('should apply CSS classes via classes prop', () => { render(Classed Tag) const tag = screen.getByText('Classed Tag') expect(tag).toHaveClass('custom-class', 'another-class') }) it('should apply id attribute', () => { render(ID Tag) const tag = screen.getByText('ID Tag') expect(tag).toHaveAttribute('id', 'unique-tag') }) }) describe('Component Composition', () => { it('should render with both variant and custom styles', () => { render( Combined ) const tag = screen.getByText('Combined') expect(tag).toHaveAttribute('data-tag', 'beta') expect(tag).toHaveStyle({ fontSize: '1rem' }) }) it('should render with all props combined', () => { render( Production ) const tag = screen.getByRole('status') expect(tag.tagName).toBe('P') expect(tag).toHaveAttribute('data-tag', 'production') expect(tag).toHaveAttribute('id', 'prod-tag') expect(tag).toHaveAttribute('aria-label', 'Production environment') expect(tag).toHaveClass('production-tag') expect(tag).toHaveStyle({ fontWeight: 'bold' }) }) }) describe('Type Safety', () => { it('should accept valid TagVariant values', () => { // These should compile without TypeScript errors const validVariants: TagVariant[] = ['alpha', 'beta', 'stable', 'production'] validVariants.forEach((variant) => { const { unmount } = render({variant}) expect(screen.getByText(variant)).toBeInTheDocument() unmount() }) }) it('should accept valid elm prop values', () => { const { rerender } = render(Span) expect(screen.getByText('Span').tagName).toBe('SPAN') rerender(Paragraph) expect(screen.getByText('Paragraph').tagName).toBe('P') }) it('should accept valid role prop values', () => { const { rerender } = render(Note) expect(screen.getByRole('note')).toBeInTheDocument() rerender(Status) expect(screen.getByRole('status')).toBeInTheDocument() }) }) describe('Edge Cases', () => { it('should require children for accessibility', () => { // TypeScript should enforce children as required // This test verifies meaningful content is provided render(Required Content) const tag = screen.getByLabelText('Tag with content') expect(tag).toBeInTheDocument() expect(tag).toHaveTextContent('Required Content') }) it('should handle multiple children', () => { render( Part 1 Part 2 ) expect(screen.getByText('Part 1')).toBeInTheDocument() expect(screen.getByText('Part 2')).toBeInTheDocument() }) it('should handle complex children with React elements', () => { render( Beta v2.0 ) expect(screen.getByText('Beta')).toBeInTheDocument() expect(screen.getByText('v2.0')).toBeInTheDocument() }) }) describe('Display Name', () => { it('should have correct displayName for debugging', () => { expect(Tag.displayName).toBe('Tag') }) }) })