diff --git a/packages/eui/src/services/accessibility/html_id_generator.test.tsx b/packages/eui/src/services/accessibility/html_id_generator.test.tsx
index 56dfe712a8b..ca57d17aa8d 100644
--- a/packages/eui/src/services/accessibility/html_id_generator.test.tsx
+++ b/packages/eui/src/services/accessibility/html_id_generator.test.tsx
@@ -7,12 +7,11 @@
*/
import React, { FunctionComponent } from 'react';
-import { shallow } from 'enzyme';
import * as uuid from 'uuid';
-import { render } from '../../test/rtl';
+import { render, renderHook } from '../../test/rtl';
+import { testOnReactVersion } from '../../test/internal';
import { htmlIdGenerator, useGeneratedHtmlId } from './html_id_generator';
-import { testOnReactVersion } from '../../test/internal';
const originalUuid = jest.requireActual('uuid');
jest.mock('uuid');
@@ -65,41 +64,38 @@ describe('htmlIdGenerator', () => {
describe('useGeneratedHtmlId', () => {
it('does not change when a component updates', () => {
- const MockComponent: React.FC = (props) => (
+ const MockComponent: React.FC<{ className?: string }> = (props) => (
);
- const component = shallow();
- const initialId = component.find('div').prop('id');
+ const { container, rerender } = render();
+ const initialId = container.firstElementChild!.id;
- component.setProps({ className: 'test' });
- const rerenderedId = component.find('div').prop('id');
+ rerender();
+ const rerenderedId = container.firstElementChild!.id;
expect(initialId).toEqual(rerenderedId);
});
it('passes prefixes and suffixes to htmlIdGenerator', () => {
- const MockComponent: React.FC = () => (
-
+ const { result } = renderHook(() =>
+ useGeneratedHtmlId({ prefix: 'hello', suffix: 'world' })
);
- const component = shallow();
- const id = component.find('div').prop('id');
- expect(id!.startsWith('hello')).toBeTruthy();
- expect(id!.endsWith('world')).toBeTruthy();
+ expect(result.current.startsWith('hello')).toBeTruthy();
+ expect(result.current.endsWith('world')).toBeTruthy();
});
it('allows overriding generated IDs with conditional IDs (typically from props)', () => {
- const MockComponent: React.FC<{ id?: string }> = ({ id, ...props }) => (
-
- );
- const component = shallow();
- expect(component.find('div').prop('id')).toEqual('hello');
+ const { result, rerender } = renderHook(useGeneratedHtmlId, {
+ initialProps: { conditionalId: 'hello' },
+ });
+ expect(result.current).toEqual('hello');
- component.setProps({ id: 'world' });
- expect(component.find('div').prop('id')).toEqual('world');
+ rerender({ conditionalId: 'world' });
+ expect(result.current).toEqual('world');
- component.setProps({ id: undefined });
- expect(component.find('div').prop('id')).toBeTruthy(); // Should fall back to a generated ID
+ rerender({ conditionalId: undefined });
+ expect(result.current).toBeTruthy(); // Should fall back to a generated ID
});
describe('version-specific tests', () => {
@@ -119,7 +115,7 @@ describe('useGeneratedHtmlId', () => {
testOnReactVersion('18')('[React 18] generates correct IDs', () => {
const { getByTestSubject } = render();
- expect(getByTestSubject('el')).toHaveAttribute('id', 'prefix:r0:suffix');
+ expect(getByTestSubject('el')).toHaveAttribute('id', 'prefix:r3:suffix');
});
testOnReactVersion(['16', '17'])(
diff --git a/packages/eui/src/services/hooks/useDependentState.test.tsx b/packages/eui/src/services/hooks/useDependentState.test.tsx
index 1e8ed9b7109..8782068f93f 100644
--- a/packages/eui/src/services/hooks/useDependentState.test.tsx
+++ b/packages/eui/src/services/hooks/useDependentState.test.tsx
@@ -6,8 +6,8 @@
* Side Public License, v 1.
*/
-import React from 'react';
-import { mount } from 'enzyme';
+import { renderHook } from '../../test/rtl';
+
import { useDependentState } from './useDependentState';
describe('useDependentState', () => {
@@ -19,25 +19,20 @@ describe('useDependentState', () => {
return sourceValue * 2;
});
- function Foo() {
- const [value] = useDependentState(doubler, [sourceValue]);
-
- return {value}
;
- }
-
- // mount the component verify the state function was called with no previous state value
- const component = mount();
+ const { result, rerender } = renderHook(() =>
+ useDependentState(doubler, [sourceValue])
+ );
expect(doubler).toHaveBeenCalledTimes(1);
expect(doubler).toHaveBeenCalledWith();
- expect(component.text()).toBe('4'); // 2 * 2
+ expect(result.current[0]).toEqual(4); // 2 * 2
doubler.mockClear();
// update the source value, force a re-render, and run checks
sourceValue = 4;
- component.setProps({});
+ rerender();
expect(doubler).toHaveBeenCalledTimes(1);
expect(doubler).toHaveBeenCalledWith(4); // check previous state value
- expect(component.text()).toBe('8'); // new value should be 4 * 2
+ expect(result.current[0]).toEqual(8); // new value should be 4 * 2
});
});
diff --git a/packages/eui/src/services/hooks/useForceRender.test.tsx b/packages/eui/src/services/hooks/useForceRender.test.tsx
index 1f6b10e56a6..1b8257f9efb 100644
--- a/packages/eui/src/services/hooks/useForceRender.test.tsx
+++ b/packages/eui/src/services/hooks/useForceRender.test.tsx
@@ -7,8 +7,8 @@
*/
import React, { useImperativeHandle, createRef, forwardRef } from 'react';
-import { act } from '@testing-library/react';
-import { mount } from 'enzyme';
+import { render, act } from '@testing-library/react';
+
import { useForceRender } from './useForceRender';
interface MockRefShape {
@@ -36,7 +36,7 @@ describe('useForceRender', () => {
it('causes the component to re-render', () => {
const ref = createRef();
- mount();
+ render();
expect(renderTracker).toHaveBeenCalledTimes(1);
act(() => {
diff --git a/packages/eui/src/services/hooks/useLatest.test.tsx b/packages/eui/src/services/hooks/useLatest.test.tsx
index d4d5b62b87d..2a2e0c4216e 100644
--- a/packages/eui/src/services/hooks/useLatest.test.tsx
+++ b/packages/eui/src/services/hooks/useLatest.test.tsx
@@ -6,8 +6,9 @@
* Side Public License, v 1.
*/
-import { mount } from 'enzyme';
import React, { MutableRefObject, useEffect } from 'react';
+import { render } from '@testing-library/react';
+
import { useLatest } from './useLatest';
describe('useLatest', () => {
@@ -22,21 +23,16 @@ describe('useLatest', () => {
it('updates the ref value but not the ref identity on render', () => {
const onRefChange = jest.fn();
const onRefCurrentValueChange = jest.fn();
+ const props = { onRefChange, onRefCurrentValueChange };
- const wrapper = mount(
-
- );
+ const { rerender } = render();
expect(onRefChange).toHaveBeenCalledTimes(1);
expect(onRefChange).toHaveBeenLastCalledWith({ current: 'first' });
expect(onRefCurrentValueChange).toHaveBeenCalledTimes(1);
expect(onRefCurrentValueChange).toHaveBeenLastCalledWith('first');
- wrapper.setProps({ value: 'second' });
+ rerender();
expect(onRefChange).toHaveBeenCalledTimes(1); // the ref's identity has not changed
expect(onRefCurrentValueChange).toHaveBeenCalledTimes(2);
diff --git a/packages/eui/src/services/hooks/useUpdateEffect.test.tsx b/packages/eui/src/services/hooks/useUpdateEffect.test.tsx
index 2599918629c..b415cfca174 100644
--- a/packages/eui/src/services/hooks/useUpdateEffect.test.tsx
+++ b/packages/eui/src/services/hooks/useUpdateEffect.test.tsx
@@ -7,7 +7,8 @@
*/
import React from 'react';
-import { mount } from 'enzyme';
+import { render } from '@testing-library/react';
+
import { useUpdateEffect } from './useUpdateEffect';
describe('useUpdateEffect', () => {
@@ -28,31 +29,31 @@ describe('useUpdateEffect', () => {
});
it('does not invoke the passed effect on initial mount', () => {
- mount();
+ render();
expect(mockEffect).not.toHaveBeenCalled();
});
it('invokes the passed effect on each component update/rerender', () => {
- const component = mount();
+ const { rerender } = render();
- component.setProps({ test: true });
+ rerender();
expect(mockEffect).toHaveBeenCalledTimes(1);
- component.setProps({ test: false });
+ rerender();
expect(mockEffect).toHaveBeenCalledTimes(2);
- component.setProps({ test: true });
+ rerender();
expect(mockEffect).toHaveBeenCalledTimes(3);
});
it('invokes returned cleanup, same as useEffect', () => {
- const component = mount();
+ const { rerender, unmount } = render();
- component.setProps({ test: true }); // Trigger first update/call
+ rerender(); // Trigger first update/call
expect(mockCleanup).not.toHaveBeenCalled();
- component.unmount(); // Trigger cleanup
+ unmount(); // Trigger cleanup
expect(mockCleanup).toHaveBeenCalled();
});
});
diff --git a/packages/eui/src/services/window_event/window_event.test.tsx b/packages/eui/src/services/window_event/window_event.test.tsx
index 8eef6f17cb5..41e74d637a4 100644
--- a/packages/eui/src/services/window_event/window_event.test.tsx
+++ b/packages/eui/src/services/window_event/window_event.test.tsx
@@ -7,61 +7,81 @@
*/
import React from 'react';
-import { shallow } from 'enzyme';
+import { render } from '@testing-library/react';
+
import { EuiWindowEvent } from './window_event';
describe('EuiWindowEvent', () => {
+ let windowAddCount = 0;
+ let windowRemoveCount = 0;
+
+ beforeAll(() => {
+ // React 16 and 17 register a bunch of error listeners which we don't need to capture
+ window.addEventListener = jest.fn((event: string) => {
+ if (event !== 'error') windowAddCount++;
+ });
+ window.removeEventListener = jest.fn((event: string) => {
+ if (event !== 'error') windowRemoveCount++;
+ });
+ });
+
beforeEach(() => {
- window.addEventListener = jest.fn();
- window.removeEventListener = jest.fn();
+ // Reset counts
+ windowAddCount = 0;
+ windowRemoveCount = 0;
});
- afterEach(() => {
+ afterAll(() => {
jest.restoreAllMocks();
});
test('attaches handler to window event on mount', () => {
const handler = () => null;
- shallow();
- expect(window.addEventListener).toHaveBeenCalledTimes(1);
+ render();
expect(window.addEventListener).toHaveBeenCalledWith('click', handler);
+ expect(windowAddCount).toEqual(1);
});
test('removes handler on unmount', () => {
const handler = () => null;
- const wrapper = shallow();
- wrapper.unmount();
- expect(window.removeEventListener).toHaveBeenLastCalledWith(
- 'click',
- handler
+ const { unmount } = render(
+
);
+ unmount();
+ expect(window.removeEventListener).toHaveBeenCalledWith('click', handler);
+ expect(windowRemoveCount).toEqual(1);
});
test('removes and re-attaches handler to window event on update', () => {
const handler1 = () => null;
const handler2 = () => null;
- const wrapper = shallow(
+ const { rerender } = render(
);
- expect(window.addEventListener).toHaveBeenLastCalledWith('click', handler1);
+ expect(window.addEventListener).toHaveBeenCalledWith('click', handler1);
- wrapper.setProps({ event: 'hover', handler: handler2 });
+ rerender();
- expect(window.removeEventListener).toHaveBeenLastCalledWith(
- 'click',
- handler1
- );
- expect(window.addEventListener).toHaveBeenLastCalledWith('hover', handler2);
+ expect(window.removeEventListener).toHaveBeenCalledWith('click', handler1);
+ expect(window.addEventListener).toHaveBeenCalledWith('keydown', handler2);
});
test('does not remove or re-attach handler if update is irrelevant', () => {
const handler = () => null;
- const wrapper = shallow();
- expect(window.addEventListener).toHaveBeenCalledTimes(1);
+ const { rerender } = render(
+
+ );
+ expect(windowAddCount).toEqual(1);
- wrapper.setProps({ whatever: 'ugh' });
- expect(window.addEventListener).toHaveBeenCalledTimes(1);
- expect(window.removeEventListener).not.toHaveBeenCalled();
+ rerender(
+
+ );
+ expect(windowAddCount).toEqual(1);
+ expect(windowRemoveCount).toEqual(0);
});
});