Skip to content

Commit 7ee73a2

Browse files
authored
chore: fix tests issues for sonar (#21)
Fix issues report refactor: rename DualScrollSync to DualScrollSyncBase and update exports for clarity test: update useValidateChildren tests to use async/await for clarity and consistency test: update scrollToSectionView tests for clarity and consistency chore: update SonarQube configuration for improved source and test inclusions chore: add vitest ESLint plugin and update configuration for test files
1 parent e38b46c commit 7ee73a2

File tree

10 files changed

+5871
-2078
lines changed

10 files changed

+5871
-2078
lines changed

eslint.config.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import storybook from 'eslint-plugin-storybook';
33
import importPlugin from 'eslint-plugin-import';
44
import simpleImportSort from 'eslint-plugin-simple-import-sort';
5+
import vitestPlugin from '@vitest/eslint-plugin';
56

67
import js from '@eslint/js';
78
import globals from 'globals';
@@ -38,6 +39,18 @@ export default tseslint.config(
3839
'simple-import-sort/imports': 'error',
3940
'@typescript-eslint/consistent-type-imports': 'error'
4041
}
42+
},
43+
{
44+
files: ['**/*.test.{ts,tsx}', '**/*.spec.{ts,tsx}'],
45+
plugins: { vitest: vitestPlugin },
46+
...vitestPlugin.configs.recommended,
47+
languageOptions: {
48+
globals: {
49+
...vitestPlugin.environments.env.globals
50+
}
51+
},
52+
settings: { vitest: { typecheck: true } },
53+
rules: { 'vitest/expect-expect': 'error' }
4154
}
4255
],
4356
storybook.configs['flat/recommended']

lib/components/DualScrollSync/DualScrollSync.test.tsx

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,23 @@
11
import { render } from '@testing-library/react';
22

3-
import { DualScrollSync } from './DualScrollSync';
3+
import { DualScrollSyncBase } from './DualScrollSync';
44

