Skip to content

Commit c934a7d

Browse files
committed
test: adding test cases
1 parent 0d3fb89 commit c934a7d

File tree

10 files changed

+288
-55
lines changed

10 files changed

+288
-55
lines changed

.husky/pre-commit

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
pnpm exec lint-staged
2-
# pnpm exec vitest run
2+
pnpm exec vitest run

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
"preview": "vite preview",
1818
"test": "vitest",
1919
"test:ui": "vitest --ui",
20+
"test:coverage": "vitest --coverage",
2021
"prepare": "husky"
2122
},
2223
"dependencies": {

src/App.tsx

+9-6
Original file line numberDiff line numberDiff line change
@@ -15,22 +15,25 @@ function App() {
1515
<button onClick={() => setVal(3)}>3</button>
1616
<SwitchIf>
1717
<If condition={val === 0}>
18-
<div>if val = 0</div>
18+
<div>If value = 0</div>
1919
</If>
2020
<ElseIf condition={val === 1}>
21-
<div>if val = 1</div>
22-
<button onClick={() => setVal2((prev) => !prev)}>sub</button>
21+
<div>ElseIf value = 1</div>
22+
<button onClick={() => setVal2((prev) => !prev)}>Nested If</button>
2323
<SwitchIf>
2424
<If condition={val2}>
25-
<div>if sub</div>
25+
<div>Sub If value = true</div>
2626
</If>
27+
<Else>
28+
<div>Sub Else value = false</div>
29+
</Else>
2730
</SwitchIf>
2831
</ElseIf>
2932
<ElseIf condition={val === 2}>
30-
<div>if val = 2</div>
33+
<div>ElseIf value = 2</div>
3134
</ElseIf>
3235
<Else>
33-
<div>Else val = {val}</div>
36+
<div>Else (fall through {val} )</div>
3437
</Else>
3538
</SwitchIf>
3639
</div>

src/__tests__/SwitchIf.test.tsx

+228
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,228 @@
1+
import { Else, ElseIf, If, SwitchIf } from '@directives';
2+
import { render } from '@testing-library/react';
3+
import { ERRORS, LogicErrors } from '@fixtures';
4+
5+
describe('SwitchIf', () => {
6+
it('should render content of If block', () => {
7+
const { getByText } = render(
8+
<SwitchIf>
9+
<If condition={true}>If Block</If>
10+
<Else>Else Block</Else>
11+
</SwitchIf>,
12+
);
13+
expect(getByText('If Block')).toBeInTheDocument();
14+
});
15+
16+
it('should render content of Else block', () => {
17+
const { getByText } = render(
18+
<SwitchIf>
19+
<If condition={false}>If Block</If>
20+
<Else>Else Block</Else>
21+
</SwitchIf>,
22+
);
23+
expect(getByText('Else Block')).toBeInTheDocument();
24+
});
25+
26+
it('should render content of ElseIf block', () => {
27+
const { getByText } = render(
28+
<SwitchIf>
29+
<If condition={false}>If Block</If>
30+
<ElseIf condition={true}>ElseIf Block</ElseIf>
31+
<Else>Else Block</Else>
32+
</SwitchIf>,
33+
);
34+
35+
expect(getByText('ElseIf Block')).toBeInTheDocument();
36+
});
37+
38+
it('should render content of ElseIf block 2', () => {
39+
const { getByText } = render(
40+
<SwitchIf>
41+
<If condition={false}>If Block</If>
42+
<ElseIf condition={false}>ElseIf Block 1</ElseIf>
43+
<ElseIf condition={true}>ElseIf Block 2</ElseIf>
44+
<ElseIf condition={false}>ElseIf Block 3</ElseIf>
45+
<Else>Else Block</Else>
46+
</SwitchIf>,
47+
);
48+
49+
expect(getByText('ElseIf Block 2')).toBeInTheDocument();
50+
});
51+
52+
it('should render content of ElseIf block 2, even when 3rd ElseIf block condition is true', () => {
53+
const { getByText } = render(
54+
<SwitchIf>
55+
<If condition={false}>If Block</If>
56+
<ElseIf condition={false}>ElseIf Block 1</ElseIf>
57+
<ElseIf condition={true}>ElseIf Block 2</ElseIf>
58+
<ElseIf condition={true}>ElseIf Block 3</ElseIf>
59+
<ElseIf condition={false}>ElseIf Block 4</ElseIf>
60+
<Else>Else Block</Else>
61+
</SwitchIf>,
62+
);
63+
64+
expect(getByText('ElseIf Block 2')).toBeInTheDocument();
65+
});
66+
67+
it("should render an error if multiple If blocks are provided'", () => {
68+
const { getByText } = render(
69+
<SwitchIf>
70+
<If condition={true}>If Block</If>
71+
<If condition={true}>If Block</If>
72+
<Else>Else Block</Else>
73+
</SwitchIf>,
74+
);
75+
76+
expect(getByText(ERRORS[LogicErrors.InvalidIfBlockOrdinal])).toBeInTheDocument();
77+
expect(getByText(ERRORS[LogicErrors.OnlyOneIfBlockExpected])).toBeInTheDocument();
78+
});
79+
80+
it("should render an error if multiple Else blocks are provided'", () => {
81+
const { getByText } = render(
82+
<SwitchIf>
83+
<If condition={true}>If Block</If>
84+
<Else>Else Block 1</Else>
85+
<Else>Else Block 2</Else>
86+
</SwitchIf>,
87+
);
88+
89+
expect(getByText(ERRORS[LogicErrors.InvalidElseBlockOrdinal])).toBeInTheDocument();
90+
expect(getByText(ERRORS[LogicErrors.OnlyOneElseBlockExpected])).toBeInTheDocument();
91+
});
92+
93+
it('should render an error if no If, ElseIf or Else block is provided', () => {
94+
const { getByText } = render(<SwitchIf />);
95+
96+
expect(getByText(ERRORS[LogicErrors.IfBlockExpected])).toBeInTheDocument();
97+
});
98+
99+
it('should render an error if, only Else block is provided', () => {
100+
const { getByText } = render(
101+
<SwitchIf>
102+
<Else>Else Block</Else>
103+
</SwitchIf>,
104+
);
105+
106+
expect(getByText(ERRORS[LogicErrors.InvalidElseBlockOrdinal])).toBeInTheDocument();
107+
expect(getByText(ERRORS[LogicErrors.IfBlockExpected])).toBeInTheDocument();
108+
});
109+
110+
it('should render an error if, only ElseIf block is provided', () => {
111+
const { getByText } = render(
112+
<SwitchIf>
113+
<ElseIf>ElseIf Block</ElseIf>
114+
</SwitchIf>,
115+
);
116+
117+
expect(getByText(ERRORS[LogicErrors.InvalidElseIfBlockOrdinal])).toBeInTheDocument();
118+
expect(getByText(ERRORS[LogicErrors.IfBlockExpected])).toBeInTheDocument();
119+
});
120+
121+
it('should render an error if, If block is empty', () => {
122+
const { getByText } = render(
123+
<SwitchIf>
124+
<If condition={true} />
125+
</SwitchIf>,
126+
);
127+
128+
expect(getByText(ERRORS[LogicErrors.ChildrenExpected])).toBeInTheDocument();
129+
});
130+
131+
it('should render an error if, ElseIf block is empty', () => {
132+
const { getByText } = render(
133+
<SwitchIf>
134+
<If condition={false}>If Block</If>
135+
<ElseIf condition={true} />
136+
</SwitchIf>,
137+
);
138+
139+
expect(getByText(ERRORS[LogicErrors.ChildrenExpected])).toBeInTheDocument();
140+
});
141+
142+
it('should render an error if, Else block is empty', () => {
143+
const { getByText } = render(
144+
<SwitchIf>
145+
<If condition={false}>If Block</If>
146+
<Else />
147+
</SwitchIf>,
148+
);
149+
150+
expect(getByText(ERRORS[LogicErrors.ChildrenExpected])).toBeInTheDocument();
151+
});
152+
153+
it('should render an error if, if no If block is provided', () => {
154+
const { getByText } = render(
155+
<SwitchIf>
156+
<ElseIf condition={true}>ElseIf Block</ElseIf>
157+
<Else>Else Block</Else>
158+
</SwitchIf>,
159+
);
160+
161+
expect(getByText(ERRORS[LogicErrors.IfBlockExpected])).toBeInTheDocument();
162+
});
163+
164+
it('should render an error if, If block is in incorrect ordinal', () => {
165+
const { getByText } = render(
166+
<SwitchIf>
167+
<Else>Else Block</Else>
168+
<If condition={true}>If Block</If>
169+
</SwitchIf>,
170+
);
171+
172+
expect(getByText(ERRORS[LogicErrors.InvalidIfBlockOrdinal])).toBeInTheDocument();
173+
});
174+
175+
it('should render an error if, If block has a direct conditional block as a child', () => {
176+
const { getByText } = render(
177+
<SwitchIf>
178+
<If condition={true}>
179+
<If condition={true}>If Block</If>
180+
</If>
181+
<Else>Else Block</Else>
182+
</SwitchIf>,
183+
);
184+
185+
expect(getByText(ERRORS[LogicErrors.SwitchBlockExpected])).toBeInTheDocument();
186+
});
187+
188+
it('should render an error if, ElseIf block has a direct conditional block as a child', () => {
189+
const { getByText } = render(
190+
<SwitchIf>
191+
<If condition={false}>If block</If>
192+
<ElseIf condition={true}>
193+
<If condition={true}>ElseIf Block</If>
194+
</ElseIf>
195+
<Else>Else Block</Else>
196+
</SwitchIf>,
197+
);
198+
199+
expect(getByText(ERRORS[LogicErrors.SwitchBlockExpected])).toBeInTheDocument();
200+
});
201+
202+
it('should render an error if, Else block has a direct conditional block as a child', () => {
203+
const { getByText } = render(
204+
<SwitchIf>
205+
<If condition={false}>If block</If>
206+
<ElseIf condition={false}>ElseIf block</ElseIf>
207+
<Else>
208+
<Else>Else</Else>
209+
</Else>
210+
</SwitchIf>,
211+
);
212+
213+
expect(getByText(ERRORS[LogicErrors.SwitchBlockExpected])).toBeInTheDocument();
214+
});
215+
216+
it('should render an error if, SwitchIf block has other elements as children', () => {
217+
const { getByText } = render(
218+
<SwitchIf>
219+
<If condition={false}>If block</If>
220+
<ElseIf condition={false}>ElseIf block</ElseIf>
221+
<Else>Else block</Else>
222+
<div>test</div>
223+
</SwitchIf>,
224+
);
225+
226+
expect(getByText(ERRORS[LogicErrors.InvalidElement])).toBeInTheDocument();
227+
});
228+
});

src/directives/if/SwitchIf.tsx

+4-3
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
1-
import { Children, createElement, FC, memo, ReactNode } from 'react';
2-
import { useValidate } from '@hooks';
31
import { Errors } from '@components';
2+
import { useValidate } from '@hooks';
3+
import { Children, createElement, FC, ReactNode } from 'react';
44

55
const useSwitchIf = (props: SwitchProps) => {
66
const errors = useValidate<SwitchProps>(props, SwitchIf.name);
7+
78
if (errors.length) {
89
return { children: createElement(Errors, { errors }) };
910
}
@@ -32,4 +33,4 @@ const SwitchIf: FC<SwitchProps> = (props) => {
3233
return <>{children}</>;
3334
};
3435

35-
export default memo(SwitchIf);
36+
export default SwitchIf;

src/fixtures/constants.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@ export const ERRORS: Record<LogicErrors, string> = {
55
[LogicErrors.OnlyOneIfBlockExpected]: "Can only have one 'If'",
66
[LogicErrors.OnlyOneElseBlockExpected]: "Can only have one 'Else'",
77
[LogicErrors.SwitchBlockExpected]: "'If', 'ElseIf', 'Else' need to be wrapped in 'Switch'",
8-
[LogicErrors.InvalidElseBlockOrdinal]: "Invalid ordinal, 'Else' should be the last",
9-
[LogicErrors.InvalidIfBlockOrdinal]: "Invalid ordinal, 'If' block should be the first",
10-
[LogicErrors.InvalidElement]: 'Invalid element',
8+
[LogicErrors.InvalidElseBlockOrdinal]: "Invalid ordinals, 'Else' should be the last",
9+
[LogicErrors.InvalidIfBlockOrdinal]: "Invalid ordinals, 'If' block should be the first",
10+
[LogicErrors.InvalidElseIfBlockOrdinal]: "Invalid ordinals, cannot have 'ElseIf' before 'If'",
1111
[LogicErrors.ChildrenExpected]: 'Should at least have one child',
12-
[LogicErrors.InvalidElseIfBlockOrdinal]: "Cannot have 'ElseIf' before 'If'",
12+
[LogicErrors.InvalidElement]: 'Invalid element',
1313
};

src/hooks/useValidate.ts

+3-4
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
1-
import { Children, PropsWithChildren, ReactNode, useMemo } from 'react';
1+
import { Children, PropsWithChildren, ReactNode } from 'react';
22
import { ValidationFactory } from '../utils';
33

44
export const useValidate = <T extends ReactNode>(props: PropsWithChildren<T>, name: string) => {
55
const { children } = props;
6-
76
const _children = Children.toArray(children);
8-
// eslint-disable-next-line react-hooks/exhaustive-deps
9-
return useMemo(() => ValidationFactory.get(name)(_children), [_children]);
7+
8+
return ValidationFactory.get(name)(_children);
109
};

0 commit comments

Comments
 (0)