Skip to content

Commit

Permalink
[RNMobile] Refactor react-native-editor initialization test (#37955)
Browse files Browse the repository at this point in the history
* Refactor react-native-editor initialization test

* Remove commented line code

* Get block list component synchronously

* Remove jest-console package import

Due to this package removal the tests related to initialization have been refactored to cover the same logic.

* Improve error handling in waitFor test helper

* Update register gutenberg tests

`initGutenberg` function now returns the Editor component instead of rendering the editor.

* Update initialize editor test case

Now the initialize editor case renders the actual Editor component including the example initial html.

* Remove async from initialize editor test case
  • Loading branch information
fluiddot committed Jan 24, 2022
1 parent 81f4a7e commit c04a386
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 37 deletions.
71 changes: 37 additions & 34 deletions packages/react-native-editor/src/test/index.test.js
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -18,24 +19,18 @@ 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 ) => {
EditorComponent = componentProvider();
}
);
registerGutenberg( registerParams );

return render( <EditorComponent /> );
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();
Expand All @@ -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( <EditorComponent /> ) );

// "invocationCallOrder" can be used to compare call orders between different mocks.
// Reference: https://git.io/JyBk0
Expand All @@ -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( <EditorComponent /> ) );

// "invocationCallOrder" can be used to compare call orders between different mocks.
// Reference: https://git.io/JyBk0
Expand All @@ -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( <EditorComponent /> ),
default: jest.fn().mockReturnValue( <MockEditor /> ),
} ) );

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( <EditorComponent /> ) );

const hookCallIndex = 0;
// "invocationCallOrder" can be used to compare call orders between different mocks.
Expand All @@ -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( <EditorComponent /> ),
default: jest.fn().mockReturnValue( <MockEditor /> ),
} ) );

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( <EditorComponent /> ) );

const hookCallIndex = 0;
// "invocationCallOrder" can be used to compare call orders between different mocks.
Expand All @@ -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( <EditorComponent /> ),
default: jest.fn().mockReturnValue( <MockEditor /> ),
} ) );

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( <EditorComponent /> ) );

const hookCallIndex = 1;
// "invocationCallOrder" can be used to compare call orders between different mocks.
Expand All @@ -176,19 +181,17 @@ describe( 'Register Gutenberg', () => {
expect( hookCallOrder ).toBeGreaterThan( onRenderEditorCallOrder );
} );

it( 'initializes the editor', async () => {
const MockEditor = () => <Text>Mock Editor</Text>;
jest.mock( '../setup', () => {
return {
__esModule: true,
default: jest.fn( () => <MockEditor /> ),
};
} );
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();
} );
} );
7 changes: 4 additions & 3 deletions test/native/helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand All @@ -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;
}
Expand Down

0 comments on commit c04a386

Please sign in to comment.