Skip to content

Commit 66ae3be

Browse files
authored
Merge pull request #47 from michaeldzjap/feature/react-testing-library
Add support for React 18 and migrate to React Testing Library
2 parents 1cf3817 + 719c8d7 commit 66ae3be

File tree

13 files changed

+3916
-2890
lines changed

13 files changed

+3916
-2890
lines changed

.eslintrc.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,14 @@
2323
"@typescript-eslint",
2424
"import",
2525
"react",
26-
"jest"
26+
"jest",
27+
"jest-dom"
2728
],
2829
"extends": [
2930
"eslint:recommended",
3031
"plugin:react/recommended",
3132
"plugin:jest/recommended",
33+
"plugin:jest-dom/recommended",
3234
"plugin:eslint-comments/recommended",
3335
"plugin:@typescript-eslint/recommended",
3436
"plugin:prettier/recommended"

__tests__/SignaturePad.test.tsx

Lines changed: 103 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import * as React from 'react';
2-
import { mount } from 'enzyme';
2+
import { act } from 'react-dom/test-utils';
3+
import { render } from '@testing-library/react';
4+
import '@testing-library/jest-dom';
35
import SigPad from 'signature_pad';
46

57
import signature from './helpers/signature';
@@ -31,49 +33,53 @@ describe('Component', () => {
3133
});
3234

3335
it('renders the component', () => {
34-
const signaturePad = mount<SignaturePad>(<SignaturePad redrawOnResize />);
36+
const { queryByTestId } = render(<SignaturePad redrawOnResize />);
3537

36-
expect(signaturePad.exists()).toBeTruthy();
38+
expect(queryByTestId('canvas-element')).toBeInTheDocument();
3739
});
3840

3941
it('loads a signature', () => {
40-
const signaturePad = mount<SignaturePad>(<SignaturePad redrawOnResize />);
41-
const instance = signaturePad.instance();
42+
const instance = React.createRef<SignaturePad>();
4243

43-
instance.clear();
44+
render(<SignaturePad ref={instance} redrawOnResize />);
4445

45-
expect(instance.isEmpty()).toBeTruthy();
46+
instance.current!.clear();
4647

47-
instance.fromDataURL(signature);
48+
expect(instance.current!.isEmpty()).toBeTruthy();
4849

49-
expect(instance.isEmpty()).toBeFalsy();
50+
instance.current!.fromDataURL(signature);
51+
52+
expect(instance.current!.isEmpty()).toBeFalsy();
5053
});
5154

5255
it('clears the signature pad', () => {
53-
const signaturePad = mount<SignaturePad>(<SignaturePad redrawOnResize />);
54-
const instance = signaturePad.instance();
56+
const instance = React.createRef<SignaturePad>();
57+
58+
render(<SignaturePad ref={instance} redrawOnResize />);
5559

56-
instance.fromDataURL(signature);
60+
instance.current!.fromDataURL(signature);
5761

58-
expect(instance.isEmpty()).toBeFalsy();
62+
expect(instance.current!.isEmpty()).toBeFalsy();
5963

60-
instance.clear();
64+
instance.current!.clear();
6165

62-
expect(instance.isEmpty()).toBeTruthy();
66+
expect(instance.current!.isEmpty()).toBeTruthy();
6367
});
6468

6569
it('returns the underlying signature pad instance', () => {
66-
const signaturePad = mount<SignaturePad>(<SignaturePad redrawOnResize />);
67-
const instance = signaturePad.instance();
70+
const instance = React.createRef<SignaturePad>();
71+
72+
render(<SignaturePad ref={instance} redrawOnResize />);
6873

69-
expect(instance.instance).toBeInstanceOf(SigPad);
74+
expect(instance.current!.instance).toBeInstanceOf(SigPad);
7075
});
7176

7277
it('returns a ref to the underlying HTML canvas element', () => {
73-
const signaturePad = mount<SignaturePad>(<SignaturePad redrawOnResize />);
74-
const instance = signaturePad.instance();
78+
const instance = React.createRef<SignaturePad>();
7579

76-
expect(instance.canvas).toBeInstanceOf(Object);
80+
render(<SignaturePad ref={instance} redrawOnResize />);
81+
82+
expect(instance.current!.canvas).toBeInstanceOf(Object);
7783
});
7884

7985
[
@@ -86,32 +92,36 @@ describe('Component', () => {
8692
{ name: 'velocity filter weight', option: 'velocityFilterWeight', expected: 1 },
8793
].forEach(({ name, option, expected }) => {
8894
it(`sets and gets the ${name}`, () => {
89-
const signaturePad = mount<SignaturePad>(<SignaturePad redrawOnResize />);
90-
const instance = signaturePad.instance();
95+
const instance = React.createRef<SignaturePad>();
96+
97+
render(<SignaturePad ref={instance} redrawOnResize />);
9198

92-
Reflect.set(instance, option, expected);
99+
Reflect.set(instance.current as SignaturePad, option, expected);
93100

94-
expect(Reflect.get(instance, option)).toBe(expected);
101+
expect(Reflect.get(instance.current as SignaturePad, option)).toBe(expected);
95102
});
96103
});
97104

98105
it('returns a signature as a data URL', () => {
99-
const signaturePad = mount<SignaturePad>(<SignaturePad redrawOnResize />);
100-
const instance = signaturePad.instance();
106+
const instance = React.createRef<SignaturePad>();
107+
108+
render(<SignaturePad ref={instance} redrawOnResize />);
101109

102-
expect(instance.toDataURL()).toContain('data:image/png;base64');
110+
expect(instance.current!.toDataURL()).toContain('data:image/png;base64');
103111
});
104112

105113
it('returns a signature as an array of data points', () => {
106-
const signaturePad = mount<SignaturePad>(<SignaturePad redrawOnResize />);
107-
const instance = signaturePad.instance();
114+
const instance = React.createRef<SignaturePad>();
108115

109-
expect(instance.toData()).toHaveLength(0);
116+
render(<SignaturePad ref={instance} redrawOnResize />);
117+
118+
expect(instance.current!.toData()).toHaveLength(0);
110119
});
111120

112121
it('draws a signature from an array of data points', () => {
113-
const signaturePad = mount<SignaturePad>(<SignaturePad redrawOnResize />);
114-
const instance = signaturePad.instance();
122+
const instance = React.createRef<SignaturePad>();
123+
124+
render(<SignaturePad ref={instance} redrawOnResize />);
115125

116126
const data = [
117127
{
@@ -123,97 +133,125 @@ describe('Component', () => {
123133
},
124134
];
125135

126-
instance.fromData(data);
136+
instance.current!.fromData(data);
127137

128-
expect(instance.toData()).toBe(data);
138+
expect(instance.current!.toData()).toStrictEqual(data);
129139
});
130140

131141
it('unbinds all event handlers', () => {
132-
const signaturePad = mount<SignaturePad>(<SignaturePad redrawOnResize />);
133-
const instance = signaturePad.instance();
134-
const spy = jest.spyOn(instance.instance, 'off');
142+
const instance = React.createRef<SignaturePad>();
143+
144+
render(<SignaturePad ref={instance} redrawOnResize />);
135145

136-
instance.off();
146+
const spy = jest.spyOn(instance.current!.instance, 'off');
147+
148+
instance.current!.off();
137149

138150
expect(spy).toHaveBeenCalled();
139151

140152
spy.mockRestore();
141153
});
142154

143155
it('rebinds all event handlers', () => {
144-
const signaturePad = mount<SignaturePad>(<SignaturePad redrawOnResize />);
145-
const instance = signaturePad.instance();
146-
const spy = jest.spyOn(instance.instance, 'on');
156+
const instance = React.createRef<SignaturePad>();
157+
158+
render(<SignaturePad ref={instance} redrawOnResize />);
159+
160+
const spy = jest.spyOn(instance.current!.instance, 'on');
147161

148-
instance.on();
162+
instance.current!.on();
149163

150164
expect(spy).toHaveBeenCalled();
151165

152166
spy.mockRestore();
153167
});
154168

155169
it('does not redraw a signature by default when the viewport dimensions change', () => {
156-
const signaturePad = mount<SignaturePad>(<SignaturePad />);
157-
const instance = signaturePad.instance();
158-
const spy = jest.spyOn(instance.instance, 'clear');
170+
const instance = React.createRef<SignaturePad>();
171+
172+
render(<SignaturePad ref={instance} />);
173+
174+
const spy = jest.spyOn(instance.current!.instance, 'clear');
159175

160176
scaleCanvas(768, 768);
161-
instance.handleResize();
177+
act(() => {
178+
instance.current!.handleResize();
179+
});
162180

163181
expect(spy).toHaveBeenCalled();
164182
});
165183

166184
it('redraws a signature when the viewport dimensions change', () => {
167-
const signaturePad = mount<SignaturePad>(<SignaturePad redrawOnResize />);
168-
const instance = signaturePad.instance();
169-
const spy = jest.spyOn(instance.instance, 'toDataURL');
185+
const instance = React.createRef<SignaturePad>();
186+
187+
render(<SignaturePad ref={instance} redrawOnResize />);
188+
189+
const spy = jest.spyOn(instance.current!.instance, 'toDataURL');
170190

171191
scaleCanvas(768, 768);
172-
instance.handleResize();
192+
act(() => {
193+
instance.current!.handleResize();
194+
});
173195

174196
expect(spy).toHaveBeenCalled();
175197
});
176198

177199
it('does not redraw a signature when the viewport dimensions have not changed', () => {
178-
const signaturePad = mount<SignaturePad>(<SignaturePad redrawOnResize />);
179-
const instance = signaturePad.instance();
180-
const spy = jest.spyOn(instance.instance, 'toDataURL');
200+
const instance = React.createRef<SignaturePad>();
181201

182-
instance.handleResize();
202+
render(<SignaturePad ref={instance} redrawOnResize />);
203+
204+
const spy = jest.spyOn(instance.current!.instance, 'toDataURL');
205+
206+
instance.current!.handleResize();
183207

184208
expect(spy).not.toHaveBeenCalled();
185209
});
186210

187211
it('does not add the resize event listener on mount', () => {
188212
const spy = jest.spyOn(window, 'addEventListener');
189-
const signaturePad = mount<SignaturePad>(<SignaturePad redrawOnResize width={512} height={512} />);
213+
const instance = React.createRef<SignaturePad>();
214+
215+
render(<SignaturePad ref={instance} redrawOnResize width={512} height={512} />);
190216

191-
expect(spy).not.toHaveBeenCalledWith('resize', Reflect.get(signaturePad.instance(), 'callResizeHandler'));
217+
expect(spy).not.toHaveBeenCalledWith(
218+
'resize',
219+
Reflect.get(instance.current as SignaturePad, 'callResizeHandler'),
220+
);
192221
});
193222

194223
it('adds the resize event listener on mount', () => {
195224
const spy = jest.spyOn(window, 'addEventListener');
196-
const signaturePad = mount<SignaturePad>(<SignaturePad />);
225+
const instance = React.createRef<SignaturePad>();
197226

198-
expect(spy).toHaveBeenCalledWith('resize', Reflect.get(signaturePad.instance(), 'callResizeHandler'));
227+
render(<SignaturePad ref={instance} />);
228+
229+
expect(spy).toHaveBeenCalledWith(
230+
'resize',
231+
Reflect.get(instance.current as SignaturePad, 'callResizeHandler'),
232+
);
199233
});
200234

201235
it('removes the resize event listener on unmount', () => {
202236
const spy = jest.spyOn(window, 'removeEventListener');
203-
const signaturePad = mount<SignaturePad>(<SignaturePad redrawOnResize />);
204-
const handler = Reflect.get(signaturePad.instance(), 'callResizeHandler');
237+
const instance = React.createRef<SignaturePad>();
238+
239+
const { unmount } = render(<SignaturePad ref={instance} redrawOnResize />);
240+
const handler = Reflect.get(instance.current as SignaturePad, 'callResizeHandler');
205241

206-
signaturePad.unmount();
242+
unmount();
207243

208244
expect(spy).toHaveBeenCalledWith('resize', handler);
209245
});
210246

211247
it('does not remove the resize event listener on unmount', () => {
212248
const spy = jest.spyOn(window, 'removeEventListener');
213-
const signaturePad = mount<SignaturePad>(<SignaturePad redrawOnResize width={512} height={512} />);
214-
const handler = Reflect.get(signaturePad.instance(), 'callResizeHandler');
249+
const instance = React.createRef<SignaturePad>();
250+
251+
const { unmount } = render(<SignaturePad ref={instance} redrawOnResize width={512} height={512} />);
252+
const handler = Reflect.get(instance.current as SignaturePad, 'callResizeHandler');
215253

216-
signaturePad.unmount();
254+
unmount();
217255

218256
expect(spy).not.toHaveBeenCalledWith('resize', handler);
219257
});

__tests__/config.ts

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

codecov.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
ignore:
2+
- "__tests__/**/*"
3+
- "example/**/*"

example/app.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import * as React from 'react';
2-
import * as ReactDOM from 'react-dom';
2+
import { createRoot } from 'react-dom/client';
33

44
import Layout from './Layout';
55

6-
ReactDOM.render(<Layout />, document.getElementById('root'));
6+
createRoot(document.getElementById('root')!).render(<Layout />);

0 commit comments

Comments
 (0)