diff --git a/packages/react-native-editor/src/test/index.test.js b/packages/react-native-editor/src/test/index.test.js index 223f4247a40695..14677da186fe2b 100644 --- a/packages/react-native-editor/src/test/index.test.js +++ b/packages/react-native-editor/src/test/index.test.js @@ -1,13 +1,14 @@ /** * External dependencies */ -import { AppRegistry, Text } from 'react-native'; -import { render, waitFor } from 'test/helpers'; +import { AppRegistry } from 'react-native'; +import { initializeEditor, render } from 'test/helpers'; /** * WordPress dependencies */ import * as wpHooks from '@wordpress/hooks'; +import '@wordpress/jest-console'; /** * Internal dependencies @@ -18,7 +19,7 @@ import setupLocale from '../setup-locale'; jest.mock( 'react-native/Libraries/ReactNative/AppRegistry' ); jest.mock( '../setup-locale' ); -const initGutenberg = ( registerParams ) => { +const getEditorComponent = ( registerParams ) => { let EditorComponent; AppRegistry.registerComponent.mockImplementation( ( name, componentProvider ) => { @@ -26,16 +27,10 @@ const initGutenberg = ( registerParams ) => { } ); registerGutenberg( registerParams ); - - return render( ); + return EditorComponent; }; describe( 'Register Gutenberg', () => { - beforeEach( () => { - // We need to reset modules to guarantee that setup module is imported on every test. - jest.resetModules(); - } ); - it( 'registers Gutenberg editor component', () => { registerGutenberg(); expect( AppRegistry.registerComponent ).toHaveBeenCalled(); @@ -53,7 +48,9 @@ describe( 'Register Gutenberg', () => { }; } ); - initGutenberg(); + const EditorComponent = getEditorComponent(); + // Modules are isolated upon editor rendering in order to guarantee that the setup module is imported on every test. + jest.isolateModules( () => render( ) ); // "invocationCallOrder" can be used to compare call orders between different mocks. // Reference: https://git.io/JyBk0 @@ -77,7 +74,9 @@ describe( 'Register Gutenberg', () => { }; } ); - initGutenberg( { beforeInitCallback } ); + const EditorComponent = getEditorComponent( { beforeInitCallback } ); + // Modules are isolated upon editor rendering in order to guarantee that the setup module is imported on every test. + jest.isolateModules( () => render( ) ); // "invocationCallOrder" can be used to compare call orders between different mocks. // Reference: https://git.io/JyBk0 @@ -94,16 +93,18 @@ describe( 'Register Gutenberg', () => { // An empty component is provided in order to listen for render calls of the editor component. const onRenderEditor = jest.fn(); - const EditorComponent = () => { + const MockEditor = () => { onRenderEditor(); return null; }; jest.mock( '../setup', () => ( { __esModule: true, - default: jest.fn().mockReturnValue( ), + default: jest.fn().mockReturnValue( ), } ) ); - initGutenberg(); + const EditorComponent = getEditorComponent(); + // Modules are isolated upon editor rendering in order to guarantee that the setup module is imported on every test. + jest.isolateModules( () => render( ) ); const hookCallIndex = 0; // "invocationCallOrder" can be used to compare call orders between different mocks. @@ -123,16 +124,18 @@ describe( 'Register Gutenberg', () => { // An empty component is provided in order to listen for render calls of the editor component. const onRenderEditor = jest.fn(); - const EditorComponent = () => { + const MockEditor = () => { onRenderEditor(); return null; }; jest.mock( '../setup', () => ( { __esModule: true, - default: jest.fn().mockReturnValue( ), + default: jest.fn().mockReturnValue( ), } ) ); - initGutenberg(); + const EditorComponent = getEditorComponent(); + // Modules are isolated upon editor rendering in order to guarantee that the setup module is imported on every test. + jest.isolateModules( () => render( ) ); const hookCallIndex = 0; // "invocationCallOrder" can be used to compare call orders between different mocks. @@ -152,16 +155,18 @@ describe( 'Register Gutenberg', () => { // An empty component is provided in order to listen for render calls of the editor component. const onRenderEditor = jest.fn(); - const EditorComponent = () => { + const MockEditor = () => { onRenderEditor(); return null; }; jest.mock( '../setup', () => ( { __esModule: true, - default: jest.fn().mockReturnValue( ), + default: jest.fn().mockReturnValue( ), } ) ); - initGutenberg(); + const EditorComponent = getEditorComponent(); + // Modules are isolated upon editor rendering in order to guarantee that the setup module is imported on every test. + jest.isolateModules( () => render( ) ); const hookCallIndex = 1; // "invocationCallOrder" can be used to compare call orders between different mocks. @@ -176,19 +181,17 @@ describe( 'Register Gutenberg', () => { expect( hookCallOrder ).toBeGreaterThan( onRenderEditorCallOrder ); } ); - it( 'initializes the editor', async () => { - const MockEditor = () => Mock Editor; - jest.mock( '../setup', () => { - return { - __esModule: true, - default: jest.fn( () => ), - }; - } ); + it( 'initializes the editor', () => { + // Unmock setup module to render the actual editor component. + jest.unmock( '../setup' ); + + const EditorComponent = getEditorComponent(); + const screen = initializeEditor( {}, { component: EditorComponent } ); + const blockList = screen.getByTestId( 'block-list-wrapper' ); - const screen = initGutenberg(); - const blockList = await waitFor( () => - screen.getByText( 'Mock Editor' ) - ); - expect( blockList ).toBeDefined(); + expect( blockList ).toHaveProperty( 'type', 'View' ); + expect( console ).toHaveLoggedWith( 'Hermes is: true' ); + // It's expected that some blocks are upgraded and inform about it (example: "Updated Block: core/cover") + expect( console ).toHaveInformed(); } ); } ); diff --git a/test/native/helpers.js b/test/native/helpers.js index b5e39752bb830c..e5ef48b8f1f21a 100644 --- a/test/native/helpers.js +++ b/test/native/helpers.js @@ -101,11 +101,12 @@ export function waitFor( { timeout, interval } = { timeout: 1000, interval: 50 } ) { let result; + let lastError; const check = ( resolve, reject, time = 0 ) => { try { result = cb(); - } catch ( e ) { - //NOOP + } catch ( error ) { + lastError = error; } if ( ! result && time < timeout ) { setTimeout( @@ -122,7 +123,7 @@ export function waitFor( ).then( () => { if ( ! result ) { reject( - `waitFor timed out after ${ timeout }ms for callback:\n${ cb }` + `waitFor timed out after ${ timeout }ms for callback:\n${ cb }\n${ lastError.toString() }` ); return; }