@gpx/render-composer
TypeScript icon, indicating that this package has built-in type declarations

3.2.0 • Public • Published

Render Composer

burrito

Create complex renders for react-testing-library



The problem

When working with Testing Library within a large project often you need to wrap your component in several providers:

const history = createMemoryHistory();
const locale = 'en';
const user = {name: 'Giorgio'};
render(
  <Router history={history}>
    <IntlProvider locale={locale}>
      <UserContext.Provider value={user}>
        <MyComponent />
      </UserContext.Provider>
    </IntlProvider>
  </Router>,
);

This can lead to a lot of overhead and is not very flexible.

The solution

Render Composer allows you to declare reusable and configurable wraps that define a single provider. These wraps can then be combined to generate more complex hierarchies.

const RouterWrap = wrap((children, {history}) => (
  <Router history={history}>{children}</Router>
)).defaultData(() => ({
  history: createMemoryHistory(),
}));

const IntlWrap = wrap((children, {locale}) => (
  <IntlProvider locale={locale}>{children}</IntlProvider>
)).defaultData({locale: 'en'});

const UserWrap = wrap((children, {user}) => (
  <UserContext.Provider value={user}>{children}</UserContext.Provider>
)).defaultData({user: {name: 'Giorgio'}});

const appRender = RouterWrap.wraps(IntlWrap)
  .wraps(UserWrap)
  .withRenderMethod(render);

appRender(<MyComponent />);

Installation

With NPM:

npm install @gpx/render-composer --save-dev

With Yarn:

yarn add @gpx/render-composer --dev

Now simply import it in your tests:

import wrap from '@gpx/render-composer';

// or

var wrap = require('@gpx/render-composer');

Usage

You can create a wrap with the wrap method:

const Wrap = wrap((children, data) => <div>{children}</div>);

data is an empty object by default. You can set some default values with defaultData:

Wrap.defaultData({foo: 'bar'});

If you need the data to be generated every time rather than be static you can also pass a function to defaultData:

Wrap.defaultData(() => ({foo: Math.random()}));

You can compose the wraps with the wraps method. You can chain as many wraps you want:

WrapA.wraps(WrapB)
  .wraps(WrapC)
  .wraps(WrapD);

Once you are satisfied with your wrap you can get a render method with withRenderMethod:

import {render} from '@testing-library/react';

const renderWrap = Wrap.withRenderMethod(render);

renderWrap(<MyComponent />);

The generated render method will also accept data to overwrite the default values you defined in your wraps. The data will be returned too:

Wrap.defaultData(() => ({foo: 'bar'}));

// This `foo` will have value `'bar'`
const {foo} = renderWrap(<MyComponent />);

// This `foo` will have value `'baz'`
const {foo} = renderWrap(<MyComponent />, {foo: 'baz'});

Note that wraps are immutable so that they can be defined in one file and exported and combined.

Dependents (0)

Package Sidebar

Install

npm i @gpx/render-composer

Weekly Downloads

1

Version

3.2.0

License

MIT

Unpacked Size

23 kB

Total Files

10

Last publish

Collaborators

  • gpx