返回 reveal.js
fragment.test.tsx
根目录 / react / src / components / fragment.test.tsx
1 import { render } from '@testing-library/react';
2 import { describe, it, expect } from 'vitest';
3 import { Fragment } from './fragment';
4
5 describe('Fragment', () => {
6 it('renders with the "fragment" class', () => {
7 const { container } = render(<Fragment>Hello</Fragment>);
8 const el = container.querySelector('.fragment');
9 expect(el).toBeInTheDocument();
10 expect(el).toHaveTextContent('Hello');
11 });
12
13 it('applies the animation class', () => {
14 const { container } = render(<Fragment animation="fade-up">Animated</Fragment>);
15
16 const el = container.querySelector('.fragment');
17 expect(el).toHaveClass('fragment', 'fade-up');
18 });
19
20 it('sets data-fragment-index when index is provided', () => {
21 const { container } = render(<Fragment index={2}>Indexed</Fragment>);
22
23 const el = container.querySelector('.fragment');
24 expect(el).toHaveAttribute('data-fragment-index', '2');
25 });
26
27 it('does not set data-fragment-index when index is omitted', () => {
28 const { container } = render(<Fragment>No index</Fragment>);
29 const el = container.querySelector('.fragment');
30 expect(el?.getAttribute('data-fragment-index')).toBeNull();
31 });
32
33 it('renders as a <span> by default', () => {
34 const { container } = render(<Fragment>Default</Fragment>);
35 const el = container.querySelector('.fragment');
36 expect(el?.tagName).toBe('SPAN');
37 });
38
39 it('renders as a custom element when "as" is provided', () => {
40 const { container } = render(<Fragment as="div">Block</Fragment>);
41
42 const el = container.querySelector('.fragment');
43 expect(el?.tagName).toBe('DIV');
44 });
45
46 it('combines fragment, animation, and custom className', () => {
47 const { container } = render(
48 <Fragment animation="grow" className="custom">
49 Combined
50 </Fragment>
51 );
52
53 const el = container.querySelector('.fragment');
54 expect(el).toHaveClass('fragment', 'grow', 'custom');
55 });
56
57 it('passes style through', () => {
58 const { container } = render(<Fragment style={{ opacity: 0.5 }}>Styled</Fragment>);
59
60 const el = container.querySelector('.fragment');
61 expect(el).toHaveStyle({ opacity: '0.5' });
62 });
63
64 it('renders the child element directly when asChild is provided', () => {
65 const { container } = render(
66 <Fragment asChild animation="fade-up">
67 <li>Item</li>
68 </Fragment>
69 );
70
71 expect(container.firstElementChild?.tagName).toBe('LI');
72 expect(container.firstElementChild).toHaveClass('fragment', 'fade-up');
73 expect(container.firstElementChild).toHaveTextContent('Item');
74 });
75
76 it('merges child className and style when asChild is provided', () => {
77 const { container } = render(
78 <Fragment asChild animation="grow" className="outer" style={{ opacity: 0.5 }}>
79 <div className="inner" style={{ color: 'red' }}>
80 Merged
81 </div>
82 </Fragment>
83 );
84
85 const el = container.firstElementChild;
86 expect(el).toHaveClass('inner', 'fragment', 'grow', 'outer');
87 expect(el).toHaveStyle({ color: 'rgb(255, 0, 0)', opacity: '0.5' });
88 });
89
90 it('sets data-fragment-index on the child when asChild is provided', () => {
91 const { container } = render(
92 <Fragment asChild index={2}>
93 <div data-fragment-index={1}>Indexed</div>
94 </Fragment>
95 );
96
97 expect(container.firstElementChild).toHaveAttribute('data-fragment-index', '2');
98 });
99
100 it('throws when asChild receives multiple children', () => {
101 expect(() =>
102 render(
103 // @ts-expect-error - This is a test
104 <Fragment asChild>
105 <span>One</span>
106 <span>Two</span>
107 </Fragment>
108 )
109 ).toThrow('Fragment with asChild expects exactly one React element child.');
110 });
111
112 it('throws when asChild receives a React.Fragment child', () => {
113 expect(() =>
114 render(
115 <Fragment asChild>
116 <>
117 <span>One</span>
118 </>
119 </Fragment>
120 )
121 ).toThrow('Fragment with asChild expects exactly one non-Fragment React element child.');
122 });
123 });
124
124 lines Plain Text