Skip to content

Commit 5b0a352

Browse files
author
Daniel A. White
committed
use vitest
1 parent b674882 commit 5b0a352

File tree

9 files changed

+803
-1266
lines changed

9 files changed

+803
-1266
lines changed

.eslintrc

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,5 @@
1212
"@typescript-eslint/prefer-optional-chain": "error",
1313
"@typescript-eslint/no-floating-promises": ["error", { "ignoreVoid": true }],
1414
"no-console": "warn"
15-
},
16-
"overrides": [
17-
{
18-
"files": ["*.spec.{ts,tsx}"],
19-
"env": {
20-
"jest": true
21-
}
22-
}
23-
]
15+
}
2416
}

jest.config.js

Lines changed: 0 additions & 21 deletions
This file was deleted.

package.json

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,10 @@
3030
"release.docs": "sl-scripts release:docs",
3131
"release.dryRun": "sl-scripts release --dry-run --debug",
3232
"storybook": "start-storybook -p 6006",
33-
"test": "jest",
34-
"test.prod": "yarn lint && yarn test --coverage --maxWorkers=2",
35-
"test.update": "yarn test --updateSnapshot",
36-
"test.watch": "yarn test --watch",
33+
"test": "vitest run",
34+
"test.prod": "yarn lint && yarn vitest run --coverage",
35+
"test.update": "yarn vitest run --updateSnapshot",
36+
"test.watch": "yarn vitest",
3737
"test.packaging": "node -e \"require('./dist/index.js')\" && node --input-type=module -e \"import './dist/index.mjs'\"",
3838
"size-limit": "size-limit"
3939
},
@@ -68,44 +68,42 @@
6868
"@storybook/core": "^6.5.0",
6969
"@storybook/manager-webpack5": "^6.5.0",
7070
"@storybook/react": "^6.5.0",
71+
"@testing-library/jest-dom": "^6.4.6",
72+
"@testing-library/react": "^12.0.0",
7173
"@types/classnames": "^2.2.11",
7274
"@types/enzyme": "^3.10.8",
73-
"@types/jest": "^29.5.12",
7475
"@types/lodash": "^4.14.149",
7576
"@types/node": "^12.7.2",
7677
"@types/react": "^16.14.0",
7778
"@types/react-dom": "^16.9.0",
7879
"@types/treeify": "^1.0.0",
7980
"@typescript-eslint/eslint-plugin": "^5.7.0",
8081
"@typescript-eslint/parser": "^5.7.0",
81-
"babel-jest": "^26.6.3",
82+
"@vitejs/plugin-react": "^4.3.1",
83+
"@vitest/ui": "^1.6.0",
8284
"babel-loader": "^8.2.2",
8385
"copyfiles": "^2.4.1",
8486
"enzyme": "^3.11.0",
8587
"enzyme-adapter-react-16": "^1.15.5",
8688
"enzyme-to-json": "^3.6.1",
8789
"eslint": "^8.4.1",
8890
"eslint-plugin-import": "^2.25.3",
89-
"eslint-plugin-jest": "^25.3.0",
9091
"eslint-plugin-prettier": "^5.1.3",
9192
"eslint-plugin-react": "^7.27.1",
9293
"eslint-plugin-react-hooks": "^4.3.0",
9394
"eslint-plugin-simple-import-sort": "^7.0.0",
94-
"jest": "^29.7.0",
95-
"jest-enzyme": "^7.1.2",
95+
"jsdom": "^24.1.0",
9696
"prettier": "^3.2.2",
9797
"react": "^16.14.0",
9898
"react-docgen-typescript-plugin": "^1.0.6",
9999
"react-dom": "^16.14.0",
100100
"size-limit": "^4.11.0",
101101
"treeify": "^1.1.0",
102-
"ts-jest": "^29.1.4",
103102
"typescript": "5.4.5",
103+
"vite": "^5.3.1",
104+
"vitest": "^1.6.0",
104105
"webpack": "^5.67.0"
105106
},
106-
"resolutions": {
107-
"jest-environment-jsdom": "^29.7.0"
108-
},
109107
"lint-staged": {
110108
"*.{ts,tsx}$": [
111109
"yarn lint.fix"

setupTests.ts

Lines changed: 0 additions & 17 deletions
This file was deleted.

src/components/JsonSchemaViewer.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ const JsonSchemaViewerInner = ({
146146
);
147147
if (isEmpty) {
148148
return (
149-
<Box className={cn(className, 'JsonSchemaViewer')} fontSize="sm">
149+
<Box className={cn(className, 'JsonSchemaViewer')} fontSize="sm" data-test="empty-text">
150150
{emptyText}
151151
</Box>
152152
);

src/components/__tests__/SchemaRow.spec.tsx

Lines changed: 38 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
1-
import 'jest-enzyme';
1+
import '@testing-library/jest-dom';
22

33
import { RootNode } from '@stoplight/json-schema-tree';
4-
import { Icon } from '@stoplight/mosaic';
5-
import { mount } from 'enzyme';
4+
import { render } from '@testing-library/react';
65
import { JSONSchema4 } from 'json-schema';
76
import * as React from 'react';
7+
import { beforeEach, describe, expect, it } from 'vitest';
88

99
import { SchemaRow } from '../SchemaRow';
1010
import { buildTree, findNodeWithPath } from '../shared/__tests__/utils';
11-
import { Properties } from '../shared/Properties';
1211

1312
describe('SchemaRow component', () => {
1413
describe('resolving error', () => {
@@ -28,13 +27,12 @@ describe('SchemaRow component', () => {
2827
tree = buildTree(schema);
2928
});
3029

31-
it('given no custom resolver, should render a generic error message', () => {
32-
const wrapper = mount(<SchemaRow schemaNode={tree.children[0]!} nestingLevel={0} />);
33-
expect(wrapper.find(Icon).at(1)).toHaveProp('aria-label', `Could not resolve '#/properties/foo'`);
34-
wrapper.unmount();
30+
it('given no custom resolver, should render a generic error message', async () => {
31+
const wrapper = render(<SchemaRow schemaNode={tree.children[0]!} nestingLevel={0} />);
32+
expect(await wrapper.findByLabelText(`Could not resolve '#/properties/foo'`)).toBeInTheDocument();
3533
});
3634

37-
it('given a custom resolver, should render a message thrown by it', () => {
35+
it('given a custom resolver, should render a message thrown by it', async () => {
3836
const message = "I don't know how to resolve it. Sorry";
3937

4038
tree = buildTree(schema, {
@@ -43,77 +41,71 @@ describe('SchemaRow component', () => {
4341
},
4442
});
4543

46-
const wrapper = mount(<SchemaRow schemaNode={tree.children[0]!} nestingLevel={0} />);
47-
expect(wrapper.find(Icon).at(1)).toHaveProp('aria-label', message);
48-
wrapper.unmount();
44+
const wrapper = render(<SchemaRow schemaNode={tree.children[0]!} nestingLevel={0} />);
45+
expect(await wrapper.findByLabelText(message)).toBeInTheDocument();
4946
});
5047
});
5148

5249
describe('resolving permission error', () => {
5350
let tree: RootNode;
5451
let schema: JSONSchema4;
5552

56-
it('given an object schema is marked as internal, a permission denied error message should be shown', () => {
53+
it('given an object schema is marked as internal, a permission denied error message should be shown', async () => {
5754
schema = {
5855
type: 'object',
5956
'x-sl-internally-excluded': true,
6057
'x-sl-error-message': 'You do not have permission to view this reference',
6158
};
6259
tree = buildTree(schema);
63-
const wrapper = mount(<SchemaRow schemaNode={tree.children[0]!} nestingLevel={0} />);
64-
expect(wrapper.find(Icon).at(0)).toHaveProp('aria-label', `You do not have permission to view this reference`);
65-
wrapper.unmount();
60+
const wrapper = render(<SchemaRow schemaNode={tree.children[0]!} nestingLevel={0} />);
61+
expect(await wrapper.findByLabelText(`You do not have permission to view this reference`)).toBeInTheDocument();
6662
});
6763

68-
it('given a number schema is marked as internal, a permission denied error messsage should be shown', () => {
64+
it('given a number schema is marked as internal, a permission denied error messsage should be shown', async () => {
6965
schema = {
7066
type: 'number',
7167
'x-sl-internally-excluded': true,
7268
'x-sl-error-message': 'You do not have permission to view this reference',
7369
};
7470
tree = buildTree(schema);
75-
const wrapper = mount(<SchemaRow schemaNode={tree.children[0]!} nestingLevel={0} />);
76-
expect(wrapper.find(Icon).at(0)).toHaveProp('aria-label', `You do not have permission to view this reference`);
77-
wrapper.unmount();
71+
const wrapper = render(<SchemaRow schemaNode={tree.children[0]!} nestingLevel={0} />);
72+
expect(await wrapper.findByLabelText(`You do not have permission to view this reference`)).toBeInTheDocument();
7873
});
7974

80-
it('given an integer schema is marked as internal, a permission denied error messsage should be shown', () => {
75+
it('given an integer schema is marked as internal, a permission denied error messsage should be shown', async () => {
8176
schema = {
8277
type: 'integer',
8378
'x-sl-internally-excluded': true,
8479
'x-sl-error-message': 'You do not have permission to view this reference',
8580
};
8681
tree = buildTree(schema);
87-
const wrapper = mount(<SchemaRow schemaNode={tree.children[0]!} nestingLevel={0} />);
88-
expect(wrapper.find(Icon).at(0)).toHaveProp('aria-label', `You do not have permission to view this reference`);
89-
wrapper.unmount();
82+
const wrapper = render(<SchemaRow schemaNode={tree.children[0]!} nestingLevel={0} />);
83+
expect(await wrapper.findByLabelText(`You do not have permission to view this reference`)).toBeInTheDocument();
9084
});
9185

92-
it('given a string schema is marked as internal, a permission denied error messsage should be shown', () => {
86+
it('given a string schema is marked as internal, a permission denied error messsage should be shown', async () => {
9387
schema = {
9488
type: 'string',
9589
'x-sl-internally-excluded': true,
9690
'x-sl-error-message': 'You do not have permission to view this reference',
9791
};
9892
tree = buildTree(schema);
99-
const wrapper = mount(<SchemaRow schemaNode={tree.children[0]!} nestingLevel={0} />);
100-
expect(wrapper.find(Icon).at(0)).toHaveProp('aria-label', `You do not have permission to view this reference`);
101-
wrapper.unmount();
93+
const wrapper = render(<SchemaRow schemaNode={tree.children[0]!} nestingLevel={0} />);
94+
expect(await wrapper.findByLabelText(`You do not have permission to view this reference`)).toBeInTheDocument();
10295
});
10396

104-
it('given a boolean schema is marked as internal, a permission denied error messsage should be shown', () => {
97+
it('given a boolean schema is marked as internal, a permission denied error messsage should be shown', async () => {
10598
schema = {
10699
type: 'boolean',
107100
'x-sl-internally-excluded': true,
108101
'x-sl-error-message': 'You do not have permission to view this reference',
109102
};
110103
tree = buildTree(schema);
111-
const wrapper = mount(<SchemaRow schemaNode={tree.children[0]!} nestingLevel={0} />);
112-
expect(wrapper.find(Icon).at(0)).toHaveProp('aria-label', `You do not have permission to view this reference`);
113-
wrapper.unmount();
104+
const wrapper = render(<SchemaRow schemaNode={tree.children[0]!} nestingLevel={0} />);
105+
expect(await wrapper.findByLabelText(`You do not have permission to view this reference`)).toBeInTheDocument();
114106
});
115107

116-
it('given an array schema is marked as internal, a permission denied error messsage should be shown', () => {
108+
it('given an array schema is marked as internal, a permission denied error messsage should be shown', async () => {
117109
schema = {
118110
title: 'test',
119111
type: 'array',
@@ -124,9 +116,8 @@ describe('SchemaRow component', () => {
124116
},
125117
};
126118
tree = buildTree(schema);
127-
const wrapper = mount(<SchemaRow schemaNode={tree.children[0]!} nestingLevel={0} />);
128-
expect(wrapper.find(Icon).at(0)).toHaveProp('aria-label', `You do not have permission to view this reference`);
129-
wrapper.unmount();
119+
const wrapper = render(<SchemaRow schemaNode={tree.children[0]!} nestingLevel={0} />);
120+
expect(await wrapper.findByLabelText(`You do not have permission to view this reference`)).toBeInTheDocument();
130121
});
131122
});
132123

@@ -140,9 +131,13 @@ describe('SchemaRow component', () => {
140131
if (!schemaNode) {
141132
throw Error('Node not found, invalid configuration');
142133
}
143-
const wrapper = mount(<SchemaRow schemaNode={schemaNode} nestingLevel={0} />);
144-
expect(wrapper.find(Properties)).toHaveProp('required', value);
145-
wrapper.unmount();
134+
const wrapper = render(<SchemaRow schemaNode={schemaNode} nestingLevel={0} />);
135+
const requiredEl = wrapper.queryByTestId('property-required');
136+
if (value) {
137+
expect(requiredEl).toBeInTheDocument();
138+
} else {
139+
expect(requiredEl).not.toBeInTheDocument();
140+
}
146141
}
147142

148143
beforeEach(() => {
@@ -276,17 +271,16 @@ describe('SchemaRow component', () => {
276271
};
277272
});
278273

279-
it('should render correct type name for binary type', () => {
274+
it('should render correct type name for binary type', async () => {
280275
const tree = buildTree(schema);
281276

282277
const schemaNode = findNodeWithPath(tree, ['properties', 'profile_photo']);
283278
if (!schemaNode) {
284279
throw Error('Node not found, invalid configuration');
285280
}
286-
const wrapper = mount(<SchemaRow schemaNode={schemaNode} nestingLevel={0} />);
287-
const spanWrapper = wrapper.find({ 'data-test': 'property-type' });
288-
expect(spanWrapper.at(0).text()).toContain('string<binary>');
289-
wrapper.unmount();
281+
const wrapper = render(<SchemaRow schemaNode={schemaNode} nestingLevel={0} />);
282+
const spanWrapper = await wrapper.findByTestId('property-type');
283+
expect(spanWrapper).toHaveTextContent('string<binary>');
290284
});
291285
});
292286
});

vite.config.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import {defineConfig} from 'vitest/config';
2+
import react from '@vitejs/plugin-react';
3+
4+
export default defineConfig({
5+
plugins: [react()],
6+
test: {
7+
environment: 'jsdom',
8+
setupFiles: './vitest.setup.ts',
9+
},
10+
})

vitest.setup.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import '@testing-library/jest-dom/vitest';
2+
3+
import { cleanup, configure } from '@testing-library/react';
4+
import { afterEach, expect, vitest } from 'vitest';
5+
6+
// @ts-ignore
7+
global.expect = expect;
8+
9+
configure({ testIdAttribute: 'data-test' });
10+
11+
afterEach(() => {
12+
cleanup();
13+
});
14+
15+
const observe = vitest.fn();
16+
const unobserve = vitest.fn();
17+
const disconnect = vitest.fn();
18+
19+
// @ts-ignore
20+
window.IntersectionObserver = vitest.fn(() => ({
21+
observe,
22+
unobserve,
23+
disconnect,
24+
}));

0 commit comments

Comments
 (0)