Skip to content

Commit

Permalink
feat(configs): improve Jest config for TypeScript (#580)
Browse files Browse the repository at this point in the history
* test(configs): fix Jest config for TypeScript

feature/typescript-jest

feature/typescript-jest

* docs: update test command

feature/typescript-jest
  • Loading branch information
connor-baer authored May 4, 2020
1 parent 477568d commit 301414d
Show file tree
Hide file tree
Showing 11 changed files with 142 additions and 77 deletions.
2 changes: 2 additions & 0 deletions .npmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
**/*.story.*
**/*.spec.*
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ yarn lint:fix
## Testing

```
yarn test:watch
yarn test
```

```javascript
Expand Down
2 changes: 1 addition & 1 deletion docs/introduction/contributing.story.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ yarn storybook
We use [Jest](https://jestjs.io/) and [react-testing-library](https://github.com/testing-library/react-testing-library) to unit test our components. Since most components are purely visual, we rely a lot on snapshot tests. Business logic should be tested with more specific assertions. To start unit tests in watch mode, run:

```bash
yarn test:watch
yarn test
```

As for linting and formatting, you can configure your editor to automatically lint and format your code on save. For this purpose, we're using [Prettier](https://prettier.io/) and [ESLint](https://eslint.org/). If you need to do it manually, you can run:
Expand Down
19 changes: 15 additions & 4 deletions jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,20 @@ module.exports = {
'react-syntax-highlighter/dist/cjs/$1'
},
transform: {
'^.+\\.jsx?$': 'babel-jest',
'^.+\\.svg$': '<rootDir>/jest.fileTransformer.js',
'^.+\\.mdx?$': '<rootDir>/jest.mdxTransformer.js'
'^.+\\.(js|jsx)$': 'babel-jest',
'^.+\\.(ts|tsx)$': 'ts-jest',
'^.+\\.(md|mdx)$': '<rootDir>/jest.mdxTransformer.js'
},
setupFilesAfterEnv: ['<rootDir>/jest.setup.js']
setupFilesAfterEnv: ['<rootDir>/jest.setup.js'],
globals: {
STORYBOOK: false,
__DEV__: false,
__PRODUCTION__: false,
__TEST__: true,
'ts-jest': {
tsConfig: {
jsx: 'react'
}
}
}
};
51 changes: 16 additions & 35 deletions jest.setup.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,50 +14,31 @@
*/

import React from 'react';
import { renderToStaticMarkup } from 'react-dom/server';
import '@testing-library/jest-dom/extend-expect';
import { createSerializer } from 'jest-emotion';
import { axe, toHaveNoViolations } from 'jest-axe';
import { render, fireEvent, wait, act } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { ThemeProvider } from 'emotion-theming';
import { light } from '@sumup/design-tokens';
import { toHaveNoViolations } from 'jest-axe';
import { fireEvent } from '@testing-library/react';

import ComponentsContext, {
defaultComponents
} from './src/components/ComponentsContext';

// eslint-disable-next-line react/prop-types
const WithProviders = ({ children }) => (
<ComponentsContext.Provider value={defaultComponents}>
<ThemeProvider theme={light}>{children}</ThemeProvider>
</ComponentsContext.Provider>
);

const renderWithProviders = renderFn => (component, ...rest) =>
renderFn(<WithProviders>{component}</WithProviders>, rest);
import {
create,
render,
renderToHtml,
renderHook,
act,
actHook,
userEvent,
wait,
axe
} from './src/util/test-utils';

global.axe = axe;
global.act = act;
global.wait = wait;
global.fireEvent = fireEvent;
global.userEvent = userEvent;
global.render = (component, options) =>
render(component, { wrapper: WithProviders, ...options });
global.renderToHtml = renderWithProviders(renderToStaticMarkup);
global.create = (...args) => {
const { container } = global.render(...args);
return container.children.length > 1
? container.children
: container.firstChild;
};

// This is defined by webpack in storybook builds using the DefinePlugin plugin.
global.STORYBOOK = false;

global.__DEV__ = false;
global.__PRODUCTION__ = false;
global.__TEST__ = true;
global.render = render;
global.renderToHtml = renderToHtml;
global.create = create;

// react-popper relies on document.createRange
if (global.document) {
Expand Down
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,7 @@
"lint:fix": "yarn lint --fix",
"lint:watch": "onchange \"src/**/*\" -- yarn lint",
"lint:ci": "yarn lint --format junit -o __reports__/eslint-results.xml",
"test": "jest --silent",
"test:watch": "yarn test --watch",
"test": "jest --watch",
"test:output": "mkdir -p __reports__ && jest --json --outputFile=__reports__/jest-results.json",
"test:ci": "yarn test:output --ci --coverage --runInBand",
"check:security": "audit-ci --critical",
Expand Down Expand Up @@ -103,9 +102,10 @@
"@testing-library/dom": "^6.5.0",
"@testing-library/jest-dom": "^4.1.0",
"@testing-library/react": "^9.1.4",
"@testing-library/react-hooks": "^2.0.1",
"@testing-library/react-hooks": "^3.2.1",
"@testing-library/user-event": "^7.0.1",
"@types/jest": "^25.2.1",
"@types/jest-axe": "^3.2.2",
"@types/lodash": "^4.14.149",
"@types/react": "^16.9.32",
"@types/react-dom": "^16.9.6",
Expand Down
21 changes: 13 additions & 8 deletions scripts/static-styles/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -107,14 +107,19 @@ function getRequiredProps(props) {
}

export function getComponentInfo(component, propOverrides = {}) {
// eslint-disable-next-line no-underscore-dangle
const { displayName, props } = component.__docgenInfo;
return {
component,
name: kebabCase(displayName),
props: getProps(props, propOverrides),
requiredProps: getRequiredProps(props)
};
try {
// eslint-disable-next-line no-underscore-dangle
const { displayName, props } = component.__docgenInfo;
return {
component,
name: kebabCase(displayName),
props: getProps(props, propOverrides),
requiredProps: getRequiredProps(props)
};
} catch (error) {
console.error(component);
throw error;
}
}

export default {
Expand Down
19 changes: 5 additions & 14 deletions jest.fileTransformer.js → src/types/global.d.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Copyright 2019, SumUp Ltd.
* Copyright 2020, SumUp Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
Expand All @@ -13,16 +13,7 @@
* limitations under the License.
*/

const { basename } = require('path');

module.exports = {
process(src, filename) {
const name = basename(filename);
return `
const React = require('react')
module.exports = {
ReactComponent: props => React.createElement('div', props, '${name}')
}
`;
}
};
declare module '*.mdx' {
const MDXComponent: (props: any) => JSX.Element;
export default MDXComponent;
}
63 changes: 63 additions & 0 deletions src/util/test-utils.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/**
* Copyright 2020, SumUp Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import React, { FunctionComponent } from 'react';
import { renderToStaticMarkup } from 'react-dom/server';
import '@testing-library/jest-dom/extend-expect';
import { axe } from 'jest-axe';
import { render as renderTest, wait, act } from '@testing-library/react';
import { renderHook, act as actHook } from '@testing-library/react-hooks';
import userEvent from '@testing-library/user-event';
import { ThemeProvider } from 'emotion-theming';
import { light } from '@sumup/design-tokens';

import ComponentsContext, {
defaultComponents
} from '../components/ComponentsContext';

export type RenderFn = (component: React.ReactElement, ...rest: any) => any;

const WithProviders: FunctionComponent = ({ children }) => (
<ComponentsContext.Provider value={defaultComponents}>
<ThemeProvider theme={light}>{children}</ThemeProvider>
</ComponentsContext.Provider>
);

const renderWithProviders = (renderer: RenderFn): RenderFn => (
component,
...rest
): RenderFn => renderer(<WithProviders>{component}</WithProviders>, rest);

const render: RenderFn = (component, options) =>
renderTest(component, { wrapper: WithProviders, ...options });
const renderToHtml: RenderFn = renderWithProviders(renderToStaticMarkup);
const create: RenderFn = (...args) => {
const { container } = render(...args);
return container.children.length > 1
? container.children
: container.firstChild;
};

export {
create,
render,
renderToHtml,
renderHook,
act,
actHook,
userEvent,
wait,
axe
};
3 changes: 1 addition & 2 deletions tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,11 @@
{
"name": "typescript-styled-plugin",
"lint": {
"validProperties": "label"
"validProperties": ["label"]
}
}
]
},
"include": ["src/**/*"],
"exclude": ["**/*.spec.*", "**/*.story.*"],
"typeRoots": ["./node_modules/@types", "./src/types/"]
}
31 changes: 22 additions & 9 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2533,13 +2533,13 @@
pretty-format "^24.0.0"
redent "^3.0.0"

"@testing-library/react-hooks@^2.0.1":
version "2.0.3"
resolved "https://registry.yarnpkg.com/@testing-library/react-hooks/-/react-hooks-2.0.3.tgz#305a6c76facb5fa1d185792b9eb11b1ca1b63fb7"
integrity sha512-adm+7b1gcysGka8VuYq/ObBrIBJTT9QmCEIqPpuxozWFfVDgxSbzBGc44ia/WYLGVt2dqFIOc6/DmAmu/pa0gQ==
"@testing-library/react-hooks@^3.2.1":
version "3.2.1"
resolved "https://registry.yarnpkg.com/@testing-library/react-hooks/-/react-hooks-3.2.1.tgz#19b6caa048ef15faa69d439c469033873ea01294"
integrity sha512-1OB6Ksvlk6BCJA1xpj8/WWz0XVd1qRcgqdaFAq+xeC6l61Ucj0P6QpA5u+Db/x9gU4DCX8ziR5b66Mlfg0M2RA==
dependencies:
"@babel/runtime" "^7.5.4"
"@types/testing-library__react-hooks" "^2.0.0"
"@types/testing-library__react-hooks" "^3.0.0"

"@testing-library/react@^9.1.4":
version "9.4.0"
Expand Down Expand Up @@ -2692,6 +2692,14 @@
"@types/istanbul-lib-coverage" "*"
"@types/istanbul-lib-report" "*"

"@types/jest-axe@^3.2.2":
version "3.2.2"
resolved "https://registry.yarnpkg.com/@types/jest-axe/-/jest-axe-3.2.2.tgz#9f66189683b91be02ba20e5defac42824f332f38"
integrity sha512-xVscGbS3nDay2GRG2TwF6xx92BbwU46gGanoelAfrweTng8OKU9pmX8AByuz5i8lWQ+y6B9PvkbtAJNDjsdSJQ==
dependencies:
"@types/jest" "*"
axe-core "^3.0.3"

"@types/jest-specific-snapshot@^0.5.3":
version "0.5.4"
resolved "https://registry.yarnpkg.com/@types/jest-specific-snapshot/-/jest-specific-snapshot-0.5.4.tgz#997364c39a59ddeff0ee790a19415e79dd061d1e"
Expand Down Expand Up @@ -2867,10 +2875,10 @@
dependencies:
pretty-format "^24.3.0"

"@types/testing-library__react-hooks@^2.0.0":
version "2.0.0"
resolved "https://registry.yarnpkg.com/@types/testing-library__react-hooks/-/testing-library__react-hooks-2.0.0.tgz#7b289d64945517ae8ba9cbcb0c5b282432aaeffa"
integrity sha512-YUVqXGCChJKEJ4aAnMXqPCq0NfPAFVsJeGIb2y/iiMjxwyu+45+vR+AHOwjJHHKEHeC0ZhOGrZ5gSEmaJe4tyQ==
"@types/testing-library__react-hooks@^3.0.0":
version "3.2.0"
resolved "https://registry.yarnpkg.com/@types/testing-library__react-hooks/-/testing-library__react-hooks-3.2.0.tgz#52f3a109bef06080e3b1e3ae7ea1c014ce859897"
integrity sha512-dE8iMTuR5lzB+MqnxlzORlXzXyCL0EKfzH0w/lau20OpkHD37EaWjZDz0iNG8b71iEtxT4XKGmSKAGVEqk46mw==
dependencies:
"@types/react" "*"
"@types/react-test-renderer" "*"
Expand Down Expand Up @@ -3754,6 +3762,11 @@ axe-core@3.4.1, axe-core@^3.3.2:
resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-3.4.1.tgz#e42623918bb85b5ef674633852cb9029db0309c5"
integrity sha512-+EhIdwR0hF6aeMx46gFDUy6qyCfsL0DmBrV3Z+LxYbsOd8e1zBaPHa3f9Rbjsz2dEwSBkLw6TwML/CAIIAqRpw==

axe-core@^3.0.3:
version "3.5.3"
resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-3.5.3.tgz#5b7c0ee7c5197d546bd3a07c3ef701896f5773e9"
integrity sha512-HZpLE7xu05+8AbpqXITGdxp1Xwk8ysAXrg7MiKRY27py3DAyEJpoJQo1727pWF3F+O79V3r+cTWhOzfB49P89w==

axios@0.19.0:
version "0.19.0"
resolved "https://registry.yarnpkg.com/axios/-/axios-0.19.0.tgz#8e09bff3d9122e133f7b8101c8fbdd00ed3d2ab8"
Expand Down

0 comments on commit 301414d

Please sign in to comment.