├── .prettierrc
├── .babelrc
├── .flowconfig
├── jest.js
├── src
├── types.js
├── DeprecatedProp.js
└── index.js
├── LICENSE
├── .gitignore
├── README.md
├── package.json
├── __tests__
└── index.js
├── lib
└── index.js
├── flow-typed
└── npm
│ └── jest_v21.x.x.js
└── yarn.lock
/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "trailingComma": "all",
3 | "singleQuote": true
4 | }
5 |
--------------------------------------------------------------------------------
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "plugins": ["transform-class-properties", "transform-object-rest-spread"],
3 | "presets": ["env", "react"]
4 | }
5 |
--------------------------------------------------------------------------------
/.flowconfig:
--------------------------------------------------------------------------------
1 | [ignore]
2 |
3 | [include]
4 |
5 | [libs]
6 | flow-typed
7 |
8 | [lints]
9 |
10 | [options]
11 |
12 | [strict]
13 |
--------------------------------------------------------------------------------
/jest.js:
--------------------------------------------------------------------------------
1 | import { configure } from 'enzyme';
2 | import Adapter from 'enzyme-adapter-react-16';
3 |
4 | configure({ adapter: new Adapter() });
5 |
--------------------------------------------------------------------------------
/src/types.js:
--------------------------------------------------------------------------------
1 | // @flow
2 |
3 | export type ProvidedProps = { [key: string]: any };
4 |
5 | export type WithRenamedPropsState = { remappedProps: ProvidedProps };
6 |
7 | export type IsDeprecatedFn = (
8 | prop: string,
9 | providedProps: ProvidedProps,
10 | ) => boolean;
11 |
12 | export type DeprecatedProps = {
13 | [key: string]:
14 | | string
15 | | null
16 | | {
17 | mapTo: string | null,
18 | isDeprecated?: IsDeprecatedFn,
19 | },
20 | };
21 |
22 | export type WarningArgs = {
23 | componentName: string,
24 | deprecatedProps: DeprecatedProps,
25 | mapTo: string | null,
26 | prop: string,
27 | value: any,
28 | };
29 |
30 | export type WarningFn = (args: WarningArgs) => string;
31 |
--------------------------------------------------------------------------------
/src/DeprecatedProp.js:
--------------------------------------------------------------------------------
1 | // @flow
2 |
3 | import type { IsDeprecatedFn, ProvidedProps, DeprecatedProps } from './types';
4 |
5 | const defaultIsDeprecatedCheck: IsDeprecatedFn = (prop, providedProps) =>
6 | prop in providedProps;
7 |
8 | export default class DeprecatedProp {
9 | key: string;
10 | mapTo: string | null;
11 | isDeprecated: boolean;
12 |
13 | constructor(
14 | key: string,
15 | providedProps: ProvidedProps = {},
16 | deprecatedProps: DeprecatedProps,
17 | ) {
18 | const providedOptions = deprecatedProps[key];
19 | const defaultOptions = {
20 | mapTo: null,
21 | isDeprecated: defaultIsDeprecatedCheck,
22 | };
23 | const options =
24 | typeof providedOptions === 'string'
25 | ? {
26 | ...defaultOptions,
27 | mapTo: providedOptions,
28 | }
29 | : {
30 | ...defaultOptions,
31 | ...providedOptions,
32 | };
33 |
34 | this.key = key;
35 | this.mapTo = options.mapTo;
36 | this.isDeprecated = options.isDeprecated(key, providedProps);
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 Joss Mackison
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 |
8 | # Runtime data
9 | pids
10 | *.pid
11 | *.seed
12 | *.pid.lock
13 |
14 | # Directory for instrumented libs generated by jscoverage/JSCover
15 | lib-cov
16 |
17 | # Coverage directory used by tools like istanbul
18 | coverage
19 |
20 | # nyc test coverage
21 | .nyc_output
22 |
23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
24 | .grunt
25 |
26 | # Bower dependency directory (https://bower.io/)
27 | bower_components
28 |
29 | # node-waf configuration
30 | .lock-wscript
31 |
32 | # Compiled binary addons (http://nodejs.org/api/addons.html)
33 | build/Release
34 |
35 | # Dependency directories
36 | node_modules/
37 | jspm_packages/
38 |
39 | # Typescript v1 declaration files
40 | typings/
41 |
42 | # Optional npm cache directory
43 | .npm
44 |
45 | # Optional eslint cache
46 | .eslintcache
47 |
48 | # Optional REPL history
49 | .node_repl_history
50 |
51 | # Output of 'npm pack'
52 | *.tgz
53 |
54 | # Yarn Integrity file
55 | .yarn-integrity
56 |
57 | # dotenv environment variables file
58 | .env
59 |
60 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # React Deprecate
2 |
3 | Higher order component to support old props and warn users about the prop change.
4 |
5 | ## Install
6 |
7 | ```bash
8 | yarn add react-deprecate
9 | ```
10 |
11 | ## Usage
12 |
13 | ```jsx
14 | import React, { Component } from 'react';
15 | import renamePropsWithWarning from 'react-deprecate';
16 |
17 | // Your component with the breaking name change
18 | class LibComponent extends Component {
19 | static propTypes = { label: PropTypes.string }
20 | render () {
21 | return {this.props.label};
22 | }
23 | }
24 |
25 | // Wrapped, with options `old` --> `new`.
26 | // Optional third argument is a custom message renderer.
27 | export default renamePropsWithWarning(
28 | LibComponent,
29 | { description: 'label', val: 'value' },
30 | ({ componentName, prop, renamedProps }) => 'Your message.'
31 | );
32 |
33 | // Old AND new props supported:
34 | // `description/val` mapped to `label/value` with a console warning in Development
35 | class UserComponent extends Component {
36 | render () {
37 | return ;
38 | }
39 | }
40 | ```
41 |
42 | ## License
43 |
44 | Copyright © 2017 Joss Mackison. MIT Licensed.
45 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-deprecate",
3 | "description": "Higher order component to support old props and warn users about the prop change.",
4 | "version": "0.1.0",
5 | "main": "lib/index.js",
6 | "files": [
7 | "lib"
8 | ],
9 | "scripts": {
10 | "build": "babel src -d lib",
11 | "test": "jest",
12 | "prepublish": "npm run build"
13 | },
14 | "jest": {
15 | "setupFiles": [
16 | "./jest.js"
17 | ]
18 | },
19 | "repository": {
20 | "type": "git",
21 | "url": "https://github.com/jossmac/react-deprecate.git"
22 | },
23 | "keywords": [
24 | "react",
25 | "deprecate",
26 | "props",
27 | "rename",
28 | "map"
29 | ],
30 | "author": "Joss mackison",
31 | "license": "MIT",
32 | "bugs": {
33 | "url": "https://github.com/jossmac/react-deprecate/issues"
34 | },
35 | "homepage": "https://github.com/jossmac/react-deprecate#readme",
36 | "peer-dependencies": {
37 | "react": "^15.0 || ^16.0"
38 | },
39 | "devDependencies": {
40 | "babel-cli": "^6.26.0",
41 | "babel-plugin-transform-class-properties": "^6.24.1",
42 | "babel-plugin-transform-object-rest-spread": "^6.26.0",
43 | "babel-preset-env": "^1.6.1",
44 | "babel-preset-flow": "^6.23.0",
45 | "babel-preset-react": "^6.24.1",
46 | "enzyme": "^3.2.0",
47 | "enzyme-adapter-react-16": "^1.1.0",
48 | "flow-bin": "^0.61.0",
49 | "jest": "^21.2.1",
50 | "jest-cli": "^21.2.1",
51 | "prop-types": "^15.6.0",
52 | "react": "^16.2.0",
53 | "react-dom": "^16.2.0"
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | // @flow
2 |
3 | import React, { Component, type ComponentType } from 'react';
4 | import DeprecatedProp from './DeprecatedProp';
5 | import type {
6 | DeprecatedProps,
7 | WarningFn,
8 | ProvidedProps,
9 | WithRenamedPropsState,
10 | } from './types';
11 |
12 | const shouldWarn = process.env.ENV !== 'production';
13 |
14 | // Attempt to get the wrapped component's name
15 | function getComponentName(target: ComponentType<*>): string {
16 | if (target.displayName && typeof target.displayName === 'string') {
17 | return target.displayName;
18 | }
19 |
20 | return target.name || 'Component';
21 | }
22 |
23 | // Default deprecation warning for consumer
24 | export const defaultWarningMessage: WarningFn = ({
25 | componentName,
26 | mapTo,
27 | prop,
28 | }): string => {
29 | if (mapTo) {
30 | return `${componentName} Warning: Prop "${prop}" is deprecated, use "${mapTo}" instead.`;
31 | }
32 |
33 | return `${componentName} Warning: Prop "${prop}" is deprecated.`;
34 | };
35 |
36 | export default function renamePropsWithWarning(
37 | WrappedComponent: ComponentType<*>,
38 | deprecatedProps: DeprecatedProps = {},
39 | warningMessage: WarningFn = defaultWarningMessage,
40 | ): ComponentType<*> {
41 | // Bail early if in production
42 | if (!shouldWarn) return WrappedComponent;
43 |
44 | const componentName = getComponentName(WrappedComponent);
45 |
46 | return class WithRenamedProps extends Component<
47 | ProvidedProps,
48 | WithRenamedPropsState,
49 | > {
50 | static displayName = `WithRenamedProps(${componentName})`;
51 |
52 | constructor(props) {
53 | super(props);
54 | this.state = {
55 | remappedProps: this.remapProps(props),
56 | };
57 | }
58 |
59 | componentWillReceiveProps(newProps) {
60 | const remappedProps = this.remapProps(newProps);
61 | this.setState({ remappedProps });
62 | }
63 |
64 | remapProps = providedProps => {
65 | const remappedProps = { ...providedProps };
66 |
67 | Object.keys(deprecatedProps).forEach(propName => {
68 | const prop = new DeprecatedProp(
69 | propName,
70 | remappedProps,
71 | deprecatedProps,
72 | );
73 | if (prop.isDeprecated) {
74 | console.warn(
75 | warningMessage({
76 | componentName,
77 | deprecatedProps,
78 | mapTo: prop.mapTo,
79 | prop: prop.key,
80 | value: providedProps[prop.key],
81 | }),
82 | );
83 | if (prop.mapTo && !(prop.mapTo in remappedProps)) {
84 | remappedProps[prop.mapTo] = remappedProps[prop.key];
85 | delete remappedProps[prop.key];
86 | }
87 | }
88 | });
89 |
90 | return remappedProps;
91 | };
92 |
93 | render() {
94 | return ;
95 | }
96 | };
97 | }
98 |
--------------------------------------------------------------------------------
/__tests__/index.js:
--------------------------------------------------------------------------------
1 | // @flow
2 |
3 | import React, { Component } from 'react';
4 | import { mount, shallow } from 'enzyme';
5 | import PropTypes from 'prop-types';
6 | import renamePropsWithWarning, { defaultWarningMessage } from '../src';
7 |
8 | type MockProps = {
9 | label: string,
10 | };
11 | class Mock extends Component {
12 | static propTypes = { label: PropTypes.string };
13 | render() {
14 | return {this.props.label};
15 | }
16 | }
17 |
18 | const MockComponent = renamePropsWithWarning(Mock, {
19 | description: 'label',
20 | val: 'value',
21 | notRemapped: null,
22 | });
23 |
24 | const text = 'A short string of innocuous text.';
25 |
26 | describe('old properties', () => {
27 | it('should be removed', () => {
28 | const wrapper = shallow();
29 | expect(wrapper.prop('description')).toBe(undefined);
30 | expect(wrapper.prop('val')).toBe(undefined);
31 | });
32 | it('should be mapped to new props', () => {
33 | const wrapper = shallow();
34 | expect(wrapper.prop('label')).toBe(text);
35 | expect(wrapper.prop('value')).toBe(3);
36 | });
37 | it('should not be mapped to new props if the value is null', () => {
38 | const wrapper = shallow();
39 | expect(wrapper.prop('notRemapped')).toBe(text);
40 | });
41 | });
42 |
43 | describe('new properties', () => {
44 | it('should be unaffected', () => {
45 | const wrapper = shallow();
46 | expect(wrapper.prop('label')).toBe(text);
47 | expect(wrapper.prop('value')).toBe(3);
48 | });
49 | });
50 |
51 | describe('other properties', () => {
52 | it('should be unaffected', () => {
53 | const wrapper = shallow();
54 | expect(wrapper.prop('other')).toBe('property');
55 | });
56 | });
57 |
58 | describe('console warning', () => {
59 | const mock = jest.spyOn(global.console, 'warn');
60 |
61 | const MockWithCustomWarning = renamePropsWithWarning(
62 | Mock,
63 | {
64 | description: 'label',
65 | val: 'value',
66 | },
67 | () => 'Some custom warning!',
68 | );
69 |
70 | it('should warn', () => {
71 | const wrapper = shallow();
72 | expect(console.warn).toBeCalled();
73 | expect(console.warn).toBeCalledWith(
74 | 'Mock Warning: Prop "description" is deprecated, use "label" instead.',
75 | );
76 | });
77 | it('should be customisable', () => {
78 | const wrapper = shallow();
79 | expect(console.warn).toBeCalledWith('Some custom warning!');
80 | });
81 | });
82 |
83 | describe('extended options', () => {
84 | type TestClassProps = {
85 | remappedProp?: any,
86 | deprecatedProp?: any,
87 | neverRemapMe?: any,
88 | };
89 | class TestClass extends Component {
90 | render() {
91 | return ;
92 | }
93 | }
94 | const Test = renamePropsWithWarning(TestClass, {
95 | remappedProp: { mapTo: 'newRemappedProp' },
96 | deprecatedProp: { mapTo: null },
97 | neverRemapMe: {
98 | mapTo: 'newProp',
99 | isDeprecated: (prop, providedProps) => false,
100 | },
101 | });
102 |
103 | it('should rename the prop if a mapTo option is provided', () => {
104 | const wrapper = shallow();
105 | expect(wrapper.props()).toEqual({
106 | newRemappedProp: 'test',
107 | });
108 | });
109 |
110 | it('should not rename the prop if the mapTo option is null', () => {
111 | const wrapper = shallow();
112 | expect(wrapper.props()).toEqual({
113 | deprecatedProp: 'test',
114 | });
115 | });
116 |
117 | it('should override the default check if an isDeprecated function is provided', () => {
118 | const mock = jest.spyOn(global.console, 'warn');
119 | mock.mockReset();
120 | const wrapper = shallow();
121 | expect(wrapper.props()).toEqual({
122 | neverRemapMe: 'test',
123 | });
124 | expect(console.warn).not.toBeCalled();
125 | });
126 | });
127 |
--------------------------------------------------------------------------------
/lib/index.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
5 | });
6 |
7 | var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
8 |
9 | var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
10 |
11 | exports.default = renamePropsWithWarning;
12 |
13 | var _react = require('react');
14 |
15 | var _react2 = _interopRequireDefault(_react);
16 |
17 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
18 |
19 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
20 |
21 | function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
22 |
23 | function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
24 |
25 | var shouldWarn = process.env.ENV !== 'production';
26 |
27 | // attempt to get the wrapped component's name
28 | function getComponentName(target) {
29 | if (target.displayName && typeof target.displayName === 'string') {
30 | return target.displayName;
31 | }
32 |
33 | return target.name || 'Component';
34 | }
35 |
36 | // deprecation warning for consumer
37 | function defaultWarningMessage(_ref) {
38 | var componentName = _ref.componentName,
39 | prop = _ref.prop,
40 | renamedProps = _ref.renamedProps;
41 |
42 | return componentName + ' Warning: Prop "' + prop + '" is deprecated, use "' + renamedProps[prop] + '" instead.';
43 | }
44 |
45 | function renamePropsWithWarning(WrappedComponent, renamedProps) {
46 | var _class, _temp;
47 |
48 | var warningMessage = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : defaultWarningMessage;
49 |
50 | // bail early if in production
51 | if (!shouldWarn) return WrappedComponent;
52 |
53 | return _temp = _class = function (_Component) {
54 | _inherits(WithRenamedProps, _Component);
55 |
56 | function WithRenamedProps() {
57 | _classCallCheck(this, WithRenamedProps);
58 |
59 | return _possibleConstructorReturn(this, (WithRenamedProps.__proto__ || Object.getPrototypeOf(WithRenamedProps)).apply(this, arguments));
60 | }
61 |
62 | _createClass(WithRenamedProps, [{
63 | key: 'componentDidMount',
64 |
65 |
66 | // warn on deprecated props
67 | value: function componentDidMount() {
68 | var _this2 = this;
69 |
70 | Object.keys(renamedProps).forEach(function (prop) {
71 | if (prop in _this2.props) {
72 | console.warn(warningMessage({
73 | componentName: getComponentName(WrappedComponent),
74 | prop: prop,
75 | renamedProps: renamedProps
76 | }));
77 | }
78 | });
79 | }
80 |
81 | // map prop names `old` --> `new`
82 |
83 | }, {
84 | key: 'render',
85 | value: function render() {
86 | var props = _extends({}, this.props);
87 |
88 | Object.keys(renamedProps).forEach(function (prop) {
89 | if (prop in props) {
90 | if (!(renamedProps[prop] in props)) {
91 | props[renamedProps[prop]] = props[prop];
92 | }
93 | delete props[prop];
94 | }
95 | });
96 |
97 | // only pass new props
98 | return _react2.default.createElement(WrappedComponent, props);
99 | }
100 | }]);
101 |
102 | return WithRenamedProps;
103 | }(_react.Component), _class.displayName = 'WithRenamedProps(' + getComponentName(WrappedComponent) + ')', _temp;
104 | }
--------------------------------------------------------------------------------
/flow-typed/npm/jest_v21.x.x.js:
--------------------------------------------------------------------------------
1 | // flow-typed signature: 107cf7068b8835594e97f938e8848244
2 | // flow-typed version: 8b4dd96654/jest_v21.x.x/flow_>=v0.39.x
3 |
4 | type JestMockFn, TReturn> = {
5 | (...args: TArguments): TReturn,
6 | /**
7 | * An object for introspecting mock calls
8 | */
9 | mock: {
10 | /**
11 | * An array that represents all calls that have been made into this mock
12 | * function. Each call is represented by an array of arguments that were
13 | * passed during the call.
14 | */
15 | calls: Array,
16 | /**
17 | * An array that contains all the object instances that have been
18 | * instantiated from this mock function.
19 | */
20 | instances: Array
21 | },
22 | /**
23 | * Resets all information stored in the mockFn.mock.calls and
24 | * mockFn.mock.instances arrays. Often this is useful when you want to clean
25 | * up a mock's usage data between two assertions.
26 | */
27 | mockClear(): void,
28 | /**
29 | * Resets all information stored in the mock. This is useful when you want to
30 | * completely restore a mock back to its initial state.
31 | */
32 | mockReset(): void,
33 | /**
34 | * Removes the mock and restores the initial implementation. This is useful
35 | * when you want to mock functions in certain test cases and restore the
36 | * original implementation in others. Beware that mockFn.mockRestore only
37 | * works when mock was created with jest.spyOn. Thus you have to take care of
38 | * restoration yourself when manually assigning jest.fn().
39 | */
40 | mockRestore(): void,
41 | /**
42 | * Accepts a function that should be used as the implementation of the mock.
43 | * The mock itself will still record all calls that go into and instances
44 | * that come from itself -- the only difference is that the implementation
45 | * will also be executed when the mock is called.
46 | */
47 | mockImplementation(
48 | fn: (...args: TArguments) => TReturn
49 | ): JestMockFn,
50 | /**
51 | * Accepts a function that will be used as an implementation of the mock for
52 | * one call to the mocked function. Can be chained so that multiple function
53 | * calls produce different results.
54 | */
55 | mockImplementationOnce(
56 | fn: (...args: TArguments) => TReturn
57 | ): JestMockFn,
58 | /**
59 | * Just a simple sugar function for returning `this`
60 | */
61 | mockReturnThis(): void,
62 | /**
63 | * Deprecated: use jest.fn(() => value) instead
64 | */
65 | mockReturnValue(value: TReturn): JestMockFn,
66 | /**
67 | * Sugar for only returning a value once inside your mock
68 | */
69 | mockReturnValueOnce(value: TReturn): JestMockFn
70 | };
71 |
72 | type JestAsymmetricEqualityType = {
73 | /**
74 | * A custom Jasmine equality tester
75 | */
76 | asymmetricMatch(value: mixed): boolean
77 | };
78 |
79 | type JestCallsType = {
80 | allArgs(): mixed,
81 | all(): mixed,
82 | any(): boolean,
83 | count(): number,
84 | first(): mixed,
85 | mostRecent(): mixed,
86 | reset(): void
87 | };
88 |
89 | type JestClockType = {
90 | install(): void,
91 | mockDate(date: Date): void,
92 | tick(milliseconds?: number): void,
93 | uninstall(): void
94 | };
95 |
96 | type JestMatcherResult = {
97 | message?: string | (() => string),
98 | pass: boolean
99 | };
100 |
101 | type JestMatcher = (actual: any, expected: any) => JestMatcherResult;
102 |
103 | type JestPromiseType = {
104 | /**
105 | * Use rejects to unwrap the reason of a rejected promise so any other
106 | * matcher can be chained. If the promise is fulfilled the assertion fails.
107 | */
108 | rejects: JestExpectType,
109 | /**
110 | * Use resolves to unwrap the value of a fulfilled promise so any other
111 | * matcher can be chained. If the promise is rejected the assertion fails.
112 | */
113 | resolves: JestExpectType
114 | };
115 |
116 | /**
117 | * Plugin: jest-enzyme
118 | */
119 | type EnzymeMatchersType = {
120 | toBeChecked(): void,
121 | toBeDisabled(): void,
122 | toBeEmpty(): void,
123 | toBePresent(): void,
124 | toContainReact(element: React$Element): void,
125 | toHaveClassName(className: string): void,
126 | toHaveHTML(html: string): void,
127 | toHaveProp(propKey: string, propValue?: any): void,
128 | toHaveRef(refName: string): void,
129 | toHaveState(stateKey: string, stateValue?: any): void,
130 | toHaveStyle(styleKey: string, styleValue?: any): void,
131 | toHaveTagName(tagName: string): void,
132 | toHaveText(text: string): void,
133 | toIncludeText(text: string): void,
134 | toHaveValue(value: any): void,
135 | toMatchElement(element: React$Element): void,
136 | toMatchSelector(selector: string): void
137 | };
138 |
139 | type JestExpectType = {
140 | not: JestExpectType & EnzymeMatchersType,
141 | /**
142 | * If you have a mock function, you can use .lastCalledWith to test what
143 | * arguments it was last called with.
144 | */
145 | lastCalledWith(...args: Array): void,
146 | /**
147 | * toBe just checks that a value is what you expect. It uses === to check
148 | * strict equality.
149 | */
150 | toBe(value: any): void,
151 | /**
152 | * Use .toHaveBeenCalled to ensure that a mock function got called.
153 | */
154 | toBeCalled(): void,
155 | /**
156 | * Use .toBeCalledWith to ensure that a mock function was called with
157 | * specific arguments.
158 | */
159 | toBeCalledWith(...args: Array): void,
160 | /**
161 | * Using exact equality with floating point numbers is a bad idea. Rounding
162 | * means that intuitive things fail.
163 | */
164 | toBeCloseTo(num: number, delta: any): void,
165 | /**
166 | * Use .toBeDefined to check that a variable is not undefined.
167 | */
168 | toBeDefined(): void,
169 | /**
170 | * Use .toBeFalsy when you don't care what a value is, you just want to
171 | * ensure a value is false in a boolean context.
172 | */
173 | toBeFalsy(): void,
174 | /**
175 | * To compare floating point numbers, you can use toBeGreaterThan.
176 | */
177 | toBeGreaterThan(number: number): void,
178 | /**
179 | * To compare floating point numbers, you can use toBeGreaterThanOrEqual.
180 | */
181 | toBeGreaterThanOrEqual(number: number): void,
182 | /**
183 | * To compare floating point numbers, you can use toBeLessThan.
184 | */
185 | toBeLessThan(number: number): void,
186 | /**
187 | * To compare floating point numbers, you can use toBeLessThanOrEqual.
188 | */
189 | toBeLessThanOrEqual(number: number): void,
190 | /**
191 | * Use .toBeInstanceOf(Class) to check that an object is an instance of a
192 | * class.
193 | */
194 | toBeInstanceOf(cls: Class<*>): void,
195 | /**
196 | * .toBeNull() is the same as .toBe(null) but the error messages are a bit
197 | * nicer.
198 | */
199 | toBeNull(): void,
200 | /**
201 | * Use .toBeTruthy when you don't care what a value is, you just want to
202 | * ensure a value is true in a boolean context.
203 | */
204 | toBeTruthy(): void,
205 | /**
206 | * Use .toBeUndefined to check that a variable is undefined.
207 | */
208 | toBeUndefined(): void,
209 | /**
210 | * Use .toContain when you want to check that an item is in a list. For
211 | * testing the items in the list, this uses ===, a strict equality check.
212 | */
213 | toContain(item: any): void,
214 | /**
215 | * Use .toContainEqual when you want to check that an item is in a list. For
216 | * testing the items in the list, this matcher recursively checks the
217 | * equality of all fields, rather than checking for object identity.
218 | */
219 | toContainEqual(item: any): void,
220 | /**
221 | * Use .toEqual when you want to check that two objects have the same value.
222 | * This matcher recursively checks the equality of all fields, rather than
223 | * checking for object identity.
224 | */
225 | toEqual(value: any): void,
226 | /**
227 | * Use .toHaveBeenCalled to ensure that a mock function got called.
228 | */
229 | toHaveBeenCalled(): void,
230 | /**
231 | * Use .toHaveBeenCalledTimes to ensure that a mock function got called exact
232 | * number of times.
233 | */
234 | toHaveBeenCalledTimes(number: number): void,
235 | /**
236 | * Use .toHaveBeenCalledWith to ensure that a mock function was called with
237 | * specific arguments.
238 | */
239 | toHaveBeenCalledWith(...args: Array): void,
240 | /**
241 | * Use .toHaveBeenLastCalledWith to ensure that a mock function was last called
242 | * with specific arguments.
243 | */
244 | toHaveBeenLastCalledWith(...args: Array): void,
245 | /**
246 | * Check that an object has a .length property and it is set to a certain
247 | * numeric value.
248 | */
249 | toHaveLength(number: number): void,
250 | /**
251 | *
252 | */
253 | toHaveProperty(propPath: string, value?: any): void,
254 | /**
255 | * Use .toMatch to check that a string matches a regular expression or string.
256 | */
257 | toMatch(regexpOrString: RegExp | string): void,
258 | /**
259 | * Use .toMatchObject to check that a javascript object matches a subset of the properties of an object.
260 | */
261 | toMatchObject(object: Object | Array