Narwhals Playing Mahjong

    @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.

    Keywords

    none

    Install

    npm i @gpx/render-composer

    DownloadsWeekly Downloads

    8

    Version

    3.2.0

    License

    MIT

    Unpacked Size

    23 kB

    Total Files

    10

    Last publish

    Collaborators

    • gpx