import React from 'react';
import MockDate from 'mockdate';
import Descriptions from '..';
import { resetWarned } from '../../_util/warning';
import mountTest from '../../../tests/shared/mountTest';
import { render } from '../../../tests/utils';
import ConfigProvider from '../../config-provider';
describe('Descriptions', () => {
mountTest(Descriptions);
const errorSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
afterEach(() => {
MockDate.reset();
errorSpy.mockReset();
});
afterAll(() => {
errorSpy.mockRestore();
});
it('when max-width: 575px, column=1', () => {
const wrapper = render(
Cloud Database
Prepaid
18:00:00
$80.00
No-Label
,
);
expect(wrapper.container.querySelectorAll('tr')).toHaveLength(5);
expect(wrapper.container.querySelectorAll('.ant-descriptions-item-label')).toHaveLength(4);
wrapper.unmount();
});
it('when max-width: 575px, column=2', () => {
const wrapper = render(
Cloud Database
Prepaid
18:00:00
$80.00
,
);
expect(wrapper.container.querySelectorAll('tr')).toHaveLength(2);
wrapper.unmount();
});
it('when max-width: 575px, column=2, span=2', () => {
const { container } = render(
,
);
expect(container.querySelectorAll('.ant-descriptions-item')[0]).toHaveAttribute('colSpan', '2');
expect(container.querySelectorAll('.ant-descriptions-item')[1]).toHaveAttribute('colSpan', '1');
expect(container.querySelectorAll('.ant-descriptions-item')[2]).toHaveAttribute('colSpan', '1');
});
it('span = filled', () => {
const { container } = render(
,
);
expect(container.querySelectorAll('.ant-descriptions-item')[0]).toHaveAttribute('colSpan', '2');
expect(container.querySelectorAll('.ant-descriptions-item')[1]).toHaveAttribute('colSpan', '1');
expect(container.querySelectorAll('.ant-descriptions-item')[2]).toHaveAttribute('colSpan', '1');
expect(container.querySelectorAll('.ant-descriptions-item')[3]).toHaveAttribute('colSpan', '2');
expect(container.querySelectorAll('.ant-descriptions-item')[4]).toHaveAttribute('colSpan', '3');
expect(container.querySelectorAll('.ant-descriptions-item')[5]).toHaveAttribute('colSpan', '1');
expect(container.querySelectorAll('.ant-descriptions-item')[6]).toHaveAttribute('colSpan', '2');
});
it('when column=6, last item span should be 5', () => {
const { container } = render(
,
);
expect(container.querySelectorAll('.ant-descriptions-item')[0]).toHaveAttribute('colSpan', '1');
expect(container.querySelectorAll('.ant-descriptions-item')[1]).toHaveAttribute('colSpan', '5');
});
it('column is number', () => {
const wrapper = render(
Cloud Database
Prepaid
18:00:00
$80.00
,
);
expect(wrapper.container.firstChild).toMatchSnapshot();
wrapper.unmount();
});
it('when typeof column is object', () => {
const wrapper = render(
Cloud Database
Prepaid
18:00:00
$80.00
,
);
expect(
Array.from(wrapper.container.querySelectorAll('td'))
.map((i) => Number(i.getAttribute('colspan')))
.filter(Boolean)
.reduce((total, cur) => total + cur, 0),
).toBe(8);
wrapper.unmount();
});
it('warning if exceed the row span', () => {
resetWarned();
render(
Cloud Database
Prepaid
,
);
expect(errorSpy).toHaveBeenCalledWith(
'Warning: [antd: Descriptions] Sum of column `span` in a line not match `column` of Descriptions.',
);
});
it('when item is rendered conditionally', () => {
const hasDiscount = false;
const wrapper = render(
Cloud Database
Prepaid
18:00:00
$80.00
{hasDiscount && $20.00}
,
);
expect(wrapper.container.firstChild).toMatchSnapshot();
wrapper.unmount();
});
it('vertical layout', () => {
const wrapper = render(
Cloud Database
Prepaid
18:00:00
$80.00
,
);
expect(wrapper.container.firstChild).toMatchSnapshot();
wrapper.unmount();
});
it('Descriptions.Item support className', () => {
const wrapper = render(
Cloud Database
,
);
expect(wrapper.container.firstChild).toMatchSnapshot();
});
it('Descriptions support colon', () => {
const wrapper = render(
Cloud Database
,
);
expect(wrapper.container.firstChild).toMatchSnapshot();
});
it('Descriptions support style', () => {
const wrapper = render(
Cloud Database
,
);
expect(wrapper.container.firstChild).toMatchSnapshot();
});
it('Descriptions support id', () => {
const wrapper = render(
Cloud Database
,
);
const descriptionItemsElement = wrapper.container.querySelector('#descriptions');
expect(descriptionItemsElement).not.toBeNull();
});
it('keep key', () => {
render(
1
,
);
expect(jest.spyOn(document, 'createElement')).not.toHaveBeenCalled();
});
// https://github.com/ant-design/ant-design/issues/19887
it('should work with React Fragment', () => {
if (!React.Fragment) {
return;
}
const wrapper = render(
bamboo
<>
bamboo
bamboo
>
,
);
expect(wrapper.container.firstChild).toMatchSnapshot();
});
// https://github.com/ant-design/ant-design/issues/20255
it('columns 5 with customize', () => {
const wrapper = render(
{/* 1 1 1 1 */}
bamboo
bamboo
bamboo
bamboo
{/* 2 2 */}
bamboo
bamboo
{/* 3 1 */}
bamboo
bamboo
,
);
function matchSpan(rowIndex: number, spans: number[]) {
const trs = Array.from(wrapper.container.querySelectorAll('tr')).at(rowIndex);
const tds = Array.from(trs?.querySelectorAll('th')!);
expect(tds).toHaveLength(spans.length);
tds.forEach((td, index) => {
expect(Number(td.getAttribute('colSpan'))).toEqual(spans[index]);
});
}
matchSpan(0, [1, 1, 1, 1]);
matchSpan(2, [2, 2]);
matchSpan(4, [3, 1]);
});
it('number value should render correct', () => {
const wrapper = render(
0
,
);
expect(wrapper.container.querySelector('th')).toHaveClass('ant-descriptions-item-label');
expect(wrapper.container.querySelector('td')).toHaveClass('ant-descriptions-item-content');
});
it('Descriptions support extra', () => {
const wrapper1 = render(
Zhou Maomao
,
);
const wrapper2 = render(
Zhou Maomao
,
);
expect(wrapper1.container.querySelector('.ant-descriptions-extra')).toBeTruthy();
expect(wrapper2.container.querySelector('.ant-descriptions-extra')).toBeFalsy();
});
it('number 0 should render correct', () => {
const wrapper = render(
{0}
,
);
expect(wrapper.container.firstChild).toMatchSnapshot();
});
it('should pass data-* and accessibility attributes', () => {
const { getByTestId } = render(
banana
,
);
const container = getByTestId('test-id');
expect(container).toHaveAttribute('data-id', '12345');
expect(container).toHaveAttribute('aria-describedby', 'some-label');
});
it('Descriptions should inherit the size from ConfigProvider if the componentSize is set', () => {
const { container } = render(
small
,
);
expect(container.querySelectorAll('.ant-descriptions-small')).toHaveLength(1);
});
it('should items work', () => {
const { container } = render(
,
);
expect(container.querySelector('.ant-descriptions-item')).toBeTruthy();
expect(container.querySelectorAll('.ant-descriptions-item')).toHaveLength(3);
expect(container).toMatchSnapshot();
});
it('Descriptions nested within an Item are unaffected by the external borderless style', () => {
const { container } = render(
,
);
const nestDesc = container.querySelectorAll('.ant-descriptions')[1];
const view = nestDesc.querySelector('.ant-descriptions-view');
expect(getComputedStyle(view!).border).toBeFalsy();
});
it('Should Descriptions not throw react key prop error in jsx mode', () => {
render(
Zhou Maomao
1810000000
,
);
expect(errorSpy).not.toHaveBeenCalledWith(
expect.stringContaining('`key` is not a prop'),
expect.anything(),
expect.anything(),
);
});
// https://github.com/ant-design/ant-design/issues/47151
it('should has .ant-descriptions-item-content className when children is falsy', () => {
const wrapper = render(
,
);
expect(wrapper.container.querySelectorAll('.ant-descriptions-item-label')).toHaveLength(1);
expect(wrapper.container.querySelectorAll('.ant-descriptions-item-content')).toHaveLength(1);
});
it('should apply custom styles to Descriptions', () => {
const customClassNames = {
root: 'custom-root',
header: 'custom-header',
title: 'custom-title',
extra: 'custom-extra',
label: 'custom-label',
content: 'custom-content',
};
const customStyles = {
root: { backgroundColor: 'red' },
header: { backgroundColor: 'black' },
title: { backgroundColor: 'yellow' },
extra: { backgroundColor: 'purple' },
label: { backgroundColor: 'blue' },
content: { backgroundColor: 'green' },
};
const { container } = render(
,
);
const rootElement = container.querySelector('.ant-descriptions') as HTMLElement;
const headerElement = container.querySelector('.ant-descriptions-header') as HTMLElement;
const titleElement = container.querySelector('.ant-descriptions-title') as HTMLElement;
const extraElement = container.querySelector('.ant-descriptions-extra') as HTMLElement;
const labelElement = container.querySelector('.ant-descriptions-item-label') as HTMLElement;
const contentElement = container.querySelector('.ant-descriptions-item-content') as HTMLElement;
const labelElements = container.querySelectorAll(
'.ant-descriptions-item-label',
) as NodeListOf;
const contentElements = container.querySelectorAll(
'.ant-descriptions-item-content',
) as NodeListOf;
// check classNames
expect(rootElement.classList).toContain('custom-root');
expect(headerElement.classList).toContain('custom-header');
expect(titleElement.classList).toContain('custom-title');
expect(extraElement.classList).toContain('custom-extra');
expect(labelElement.classList).toContain('custom-label');
expect(contentElement.classList).toContain('custom-content');
// check styles
expect(rootElement.style.backgroundColor).toBe('red');
expect(headerElement.style.backgroundColor).toBe('black');
expect(titleElement.style.backgroundColor).toBe('yellow');
expect(extraElement.style.backgroundColor).toBe('purple');
expect(labelElement.style.backgroundColor).toBe('blue');
expect(contentElement.style.backgroundColor).toBe('green');
expect(labelElements[1].style.color).toBe('orange');
expect(contentElements[1].style.color).toBe('yellow');
expect(labelElements[0].style.color).not.toBe('orange');
expect(contentElements[0].style.color).not.toBe('yellow');
});
});