55
describe('DualScrollSync', () => {
66
it('should render children correctly', () => {
77
const { getByTestId } = render(
8-
<DualScrollSync>
8+
<DualScrollSyncBase>
99
<div>Test Content</div>
10-
</DualScrollSync>
10+
</DualScrollSyncBase>
1111
);
1212

1313
expect(getByTestId('dual-scroll-sync')).toBeInTheDocument();
1414
});
1515

1616
it('should render with provided id', () => {
1717
const { getByTestId } = render(
18-
<DualScrollSync id="custom-id">
18+
<DualScrollSyncBase id="custom-id">
1919
<div>Test Content</div>
20-
</DualScrollSync>
20+
</DualScrollSyncBase>
2121
);
2222

2323
expect(getByTestId('custom-id')).toBeInTheDocument();
@@ -29,7 +29,7 @@ describe('DualScrollSync', () => {
2929
{ label: 'Item 2', sectionKey: 's2' }
3030
];
3131

32-
const { getByTestId } = render(<DualScrollSync items={items} id="test" />);
32+
const { getByTestId } = render(<DualScrollSyncBase items={items} id="test" />);
3333

3434
expect(getByTestId('test-nav-id')).toBeInTheDocument();
3535
expect(getByTestId('test-nav-id-item-s1')).toBeInTheDocument();
@@ -41,9 +41,9 @@ describe('DualScrollSync', () => {
4141

4242
it('should render children when items prop is not provided', () => {
4343
const { getByTestId, getByText } = render(
44-
<DualScrollSync id="test">
44+
<DualScrollSyncBase id="test">
4545
<h1 data-testid="child-heading">Child Heading</h1>
46-
</DualScrollSync>
46+
</DualScrollSyncBase>
4747
);
4848

4949
expect(getByTestId('test')).toBeInTheDocument();

lib/components/DualScrollSync/DualScrollSync.tsx

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,19 @@ import { DualScrollSyncContext } from '@/contexts';
66
import { useScrollSyncObserver, useValidateChildren } from '@/hooks';
77

88
import styles from './DualScrollSync.module.scss';
9-
import type { DualScrollSyncProps } from './DualScrollSync.types';
9+
import type { DualScrollSyncProps, DualScrollSyncType } from './DualScrollSync.types';
1010
import { DualScrollSyncContent } from './DualScrollSyncContent';
1111
import { DualScrollSyncContentSection } from './DualScrollSyncContentSection/DualScrollSyncContentSection';
1212
import { DualScrollSyncLabel } from './DualScrollSyncLabel/DualScrollSyncLabel';
1313
import { DualScrollSyncNav } from './DualScrollSyncNav';
1414
import { DualScrollSyncNavItem } from './DualScrollSyncNavItem';
1515

16-
export const DualScrollSync: FC<DualScrollSyncProps> = ({ children, id, items, onItemClick }) => {
16+
export const DualScrollSyncBase: FC<DualScrollSyncProps> = ({
17+
children,
18+
id,
19+
items,
20+
onItemClick
21+
}) => {
1722
const baseId = id ?? 'dual-scroll-sync';
1823
const navId = `${baseId}-nav`;
1924
const contentId = `${baseId}-content`;
@@ -80,4 +85,12 @@ export const DualScrollSync: FC<DualScrollSyncProps> = ({ children, id, items, o
8085
);
8186
};
8287

83-
DualScrollSync.displayName = 'DualScrollSync';
88+
DualScrollSyncBase.displayName = 'DualScrollSync';
89+
90+
export const DualScrollSync: DualScrollSyncType = Object.assign(DualScrollSyncBase, {
91+
Nav: DualScrollSyncNav,
92+
NavItem: DualScrollSyncNavItem,
93+
Content: DualScrollSyncContent,
94+
ContentSection: DualScrollSyncContentSection,
95+
Label: DualScrollSyncLabel
96+
});
Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,6 @@
1-
import { DualScrollSync as DualScrollSyncBase } from './DualScrollSync';
2-
import type { DualScrollSyncType } from './DualScrollSync.types';
3-
import { DualScrollSyncContent } from './DualScrollSyncContent';
4-
import { DualScrollSyncContentSection } from './DualScrollSyncContentSection/DualScrollSyncContentSection';
5-
import { DualScrollSyncLabel } from './DualScrollSyncLabel';
6-
import { DualScrollSyncNav } from './DualScrollSyncNav';
7-
import { DualScrollSyncNavItem } from './DualScrollSyncNavItem';
8-
1+
export { DualScrollSync } from './DualScrollSync';
92
export type { DualScrollSyncItem, DualScrollSyncProps } from './DualScrollSync.types';
103
export type * from './DualScrollSyncContent';
114
export type * from './DualScrollSyncContentSection';
125
export type * from './DualScrollSyncNav';
136
export type * from './DualScrollSyncNavItem';
14-
15-
export const DualScrollSync: DualScrollSyncType = Object.assign(DualScrollSyncBase, {
16-
Nav: DualScrollSyncNav,
17-
NavItem: DualScrollSyncNavItem,
18-
Content: DualScrollSyncContent,
19-
ContentSection: DualScrollSyncContentSection,
20-
Label: DualScrollSyncLabel
21-
});

lib/hooks/useValidateChildren.test.tsx

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { renderHook, waitFor } from '@testing-library/react';
2-
import type { FC } from 'react';
2+
import { act, type FC } from 'react';
33
import { vi } from 'vitest';
44

55
import { DualScrollSyncContent } from '@/components/DualScrollSync/DualScrollSyncContent';
@@ -22,17 +22,20 @@ describe('useValidateChildren', () => {
2222
warnSpy.mockRestore();
2323
});
2424

25-
it('should not log warnings when items prop is provided', () => {
25+
it('should not log warnings when items prop is provided', async () => {
2626
const items = [
2727
{ sectionKey: 'section1', label: 'Section 1', children: <div>Content 1</div> },
2828
{ sectionKey: 'section2', label: 'Section 2', children: <div>Content 2</div> }
2929
];
3030

31-
renderHook(() => useValidateChildren({ items, children: null }));
32-
expect(warnSpy).not.toHaveBeenCalled();
31+
act(() => renderHook(() => useValidateChildren({ items, children: null })));
32+
33+
await waitFor(() => {
34+
expect(warnSpy).toHaveBeenCalledTimes(0);
35+
});
3336
});
3437

35-
it('should not log warnings when NavItems and ContentSections match', () => {
38+
it('should not log warnings when NavItems and ContentSections match', async () => {
3639
const children = (
3740
<>
3841
<DualScrollSyncNav>
@@ -46,8 +49,11 @@ describe('useValidateChildren', () => {
4649
</>
4750
);
4851

49-
renderHook(() => useValidateChildren({ children, items: undefined }));
50-
expect(warnSpy).not.toHaveBeenCalled();
52+
act(() => renderHook(() => useValidateChildren({ children, items: undefined })));
53+
54+
await waitFor(() => {
55+
expect(warnSpy).toHaveBeenCalledTimes(0);
56+
});
5157
});
5258

5359
it('should log warnings for missing ContentSections', async () => {
@@ -63,7 +69,7 @@ describe('useValidateChildren', () => {
6369
</>
6470
);
6571

66-
renderHook(() => useValidateChildren({ children, items: undefined }));
72+
act(() => renderHook(() => useValidateChildren({ children, items: undefined })));
6773

6874
await waitFor(() => {
6975
expect(warnSpy).toHaveBeenCalledWith(
@@ -85,7 +91,7 @@ describe('useValidateChildren', () => {
8591
</>
8692
);
8793

88-
renderHook(() => useValidateChildren({ children, items: undefined }));
94+
act(() => renderHook(() => useValidateChildren({ children, items: undefined })));
8995

9096
await waitFor(() => {
9197
expect(warnSpy).toHaveBeenCalledWith('[DualScrollSync] Missing NavItem for "section2"');
@@ -107,7 +113,7 @@ describe('useValidateChildren', () => {
107113
</div>
108114
);
109115

110-
renderHook(() => useValidateChildren({ children, items: undefined }));
116+
act(() => renderHook(() => useValidateChildren({ children, items: undefined })));
111117

112118
await waitFor(() => {
113119
expect(warnSpy).toHaveBeenCalledWith(
@@ -116,10 +122,13 @@ describe('useValidateChildren', () => {
116122
});
117123
});
118124

119-
it('should not log warnings for string children', () => {
125+
it('should not log warnings for string children', async () => {
120126
const children = <span>Hello World</span>;
121127

122-
renderHook(() => useValidateChildren({ children, items: undefined }));
123-
expect(warnSpy).not.toHaveBeenCalled();
128+
act(() => renderHook(() => useValidateChildren({ children, items: undefined })));
129+
130+
await waitFor(() => {
131+
expect(warnSpy).toHaveBeenCalledTimes(0);
132+
});
124133
});
125134
});

lib/utils/scrollToSectionView.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,12 @@ describe('scrollToSectionView', () => {
4141

4242
it("should' not scroll if container is null", () => {
4343
scrollToSectionView(null, target);
44-
expect(container.scrollTo).not.toHaveBeenCalled();
44+
expect(container.scrollTo).toHaveBeenCalledTimes(0);
4545
});
4646

4747
it("should' not scroll if target is null", () => {
4848
scrollToSectionView(container, null);
49-
expect(container.scrollTo).not.toHaveBeenCalled();
49+
expect(container.scrollTo).toHaveBeenCalledTimes(0);
5050
});
5151

5252
it('should calculate scrollTop correctly and call scrollTo', () => {

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@
6767
"@vitejs/plugin-react-swc": "^4.0.0",
6868
"@vitest/browser": "^3.2.4",
6969
"@vitest/coverage-v8": "^3.2.4",
70+
"@vitest/eslint-plugin": "^1.3.8",
7071
"chromatic": "^13.1.3",
7172
"conventional-changelog-cli": "^5.0.0",
7273
"conventional-changelog-conventionalcommits": "^9.1.0",

0 commit comments

Comments
 (0)