97 lines
3.4 KiB
TypeScript
97 lines
3.4 KiB
TypeScript
|
|
import { describe, it, expect } from 'vitest'
|
||
|
|
import { render, screen } from '@testing-library/react'
|
||
|
|
import { ProjectMetadata } from './ProjectMetadata'
|
||
|
|
|
||
|
|
const DEFAULT_PROPS = {
|
||
|
|
year: '2024',
|
||
|
|
role: 'Frontend Engineer',
|
||
|
|
stack: ['React', 'TypeScript', 'Tailwind'],
|
||
|
|
}
|
||
|
|
|
||
|
|
describe('ProjectMetadata', () => {
|
||
|
|
describe('rendering', () => {
|
||
|
|
it('renders the year value', () => {
|
||
|
|
render(<ProjectMetadata {...DEFAULT_PROPS} />)
|
||
|
|
expect(screen.getByText('2024')).toBeInTheDocument()
|
||
|
|
})
|
||
|
|
|
||
|
|
it('renders the YEAR label', () => {
|
||
|
|
render(<ProjectMetadata {...DEFAULT_PROPS} />)
|
||
|
|
expect(screen.getByText('YEAR')).toBeInTheDocument()
|
||
|
|
})
|
||
|
|
|
||
|
|
it('renders the role value', () => {
|
||
|
|
render(<ProjectMetadata {...DEFAULT_PROPS} />)
|
||
|
|
expect(screen.getByText('Frontend Engineer')).toBeInTheDocument()
|
||
|
|
})
|
||
|
|
|
||
|
|
it('renders the ROLE label', () => {
|
||
|
|
render(<ProjectMetadata {...DEFAULT_PROPS} />)
|
||
|
|
expect(screen.getByText('ROLE')).toBeInTheDocument()
|
||
|
|
})
|
||
|
|
|
||
|
|
it('renders the STACK label', () => {
|
||
|
|
render(<ProjectMetadata {...DEFAULT_PROPS} />)
|
||
|
|
expect(screen.getByText('STACK')).toBeInTheDocument()
|
||
|
|
})
|
||
|
|
|
||
|
|
it('renders each stack technology', () => {
|
||
|
|
render(<ProjectMetadata {...DEFAULT_PROPS} />)
|
||
|
|
expect(screen.getByText('React')).toBeInTheDocument()
|
||
|
|
expect(screen.getByText('TypeScript')).toBeInTheDocument()
|
||
|
|
expect(screen.getByText('Tailwind')).toBeInTheDocument()
|
||
|
|
})
|
||
|
|
})
|
||
|
|
|
||
|
|
describe('structure', () => {
|
||
|
|
it('outer div has space-y-6', () => {
|
||
|
|
const { container } = render(<ProjectMetadata {...DEFAULT_PROPS} />)
|
||
|
|
expect(container.firstChild).toHaveClass('space-y-6')
|
||
|
|
})
|
||
|
|
|
||
|
|
it('year section has no brutal-border-top (first section)', () => {
|
||
|
|
const { container } = render(<ProjectMetadata {...DEFAULT_PROPS} />)
|
||
|
|
const sections = container.firstChild!.childNodes
|
||
|
|
expect(sections[0]).not.toHaveClass('brutal-border-top')
|
||
|
|
})
|
||
|
|
|
||
|
|
it('role section has brutal-border-top and pt-6', () => {
|
||
|
|
const { container } = render(<ProjectMetadata {...DEFAULT_PROPS} />)
|
||
|
|
const sections = container.firstChild!.childNodes
|
||
|
|
expect(sections[1]).toHaveClass('brutal-border-top', 'pt-6')
|
||
|
|
})
|
||
|
|
|
||
|
|
it('stack section has brutal-border-top and pt-6', () => {
|
||
|
|
const { container } = render(<ProjectMetadata {...DEFAULT_PROPS} />)
|
||
|
|
const sections = container.firstChild!.childNodes
|
||
|
|
expect(sections[2]).toHaveClass('brutal-border-top', 'pt-6')
|
||
|
|
})
|
||
|
|
|
||
|
|
it('label has text-xs uppercase tracking-wider opacity-60', () => {
|
||
|
|
render(<ProjectMetadata {...DEFAULT_PROPS} />)
|
||
|
|
const yearLabel = screen.getByText('YEAR')
|
||
|
|
expect(yearLabel).toHaveClass('text-xs', 'uppercase', 'tracking-wider', 'opacity-60')
|
||
|
|
})
|
||
|
|
|
||
|
|
it('year value has text-base font-bold', () => {
|
||
|
|
render(<ProjectMetadata {...DEFAULT_PROPS} />)
|
||
|
|
const yearValue = screen.getByText('2024')
|
||
|
|
expect(yearValue).toHaveClass('text-base', 'font-bold')
|
||
|
|
})
|
||
|
|
|
||
|
|
it('each stack tech is rendered as a <p> with text-sm', () => {
|
||
|
|
render(<ProjectMetadata {...DEFAULT_PROPS} />)
|
||
|
|
const techEl = screen.getByText('React')
|
||
|
|
expect(techEl.tagName).toBe('P')
|
||
|
|
expect(techEl).toHaveClass('text-sm')
|
||
|
|
})
|
||
|
|
})
|
||
|
|
|
||
|
|
describe('className passthrough', () => {
|
||
|
|
it('merges custom className onto outer div', () => {
|
||
|
|
const { container } = render(<ProjectMetadata {...DEFAULT_PROPS} className="my-custom" />)
|
||
|
|
expect(container.firstChild).toHaveClass('my-custom')
|
||
|
|
})
|
||
|
|
})
|
||
|
|
})
|