From e1f15b5d228fa79f507e3cf56f57e0b35521b3b3 Mon Sep 17 00:00:00 2001 From: SleepWalker Date: Thu, 21 May 2020 21:08:47 +0300 Subject: [PATCH] Fix all tests and replace enzyme with @testing-library/react --- jest/setupAfterEnv.js | 5 +- package.json | 2 - packages/app/components/auth/actions.test.ts | 2 +- .../components/contact/ContactForm.test.tsx | 278 ++++++------- .../app/components/contact/ContactForm.tsx | 7 +- packages/app/components/i18n/IntlProvider.tsx | 5 + .../changePassword/ChangePassword.test.tsx | 56 ++- packages/app/components/ui/form/FormError.tsx | 6 +- .../app/components/ui/form/Input.test.tsx | 14 +- .../components/ui/popup/PopupStack.test.tsx | 119 +++--- .../app/components/ui/popup/PopupStack.tsx | 3 +- .../containers/AuthFlowRouteContents.test.tsx | 32 +- packages/app/package.json | 7 +- packages/app/pages/rules/RulesPage.test.tsx | 66 +-- packages/app/services/api/options.test.ts | 14 +- .../app/services/authFlow/AuthFlow.test.ts | 9 - packages/app/shell/TestContextProvider.tsx | 18 + packages/app/shell/index.ts | 1 - packages/app/shell/index.tsx | 2 + yarn.lock | 384 ++++++------------ 20 files changed, 430 insertions(+), 600 deletions(-) create mode 100644 packages/app/shell/TestContextProvider.tsx delete mode 100644 packages/app/shell/index.ts create mode 100644 packages/app/shell/index.tsx diff --git a/jest/setupAfterEnv.js b/jest/setupAfterEnv.js index a89a3a6..a267223 100644 --- a/jest/setupAfterEnv.js +++ b/jest/setupAfterEnv.js @@ -1,8 +1,5 @@ import 'app/polyfills'; -import { configure } from 'enzyme'; -import Adapter from 'enzyme-adapter-react-16'; - -configure({ adapter: new Adapter() }); +import '@testing-library/jest-dom'; if (!window.localStorage) { window.localStorage = { diff --git a/package.json b/package.json index eb4a8a4..f15e800 100644 --- a/package.json +++ b/package.json @@ -69,7 +69,6 @@ "/jest/setupAfterEnv.js" ], "resetMocks": true, - "resetModules": true, "restoreMocks": true, "watchPlugins": [ "jest-watch-typeahead/filename", @@ -155,7 +154,6 @@ "postcss-scss": "^2.1.1", "prettier": "^2.0.5", "raw-loader": "^4.0.1", - "react-test-renderer": "^16.13.1", "sass-loader": "^8.0.2", "sinon": "^9.0.2", "sitemap-webpack-plugin": "^0.8.0", diff --git a/packages/app/components/auth/actions.test.ts b/packages/app/components/auth/actions.test.ts index cf168d7..630cf4a 100644 --- a/packages/app/components/auth/actions.test.ts +++ b/packages/app/components/auth/actions.test.ts @@ -124,7 +124,7 @@ describe('components/auth/actions', () => { return callThunk(oAuthComplete).then(() => { expect(request.post, 'to have a call satisfying', [ - '/api/oauth2/v1/complete?client_id=&redirect_uri=&response_type=&description=&scope=&prompt=&login_hint=&state=', + '/api/oauth2/v1/complete?client_id=&redirect_uri=&response_type=&description=&scope=&prompt=none&login_hint=&state=', {}, ]); }); diff --git a/packages/app/components/contact/ContactForm.test.tsx b/packages/app/components/contact/ContactForm.test.tsx index afef3c2..99327b5 100644 --- a/packages/app/components/contact/ContactForm.test.tsx +++ b/packages/app/components/contact/ContactForm.test.tsx @@ -1,61 +1,60 @@ -import React, { ComponentProps } from 'react'; +import React from 'react'; import expect from 'app/test/unexpected'; import sinon from 'sinon'; -import { shallow, mount, ShallowWrapper, ReactWrapper } from 'enzyme'; -import { IntlProvider } from 'react-intl'; +import { render, fireEvent, waitFor, screen } from '@testing-library/react'; import feedback from 'app/services/api/feedback'; import { User } from 'app/components/user'; +import { TestContextProvider } from 'app/shell'; import { ContactForm } from './ContactForm'; -type ContactFormShallowType = ShallowWrapper< - ComponentProps, - any, - ContactForm ->; +beforeEach(() => { + sinon.stub(feedback, 'send').returns(Promise.resolve() as any); +}); + +afterEach(() => { + (feedback.send as any).restore(); +}); describe('ContactForm', () => { - describe('when rendered', () => { + it('should contain Form', () => { const user = {} as User; - let component: ContactFormShallowType; - beforeEach(() => { - component = shallow(); - }); + render( + + + , + ); + + expect(screen.getAllByRole('textbox').length, 'to be greater than', 1); + + expect( + screen.getByRole('button', { name: /Send/ }), + 'to have property', + 'type', + 'submit', + ); [ { - type: 'Input', + label: 'subject', name: 'subject', }, { - type: 'Input', + label: 'E‑mail', name: 'email', }, { - type: 'Dropdown', - name: 'category', - }, - { - type: 'TextArea', + label: 'message', name: 'message', }, ].forEach((el) => { - it(`should have ${el.name} field`, () => { - expect(component.find(`${el.type}[name="${el.name}"]`), 'to satisfy', { - length: 1, - }); - }); - }); - - it('should contain Form', () => { - expect(component.find('Form'), 'to satisfy', { length: 1 }); - }); - - it('should contain submit Button', () => { - expect(component.find('Button[type="submit"]'), 'to satisfy', { - length: 1, - }); + expect( + screen.getByLabelText(el.label, { exact: false }), + 'to have property', + 'name', + el.name, + ); }); }); @@ -63,148 +62,109 @@ describe('ContactForm', () => { const user = { email: 'foo@bar.com', } as User; - let component: ContactFormShallowType; - - beforeEach(() => { - component = shallow(); - }); it('should render email field with user email', () => { + render( + + + , + ); + + expect(screen.getByDisplayValue(user.email), 'to be a', HTMLInputElement); + }); + }); + + it('should submit and then hide form and display success message', async () => { + const user = { + email: 'foo@bar.com', + } as User; + + render( + + + , + ); + + fireEvent.change(screen.getByLabelText(/subject/i), { + target: { + value: 'subject', + }, + }); + + fireEvent.change(screen.getByLabelText(/message/i), { + target: { + value: 'the message', + }, + }); + + const button = screen.getByRole('button', { name: 'Send' }); + + expect(button, 'to have property', 'disabled', false); + + fireEvent.click(button); + + expect(button, 'to have property', 'disabled', true); + expect(feedback.send, 'to have a call exhaustively satisfying', [ + { + subject: 'subject', + email: user.email, + category: '', + message: 'the message', + }, + ]); + + await waitFor(() => { expect( - component.find('Input[name="email"]').prop('defaultValue'), - 'to equal', - user.email, + screen.getByText('Your message was received', { exact: false }), + 'to be a', + HTMLElement, ); }); + + expect(screen.getByText(user.email), 'to be a', HTMLElement); + + expect(screen.queryByRole('button', { name: /Send/ }), 'to be null'); }); - describe('when email was successfully sent', () => { + it('should show validation messages', async () => { const user = { email: 'foo@bar.com', } as User; - let component: ContactFormShallowType; - beforeEach(() => { - component = shallow(); + (feedback.send as any).callsFake(() => + Promise.reject({ + success: false, + errors: { email: 'error.email_invalid' }, + }), + ); - component.setState({ isSuccessfullySent: true }); + render( + + + , + ); + + fireEvent.change(screen.getByLabelText(/subject/i), { + target: { + value: 'subject', + }, }); - it('should not contain Form', () => { - expect(component.find('Form'), 'to satisfy', { length: 0 }); + fireEvent.change(screen.getByLabelText(/message/i), { + target: { + value: 'the message', + }, }); - }); - xdescribe('validation', () => { - const user = { - email: 'foo@bar.com', - } as User; - let component: ContactForm; - let wrapper: ReactWrapper; + fireEvent.click(screen.getByRole('button', { name: 'Send' })); - beforeEach(() => { - // TODO: add polyfill for from validation for jsdom - - wrapper = mount( - - (component = el!)} /> - , + await waitFor(() => { + expect( + screen.getByRole('alert'), + 'to have property', + 'innerHTML', + 'E‑mail is invalid', ); }); - - it('should require email, subject and message', () => { - // wrapper.find('[type="submit"]').simulate('click'); - wrapper.find('form').simulate('submit'); - - expect(component.form.hasErrors(), 'to be true'); - }); - }); - - describe('when user submits form', () => { - const user = { - email: 'foo@bar.com', - } as User; - let component: ContactForm; - let wrapper: ReactWrapper; - const requestData = { - email: user.email, - subject: 'Test subject', - message: 'Test message', - }; - - beforeEach(() => { - sinon.stub(feedback, 'send'); - - // TODO: add polyfill for from validation for jsdom - if (!(Element.prototype as any).checkValidity) { - (Element.prototype as any).checkValidity = () => true; - } - - // TODO: try to rewrite with unexpected-react - wrapper = mount( - - (component = el!)} /> - , - ); - - wrapper.find('input[name="email"]').getDOMNode().value = - requestData.email; - wrapper - .find('input[name="subject"]') - .getDOMNode().value = requestData.subject; - wrapper - .find('textarea[name="message"]') - .getDOMNode().value = requestData.message; - }); - - afterEach(() => { - (feedback.send as any).restore(); - }); - - xit('should call onSubmit', () => { - sinon.stub(component, 'onSubmit'); - - wrapper.find('form').simulate('submit'); - - expect(component.onSubmit, 'was called'); - }); - - it('should call send with required data', () => { - (feedback.send as any).returns(Promise.resolve()); - - component.onSubmit(); - - expect(feedback.send, 'to have a call satisfying', [requestData]); - }); - - it('should set isSuccessfullySent', () => { - (feedback.send as any).returns(Promise.resolve()); - - return component - .onSubmit() - .then(() => - expect(component.state, 'to satisfy', { isSuccessfullySent: true }), - ); - }); - - it('should handle isLoading during request', () => { - (feedback.send as any).returns(Promise.resolve()); - - const promise = component.onSubmit(); - - expect(component.state, 'to satisfy', { isLoading: true }); - - return promise.then(() => - expect(component.state, 'to satisfy', { isLoading: false }), - ); - }); - - it('should render success message with user email', () => { - (feedback.send as any).returns(Promise.resolve()); - - return component - .onSubmit() - .then(() => expect(wrapper.text(), 'to contain', user.email)); - }); }); }); diff --git a/packages/app/components/contact/ContactForm.tsx b/packages/app/components/contact/ContactForm.tsx index 79ee497..461f7ed 100644 --- a/packages/app/components/contact/ContactForm.tsx +++ b/packages/app/components/contact/ContactForm.tsx @@ -140,7 +140,12 @@ export class ContactForm extends React.Component<
-
); diff --git a/packages/app/components/i18n/IntlProvider.tsx b/packages/app/components/i18n/IntlProvider.tsx index f0c8145..ea0f79c 100644 --- a/packages/app/components/i18n/IntlProvider.tsx +++ b/packages/app/components/i18n/IntlProvider.tsx @@ -11,6 +11,11 @@ const IntlProvider: ComponentType = ({ children }) => { ); useEffect(() => { + if (process.env.NODE_ENV === 'test') { + // disable async modules loading in tests + return; + } + (async () => { setIntl(await i18n.changeLocale(locale)); })(); diff --git a/packages/app/components/profile/changePassword/ChangePassword.test.tsx b/packages/app/components/profile/changePassword/ChangePassword.test.tsx index 0af2064..dc09dc7 100644 --- a/packages/app/components/profile/changePassword/ChangePassword.test.tsx +++ b/packages/app/components/profile/changePassword/ChangePassword.test.tsx @@ -1,25 +1,57 @@ import React from 'react'; -import expect from 'app/test/unexpected'; +import uxpect from 'app/test/unexpected'; +import { render, fireEvent, screen } from '@testing-library/react'; import sinon from 'sinon'; +import { TestContextProvider } from 'app/shell'; -import { shallow } from 'enzyme'; - -import ChangePassword from 'app/components/profile/changePassword/ChangePassword'; +import ChangePassword from './ChangePassword'; describe('', () => { it('renders two components', () => { - const component = shallow( {}} />); + render( + + {}} /> + , + ); - expect(component.find('Input'), 'to satisfy', { length: 2 }); + expect( + screen.getByLabelText('New password', { exact: false }), + ).toBeInTheDocument(); + expect( + screen.getByLabelText('Repeat the password', { exact: false }), + ).toBeInTheDocument(); }); - it('should call onSubmit if passwords entered', () => { - const onSubmit = sinon.spy(() => ({ catch: () => {} })).named('onSubmit'); - // @ts-ignore - const component = shallow(); + it('should call onSubmit if passwords entered', async () => { + const onSubmit = sinon.spy(() => Promise.resolve()).named('onSubmit'); - component.find('Form').simulate('submit'); + render( + + + , + ); - expect(onSubmit, 'was called'); + fireEvent.change(screen.getByLabelText('New password', { exact: false }), { + target: { + value: '123', + }, + }); + + fireEvent.change( + screen.getByLabelText('Repeat the password', { exact: false }), + { + target: { + value: '123', + }, + }, + ); + + fireEvent.click( + screen + .getByRole('button', { name: 'Change password' }) + .closest('button') as HTMLButtonElement, + ); + + uxpect(onSubmit, 'was called'); }); }); diff --git a/packages/app/components/ui/form/FormError.tsx b/packages/app/components/ui/form/FormError.tsx index bd0fbad..0afba46 100644 --- a/packages/app/components/ui/form/FormError.tsx +++ b/packages/app/components/ui/form/FormError.tsx @@ -30,7 +30,11 @@ const FormError: ComponentType = ({ error }) => { content = resolveError(error); } - return
{content}
; + return ( +
+ {content} +
+ ); }; export default FormError; diff --git a/packages/app/components/ui/form/Input.test.tsx b/packages/app/components/ui/form/Input.test.tsx index f003780..d1e7467 100644 --- a/packages/app/components/ui/form/Input.test.tsx +++ b/packages/app/components/ui/form/Input.test.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import { mount } from 'enzyme'; +import { render, screen } from '@testing-library/react'; import expect from 'app/test/unexpected'; import { IntlProvider } from 'react-intl'; @@ -7,9 +7,9 @@ import Input from './Input'; describe('Input', () => { it('should return input value', () => { - let component: any; + let component: Input | null = null; - const wrapper = mount( + render( { , ); - expect( - wrapper.find('input[name="test"]').getDOMNode().value, - 'to equal', - 'foo', - ); - expect(component.getValue(), 'to equal', 'foo'); + expect(screen.getByDisplayValue('foo'), 'to be a', HTMLElement); + expect(component && (component as Input).getValue(), 'to equal', 'foo'); }); }); diff --git a/packages/app/components/ui/popup/PopupStack.test.tsx b/packages/app/components/ui/popup/PopupStack.test.tsx index d3c315c..377d5fe 100644 --- a/packages/app/components/ui/popup/PopupStack.test.tsx +++ b/packages/app/components/ui/popup/PopupStack.test.tsx @@ -1,15 +1,18 @@ import sinon from 'sinon'; -import expect from 'app/test/unexpected'; - +import uxpect from 'app/test/unexpected'; +import { render, fireEvent, waitFor, screen } from '@testing-library/react'; import React from 'react'; -import { shallow, mount } from 'enzyme'; +import { PopupStack } from './PopupStack'; -import PopupStack from 'app/components/ui/popup/PopupStack'; -import styles from 'app/components/ui/popup/popup.scss'; - -function DummyPopup(_props: Record) { - return null; +function DummyPopup({ onClose }: Record) { + return ( +
+ +
+ ); } describe('', () => { @@ -25,60 +28,42 @@ describe('', () => { }, ], }; - const component = shallow(); - expect(component.find(DummyPopup), 'to satisfy', { length: 2 }); + render(); + + const popups = screen.getAllByRole('dialog'); + + uxpect(popups, 'to have length', 2); }); - it('should pass onClose as props', () => { - const expectedProps = { - foo: 'bar', - }; - - const props: any = { - destroy: () => {}, - popups: [ - { - Popup: (popupProps = { onClose: Function }) => { - // eslint-disable-next-line - expect(popupProps.onClose, 'to be a', 'function'); - - return ; - }, - }, - ], - }; - const component = mount(); - - const popup = component.find(DummyPopup); - expect(popup, 'to satisfy', { length: 1 }); - expect(popup.props(), 'to equal', expectedProps); - }); - - it('should hide popup, when onClose called', () => { + it('should hide popup, when onClose called', async () => { + const destroy = sinon.stub().named('props.destroy'); const props: any = { popups: [ { Popup: DummyPopup, }, - { - Popup: DummyPopup, - }, ], - destroy: sinon.stub().named('props.destroy'), + destroy, }; - const component = shallow(); - component.find(DummyPopup).last().prop('onClose')(); + const { rerender } = render(); - expect(props.destroy, 'was called once'); - expect(props.destroy, 'to have a call satisfying', [ - expect.it('to be', props.popups[1]), + fireEvent.click(screen.getByRole('button', { name: 'close' })); + + uxpect(destroy, 'was called once'); + uxpect(destroy, 'to have a call satisfying', [ + uxpect.it('to be', props.popups[0]), ]); + + rerender(); + + await waitFor(() => { + expect(screen.queryByRole('dialog')).not.toBeInTheDocument(); + }); }); it('should hide popup, when overlay clicked', () => { - const preventDefault = sinon.stub().named('event.preventDefault'); const props: any = { destroy: sinon.stub().named('props.destroy'), popups: [ @@ -87,16 +72,15 @@ describe('', () => { }, ], }; - const component = shallow(); - const overlay = component.find(`.${styles.overlay}`); - overlay.simulate('click', { target: 1, currentTarget: 1, preventDefault }); + render(); - expect(props.destroy, 'was called once'); - expect(preventDefault, 'was called once'); + fireEvent.click(screen.getByRole('dialog')); + + uxpect(props.destroy, 'was called once'); }); - it('should hide popup on overlay click if disableOverlayClose', () => { + it('should not hide popup on overlay click if disableOverlayClose', () => { const props: any = { destroy: sinon.stub().named('props.destroy'), popups: [ @@ -106,16 +90,12 @@ describe('', () => { }, ], }; - const component = shallow(); - const overlay = component.find(`.${styles.overlay}`); - overlay.simulate('click', { - target: 1, - currentTarget: 1, - preventDefault() {}, - }); + render(); - expect(props.destroy, 'was not called'); + fireEvent.click(screen.getByRole('dialog')); + + uxpect(props.destroy, 'was not called'); }); it('should hide popup, when esc pressed', () => { @@ -127,14 +107,15 @@ describe('', () => { }, ], }; - mount(); + + render(); const event = new Event('keyup'); // @ts-ignore event.which = 27; document.dispatchEvent(event); - expect(props.destroy, 'was called once'); + uxpect(props.destroy, 'was called once'); }); it('should hide first popup in stack if esc pressed', () => { @@ -151,16 +132,17 @@ describe('', () => { }, ], }; - mount(); + + render(); const event = new Event('keyup'); // @ts-ignore event.which = 27; document.dispatchEvent(event); - expect(props.destroy, 'was called once'); - expect(props.destroy, 'to have a call satisfying', [ - expect.it('to be', props.popups[1]), + uxpect(props.destroy, 'was called once'); + uxpect(props.destroy, 'to have a call satisfying', [ + uxpect.it('to be', props.popups[1]), ]); }); @@ -174,13 +156,14 @@ describe('', () => { }, ], }; - mount(); + + render(); const event = new Event('keyup'); // @ts-ignore event.which = 27; document.dispatchEvent(event); - expect(props.destroy, 'was not called'); + uxpect(props.destroy, 'was not called'); }); }); diff --git a/packages/app/components/ui/popup/PopupStack.tsx b/packages/app/components/ui/popup/PopupStack.tsx index 469a69b..26e603a 100644 --- a/packages/app/components/ui/popup/PopupStack.tsx +++ b/packages/app/components/ui/popup/PopupStack.tsx @@ -48,6 +48,7 @@ export class PopupStack extends React.Component { >
@@ -60,7 +61,7 @@ export class PopupStack extends React.Component { } onClose(popup: PopupConfig) { - return this.props.destroy.bind(null, popup); + return () => this.props.destroy(popup); } onOverlayClick(popup: PopupConfig) { diff --git a/packages/app/containers/AuthFlowRouteContents.test.tsx b/packages/app/containers/AuthFlowRouteContents.test.tsx index 343e8d4..e5143ab 100644 --- a/packages/app/containers/AuthFlowRouteContents.test.tsx +++ b/packages/app/containers/AuthFlowRouteContents.test.tsx @@ -1,7 +1,7 @@ import React from 'react'; import sinon from 'sinon'; -import expect from 'app/test/unexpected'; -import { mount } from 'enzyme'; +import uxpect from 'app/test/unexpected'; +import { render, screen } from '@testing-library/react'; import authFlow from 'app/services/authFlow'; import AuthFlowRouteContents from './AuthFlowRouteContents'; @@ -15,8 +15,12 @@ describe('AuthFlowRouteContents', () => { (authFlow.handleRequest as any).restore(); }); - function Component() { - return
; + let componentProps: { [key: string]: any }; + + function Component(props: { [key: string]: any }) { + componentProps = props; + + return
; } it('should render component if route allowed', () => { @@ -26,7 +30,7 @@ describe('AuthFlowRouteContents', () => { query: new URLSearchParams(), }; - const routerProps = { + const routerProps: any = { location: { pathname: authRequest.path, search: '', @@ -35,26 +39,26 @@ describe('AuthFlowRouteContents', () => { match: { params: authRequest.params, }, - } as any; + }; (authFlow.handleRequest as any).callsArg(2); - const wrapper = mount( + render( , ); - const component = wrapper.find(Component); + const component = screen.getByTestId('test-component'); - expect(authFlow.handleRequest, 'to have a call satisfying', [ + uxpect(authFlow.handleRequest, 'to have a call satisfying', [ { ...authRequest, - query: expect.it('to be a', URLSearchParams), + query: uxpect.it('to be a', URLSearchParams), }, - expect.it('to be a function'), - expect.it('to be a function'), + uxpect.it('to be a function'), + uxpect.it('to be a function'), ]); - expect(component.exists(), 'to be true'); - expect(component.props(), 'to equal', routerProps); + expect(component).toBeInTheDocument(); + uxpect(componentProps, 'to equal', routerProps); }); }); diff --git a/packages/app/package.json b/packages/app/package.json index 60d33c2..5ecef47 100644 --- a/packages/app/package.json +++ b/packages/app/package.json @@ -34,8 +34,9 @@ "whatwg-fetch": "^3.0.0" }, "devDependencies": { + "@testing-library/jest-dom": "^5.8.0", + "@testing-library/react": "^10.0.4", "@types/debounce": "^1.2.0", - "@types/enzyme": "^3.10.5", "@types/intl": "^1.2.0", "@types/promise.prototype.finally": "^2.0.4", "@types/raf": "^3.4.0", @@ -44,8 +45,6 @@ "@types/react-motion": "^0.0.29", "@types/react-transition-group": "^4.2.4", "@types/webfontloader": "^1.6.30", - "@types/webpack-env": "^1.15.2", - "enzyme": "^3.8.0", - "enzyme-adapter-react-16": "^1.15.1" + "@types/webpack-env": "^1.15.2" } } diff --git a/packages/app/pages/rules/RulesPage.test.tsx b/packages/app/pages/rules/RulesPage.test.tsx index 98b225b..030fd63 100644 --- a/packages/app/pages/rules/RulesPage.test.tsx +++ b/packages/app/pages/rules/RulesPage.test.tsx @@ -1,85 +1,63 @@ -import React, { ComponentProps } from 'react'; +import React from 'react'; import sinon from 'sinon'; import expect from 'app/test/unexpected'; -import { shallow, ShallowWrapper } from 'enzyme'; +import { render, fireEvent, createEvent, screen } from '@testing-library/react'; +import { TestContextProvider } from 'app/shell'; import RulesPage from './RulesPage'; -type RulesPageShallowType = ShallowWrapper< - ComponentProps, - any, - RulesPage ->; - describe('RulesPage', () => { describe('#onRuleClick()', () => { const id = 'rule-1-2'; const pathname = '/foo'; const search = '?bar'; - let page: RulesPageShallowType; + let page: HTMLElement; let replace: Function; beforeEach(() => { replace = sinon.stub().named('history.replace'); - page = shallow( - , - ); + ({ container: page } = render( + + + , + )); }); it('should update location on rule click', () => { const expectedUrl = `/foo?bar#${id}`; - page.find(`#${id}`).simulate('click', { - target: document.createElement('li'), - - currentTarget: { - id, - }, - }); + fireEvent.click(page.querySelector(`#${id}`) as HTMLElement); expect(replace, 'to have a call satisfying', [expectedUrl]); }); it('should not update location if link was clicked', () => { - page.find(`#${id}`).simulate('click', { - target: document.createElement('a'), - - currentTarget: { - id, - }, - }); + fireEvent.click(screen.getByText('/register', { exact: false })); expect(replace, 'was not called'); }); it('should not update location if defaultPrevented', () => { - page.find(`#${id}`).simulate('click', { - defaultPrevented: true, + const el = page.querySelector(`#${id}`) as HTMLElement; + const event = createEvent.click(el); - target: { - tagName: 'li', - }, + event.preventDefault(); - currentTarget: { - id, - }, - }); + fireEvent(el, event); expect(replace, 'was not called'); }); it('should not update location if no id', () => { - page.find(`#${id}`).simulate('click', { - target: { - tagName: 'li', - }, + const el = page.querySelector(`#${id}`) as HTMLElement; - currentTarget: {}, - }); + el.id = ''; + + fireEvent.click(el); expect(replace, 'was not called'); }); diff --git a/packages/app/services/api/options.test.ts b/packages/app/services/api/options.test.ts index 1e2c754..f7e566a 100644 --- a/packages/app/services/api/options.test.ts +++ b/packages/app/services/api/options.test.ts @@ -4,7 +4,9 @@ import request from 'app/services/request'; import options from './options'; describe('services/api/options', () => { - const expectedResp = { foo: 'bar' }; + const expectedResp = { + foo: 'bar', + }; beforeEach(() => { sinon @@ -24,7 +26,10 @@ describe('services/api/options', () => { it('should request options without token', () => options.get().then((resp) => { - expect(resp, 'to be', expectedResp); + expect(resp, 'to satisfy', { + ...expectedResp, + originalResponse: expect.it('to be a', Response), + }); expect(request.get, 'to have a call satisfying', [ '/api/options', {}, @@ -36,7 +41,10 @@ describe('services/api/options', () => { // NOTE: this is bad practice, but we are relying on the state from // the previous test options.get().then((resp) => { - expect(resp, 'to be', expectedResp); + expect(resp, 'to satisfy', { + ...expectedResp, + originalResponse: expect.it('to be a', Response), + }); expect(request.get, 'was not called'); })); }); diff --git a/packages/app/services/authFlow/AuthFlow.test.ts b/packages/app/services/authFlow/AuthFlow.test.ts index 6feb1f9..3e081d2 100644 --- a/packages/app/services/authFlow/AuthFlow.test.ts +++ b/packages/app/services/authFlow/AuthFlow.test.ts @@ -30,15 +30,6 @@ describe('AuthFlow', () => { flow = new AuthFlow(actions); }); - it('throws when no actions provided', () => { - expect( - // @ts-ignore - () => new AuthFlow(), - 'to throw', - 'AuthFlow requires an actions object', - ); - }); - it('should not allow to mutate actions', () => { expect( // @ts-ignore diff --git a/packages/app/shell/TestContextProvider.tsx b/packages/app/shell/TestContextProvider.tsx new file mode 100644 index 0000000..8f95de0 --- /dev/null +++ b/packages/app/shell/TestContextProvider.tsx @@ -0,0 +1,18 @@ +import React from 'react'; +import { createMemoryHistory } from 'history'; +import storeFactory from 'app/storeFactory'; + +import ContextProvider from './ContextProvider'; + +type ContextProps = React.ComponentProps; + +function TestContextProvider( + props: Partial & { children: ContextProps['children'] }, +) { + const store = React.useMemo(storeFactory, []); + const history = React.useMemo(createMemoryHistory, []); + + return ; +} + +export default TestContextProvider; diff --git a/packages/app/shell/index.ts b/packages/app/shell/index.ts deleted file mode 100644 index cab2d0d..0000000 --- a/packages/app/shell/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { default as ContextProvider } from './ContextProvider'; diff --git a/packages/app/shell/index.tsx b/packages/app/shell/index.tsx new file mode 100644 index 0000000..bd813dd --- /dev/null +++ b/packages/app/shell/index.tsx @@ -0,0 +1,2 @@ +export { default as ContextProvider } from './ContextProvider'; +export { default as TestContextProvider } from './TestContextProvider'; diff --git a/yarn.lock b/yarn.lock index b623312..cf6be4e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1787,7 +1787,7 @@ pirates "^4.0.0" source-map-support "^0.5.16" -"@babel/runtime-corejs3@^7.8.3": +"@babel/runtime-corejs3@^7.7.4", "@babel/runtime-corejs3@^7.8.3": version "7.9.6" resolved "https://registry.yarnpkg.com/@babel/runtime-corejs3/-/runtime-corejs3-7.9.6.tgz#67aded13fffbbc2cb93247388cf84d77a4be9a71" integrity sha512-6toWAfaALQjt3KMZQc6fABqZwUDDuWzz+cAfPhqyEnzxvdWOAkjwPNxgF8xlmo7OWLsSjaKjsskpKHRLaMArOA== @@ -1809,7 +1809,7 @@ dependencies: regenerator-runtime "^0.13.2" -"@babel/runtime@^7.8.4", "@babel/runtime@^7.9.2": +"@babel/runtime@^7.8.4", "@babel/runtime@^7.9.2", "@babel/runtime@^7.9.6": version "7.9.6" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.9.6.tgz#a9102eb5cadedf3f31d08a9ecf294af7827ea29f" integrity sha512-64AF1xY3OAkFHqOb9s4jpgk1Mm5vDZ4L3acHvAml+53nO1XbXLuDodsVpO4OIUsmemlUHMxNdYMNJmsvOwLrvQ== @@ -2891,6 +2891,40 @@ "@svgr/plugin-svgo" "^4.3.1" loader-utils "^1.2.3" +"@testing-library/dom@^7.2.2": + version "7.5.7" + resolved "https://registry.yarnpkg.com/@testing-library/dom/-/dom-7.5.7.tgz#c4bf683a65083d4a78644588cfa4ad684c113fc7" + integrity sha512-835MiwAxQE7xjSrhpeJbv41UQRmsPJQ0tGfzWiJMdZj2LBbdG5cT8Z44Viv11/XucCmJHr/v8q7VpZnuSimscg== + dependencies: + "@babel/runtime" "^7.9.6" + aria-query "^4.0.2" + dom-accessibility-api "^0.4.4" + pretty-format "^25.5.0" + +"@testing-library/jest-dom@^5.8.0": + version "5.8.0" + resolved "https://registry.yarnpkg.com/@testing-library/jest-dom/-/jest-dom-5.8.0.tgz#815e830129c4dda6c8e9a725046397acec523669" + integrity sha512-9Y4FxYIxfwHpUyJVqI8EOfDP2LlEBqKwXE3F+V8ightji0M2rzQB+9kqZ5UJxNs+9oXJIgvYj7T3QaXLNHVDMw== + dependencies: + "@babel/runtime" "^7.9.2" + "@types/testing-library__jest-dom" "^5.0.2" + chalk "^3.0.0" + css "^2.2.4" + css.escape "^1.5.1" + jest-diff "^25.1.0" + jest-matcher-utils "^25.1.0" + lodash "^4.17.15" + redent "^3.0.0" + +"@testing-library/react@^10.0.4": + version "10.0.4" + resolved "https://registry.yarnpkg.com/@testing-library/react/-/react-10.0.4.tgz#8e0e299cd91acc626d81ed8489fdc13df864c31d" + integrity sha512-2e1B5debfuiIGbvUuiSXybskuh7ZTVJDDvG/IxlzLOY9Co/mKFj9hIklAe2nGZYcOUxFaiqWrRZ9vCVGzJfRlQ== + dependencies: + "@babel/runtime" "^7.9.6" + "@testing-library/dom" "^7.2.2" + "@types/testing-library__react" "^10.0.1" + "@types/anymatch@*": version "1.3.1" resolved "https://registry.yarnpkg.com/@types/anymatch/-/anymatch-1.3.1.tgz#336badc1beecb9dacc38bea2cf32adf627a8421a" @@ -2957,13 +2991,6 @@ resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.2.7.tgz#1c8c25cbf6e59ffa7d6b9652c78e547d9a41692d" integrity sha512-luq8meHGYwvky0O7u0eQZdA7B4Wd9owUCqvbw2m3XCrCU8mplYOujMBbvyS547AxJkC+pGnd0Cm15eNxEUNU8g== -"@types/cheerio@*": - version "0.22.15" - resolved "https://registry.yarnpkg.com/@types/cheerio/-/cheerio-0.22.15.tgz#69040ffa92c309beeeeb7e92db66ac3f80700c0b" - integrity sha512-UGiiVtJK5niCqMKYmLEFz1Wl/3L5zF/u78lu8CwoUywWXRr9LDimeYuOzXVLXBMO758fcTdFtgjvqlztMH90MA== - dependencies: - "@types/node" "*" - "@types/color-name@^1.1.1": version "1.1.1" resolved "https://registry.yarnpkg.com/@types/color-name/-/color-name-1.1.1.tgz#1c1261bbeaa10a8055bbc5d8ab84b7b2afc846a0" @@ -2974,14 +3001,6 @@ resolved "https://registry.yarnpkg.com/@types/debounce/-/debounce-1.2.0.tgz#9ee99259f41018c640b3929e1bb32c3dcecdb192" integrity sha512-bWG5wapaWgbss9E238T0R6bfo5Fh3OkeoSt245CM7JJwVwpw6MEBCbIxLq5z8KzsE3uJhzcIuQkyiZmzV3M/Dw== -"@types/enzyme@^3.10.5": - version "3.10.5" - resolved "https://registry.yarnpkg.com/@types/enzyme/-/enzyme-3.10.5.tgz#fe7eeba3550369eed20e7fb565bfb74eec44f1f0" - integrity sha512-R+phe509UuUYy9Tk0YlSbipRpfVtIzb/9BHn5pTEtjJTF5LXvUjrIQcZvNyANNEyFrd2YGs196PniNT1fgvOQA== - dependencies: - "@types/cheerio" "*" - "@types/react" "*" - "@types/eslint-visitor-keys@^1.0.0": version "1.0.0" resolved "https://registry.yarnpkg.com/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#1ee30d79544ca84d68d4b3cdb0af4f205663dd2d" @@ -3073,7 +3092,7 @@ "@types/istanbul-lib-coverage" "*" "@types/istanbul-lib-report" "*" -"@types/jest@^25.2.3": +"@types/jest@*", "@types/jest@^25.2.3": version "25.2.3" resolved "https://registry.yarnpkg.com/@types/jest/-/jest-25.2.3.tgz#33d27e4c4716caae4eced355097a47ad363fdcaf" integrity sha512-JXc1nK/tXHiDhV55dvfzqtmP4S3sy3T3ouV2tkViZgxY/zeUkcpQcQPGRlgF4KmWzWW5oiWYSZwtCB+2RsE4Fw== @@ -3187,7 +3206,7 @@ "@types/history" "*" "@types/react" "*" -"@types/react-dom@^16.9.8": +"@types/react-dom@*", "@types/react-dom@^16.9.8": version "16.9.8" resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-16.9.8.tgz#fe4c1e11dfc67155733dfa6aa65108b4971cb423" integrity sha512-ykkPQ+5nFknnlU6lDd947WbQ6TE3NNzbQAkInC2EKY1qeYdTKp7onFusmYZb+ityzx2YviqT6BXSu+LyWWJwcA== @@ -3331,6 +3350,29 @@ resolved "https://registry.yarnpkg.com/@types/tapable/-/tapable-1.0.5.tgz#9adbc12950582aa65ead76bffdf39fe0c27a3c02" integrity sha512-/gG2M/Imw7cQFp8PGvz/SwocNrmKFjFsm5Pb8HdbHkZ1K8pmuPzOX4VeVoiEecFCVf4CsN1r3/BRvx+6sNqwtQ== +"@types/testing-library__dom@*": + version "7.0.2" + resolved "https://registry.yarnpkg.com/@types/testing-library__dom/-/testing-library__dom-7.0.2.tgz#2906f8a0dce58b0746c6ab606f786bd06fe6940e" + integrity sha512-8yu1gSwUEAwzg2OlPNbGq+ixhmSviGurBu1+ivxRKq1eRcwdjkmlwtPvr9VhuxTq2fNHBWN2po6Iem3Xt5A6rg== + dependencies: + pretty-format "^25.1.0" + +"@types/testing-library__jest-dom@^5.0.2": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@types/testing-library__jest-dom/-/testing-library__jest-dom-5.7.0.tgz#078790bf4dc89152a74428591a228ec5f9433251" + integrity sha512-LoZ3uonlnAbJUz4bg6UoeFl+frfndXngmkCItSjJ8DD5WlRfVqPC5/LgJASsY/dy7AHH2YJ7PcsdASOydcVeFA== + dependencies: + "@types/jest" "*" + +"@types/testing-library__react@^10.0.1": + version "10.0.1" + resolved "https://registry.yarnpkg.com/@types/testing-library__react/-/testing-library__react-10.0.1.tgz#92bb4a02394bf44428e35f1da2970ed77f803593" + integrity sha512-RbDwmActAckbujLZeVO/daSfdL1pnjVqas25UueOkAY5r7vriavWf0Zqg7ghXMHa8ycD/kLkv8QOj31LmSYwww== + dependencies: + "@types/react-dom" "*" + "@types/testing-library__dom" "*" + pretty-format "^25.1.0" + "@types/uglify-js@*": version "3.9.0" resolved "https://registry.yarnpkg.com/@types/uglify-js/-/uglify-js-3.9.0.tgz#4490a140ca82aa855ad68093829e7fd6ae94ea87" @@ -3835,22 +3877,6 @@ airbnb-js-shims@^2.2.1: string.prototype.padstart "^3.0.0" symbol.prototype.description "^1.0.0" -airbnb-prop-types@^2.15.0: - version "2.15.0" - resolved "https://registry.yarnpkg.com/airbnb-prop-types/-/airbnb-prop-types-2.15.0.tgz#5287820043af1eb469f5b0af0d6f70da6c52aaef" - integrity sha512-jUh2/hfKsRjNFC4XONQrxo/n/3GG4Tn6Hl0WlFQN5PY9OMC9loSCoAYKnZsWaP8wEfd5xcrPloK0Zg6iS1xwVA== - dependencies: - array.prototype.find "^2.1.0" - function.prototype.name "^1.1.1" - has "^1.0.3" - is-regex "^1.0.4" - object-is "^1.0.1" - object.assign "^4.1.0" - object.entries "^1.1.0" - prop-types "^15.7.2" - prop-types-exact "^1.2.0" - react-is "^16.9.0" - ajv-errors@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/ajv-errors/-/ajv-errors-1.0.1.tgz#f35986aceb91afadec4102fbd85014950cefa64d" @@ -4035,6 +4061,14 @@ argparse@^1.0.6, argparse@^1.0.7: dependencies: sprintf-js "~1.0.2" +aria-query@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/aria-query/-/aria-query-4.0.2.tgz#250687b4ccde1ab86d127da0432ae3552fc7b145" + integrity sha512-S1G1V790fTaigUSM/Gd0NngzEfiMy9uTUfMyHhKhVyy4cH5O/eTuR01ydhGL0z4Za1PXFTRGH3qL8VhUQuEO5w== + dependencies: + "@babel/runtime" "^7.7.4" + "@babel/runtime-corejs3" "^7.7.4" + arr-diff@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" @@ -4069,11 +4103,6 @@ array-equal@^1.0.0: resolved "https://registry.yarnpkg.com/array-equal/-/array-equal-1.0.0.tgz#8c2a5ef2472fd9ea742b04c77a75093ba2757c93" integrity sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM= -array-filter@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/array-filter/-/array-filter-1.0.0.tgz#baf79e62e6ef4c2a4c0b831232daffec251f9d83" - integrity sha1-uveeYubvTCpMC4MSMtr/7CUfnYM= - array-find-index@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/array-find-index/-/array-find-index-1.0.2.tgz#df010aa1287e164bbda6f9723b0a96a1ec4187a1" @@ -4115,15 +4144,7 @@ array-unique@^0.3.2: resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" integrity sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg= -array.prototype.find@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/array.prototype.find/-/array.prototype.find-2.1.0.tgz#630f2eaf70a39e608ac3573e45cf8ccd0ede9ad7" - integrity sha512-Wn41+K1yuO5p7wRZDl7890c3xvv5UBrfVXTVIe28rSQb6LS0fZMDrQB6PAcxQFRFy6vJTLDc3A2+3CjQdzVKRg== - dependencies: - define-properties "^1.1.3" - es-abstract "^1.13.0" - -array.prototype.flat@^1.2.1, array.prototype.flat@^1.2.3: +array.prototype.flat@^1.2.1: version "1.2.3" resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.2.3.tgz#0de82b426b0318dbfdb940089e38b043d37f6c7b" integrity sha512-gBlRZV0VSmfPIeWfuuy56XZMvbVfbEUnOXUvt3F/eUUUSyzlgLxhEX4YAEpxNAogRGehPSnfXyPtYyKAhkzQhQ== @@ -5292,18 +5313,6 @@ cheerio@0.22.0: lodash.reject "^4.4.0" lodash.some "^4.4.0" -cheerio@^1.0.0-rc.3: - version "1.0.0-rc.3" - resolved "https://registry.yarnpkg.com/cheerio/-/cheerio-1.0.0-rc.3.tgz#094636d425b2e9c0f4eb91a46c05630c9a1a8bf6" - integrity sha512-0td5ijfUPuubwLUu0OBoe98gZj8C/AA+RW3v67GPlGOrvxWjZmBXiBCRU+I8VEiNyJzjth40POfHiz2RB3gImA== - dependencies: - css-select "~1.2.0" - dom-serializer "~0.1.1" - entities "~1.1.1" - htmlparser2 "^3.9.1" - lodash "^4.15.0" - parse5 "^3.0.1" - chokidar@^2.0.4, chokidar@^2.1.8: version "2.1.8" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.1.8.tgz#804b3a7b6a99358c3c5c61e71d8728f041cff917" @@ -6096,6 +6105,21 @@ css-what@^3.2.1: resolved "https://registry.yarnpkg.com/css-what/-/css-what-3.2.1.tgz#f4a8f12421064621b456755e34a03a2c22df5da1" integrity sha512-WwOrosiQTvyms+Ti5ZC5vGEK0Vod3FTt1ca+payZqvKuGJF+dq7bG63DstxtN0dpm6FxY27a/zS3Wten+gEtGw== +css.escape@^1.5.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/css.escape/-/css.escape-1.5.1.tgz#42e27d4fa04ae32f931a4b4d4191fa9cddee97cb" + integrity sha1-QuJ9T6BK4y+TGktNQZH6nN3ul8s= + +css@^2.2.4: + version "2.2.4" + resolved "https://registry.yarnpkg.com/css/-/css-2.2.4.tgz#c646755c73971f2bba6a601e2cf2fd71b1298929" + integrity sha512-oUnjmWpy0niI3x/mPL8dVEI1l7MnG3+HHyRPHf+YFSbK+svOhXpmSOcDURUh2aOCgl2grzrOPt1nHLuCVFULLw== + dependencies: + inherits "^2.0.3" + source-map "^0.6.1" + source-map-resolve "^0.5.2" + urix "^0.1.0" + cssesc@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-2.0.0.tgz#3b13bd1bb1cb36e1bcb5a4dcd27f54c5dcb35703" @@ -6566,11 +6590,6 @@ dir-glob@2.0.0: arrify "^1.0.1" path-type "^3.0.0" -discontinuous-range@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/discontinuous-range/-/discontinuous-range-1.0.0.tgz#e38331f0844bba49b9a9cb71c771585aab1bc65a" - integrity sha1-44Mx8IRLukm5qctxx3FYWqsbxlo= - dns-equal@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/dns-equal/-/dns-equal-1.0.0.tgz#b39e7f1da6eb0a75ba9c17324b34753c47e0654d" @@ -6605,6 +6624,11 @@ doctrine@^3.0.0: dependencies: esutils "^2.0.2" +dom-accessibility-api@^0.4.4: + version "0.4.4" + resolved "https://registry.yarnpkg.com/dom-accessibility-api/-/dom-accessibility-api-0.4.4.tgz#c2f9fb8b591bc19581e7ef3e6fe35baf1967c498" + integrity sha512-XBM62jdDc06IXSujkqw6BugEWiDkp6jphtzVJf1kgPQGvfzaU7/jRtRSF/mxc8DBCIm2LS3bN1dCa5Sfxx982A== + dom-converter@^0.2: version "0.2.0" resolved "https://registry.yarnpkg.com/dom-converter/-/dom-converter-0.2.0.tgz#6721a9daee2e293682955b6afe416771627bb768" @@ -6628,7 +6652,7 @@ dom-serializer@0, dom-serializer@^0.2.1: domelementtype "^2.0.1" entities "^2.0.0" -dom-serializer@~0.1.0, dom-serializer@~0.1.1: +dom-serializer@~0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.1.1.tgz#1ec4059e284babed36eec2941d4a970a189ce7c0" integrity sha512-l0IU0pPzLWSHBcieZbpOKgkIn3ts3vAh7ZuFyXNwJxJXk/c4Gwj9xaTJwIDVQCXawWD0qb3IzMGH5rglQaO0XA== @@ -6922,69 +6946,6 @@ env-ci@^2.1.0: execa "^1.0.0" java-properties "^0.2.9" -enzyme-adapter-react-16@^1.15.1: - version "1.15.2" - resolved "https://registry.yarnpkg.com/enzyme-adapter-react-16/-/enzyme-adapter-react-16-1.15.2.tgz#b16db2f0ea424d58a808f9df86ab6212895a4501" - integrity sha512-SkvDrb8xU3lSxID8Qic9rB8pvevDbLybxPK6D/vW7PrT0s2Cl/zJYuXvsd1EBTz0q4o3iqG3FJhpYz3nUNpM2Q== - dependencies: - enzyme-adapter-utils "^1.13.0" - enzyme-shallow-equal "^1.0.1" - has "^1.0.3" - object.assign "^4.1.0" - object.values "^1.1.1" - prop-types "^15.7.2" - react-is "^16.12.0" - react-test-renderer "^16.0.0-0" - semver "^5.7.0" - -enzyme-adapter-utils@^1.13.0: - version "1.13.0" - resolved "https://registry.yarnpkg.com/enzyme-adapter-utils/-/enzyme-adapter-utils-1.13.0.tgz#01c885dde2114b4690bf741f8dc94cee3060eb78" - integrity sha512-YuEtfQp76Lj5TG1NvtP2eGJnFKogk/zT70fyYHXK2j3v6CtuHqc8YmgH/vaiBfL8K1SgVVbQXtTcgQZFwzTVyQ== - dependencies: - airbnb-prop-types "^2.15.0" - function.prototype.name "^1.1.2" - object.assign "^4.1.0" - object.fromentries "^2.0.2" - prop-types "^15.7.2" - semver "^5.7.1" - -enzyme-shallow-equal@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/enzyme-shallow-equal/-/enzyme-shallow-equal-1.0.1.tgz#7afe03db3801c9b76de8440694096412a8d9d49e" - integrity sha512-hGA3i1so8OrYOZSM9whlkNmVHOicJpsjgTzC+wn2JMJXhq1oO4kA4bJ5MsfzSIcC71aLDKzJ6gZpIxrqt3QTAQ== - dependencies: - has "^1.0.3" - object-is "^1.0.2" - -enzyme@^3.8.0: - version "3.11.0" - resolved "https://registry.yarnpkg.com/enzyme/-/enzyme-3.11.0.tgz#71d680c580fe9349f6f5ac6c775bc3e6b7a79c28" - integrity sha512-Dw8/Gs4vRjxY6/6i9wU0V+utmQO9kvh9XLnz3LIudviOnVYDEe2ec+0k+NQoMamn1VrjKgCUOWj5jG/5M5M0Qw== - dependencies: - array.prototype.flat "^1.2.3" - cheerio "^1.0.0-rc.3" - enzyme-shallow-equal "^1.0.1" - function.prototype.name "^1.1.2" - has "^1.0.3" - html-element-map "^1.2.0" - is-boolean-object "^1.0.1" - is-callable "^1.1.5" - is-number-object "^1.0.4" - is-regex "^1.0.5" - is-string "^1.0.5" - is-subset "^0.1.1" - lodash.escape "^4.0.1" - lodash.isequal "^4.5.0" - object-inspect "^1.7.0" - object-is "^1.0.2" - object.assign "^4.1.0" - object.entries "^1.1.1" - object.values "^1.1.1" - raf "^3.4.1" - rst-selector-parser "^2.2.3" - string.prototype.trim "^1.2.1" - errno@^0.1.3, errno@~0.1.7: version "0.1.7" resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.7.tgz#4684d71779ad39af177e3f007996f7c67c852618" @@ -6999,7 +6960,7 @@ error-ex@^1.2.0, error-ex@^1.3.1: dependencies: is-arrayish "^0.2.1" -es-abstract@^1.13.0, es-abstract@^1.17.0, es-abstract@^1.17.0-next.0: +es-abstract@^1.17.0, es-abstract@^1.17.0-next.0: version "1.17.0" resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.17.0.tgz#f42a517d0036a5591dbb2c463591dc8bb50309b1" integrity sha512-yYkE07YF+6SIBmg1MsJ9dlub5L48Ek7X0qz+c/CPCHS9EBXfESorzng4cJQjJW5/pB6vDF41u7F8vUhLVDqIug== @@ -7987,7 +7948,7 @@ function-bind@^1.1.1: resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== -function.prototype.name@^1.1.0, function.prototype.name@^1.1.1, function.prototype.name@^1.1.2: +function.prototype.name@^1.1.0: version "1.1.2" resolved "https://registry.yarnpkg.com/function.prototype.name/-/function.prototype.name-1.1.2.tgz#5cdf79d7c05db401591dfde83e3b70c5123e9a45" integrity sha512-C8A+LlHBJjB2AdcRPorc5JvJ5VUoWlXdEHLOJdCI7kjHEtGTpHQUiqMvCIKUwIsGwZX2jZJy761AXsn356bJQg== @@ -8518,13 +8479,6 @@ html-comment-regex@^1.1.0: resolved "https://registry.yarnpkg.com/html-comment-regex/-/html-comment-regex-1.1.2.tgz#97d4688aeb5c81886a364faa0cad1dda14d433a7" integrity sha512-P+M65QY2JQ5Y0G9KKdlDpo0zK+/OHptU5AaBwUfAIDJZk1MYf32Frm84EcOytfJE0t5JvkAnKlmjsXDnWzCJmQ== -html-element-map@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/html-element-map/-/html-element-map-1.2.0.tgz#dfbb09efe882806af63d990cf6db37993f099f22" - integrity sha512-0uXq8HsuG1v2TmQ8QkIhzbrqeskE4kn52Q18QJ9iAA/SnHoEKXWiUxHQtclRsCFWEUD2So34X+0+pZZu862nnw== - dependencies: - array-filter "^1.0.0" - html-encoding-sniffer@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz#e70d84b94da53aa375e11fe3a351be6642ca46f8" @@ -9094,11 +9048,6 @@ is-binary-path@~2.1.0: dependencies: binary-extensions "^2.0.0" -is-boolean-object@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.0.1.tgz#10edc0900dd127697a92f6f9807c7617d68ac48e" - integrity sha512-TqZuVwa/sppcrhUCAYkGBk7w0yxfQQnxq28fjkO53tnK9FQXmdwz2JS5+GjsWQ6RByES1K40nI+yDic5c9/aAQ== - is-buffer@^1.0.2, is-buffer@^1.1.5: version "1.1.6" resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" @@ -9288,11 +9237,6 @@ is-map@^2.0.0: resolved "https://registry.yarnpkg.com/is-map/-/is-map-2.0.1.tgz#520dafc4307bb8ebc33b813de5ce7c9400d644a1" integrity sha512-T/S49scO8plUiAOA2DBTBG3JHpn1yiw0kRp6dgiZ0v2/6twi5eiB0rHtHFH9ZIrvlWc6+4O+m4zg5+Z833aXgw== -is-number-object@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.4.tgz#36ac95e741cf18b283fc1ddf5e83da798e3ec197" - integrity sha512-zohwelOAur+5uXtk8O3GPQ1eAcu4ZX3UwxQhUlfFFMNpUd83gXgjbhJh6HmB6LUNV/ieOLQuDwJO3dWJosUeMw== - is-number@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" @@ -9419,11 +9363,6 @@ is-string@^1.0.4, is-string@^1.0.5: resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.5.tgz#40493ed198ef3ff477b8c7f92f644ec82a5cd3a6" integrity sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ== -is-subset@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/is-subset/-/is-subset-0.1.1.tgz#8a59117d932de1de00f245fcdd39ce43f1e939a6" - integrity sha1-ilkRfZMt4d4A8kX83TnOQ/HpOaY= - is-svg@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/is-svg/-/is-svg-3.0.0.tgz#9321dbd29c212e5ca99c4fa9794c714bcafa2f75" @@ -9635,7 +9574,7 @@ jest-config@^26.0.1: micromatch "^4.0.2" pretty-format "^26.0.1" -jest-diff@^25.2.1: +jest-diff@^25.1.0, jest-diff@^25.2.1, jest-diff@^25.5.0: version "25.5.0" resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-25.5.0.tgz#1dd26ed64f96667c068cef026b677dfa01afcfa9" integrity sha512-z1kygetuPiREYdNIumRpAHY6RXiGmp70YHptjdaxTWGmA085W3iCnXNx0DhflK3vwrKmrRWyY1wUpkPMVxMK7A== @@ -9757,6 +9696,16 @@ jest-leak-detector@^26.0.1: jest-get-type "^26.0.0" pretty-format "^26.0.1" +jest-matcher-utils@^25.1.0: + version "25.5.0" + resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-25.5.0.tgz#fbc98a12d730e5d2453d7f1ed4a4d948e34b7867" + integrity sha512-VWI269+9JS5cpndnpCwm7dy7JtGQT30UHfrnM3mXl22gHGt/b7NkjBqXfbhZ8V4B7ANUsjK18PlSBmG0YH7gjw== + dependencies: + chalk "^3.0.0" + jest-diff "^25.5.0" + jest-get-type "^25.2.6" + pretty-format "^25.5.0" + jest-matcher-utils@^26.0.1: version "26.0.1" resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-26.0.1.tgz#12e1fc386fe4f14678f4cc8dbd5ba75a58092911" @@ -10488,11 +10437,6 @@ lodash.defaults@^4.0.1: resolved "https://registry.yarnpkg.com/lodash.defaults/-/lodash.defaults-4.2.0.tgz#d09178716ffea4dde9e5fb7b37f6f0802274580c" integrity sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw= -lodash.escape@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/lodash.escape/-/lodash.escape-4.0.1.tgz#c9044690c21e04294beaa517712fded1fa88de98" - integrity sha1-yQRGkMIeBClL6qUXcS/e0fqI3pg= - lodash.filter@^4.4.0: version "4.6.0" resolved "https://registry.yarnpkg.com/lodash.filter/-/lodash.filter-4.6.0.tgz#668b1d4981603ae1cc5a6fa760143e480b4c4ace" @@ -10503,11 +10447,6 @@ lodash.flatten@^4.2.0: resolved "https://registry.yarnpkg.com/lodash.flatten/-/lodash.flatten-4.4.0.tgz#f31c22225a9632d2bbf8e4addbef240aa765a61f" integrity sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8= -lodash.flattendeep@^4.4.0: - version "4.4.0" - resolved "https://registry.yarnpkg.com/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz#fb030917f86a3134e5bc9bec0d69e0013ddfedb2" - integrity sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI= - lodash.foreach@^4.3.0: version "4.5.0" resolved "https://registry.yarnpkg.com/lodash.foreach/-/lodash.foreach-4.5.0.tgz#1a6a35eace401280c7f06dddec35165ab27e3e53" @@ -10518,11 +10457,6 @@ lodash.get@^4.4.2: resolved "https://registry.yarnpkg.com/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99" integrity sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk= -lodash.isequal@^4.5.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0" - integrity sha1-QVxEePK8wwEgwizhDtMib30+GOA= - lodash.map@^4.4.0: version "4.6.0" resolved "https://registry.yarnpkg.com/lodash.map/-/lodash.map-4.6.0.tgz#771ec7839e3473d9c4cde28b19394c3562f4f6d3" @@ -10578,7 +10512,7 @@ lodash.uniq@^4.5.0: resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M= -lodash@4.17.15, lodash@^4.0.0, lodash@^4.15.0, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.4, lodash@~4.17.10: +lodash@4.17.15, lodash@^4.0.0, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.4, lodash@~4.17.10: version "4.17.15" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548" integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A== @@ -11091,11 +11025,6 @@ moment@2.24.0, moment@^2.18.1: resolved "https://registry.yarnpkg.com/moment/-/moment-2.24.0.tgz#0d055d53f5052aa653c9f6eb68bb5d12bf5c2b5b" integrity sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg== -moo@^0.4.3: - version "0.4.3" - resolved "https://registry.yarnpkg.com/moo/-/moo-0.4.3.tgz#3f847a26f31cf625a956a87f2b10fbc013bfd10e" - integrity sha512-gFD2xGCl8YFgGHsqJ9NKRVdwlioeW3mI1iqfLNYQOv0+6JRwG58Zk9DIGQgyIaffSYaO1xsKnMaYzzNr1KyIAw== - move-concurrently@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/move-concurrently/-/move-concurrently-1.0.1.tgz#be2c005fda32e0b29af1f05d7c4b33214c701f92" @@ -11190,17 +11119,6 @@ ncp@1.0.x: resolved "https://registry.yarnpkg.com/ncp/-/ncp-1.0.1.tgz#d15367e5cb87432ba117d2bf80fdf45aecfb4246" integrity sha1-0VNn5cuHQyuhF9K/gP30Wuz7QkY= -nearley@^2.7.10: - version "2.19.0" - resolved "https://registry.yarnpkg.com/nearley/-/nearley-2.19.0.tgz#37717781d0fd0f2bfc95e233ebd75678ca4bda46" - integrity sha512-2v52FTw7RPqieZr3Gth1luAXZR7Je6q3KaDHY5bjl/paDUdMu35fZ8ICNgiYJRr3tf3NMvIQQR1r27AvEr9CRA== - dependencies: - commander "^2.19.0" - moo "^0.4.3" - railroad-diagrams "^1.0.0" - randexp "0.4.6" - semver "^5.4.1" - neatequal@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/neatequal/-/neatequal-1.0.0.tgz#2ee1211bc9fa6e4c55715fd210bb05602eb1ae3b" @@ -11527,11 +11445,6 @@ object-is@^1.0.1: define-properties "^1.1.3" es-abstract "^1.17.5" -object-is@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.0.2.tgz#6b80eb84fe451498f65007982f035a5b445edec4" - integrity sha512-Epah+btZd5wrrfjkJZq1AOB9O6OxUQto45hzFd7lXGrpHPGE0W1k+426yrZV+k6NJOzLNNW/nVsmZdIWsAqoOQ== - object-keys@^1.0.11, object-keys@^1.0.12, object-keys@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" @@ -11975,13 +11888,6 @@ parse5@5.1.1: resolved "https://registry.yarnpkg.com/parse5/-/parse5-5.1.1.tgz#f68e4e5ba1852ac2cadc00f4555fff6c2abb6178" integrity sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug== -parse5@^3.0.1: - version "3.0.3" - resolved "https://registry.yarnpkg.com/parse5/-/parse5-3.0.3.tgz#042f792ffdd36851551cf4e9e066b3874ab45b5c" - integrity sha512-rgO9Zg5LLLkfJF9E6CCmXlSE4UVceloys8JrFqCcHloC3usd/kJCyPDwH2SOlzix2j3xaP9sUX3e8+kvkuleAA== - dependencies: - "@types/node" "*" - parseurl@~1.3.2, parseurl@~1.3.3: version "1.3.3" resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" @@ -12684,7 +12590,7 @@ pretty-error@^2.1.1: renderkid "^2.0.1" utila "~0.4" -pretty-format@^25.2.1, pretty-format@^25.5.0: +pretty-format@^25.1.0, pretty-format@^25.2.1, pretty-format@^25.5.0: version "25.5.0" resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-25.5.0.tgz#7873c1d774f682c34b8d48b6743a2bf2ac55791a" integrity sha512-kbo/kq2LQ/A/is0PQwsEHM7Ca6//bGPPvU6UnsdDRSKTWxT/ru/xb88v4BJf6a69H+uTytOEsTusT9ksd/1iWQ== @@ -12811,15 +12717,6 @@ prompts@^2.0.1: kleur "^3.0.3" sisteransi "^1.0.3" -prop-types-exact@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/prop-types-exact/-/prop-types-exact-1.2.0.tgz#825d6be46094663848237e3925a98c6e944e9869" - integrity sha512-K+Tk3Kd9V0odiXFP9fwDHUYRyvK3Nun3GVyPapSIs5OBkITAm15W0CPFD/YKTkMUAbc0b9CUwRQp2ybiBIq+eA== - dependencies: - has "^1.0.3" - object.assign "^4.1.0" - reflect.ownkeys "^0.2.0" - prop-types@^15.5.0, prop-types@^15.5.8, prop-types@^15.6.0, prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.2: version "15.7.2" resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5" @@ -12976,11 +12873,6 @@ raf@^3.1.0, raf@^3.4.1: dependencies: performance-now "^2.1.0" -railroad-diagrams@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/railroad-diagrams/-/railroad-diagrams-1.0.0.tgz#eb7e6267548ddedfb899c1b90e57374559cddb7e" - integrity sha1-635iZ1SN3t+4mcG5Dlc3RVnN234= - ramda@0.26.1: version "0.26.1" resolved "https://registry.yarnpkg.com/ramda/-/ramda-0.26.1.tgz#8d41351eb8111c55353617fc3bbffad8e4d35d06" @@ -12991,14 +12883,6 @@ ramda@^0.21.0: resolved "https://registry.yarnpkg.com/ramda/-/ramda-0.21.0.tgz#a001abedb3ff61077d4ff1d577d44de77e8d0a35" integrity sha1-oAGr7bP/YQd9T/HVd9RN536NCjU= -randexp@0.4.6: - version "0.4.6" - resolved "https://registry.yarnpkg.com/randexp/-/randexp-0.4.6.tgz#e986ad5e5e31dae13ddd6f7b3019aa7c87f60ca3" - integrity sha512-80WNmd9DA0tmZrw9qQa62GPPWfuXJknrmVmLcxvq4uZBdYqb1wYoKTmnlGUchvVWe0XiLupYkBoXVOxz3C8DYQ== - dependencies: - discontinuous-range "1.0.0" - ret "~0.1.10" - randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5: version "2.1.0" resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" @@ -13228,7 +13112,7 @@ react-intl@^4.5.5: intl-messageformat-parser "^5.0.4" shallow-equal "^1.2.1" -react-is@^16.12.0, react-is@^16.6.0, react-is@^16.8.6, react-is@^16.9.0: +react-is@^16.12.0, react-is@^16.6.0, react-is@^16.9.0: version "16.12.0" resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.12.0.tgz#2cc0fe0fba742d97fd527c42a13bec4eeb06241c" integrity sha512-rPCkf/mWBtKc97aLL9/txD8DZdemK0vkA3JMLShjlJB3Pj3s+lpf1KaBzMfQrAmhMQB0n1cU/SUGgKKBCe837Q== @@ -13334,26 +13218,6 @@ react-syntax-highlighter@^11.0.2: prismjs "^1.8.4" refractor "^2.4.1" -react-test-renderer@^16.0.0-0: - version "16.12.0" - resolved "https://registry.yarnpkg.com/react-test-renderer/-/react-test-renderer-16.12.0.tgz#11417ffda579306d4e841a794d32140f3da1b43f" - integrity sha512-Vj/teSqt2oayaWxkbhQ6gKis+t5JrknXfPVo+aIJ8QwYAqMPH77uptOdrlphyxl8eQI/rtkOYg86i/UWkpFu0w== - dependencies: - object-assign "^4.1.1" - prop-types "^15.6.2" - react-is "^16.8.6" - scheduler "^0.18.0" - -react-test-renderer@^16.13.1: - version "16.13.1" - resolved "https://registry.yarnpkg.com/react-test-renderer/-/react-test-renderer-16.13.1.tgz#de25ea358d9012606de51e012d9742e7f0deabc1" - integrity sha512-Sn2VRyOK2YJJldOqoh8Tn/lWQ+ZiKhyZTPtaO0Q6yNj+QDbmRkVFap6pZPy3YQk8DScRDfyqm/KxKYP9gCMRiQ== - dependencies: - object-assign "^4.1.1" - prop-types "^15.6.2" - react-is "^16.8.6" - scheduler "^0.19.1" - react-textarea-autosize@^7.1.0, react-textarea-autosize@^7.1.2: version "7.1.2" resolved "https://registry.yarnpkg.com/react-textarea-autosize/-/react-textarea-autosize-7.1.2.tgz#70fdb333ef86bcca72717e25e623e90c336e2cda" @@ -13554,6 +13418,14 @@ redent@^1.0.0: indent-string "^2.1.0" strip-indent "^1.0.1" +redent@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/redent/-/redent-3.0.0.tgz#e557b7998316bb53c9f1f56fa626352c6963059f" + integrity sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg== + dependencies: + indent-string "^4.0.0" + strip-indent "^3.0.0" + redux-localstorage@^0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/redux-localstorage/-/redux-localstorage-0.4.1.tgz#faf6d719c581397294d811473ffcedee065c933c" @@ -13572,11 +13444,6 @@ redux@^4.0.0, redux@^4.0.5: loose-envify "^1.4.0" symbol-observable "^1.2.0" -reflect.ownkeys@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/reflect.ownkeys/-/reflect.ownkeys-0.2.0.tgz#749aceec7f3fdf8b63f927a04809e90c5c0b3460" - integrity sha1-dJrO7H8/34tj+SegSAnpDFwLNGA= - refractor@^2.4.1: version "2.10.0" resolved "https://registry.yarnpkg.com/refractor/-/refractor-2.10.0.tgz#4cc7efc0028a87924a9b31d82d129dec831a287b" @@ -13965,14 +13832,6 @@ ripemd160@^2.0.0, ripemd160@^2.0.1: hash-base "^3.0.0" inherits "^2.0.1" -rst-selector-parser@^2.2.3: - version "2.2.3" - resolved "https://registry.yarnpkg.com/rst-selector-parser/-/rst-selector-parser-2.2.3.tgz#81b230ea2fcc6066c89e3472de794285d9b03d91" - integrity sha1-gbIw6i/MYGbInjRy3nlChdmwPZE= - dependencies: - lodash.flattendeep "^4.4.0" - nearley "^2.7.10" - rsvp@^4.8.4: version "4.8.5" resolved "https://registry.yarnpkg.com/rsvp/-/rsvp-4.8.5.tgz#c8f155311d167f68f21e168df71ec5b083113734" @@ -14165,7 +14024,7 @@ semver-regex@^2.0.0: resolved "https://registry.yarnpkg.com/semver-regex/-/semver-regex-2.0.0.tgz#a93c2c5844539a770233379107b38c7b4ac9d338" integrity sha512-mUdIBBvdn0PLOeP3TEkMH7HHeUP3GjsXCwKarjv/kGmUFOYg1VqEemKhoQpWMu6X2I8kHeuVdGibLGkVK+/5Qw== -"semver@2 || 3 || 4 || 5", semver@^5.4.1, semver@^5.5.0, semver@^5.5.1, semver@^5.6.0, semver@^5.7.0, semver@^5.7.1: +"semver@2 || 3 || 4 || 5", semver@^5.4.1, semver@^5.5.0, semver@^5.5.1, semver@^5.6.0, semver@^5.7.0: version "5.7.1" resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== @@ -14547,7 +14406,7 @@ source-list-map@^2.0.0: resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.1.tgz#3993bd873bfc48479cca9ea3a547835c7c154b34" integrity sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw== -source-map-resolve@^0.5.0: +source-map-resolve@^0.5.0, source-map-resolve@^0.5.2: version "0.5.3" resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.3.tgz#190866bece7553e1f8f267a2ee82c606b5509a1a" integrity sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw== @@ -14949,15 +14808,6 @@ string.prototype.padstart@^3.0.0: define-properties "^1.1.3" es-abstract "^1.17.0-next.1" -string.prototype.trim@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/string.prototype.trim/-/string.prototype.trim-1.2.1.tgz#141233dff32c82bfad80684d7e5f0869ee0fb782" - integrity sha512-MjGFEeqixw47dAMFMtgUro/I0+wNqZB5GKXGt1fFr24u3TzDXCPu7J9Buppzoe3r/LqkSDLDDJzE15RGWDGAVw== - dependencies: - define-properties "^1.1.3" - es-abstract "^1.17.0-next.1" - function-bind "^1.1.1" - string.prototype.trimend@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz#85812a6b847ac002270f5808146064c995fb6913"