Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(configs): improve Jest config for TypeScript #580

Merged
merged 2 commits into from
May 4, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@ [email protected], 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==

[email protected]:
version "0.19.0"
resolved "https://registry.yarnpkg.com/axios/-/axios-0.19.0.tgz#8e09bff3d9122e133f7b8101c8fbdd00ed3d2ab8"
Expand Down