import { describe, test, expect, beforeEach } from 'vitest'
import { render } from '@testing-library/react'
import { Row } from './row'
import { useWidgetStore } from '../../stores/widget-store'
import type { FormulaWidgetState } from '../types'
describe('Row', () => {
beforeEach(() => {
useWidgetStore.getState().clearWidgets()
})
test('returns null when widget does not exist', () => {
const { container } = render(
Content
,
)
expect(container.firstChild).toBeNull()
})
test('returns null when widget data is undefined', () => {
useWidgetStore.getState().setWidget('test-row', {
type: 'formula',
})
const { container } = render(
Content
,
)
expect(container.firstChild).toBeNull()
})
test('renders nothing for empty data array', () => {
useWidgetStore.getState().setWidget('test-row', {
type: 'formula',
data: [],
})
const { container } = render(
Content
,
)
// map returns empty array, which renders nothing
expect(container.firstChild).toBeNull()
})
test('renders direct children for single data item', () => {
useWidgetStore.getState().setWidget('test-row', {
type: 'formula',
data: [{ value: 100 }],
})
const { container } = render(
Content
,
)
expect(container.querySelector('[data-testid="child"]')).toBeTruthy()
})
test('renders direct children for multiple data items', () => {
useWidgetStore.getState().setWidget('test-row', {
type: 'formula',
data: [{ value: 100 }, { value: 200 }, { value: 300 }],
})
const { container } = render(
Content
,
)
const children = container.querySelectorAll('.child')
expect(children.length).toBe(3)
})
test('calls render prop function with correct index for single item', () => {
useWidgetStore.getState().setWidget('test-row', {
type: 'formula',
data: [{ value: 100 }],
})
const { container } = render(
{({ index }) => Index: {index}
}
,
)
const element = container.querySelector('[data-index="0"]')
expect(element).toBeTruthy()
expect(element?.textContent).toBe('Index: 0')
})
test('calls render prop function with correct indices for multiple items', () => {
useWidgetStore.getState().setWidget('test-row', {
type: 'formula',
data: [{ value: 100 }, { value: 200 }, { value: 300 }],
})
const { container } = render(
{({ index }) => Index: {index}
}
,
)
expect(container.querySelector('[data-index="0"]')).toBeTruthy()
expect(container.querySelector('[data-index="1"]')).toBeTruthy()
expect(container.querySelector('[data-index="2"]')).toBeTruthy()
})
test('applies row flexbox styles to each row', () => {
useWidgetStore.getState().setWidget('test-row', {
type: 'formula',
data: [{ value: 100 }],
})
const { container } = render(
Content
,
)
// Check that Box elements are rendered (we can't directly test sx styles)
expect(container.firstChild).toBeTruthy()
})
test('creates separate rows for each data item', () => {
useWidgetStore.getState().setWidget('test-row', {
type: 'formula',
data: [{ value: 100 }, { value: 200 }],
})
const { container } = render(
{({ index }) => Row {index}}
,
)
const boxes = container.querySelectorAll('.MuiBox-root')
expect(boxes.length).toBe(2)
})
test('assigns correct key to each row', () => {
useWidgetStore.getState().setWidget('test-row', {
type: 'formula',
data: [{ value: 100 }, { value: 200 }, { value: 300 }],
})
const { container } = render(
Content
,
)
// Each data item should create a row
const boxes = container.querySelectorAll('.MuiBox-root')
expect(boxes.length).toBe(3)
})
test('handles render prop returning null', () => {
useWidgetStore.getState().setWidget('test-row', {
type: 'formula',
data: [{ value: 100 }],
})
const { container } = render({() => null}
)
// Row should still render Box, but with null children
expect(container.firstChild).toBeTruthy()
})
test('handles render prop returning multiple elements', () => {
useWidgetStore.getState().setWidget('test-row', {
type: 'formula',
data: [{ value: 100 }],
})
const { container } = render(
{({ index }) => (
<>
A
B
{index}
>
)}
,
)
const spans = container.querySelectorAll('span')
expect(spans.length).toBe(3)
expect(spans[0]?.textContent).toBe('A')
expect(spans[1]?.textContent).toBe('B')
expect(spans[2]?.textContent).toBe('0')
})
test('updates when widget data changes', () => {
useWidgetStore.getState().setWidget('test-row', {
type: 'formula',
data: [{ value: 100 }],
})
const { container, rerender } = render(
Content
,
)
let boxes = container.querySelectorAll('.MuiBox-root')
expect(boxes.length).toBe(1)
useWidgetStore.getState().setWidget('test-row', {
data: [{ value: 100 }, { value: 200 }],
})
rerender(
Content
,
)
boxes = container.querySelectorAll('.MuiBox-root')
expect(boxes.length).toBe(2)
})
test('updates when widget is removed', () => {
useWidgetStore.getState().setWidget('test-row', {
type: 'formula',
data: [{ value: 100 }],
})
const { container, rerender } = render(
Content
,
)
expect(container.firstChild).toBeTruthy()
useWidgetStore.getState().removeWidget('test-row')
rerender(
Content
,
)
expect(container.firstChild).toBeNull()
})
test('handles single data item', () => {
useWidgetStore.getState().setWidget('test-row', {
type: 'formula',
data: [{ value: 100 }],
})
const { container } = render(
{({ index }) => Item {index}
}
,
)
expect(container.textContent).toContain('Item 0')
})
test('handles many data items', () => {
const data = Array.from({ length: 10 }, (_, i) => ({ value: i }))
useWidgetStore.getState().setWidget('test-row', {
type: 'formula',
data,
})
const { container } = render(
{({ index }) => Item {index}
}
,
)
const items = container.querySelectorAll('.item')
expect(items.length).toBe(10)
})
test('passes only index in render prop', () => {
useWidgetStore.getState().setWidget('test-row', {
type: 'formula',
data: [{ value: 100 }],
})
render(
{(props) => {
// Check that only index is passed
expect(Object.keys(props)).toEqual(['index'])
expect(typeof props.index).toBe('number')
return Content
}}
,
)
})
test('handles complex children elements', () => {
useWidgetStore.getState().setWidget('test-row', {
type: 'formula',
data: [{ value: 100 }],
})
const { container } = render(
Nested
Content
,
)
expect(container.querySelector('span')).toBeTruthy()
expect(container.querySelector('strong')).toBeTruthy()
})
test('render prop can access external variables', () => {
useWidgetStore.getState().setWidget('test-row', {
type: 'formula',
data: [{ value: 100 }, { value: 200 }],
})
const externalValue = 'External'
const { container } = render(
{({ index }) => (
{externalValue} {index}
)}
,
)
expect(container.textContent).toContain('External 0')
expect(container.textContent).toContain('External 1')
})
test('handles data array with different value types', () => {
useWidgetStore.getState().setWidget('test-row', {
type: 'formula',
data: [
{ value: 0 },
{ value: -100 },
{ value: 123.456 },
{ value: 1000000 },
],
})
const { container } = render(
{({ index }) => Item {index}
}
,
)
const items = container.querySelectorAll('.item')
expect(items.length).toBe(4)
})
})