@render-with/react-intl
TypeScript icon, indicating that this package has built-in type declarations

3.0.0 • Public • Published

Render decorators 🪆 for React Intl

GitHub Workflow Status Code Coverage npm (scoped) NPM PRs welcome All Contributors

Use the withIntl(..) decorator if your component under test requires a React IntlProvider:

Example:

import { render, screen, withIntl } from './test-utils'

it('presents home page in German when locale is German', () => {
  render(<HomePage />, withIntl('de'))
  expect(screen.getByRole('heading', { name: /willkommen/i })).toBeInTheDocument()
})

Note: Refer to the core library to learn more about how decorators can simplify writing tests for React components with React Testing Library.

Table of Contents

Installation

This library is distributed via npm, which is bundled with node and should be installed as one of your project's devDependencies.

First, install the core library with a render function that supports decorators:

npm install --save-dev @render-with/decorators

Next, install the React Intl decorators provided by this library:

npm install --save-dev @render-with/react-intl
...

or

for installation via yarn:

yarn add --dev @render-with/decorators
yarn add --dev @render-with/react-intl

This library has the following peerDependencies:

npm peer dependency version

and supports the following node versions:

node-current (scoped)

Setup

In your test-utils file, re-export the render function that supports decorators and the React Intl decorators:

// test-utils.js
// ...
export * from '@testing-library/react'  // makes all React Testing Library's exports available
export * from '@render-with/decorators' // overrides React Testing Library's render function
export * from '@render-with/react-intl' // makes decorators like withIntl(..) available

Then, create a withIntl provider using configureWithIntl. The configuration function comes in two flavors:

You can either pass an object that maps locales to the corresponding messages:

// test-utils.js
// ...
const TRANSLATIONS = {
  en: englishTranslations,
  de: germanTranslations,
}

export const withIntl = configureWithIntl(TRANSLATIONS)

Or you can pass a function that returns messages for a given locale:

// test-utils.js
// ...
const getMessagesForLocale = locale => { /* retrieve messages for locale */ }

export const withIntl = configureWithIntl(getMessagesForLocale)

What configuration to choose depends on your project's React Intl setup.

Finally, use the React Intl decorator in your tests:

import { render, screen, withIntl } from './test-utils'

it('presents home page in German when locale is German', () => {
  render(<HomePage />, withIntl('de'))
  expect(screen.getByRole('heading', { name: /willkommen/i })).toBeInTheDocument()
})

Test Scenarios

The following examples represent tests for these translation messages:

{
  "en": {
    "greeting": "Welcome",
    "username": "Username",
    "...": "..."
  },
  "de": {
    "greeting": "Willkommen",
    "username": "Nutzername",
    "...": "..."
  }
}

and this <HomePage /> component:

import { FormattedMessage as T } from 'react-intl'

const HomePage = () => {
  const { t } = useIntl()
  
  return (
    <div>
      <h1><T id='greeting' defaultMessage='Welcome' /></h1>
      <input type='text' placeholder={t({ id: 'username', defaultMessage: 'Username' })} />
      <!-- ... -->
    </div>
  )
}

Just need an IntlProver?

If your test does not care about the locale or is okay with the default locale, you can use the withIntl(..) decorator and omit the locale argument. The decorator will create, configure and use an IntlPRovider for you:

import { render, screen, withIntl } from './test-utils'

it('shows title', () => {
  render(<HomePage />, withIntl())
  expect(screen.getByRole('heading', { name: /welcome/i })).toBeInTheDocument()
})

Need to verify translations?

If your test does care about the locale, you can use the withIntl(..) decorator and pass a locale as argument:

import { render, screen, withIntl } from './test-utils'

it('shows title', () => {
  render(<HomePage />, withIntl('de'))
  expect(screen.getByRole('heading', { name: /willkommen/i })).toBeInTheDocument()
})

API

Note: This API reference uses simplified types. You can find the full type specification here.

function configureWithIntl(translations: Translations | getMessagesForLocale, defaultLocale?: string): withIntl

Creates a withIntl decorator that wraps the component under test in a React IntlProvider.

type withIntl = (locale?: string) => Decorator

Wraps component under test in a React IntlProvider. It can resolve messages with the given locale.

type Translations = { [locale: string]: Messages }

An object that maps locales to messages.

type getMessagesForLocale = (locale: string) => Messages

A function that retrieves messages for a given local.

type Messages = { [id: string]: string }

An object that maps translation ids to translation texts.

function withMessages(messages: Messages, locale?: string, defaultLocale?: string): Decorator

Wraps component under test in a React IntlProvider that is configured with the given messages, locale, and defaultLocale. This decorator is used under the hood when creating a withIntl decorator with configureWithIntl.

Issues

Looking to contribute? PRs are welcome. Checkout this project's Issues on GitHub for existing issues.

🐛 Bugs

Please file an issue for bugs, missing documentation, or unexpected behavior.

See Bugs

💡 Feature Requests

Please file an issue to suggest new features. Vote on feature requests by adding a 👍. This helps maintainers prioritize what to work on.

See Feature Requests

📚 More Libraries

Please file an issue on the core project to suggest additional libraries that would benefit from decorators. Vote on library support adding a 👍. This helps maintainers prioritize what to work on.

See Library Requests

Questions

For questions related to using the library, file an issue on GitHub.

See Questions

Changelog

Every release is documented on the GitHub Releases page.

Contributors

Thanks goes to these people:

cultivate(software)
cultivate(software)

💼 💵
David Bieder
David Bieder

💻 ⚠️ 📖 👀 🚇 🚧 🤔
Jerome Weiß
Jerome Weiß

📖 🚇 🚧
Maurice Reichelt
Maurice Reichelt

📖 🚇 🚧

This project follows the all-contributors specification. Contributions of any kind welcome!

LICENSE

MIT

Package Sidebar

Install

npm i @render-with/react-intl

Weekly Downloads

1

Version

3.0.0

License

MIT

Unpacked Size

17 kB

Total Files

5

Last publish

Collaborators

  • mauricereichelt
  • davidbieder