Skip to content

Commit

Permalink
Improve async component mounting (#24)
Browse files Browse the repository at this point in the history
* Flush promises to handle async React lifecycle methods

* Mount components with async by default

* Await componentDidMount method by default

* Handle null instance in mount

* Add test for async componentDidMount

* Update test to use text helper function

* Make flushPromises util async
  • Loading branch information
SHA-4 committed Mar 5, 2020
1 parent 0b59386 commit 8197d07
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 6 deletions.
12 changes: 9 additions & 3 deletions src/tester.tsx
@@ -1,6 +1,7 @@
import React, { Fragment } from 'react';

import {
flushPromises,
getInstance,
getValue,
isString,
Expand Down Expand Up @@ -200,9 +201,14 @@ class Tester {
this.createShallowWrapper();
}

if (mountOpts.async) {
await this.sleep();
this.update();
if (mountOpts.async !== false) {
if (this.instance) {
await this.instance.componentDidMount();
}

// See https://github.com/enzymejs/enzyme/issues/1587
await flushPromises();
await this.refresh();
}

return this;
Expand Down
6 changes: 5 additions & 1 deletion src/utils.ts
Expand Up @@ -4,7 +4,7 @@

export function getInstance (component: any) {
const instance = component.instance();
return instance.wrappedInstance || instance;
return instance && (instance.wrappedInstance || instance);
}

export function getValue (tester: any, value: unknown) {
Expand All @@ -22,3 +22,7 @@ export function capitalize (string: string) {
export function isString (value: unknown): value is string {
return typeof value === 'string' || value instanceof String;
}

export async function flushPromises () {
return new Promise<void>((resolve, _reject) => setImmediate(resolve));
}
32 changes: 30 additions & 2 deletions test/tester.test.tsx
@@ -1,13 +1,35 @@
/* global it, describe, expect */
import React from 'react';
import React, { Component } from 'react';
import { Tester } from '../src';
import { sleep } from '../src/utils';

const COMPONENT_ID = 'testing-component';

const MyTestingComponent = (props: any) => <div id={COMPONENT_ID} {...props} />;

describe('Tester', () => {
class AsyncComponent extends Component {
public constructor (props: object) {
super(props);
this.state = { status: 'loading' };
}

public async componentDidMount () {
await sleep(10);
this.setState({
status: 'done',
});
}

public render () {
return (
<div>
{this.state.status}
</div>
);
}
}

describe('Tester', () => {
it('Init tests', async () => {
const tester = await new Tester(MyTestingComponent).mount();
expect(tester.wrapper).toBeTruthy();
Expand All @@ -19,4 +41,10 @@ describe('Tester', () => {
expect(tester.wrapper).toBeTruthy();
expect(tester.wrapper.html()).toContain('test-hook-component');
});

it('Awaits async componentDidMount', async () => {
const tester = await new Tester(AsyncComponent).mount();
expect(tester.text()).toContain('done');
});

});

0 comments on commit 8197d07

Please sign in to comment.