Merge branch 'feature/gatsby-no-enzyme' into 'gatsby'

Replacing Enzyme with react-testing-library

See merge request javallone/regexper-static!42
This commit is contained in:
Jeff Avallone 2019-03-25 01:51:26 +00:00
commit dd8c405482
54 changed files with 2549 additions and 2055 deletions

View File

@ -1,8 +1,3 @@
import Enzyme from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
Enzyme.configure({ adapter: new Adapter() });
global.___loader = { global.___loader = {
enqueue: jest.fn() enqueue: jest.fn()
}; };

View File

@ -56,11 +56,9 @@
"node_modules" "node_modules"
], ],
"setupFilesAfterEnv": [ "setupFilesAfterEnv": [
"react-testing-library/cleanup-after-each",
"<rootDir>/jest/setup.js" "<rootDir>/jest/setup.js"
], ],
"snapshotSerializers": [
"enzyme-to-json/serializer"
],
"testPathIgnorePatterns": [ "testPathIgnorePatterns": [
"node_modules", "node_modules",
".cache" ".cache"
@ -85,9 +83,6 @@
"babel-jest": "^24.5.0", "babel-jest": "^24.5.0",
"babel-plugin-dynamic-import-node": "^2.2.0", "babel-plugin-dynamic-import-node": "^2.2.0",
"babel-preset-gatsby": "^0.1.6", "babel-preset-gatsby": "^0.1.6",
"enzyme": "^3.8.0",
"enzyme-adapter-react-16": "^1.7.1",
"enzyme-to-json": "^3.3.5",
"eslint": "^5.11.1", "eslint": "^5.11.1",
"eslint-plugin-jest": "^22.1.2", "eslint-plugin-jest": "^22.1.2",
"eslint-plugin-react": "^7.12.1", "eslint-plugin-react": "^7.12.1",
@ -114,6 +109,7 @@
"react-feather": "^1.1.5", "react-feather": "^1.1.5",
"react-helmet": "^5.2.0", "react-helmet": "^5.2.0",
"react-i18next": "^10.5.3", "react-i18next": "^10.5.3",
"react-modal": "^3.8.1" "react-modal": "^3.8.1",
"react-testing-library": "^6.0.2"
} }
} }

View File

@ -0,0 +1,19 @@
const React = require('react');
const buildMock = component => {
const componentName = component.displayName || component.name || 'Component';
const Mock = ({ children, ...props }) => (
<span
data-component={ componentName }
data-props={ JSON.stringify(props, null, ' ') }>{ children }</span>
);
Mock.propTypes = component.propTypes;
return Mock;
};
module.exports = path => {
const actual = jest.requireActual(path);
return buildMock(actual.default || actual);
};
module.exports.buildMock = buildMock;

6
src/__mocks__/react-i18next.js vendored Normal file
View File

@ -0,0 +1,6 @@
const reactI18next = jest.requireActual('react-i18next');
module.exports = {
...reactI18next,
Trans: require('__mocks__/component-mock').buildMock(reactI18next.Trans)
};

View File

@ -1,293 +1,255 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP // Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`App removing rendered expression 1`] = ` exports[`App removing rendered expression 1`] = `
<Fragment> <DocumentFragment>
<withI18nextTranslation(Form) <span
expr="test expression" data-component="withI18nextTranslation(Form)"
onSubmit={[Function]} data-props="{
syntax="js" \\"syntax\\": \\"js\\",
syntaxList={ \\"expr\\": \\"test expression\\",
Array [ \\"syntaxList\\": [
Object { {
"id": "testJS", \\"id\\": \\"testJS\\",
"label": "Testing JS", \\"label\\": \\"Testing JS\\"
}, },
Object { {
"id": "other", \\"id\\": \\"other\\",
"label": "Other", \\"label\\": \\"Other\\"
},
]
} }
]
}"
> >
<withI18nextTranslation(FormActions) /> <span
</withI18nextTranslation(Form)> data-component="withI18nextTranslation(FormActions)"
<Render data-props="{}"
data="LAYOUT(PARSED(test expression))"
onRender={[Function]}
/> />
</Fragment> </span>
<span
data-component="Render"
data-props="{
\\"data\\": \\"LAYOUT(PARSED(test expression))\\"
}"
/>
</DocumentFragment>
`; `;
exports[`App removing rendered expression 2`] = ` exports[`App removing rendered expression 2`] = `
<Fragment> <DocumentFragment>
<withI18nextTranslation(Form) <span
expr="" data-component="withI18nextTranslation(Form)"
onSubmit={[Function]} data-props="{
syntax="js" \\"syntax\\": \\"js\\",
syntaxList={ \\"expr\\": \\"\\",
Array [ \\"syntaxList\\": [
Object { {
"id": "testJS", \\"id\\": \\"testJS\\",
"label": "Testing JS", \\"label\\": \\"Testing JS\\"
}, },
Object { {
"id": "other", \\"id\\": \\"other\\",
"label": "Other", \\"label\\": \\"Other\\"
},
]
} }
]
}"
/> />
</Fragment> </DocumentFragment>
`; `;
exports[`App rendering 1`] = ` exports[`App rendering 1`] = `
<Fragment> <DocumentFragment>
<withI18nextTranslation(Form) <span
expr="" data-component="withI18nextTranslation(Form)"
onSubmit={[Function]} data-props="{
syntax="js" \\"syntax\\": \\"js\\",
syntaxList={ \\"expr\\": \\"\\",
Array [ \\"syntaxList\\": [
Object { {
"id": "testJS", \\"id\\": \\"testJS\\",
"label": "Testing JS", \\"label\\": \\"Testing JS\\"
}, },
Object { {
"id": "other", \\"id\\": \\"other\\",
"label": "Other", \\"label\\": \\"Other\\"
},
]
} }
]
}"
/> />
</Fragment> </DocumentFragment>
`; `;
exports[`App rendering an expression 1`] = ` exports[`App rendering an expression 1`] = `
<Fragment> <DocumentFragment>
<withI18nextTranslation(Form) <span
expr="" data-component="withI18nextTranslation(Form)"
onSubmit={[Function]} data-props="{
syntax="js" \\"syntax\\": \\"js\\",
syntaxList={ \\"expr\\": \\"\\",
Array [ \\"syntaxList\\": [
Object { {
"id": "testJS", \\"id\\": \\"testJS\\",
"label": "Testing JS", \\"label\\": \\"Testing JS\\"
}, },
Object { {
"id": "other", \\"id\\": \\"other\\",
"label": "Other", \\"label\\": \\"Other\\"
},
]
} }
]
}"
/> />
</Fragment> </DocumentFragment>
`; `;
exports[`App rendering an expression 2`] = ` exports[`App rendering an expression 2`] = `
<Fragment> <DocumentFragment>
<withI18nextTranslation(Form) <span
expr="test expression" data-component="withI18nextTranslation(Form)"
onSubmit={[Function]} data-props="{
syntax="js" \\"syntax\\": \\"js\\",
syntaxList={ \\"expr\\": \\"test expression\\",
Array [ \\"syntaxList\\": [
Object { {
"id": "testJS", \\"id\\": \\"testJS\\",
"label": "Testing JS", \\"label\\": \\"Testing JS\\"
}, },
Object { {
"id": "other", \\"id\\": \\"other\\",
"label": "Other", \\"label\\": \\"Other\\"
},
]
} }
]
}"
/> />
<withI18nextTranslation(Loader) /> <span
</Fragment> data-component="withI18nextTranslation(Loader)"
data-props="{}"
/>
</DocumentFragment>
`; `;
exports[`App rendering an expression 3`] = ` exports[`App rendering an expression 3`] = `
<Fragment> <DocumentFragment>
<withI18nextTranslation(Form) <span
expr="test expression" data-component="withI18nextTranslation(Form)"
onSubmit={[Function]} data-props="{
syntax="js" \\"syntax\\": \\"js\\",
syntaxList={ \\"expr\\": \\"test expression\\",
Array [ \\"syntaxList\\": [
Object { {
"id": "testJS", \\"id\\": \\"testJS\\",
"label": "Testing JS", \\"label\\": \\"Testing JS\\"
},
Object {
"id": "other",
"label": "Other",
}, },
{
\\"id\\": \\"other\\",
\\"label\\": \\"Other\\"
}
] ]
} }"
> >
<withI18nextTranslation(FormActions) /> <span
</withI18nextTranslation(Form)> data-component="withI18nextTranslation(FormActions)"
<Render data-props="{}"
data="LAYOUT(PARSED(test expression))"
onRender={[Function]}
/> />
</Fragment> </span>
`; <span
data-component="Render"
exports[`App rendering image details 1`] = ` data-props="{
<Fragment> \\"data\\": \\"LAYOUT(PARSED(test expression))\\"
<withI18nextTranslation(Form) }"
expr="test expression"
onSubmit={[Function]}
syntax="js"
syntaxList={
Array [
Object {
"id": "testJS",
"label": "Testing JS",
},
Object {
"id": "other",
"label": "Other",
},
]
}
>
<withI18nextTranslation(FormActions) />
</withI18nextTranslation(Form)>
<Render
data="LAYOUT(PARSED(test expression))"
onRender={[Function]}
/> />
</Fragment> </DocumentFragment>
`;
exports[`App rendering image details 2`] = `
<Fragment>
<withI18nextTranslation(Form)
expr="test expression"
onSubmit={[Function]}
syntax="js"
syntaxList={
Array [
Object {
"id": "testJS",
"label": "Testing JS",
},
Object {
"id": "other",
"label": "Other",
},
]
}
>
<withI18nextTranslation(FormActions)
imageDetails={
Object {
"svg": "test svg content",
}
}
/>
</withI18nextTranslation(Form)>
<Render
data="LAYOUT(PARSED(test expression))"
onRender={[Function]}
/>
</Fragment>
`; `;
exports[`App rendering with an invalid syntax 1`] = ` exports[`App rendering with an invalid syntax 1`] = `
<Fragment> <DocumentFragment>
<withI18nextTranslation(Form) <span
expr="" data-component="withI18nextTranslation(Form)"
onSubmit={[Function]} data-props="{
syntax="invalid" \\"syntax\\": \\"invalid\\",
syntaxList={ \\"expr\\": \\"\\",
Array [ \\"syntaxList\\": [
Object { {
"id": "testJS", \\"id\\": \\"testJS\\",
"label": "Testing JS", \\"label\\": \\"Testing JS\\"
}, },
Object { {
"id": "other", \\"id\\": \\"other\\",
"label": "Other", \\"label\\": \\"Other\\"
},
]
} }
]
}"
/> />
</Fragment> </DocumentFragment>
`; `;
exports[`App rendering with an invalid syntax 2`] = ` exports[`App rendering with an invalid syntax 2`] = `
<Fragment> <DocumentFragment>
<withI18nextTranslation(Form) <span
expr="test expression" data-component="withI18nextTranslation(Form)"
onSubmit={[Function]} data-props="{
syntax="invalid" \\"syntax\\": \\"invalid\\",
syntaxList={ \\"expr\\": \\"test expression\\",
Array [ \\"syntaxList\\": [
Object { {
"id": "testJS", \\"id\\": \\"testJS\\",
"label": "Testing JS", \\"label\\": \\"Testing JS\\"
}, },
Object { {
"id": "other", \\"id\\": \\"other\\",
"label": "Other", \\"label\\": \\"Other\\"
},
]
} }
]
}"
/> />
<withI18nextTranslation(Loader) /> <span
</Fragment> data-component="withI18nextTranslation(Loader)"
data-props="{}"
/>
</DocumentFragment>
`; `;
exports[`App rendering with an invalid syntax 3`] = ` exports[`App rendering with an invalid syntax 3`] = `
<Fragment> <DocumentFragment>
<withI18nextTranslation(Form) <span
expr="test expression" data-component="withI18nextTranslation(Form)"
onSubmit={[Function]} data-props="{
syntax="invalid" \\"syntax\\": \\"invalid\\",
syntaxList={ \\"expr\\": \\"test expression\\",
Array [ \\"syntaxList\\": [
Object { {
"id": "testJS", \\"id\\": \\"testJS\\",
"label": "Testing JS", \\"label\\": \\"Testing JS\\"
}, },
Object { {
"id": "other", \\"id\\": \\"other\\",
"label": "Other", \\"label\\": \\"Other\\"
},
]
} }
]
}"
/> />
<Message <span
heading="TRANSLATE(Render Failure)" data-component="Message"
type="error" data-props="{
\\"type\\": \\"error\\",
\\"heading\\": \\"TRANSLATE(Render Failure)\\"
}"
> >
<p> <p>
<Trans> <span
data-component="Trans"
data-props="{}"
>
An error occurred while rendering the regular expression. An error occurred while rendering the regular expression.
</Trans> </span>
</p> </p>
<a <a
href="#retry" href="#retry"
onClick={[Function]}
> >
<Trans> <span
data-component="Trans"
data-props="{}"
>
Retry Retry
</Trans> </span>
</a> </a>
</Message> </span>
</Fragment> </DocumentFragment>
`; `;

View File

@ -1,5 +1,14 @@
jest.mock('components/Form', () =>
require('__mocks__/component-mock')('components/Form'));
jest.mock('components/FormActions', () =>
require('__mocks__/component-mock')('components/FormActions'));
jest.mock('components/Loader', () =>
require('__mocks__/component-mock')('components/Loader'));
jest.mock('components/Message', () =>
require('__mocks__/component-mock')('components/Message'));
import React from 'react'; import React from 'react';
import { shallow } from 'enzyme'; import { render } from 'react-testing-library';
import { mockT } from 'i18n'; import { mockT } from 'i18n';
import { App } from 'components/App'; import { App } from 'components/App';
@ -7,7 +16,7 @@ import { App } from 'components/App';
jest.mock('syntax/js', () => ({ jest.mock('syntax/js', () => ({
parse: expr => `PARSED(${ expr })`, parse: expr => `PARSED(${ expr })`,
layout: parsed => `LAYOUT(${ parsed })`, layout: parsed => `LAYOUT(${ parsed })`,
Render: () => '' Render: require('__mocks__/component-mock').buildMock(function Render() {})
})); }));
const syntaxList = [ const syntaxList = [
@ -18,115 +27,64 @@ const commonProps = { syntaxList, t: mockT };
describe('App', () => { describe('App', () => {
test('rendering', () => { test('rendering', () => {
const component = shallow( const { asFragment } = render(
<App expr="" syntax="js" { ...commonProps } /> <App expr="" syntax="js" { ...commonProps } />
); );
expect(component).toMatchSnapshot(); expect(asFragment()).toMatchSnapshot();
}); });
test('rendering an expression', async () => { test('rendering an expression', async () => {
const component = shallow( const { asFragment, rerender } = render(
<App expr="" syntax="js" { ...commonProps } /> <App expr="" syntax="js" { ...commonProps } />
); );
expect(component).toMatchSnapshot(); expect(asFragment()).toMatchSnapshot();
component.setProps({ rerender(
expr: 'test expression' <App expr="test expression" syntax="js" { ...commonProps } />
}); );
expect(component).toMatchSnapshot(); expect(asFragment()).toMatchSnapshot();
// Give a beat for module to load // Give a beat for module to load
await new Promise(resolve => setTimeout(resolve)); await new Promise(resolve => setTimeout(resolve));
expect(component).toMatchSnapshot(); expect(asFragment()).toMatchSnapshot();
}); });
test('rendering with an invalid syntax', async () => { test('rendering with an invalid syntax', async () => {
jest.spyOn(console, 'error').mockImplementation(() => {}); jest.spyOn(console, 'error').mockImplementation(() => {});
const component = shallow( const { asFragment, rerender } = render(
<App expr="" syntax="invalid" { ...commonProps } /> <App expr="" syntax="invalid" { ...commonProps } />
); );
expect(component).toMatchSnapshot(); expect(asFragment()).toMatchSnapshot();
component.setProps({ rerender(
expr: 'test expression'
});
expect(component).toMatchSnapshot();
// Give a beat for module to load
await new Promise(resolve => setTimeout(resolve));
expect(component).toMatchSnapshot();
});
test('removing rendered expression', async () => {
const component = shallow(
<App expr="test expression" syntax="js" { ...commonProps } />
);
// Give a beat for module to load
await new Promise(resolve => setTimeout(resolve));
expect(component).toMatchSnapshot();
component.setProps({
expr: ''
});
expect(component).toMatchSnapshot();
});
test('rendering image details', async () => {
const component = shallow(
<App expr="test expression" syntax="js" { ...commonProps } />
);
// Give a beat for module to load
await new Promise(resolve => setTimeout(resolve));
expect(component).toMatchSnapshot();
component.instance().handleSvg({
svg: 'test svg content'
});
expect(component).toMatchSnapshot();
});
test('retrying expression rendering', () => {
jest.spyOn(console, 'error').mockImplementation(() => {});
const component = shallow(
<App expr="test expression" syntax="invalid" { ...commonProps } /> <App expr="test expression" syntax="invalid" { ...commonProps } />
); );
const instance = component.instance(); expect(asFragment()).toMatchSnapshot();
const event = { preventDefault: jest.fn() };
jest.spyOn(instance, 'handleRender'); // Give a beat for module to load
await new Promise(resolve => setTimeout(resolve));
instance.handleRetry(event); expect(asFragment()).toMatchSnapshot();
expect(event.preventDefault).toHaveBeenCalled();
expect(instance.handleRender).toHaveBeenCalled();
}); });
test('submitting an expression to render', () => { test('removing rendered expression', async () => {
const component = shallow( const { asFragment, rerender } = render(
<App expr="test expression" syntax="js" { ...commonProps } />
);
// Give a beat for module to load
await new Promise(resolve => setTimeout(resolve));
expect(asFragment()).toMatchSnapshot();
rerender(
<App expr="" syntax="js" { ...commonProps } /> <App expr="" syntax="js" { ...commonProps } />
); );
const instance = component.instance(); expect(asFragment()).toMatchSnapshot();
instance.handleSubmit({ syntax: 'test', expr: '' });
expect(document.location.hash).toEqual('');
instance.handleSubmit({ syntax: 'test', expr: 'test expression' });
expect(document.location.hash).toEqual('#syntax=test&expr=test+expression');
}); });
}); });

View File

@ -1,24 +1,31 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP // Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Footer rendering 1`] = ` exports[`Footer rendering 1`] = `
<footer <DocumentFragment>
className="footer" <footer
> class="footer"
>
<ul <ul
className="list" class="list"
> >
<li> <li>
<Trans> <span
data-component="Trans"
data-props="{}"
>
Created by Created by
<a <a
href="mailto:jeff.avallone@gmail.com" href="mailto:jeff.avallone@gmail.com"
> >
Jeff Avallone Jeff Avallone
</a> </a>
</Trans> </span>
</li> </li>
<li> <li>
<Trans> <span
data-component="Trans"
data-props="{}"
>
Generated images licensed: Generated images licensed:
<a <a
href="http://creativecommons.org/licenses/by/3.0/" href="http://creativecommons.org/licenses/by/3.0/"
@ -30,13 +37,14 @@ exports[`Footer rendering 1`] = `
src="cc-by.svg" src="cc-by.svg"
/> />
</a> </a>
</Trans> </span>
</li> </li>
</ul> </ul>
<div <div
className="buildId" class="buildId"
> >
abc-123 abc-123
</div> </div>
</footer> </footer>
</DocumentFragment>
`; `;

View File

@ -1,14 +1,14 @@
import React from 'react'; import React from 'react';
import { shallow } from 'enzyme'; import { render } from 'react-testing-library';
import { mockT } from 'i18n'; import { mockT } from 'i18n';
import { Footer } from 'components/Footer'; import { Footer } from 'components/Footer';
describe('Footer', () => { describe('Footer', () => {
test('rendering', () => { test('rendering', () => {
const component = shallow( const { asFragment } = render(
<Footer buildId="abc-123" t={ mockT } /> <Footer buildId="abc-123" t={ mockT } />
); );
expect(component).toMatchSnapshot(); expect(asFragment()).toMatchSnapshot();
}); });
}); });

View File

@ -1,53 +1,54 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP // Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Form rendering 1`] = ` exports[`Form rendering 1`] = `
<div <DocumentFragment>
className="form" <div
data-requires-js={true} class="form"
> data-requires-js="true"
>
<form <form
onSubmit={[Function]} data-testid="form"
> >
<textarea <textarea
autoFocus={true} data-testid="expr-input"
name="expr" name="expr"
onChange={[Function]}
onKeyPress={[Function]}
placeholder="TRANSLATE(Enter regular expression to display)" placeholder="TRANSLATE(Enter regular expression to display)"
/> />
<button <button
type="submit" type="submit"
> >
<Trans> <span
data-component="Trans"
data-props="{}"
>
Display Display
</Trans> </span>
</button> </button>
<div <div
className="select" class="select"
> >
<select <select
data-testid="syntax-select"
name="syntax" name="syntax"
onChange={[Function]}
> >
<option <option
key="testJS"
value="testJS" value="testJS"
> >
TRANSLATE(Testing JS) TRANSLATE(Testing JS)
</option> </option>
<option <option
key="other"
value="other" value="other"
> >
TRANSLATE(Other) TRANSLATE(Other)
</option> </option>
</select> </select>
<ChevronsDown <span
color="currentColor" data-component="ChevronsDown"
size="24" data-props="{}"
/> />
</div> </div>
Actions Actions
</form> </form>
</div> </div>
</DocumentFragment>
`; `;

View File

@ -54,8 +54,9 @@ class Form extends React.PureComponent {
const { expr, syntax } = this.state; const { expr, syntax } = this.state;
return <div className={ style.form } data-requires-js> return <div className={ style.form } data-requires-js>
<form onSubmit={ this.handleSubmit }> <form data-testid="form" onSubmit={ this.handleSubmit }>
<textarea <textarea
data-testid="expr-input"
name="expr" name="expr"
value={ expr } value={ expr }
onKeyPress={ this.handleKeyPress } onKeyPress={ this.handleKeyPress }
@ -65,6 +66,7 @@ class Form extends React.PureComponent {
<button type="submit"><Trans>Display</Trans></button> <button type="submit"><Trans>Display</Trans></button>
<div className={ style.select }> <div className={ style.select }>
<select <select
data-testid="syntax-select"
name="syntax" name="syntax"
value={ syntax } value={ syntax }
onChange={ this.handleChange } > onChange={ this.handleChange } >

View File

@ -1,5 +1,9 @@
jest.mock('react-feather/dist/icons/chevrons-down', () =>
require('__mocks__/component-mock')(
'react-feather/dist/icons/chevrons-down'));
import React from 'react'; import React from 'react';
import { shallow } from 'enzyme'; import { render, fireEvent } from 'react-testing-library';
import { mockT } from 'i18n'; import { mockT } from 'i18n';
import { Form } from 'components/Form'; import { Form } from 'components/Form';
@ -12,76 +16,66 @@ const commonProps = { syntaxList, t: mockT };
describe('Form', () => { describe('Form', () => {
test('rendering', () => { test('rendering', () => {
const component = shallow( const { asFragment } = render(
<Form onSubmit={ jest.fn() } { ...commonProps }> <Form onSubmit={ jest.fn() } { ...commonProps }>
Actions Actions
</Form> </Form>
); );
expect(component).toMatchSnapshot(); expect(asFragment()).toMatchSnapshot();
}); });
describe('submitting expression', () => { describe('submitting expression', () => {
test('submitting form', () => { test('submitting form', () => {
const onSubmit = jest.fn(); const onSubmit = jest.fn();
const component = shallow( const { getByTestId } = render(
<Form onSubmit={ onSubmit } { ...commonProps } /> <Form onSubmit={ onSubmit } { ...commonProps } />
); );
const exprInput = component.find('[name="expr"]'); fireEvent.change(getByTestId('expr-input'), {
const syntaxInput = component.find('[name="syntax"]'); target: { value: 'Test expression' }
exprInput.simulate('change', {
target: {
name: 'expr',
value: 'Test expression'
}
}); });
syntaxInput.simulate('change', { fireEvent.change(getByTestId('syntax-select'), {
target: { target: { value: 'other' }
name: 'syntax',
value: 'test'
}
}); });
const eventObj = { preventDefault: jest.fn() }; const event = new Event('submit');
component.find('form').simulate('submit', eventObj); jest.spyOn(event, 'preventDefault');
expect(eventObj.preventDefault).toHaveBeenCalled(); fireEvent(getByTestId('form'), event);
expect(event.preventDefault).toHaveBeenCalled();
expect(onSubmit).toHaveBeenCalledWith({ expect(onSubmit).toHaveBeenCalledWith({
expr: 'Test expression', expr: 'Test expression',
syntax: 'test' syntax: 'other'
}); });
}); });
test('submitting form with Shift+Enter', () => { test('submitting form with Shift+Enter', () => {
const component = shallow( const onSubmit = jest.fn();
<Form onSubmit={ jest.fn() } { ...commonProps } /> const { getByTestId } = render(
<Form onSubmit={ onSubmit } { ...commonProps } />
); );
const form = component.instance();
const eventObj = { fireEvent.keyPress(getByTestId('expr-input'), {
preventDefault: Function.prototype,
charCode: 13, charCode: 13,
shiftKey: true shiftKey: true
}; });
jest.spyOn(form, 'handleSubmit');
component.find('textarea').simulate('keypress', eventObj);
expect(form.handleSubmit).toHaveBeenCalled(); expect(onSubmit).toHaveBeenCalled();
}); });
test('not submitting with just Enter', () => { test('not submitting with just Enter', () => {
const component = shallow( const onSubmit = jest.fn();
<Form onSubmit={ jest.fn() } { ...commonProps } /> const { getByTestId } = render(
<Form onSubmit={ onSubmit } { ...commonProps } />
); );
const form = component.instance();
const eventObj = { fireEvent.keyPress(getByTestId('expr-input'), {
preventDefault: Function.prototype,
charCode: 13, charCode: 13,
shiftKey: false shiftKey: false
}; });
jest.spyOn(form, 'handleSubmit');
component.find('textarea').simulate('keypress', eventObj);
expect(form.handleSubmit).not.toHaveBeenCalled(); expect(onSubmit).not.toHaveBeenCalled();
}); });
}); });
}); });

View File

@ -1,24 +1,27 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP // Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`FormActions rendering 1`] = ` exports[`FormActions rendering 1`] = `
<ul <DocumentFragment>
className="actions" <ul
/> class="actions"
/>
</DocumentFragment>
`; `;
exports[`FormActions rendering download links 1`] = ` exports[`FormActions rendering download links 1`] = `
<ul <DocumentFragment>
className="actions" <ul
> class="actions"
>
<li> <li>
<a <a
download="image.png" download="image.png"
href="http://example.com/image.png" href="http://example.com/image.png"
type="image/png" type="image/png"
> >
<Download <span
color="currentColor" data-component="Download"
size="24" data-props="{}"
/> />
TRANSLATE(Example PNG Link) TRANSLATE(Example PNG Link)
</a> </a>
@ -29,49 +32,56 @@ exports[`FormActions rendering download links 1`] = `
href="http://example.com/image.svg" href="http://example.com/image.svg"
type="image/svg+xml" type="image/svg+xml"
> >
<Download <span
color="currentColor" data-component="Download"
size="24" data-props="{}"
/> />
TRANSLATE(Example SVG Link) TRANSLATE(Example SVG Link)
</a> </a>
</li> </li>
</ul> </ul>
</DocumentFragment>
`; `;
exports[`FormActions rendering download links with data after mounting 1`] = ` exports[`FormActions rendering download links with data after mounting 1`] = `
<ul <DocumentFragment>
className="actions" <ul
> class="actions"
>
<li> <li>
<a <a
href="http://example.com" href="http://example.com"
> >
<Link <span
color="currentColor" data-component="Link"
size="24" data-props="{}"
/> />
<Trans> <span
data-component="Trans"
data-props="{}"
>
Permalink Permalink
</Trans> </span>
</a> </a>
</li> </li>
</ul> </ul>
</DocumentFragment>
`; `;
exports[`FormActions rendering download links with data after mounting 2`] = ` exports[`FormActions rendering download links with data after mounting 2`] = `
<ul <DocumentFragment>
className="actions" <ul
> class="actions"
>
<li> <li>
<a <a
download="image.png" download="image.png"
href="http://example.com/image.png" href="http://example.com/image.png"
type="image/png" type="image/png"
> >
<Download <span
color="currentColor" data-component="Download"
size="24" data-props="{}"
/> />
TRANSLATE(Example PNG Link) TRANSLATE(Example PNG Link)
</a> </a>
@ -82,9 +92,9 @@ exports[`FormActions rendering download links with data after mounting 2`] = `
href="http://example.com/image.svg" href="http://example.com/image.svg"
type="image/svg+xml" type="image/svg+xml"
> >
<Download <span
color="currentColor" data-component="Download"
size="24" data-props="{}"
/> />
TRANSLATE(Example SVG Link) TRANSLATE(Example SVG Link)
</a> </a>
@ -93,31 +103,36 @@ exports[`FormActions rendering download links with data after mounting 2`] = `
<a <a
href="http://example.com" href="http://example.com"
> >
<Link <span
color="currentColor" data-component="Link"
size="24" data-props="{}"
/> />
<Trans> <span
data-component="Trans"
data-props="{}"
>
Permalink Permalink
</Trans> </span>
</a> </a>
</li> </li>
</ul> </ul>
</DocumentFragment>
`; `;
exports[`FormActions rendering download links with data after mounting 3`] = ` exports[`FormActions rendering download links with data after mounting 3`] = `
<ul <DocumentFragment>
className="actions" <ul
> class="actions"
>
<li> <li>
<a <a
download="image.png" download="image.png"
href="http://example.com/image.png" href="http://example.com/image.png"
type="image/png" type="image/png"
> >
<Download <span
color="currentColor" data-component="Download"
size="24" data-props="{}"
/> />
TRANSLATE(Example PNG Link) TRANSLATE(Example PNG Link)
</a> </a>
@ -128,9 +143,9 @@ exports[`FormActions rendering download links with data after mounting 3`] = `
href="http://example.com/image.svg" href="http://example.com/image.svg"
type="image/svg+xml" type="image/svg+xml"
> >
<Download <span
color="currentColor" data-component="Download"
size="24" data-props="{}"
/> />
TRANSLATE(Example SVG Link) TRANSLATE(Example SVG Link)
</a> </a>
@ -139,34 +154,43 @@ exports[`FormActions rendering download links with data after mounting 3`] = `
<a <a
href="http://example.com" href="http://example.com"
> >
<Link <span
color="currentColor" data-component="Link"
size="24" data-props="{}"
/> />
<Trans> <span
data-component="Trans"
data-props="{}"
>
Permalink Permalink
</Trans> </span>
</a> </a>
</li> </li>
</ul> </ul>
</DocumentFragment>
`; `;
exports[`FormActions rendering with a permalink 1`] = ` exports[`FormActions rendering with a permalink 1`] = `
<ul <DocumentFragment>
className="actions" <ul
> class="actions"
>
<li> <li>
<a <a
href="http://example.com" href="http://example.com"
> >
<Link <span
color="currentColor" data-component="Link"
size="24" data-props="{}"
/> />
<Trans> <span
data-component="Trans"
data-props="{}"
>
Permalink Permalink
</Trans> </span>
</a> </a>
</li> </li>
</ul> </ul>
</DocumentFragment>
`; `;

View File

@ -1,7 +1,13 @@
jest.mock('./links'); jest.mock('./links');
jest.mock('react-feather/dist/icons/download', () =>
require('__mocks__/component-mock')(
'react-feather/dist/icons/download'));
jest.mock('react-feather/dist/icons/link', () =>
require('__mocks__/component-mock')(
'react-feather/dist/icons/link'));
import React from 'react'; import React from 'react';
import { shallow } from 'enzyme'; import { render } from 'react-testing-library';
import { mockT } from 'i18n'; import { mockT } from 'i18n';
import { FormActions } from 'components/FormActions'; import { FormActions } from 'components/FormActions';
@ -22,17 +28,17 @@ createSvgLink.mockResolvedValue({
describe('FormActions', () => { describe('FormActions', () => {
test('rendering', () => { test('rendering', () => {
const component = shallow( const { asFragment } = render(
<FormActions t={ mockT } /> <FormActions t={ mockT } />
); );
expect(component).toMatchSnapshot(); expect(asFragment()).toMatchSnapshot();
}); });
test('rendering with a permalink', () => { test('rendering with a permalink', () => {
const component = shallow( const { asFragment } = render(
<FormActions permalinkUrl="http://example.com" t={ mockT } /> <FormActions permalinkUrl="http://example.com" t={ mockT } />
); );
expect(component).toMatchSnapshot(); expect(asFragment()).toMatchSnapshot();
}); });
test('rendering download links', async () => { test('rendering download links', async () => {
@ -42,47 +48,49 @@ describe('FormActions', () => {
height: 20 height: 20
}; };
const component = shallow( const { asFragment } = render(
<FormActions imageDetails={ imageDetails } t={ mockT } /> <FormActions imageDetails={ imageDetails } t={ mockT } />
); );
// Give a beat for mocked promises to resolve // Give a beat for mocked promises to resolve
await new Promise(resolve => setTimeout(resolve)); await new Promise(resolve => setTimeout(resolve));
expect(component).toMatchSnapshot(); expect(asFragment()).toMatchSnapshot();
}); });
test('rendering download links with data after mounting', async () => { test('rendering download links with data after mounting', async () => {
const component = shallow( const { asFragment, rerender } = render(
<FormActions t={ mockT } /> <FormActions t={ mockT } />
); );
component.setProps({ permalinkUrl: 'http://example.com' }); rerender(
<FormActions permalinkUrl="http://example.com" t={ mockT } />
);
expect(component).toMatchSnapshot(); expect(asFragment()).toMatchSnapshot();
component.setProps({ rerender(
imageDetails: { <FormActions
svg: 'test image' permalinkUrl="http://example.com"
} imageDetails={ { svg: 'test-image' } }
}); t={ mockT } />
);
// Give a beat for mocked promises to resolve // Give a beat for mocked promises to resolve
await new Promise(resolve => setTimeout(resolve)); await new Promise(resolve => setTimeout(resolve));
expect(component).toMatchSnapshot(); expect(asFragment()).toMatchSnapshot();
component.setProps({ rerender(
imageDetails: { <FormActions
svg: 'test image', permalinkUrl="http://example.com"
width: 10, imageDetails={ { svg: 'test-image', width: 10, height: 20 } }
height: 20 t={ mockT } />
} );
});
// Give a beat for mocked promises to resolve // Give a beat for mocked promises to resolve
await new Promise(resolve => setTimeout(resolve)); await new Promise(resolve => setTimeout(resolve));
expect(component).toMatchSnapshot(); expect(asFragment()).toMatchSnapshot();
}); });
}); });

View File

@ -1,182 +1,30 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP // Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Header closing the Privacy Policy modal 1`] = `
<Fragment>
<Modal
ariaHideApp={true}
bodyOpenClassName="ReactModal__Body--open"
closeTimeoutMS={0}
isOpen={true}
onRequestClose={[Function]}
parentSelector={[Function]}
portalClassName="ReactModalPortal"
role="dialog"
shouldCloseOnEsc={true}
shouldCloseOnOverlayClick={true}
shouldFocusAfterRender={true}
shouldReturnFocusAfterClose={true}
>
<withI18nextTranslation(PrivacyPolicy)
onClose={[Function]}
/>
</Modal>
<header
className="header"
data-banner={null}
>
<h1>
<mockConstructor
to="/"
>
Regexper
</mockConstructor>
</h1>
<ul
className="list"
>
<li>
<a
href="https://gitlab.com/javallone/regexper-static"
rel="external noopener noreferrer"
target="_blank"
>
<Gitlab
color="currentColor"
size="24"
/>
<Trans>
Source on GitLab
</Trans>
</a>
</li>
<li>
<mockConstructor
onClick={[Function]}
to="/privacy"
>
<Trans>
Privacy Policy
</Trans>
</mockConstructor>
</li>
<li>
<withI18nextTranslation(InstallPrompt) />
</li>
<li
data-requires-js={true}
>
<withI18nextTranslation(LocaleSwitcher) />
</li>
</ul>
</header>
</Fragment>
`;
exports[`Header closing the Privacy Policy modal 2`] = `
<Fragment>
<Modal
ariaHideApp={true}
bodyOpenClassName="ReactModal__Body--open"
closeTimeoutMS={0}
isOpen={false}
onRequestClose={[Function]}
parentSelector={[Function]}
portalClassName="ReactModalPortal"
role="dialog"
shouldCloseOnEsc={true}
shouldCloseOnOverlayClick={true}
shouldFocusAfterRender={true}
shouldReturnFocusAfterClose={true}
>
<withI18nextTranslation(PrivacyPolicy)
onClose={[Function]}
/>
</Modal>
<header
className="header"
data-banner={null}
>
<h1>
<mockConstructor
to="/"
>
Regexper
</mockConstructor>
</h1>
<ul
className="list"
>
<li>
<a
href="https://gitlab.com/javallone/regexper-static"
rel="external noopener noreferrer"
target="_blank"
>
<Gitlab
color="currentColor"
size="24"
/>
<Trans>
Source on GitLab
</Trans>
</a>
</li>
<li>
<mockConstructor
onClick={[Function]}
to="/privacy"
>
<Trans>
Privacy Policy
</Trans>
</mockConstructor>
</li>
<li>
<withI18nextTranslation(InstallPrompt) />
</li>
<li
data-requires-js={true}
>
<withI18nextTranslation(LocaleSwitcher) />
</li>
</ul>
</header>
</Fragment>
`;
exports[`Header opening the Privacy Policy modal 1`] = ` exports[`Header opening the Privacy Policy modal 1`] = `
<Fragment> <DocumentFragment>
<Modal <span
ariaHideApp={true} data-component="Modal"
bodyOpenClassName="ReactModal__Body--open" data-props="{
closeTimeoutMS={0} \\"isOpen\\": true
isOpen={true} }"
onRequestClose={[Function]}
parentSelector={[Function]}
portalClassName="ReactModalPortal"
role="dialog"
shouldCloseOnEsc={true}
shouldCloseOnOverlayClick={true}
shouldFocusAfterRender={true}
shouldReturnFocusAfterClose={true}
> >
<withI18nextTranslation(PrivacyPolicy) <span
onClose={[Function]} data-component="withI18nextTranslation(PrivacyPolicy)"
data-props="{}"
/> />
</Modal> </span>
<header <header
className="header" class="header"
data-banner={null}
> >
<h1> <h1>
<mockConstructor <a
to="/" href="/"
> >
Regexper Regexper
</mockConstructor> </a>
</h1> </h1>
<ul <ul
className="list" class="list"
> >
<li> <li>
<a <a
@ -184,71 +32,380 @@ exports[`Header opening the Privacy Policy modal 1`] = `
rel="external noopener noreferrer" rel="external noopener noreferrer"
target="_blank" target="_blank"
> >
<Gitlab <span
color="currentColor" data-component="Gitlab"
size="24" data-props="{}"
/> />
<Trans> <span
data-component="Trans"
data-props="{}"
>
Source on GitLab Source on GitLab
</Trans> </span>
</a> </a>
</li> </li>
<li> <li>
<mockConstructor <a
onClick={[Function]} data-testid="privacy-link"
to="/privacy" href="/privacy"
>
<span
data-component="Trans"
data-props="{}"
> >
<Trans>
Privacy Policy Privacy Policy
</Trans> </span>
</mockConstructor> </a>
</li> </li>
<li> <li>
<withI18nextTranslation(InstallPrompt) /> <span
data-component="withI18nextTranslation(InstallPrompt)"
data-props="{}"
/>
</li> </li>
<li <li
data-requires-js={true} data-requires-js="true"
> >
<withI18nextTranslation(LocaleSwitcher) /> <span
data-component="withI18nextTranslation(LocaleSwitcher)"
data-props="{}"
/>
</li> </li>
</ul> </ul>
</header> </header>
</Fragment> </DocumentFragment>
`;
exports[`Header opening the Privacy Policy modal while holding alt key 1`] = `
<DocumentFragment>
<span
data-component="Modal"
data-props="{
\\"isOpen\\": false
}"
>
<span
data-component="withI18nextTranslation(PrivacyPolicy)"
data-props="{}"
/>
</span>
<header
class="header"
>
<h1>
<a
href="/"
>
Regexper
</a>
</h1>
<ul
class="list"
>
<li>
<a
href="https://gitlab.com/javallone/regexper-static"
rel="external noopener noreferrer"
target="_blank"
>
<span
data-component="Gitlab"
data-props="{}"
/>
<span
data-component="Trans"
data-props="{}"
>
Source on GitLab
</span>
</a>
</li>
<li>
<a
data-testid="privacy-link"
href="/privacy"
>
<span
data-component="Trans"
data-props="{}"
>
Privacy Policy
</span>
</a>
</li>
<li>
<span
data-component="withI18nextTranslation(InstallPrompt)"
data-props="{}"
/>
</li>
<li
data-requires-js="true"
>
<span
data-component="withI18nextTranslation(LocaleSwitcher)"
data-props="{}"
/>
</li>
</ul>
</header>
</DocumentFragment>
`;
exports[`Header opening the Privacy Policy modal while holding ctrl key 1`] = `
<DocumentFragment>
<span
data-component="Modal"
data-props="{
\\"isOpen\\": false
}"
>
<span
data-component="withI18nextTranslation(PrivacyPolicy)"
data-props="{}"
/>
</span>
<header
class="header"
>
<h1>
<a
href="/"
>
Regexper
</a>
</h1>
<ul
class="list"
>
<li>
<a
href="https://gitlab.com/javallone/regexper-static"
rel="external noopener noreferrer"
target="_blank"
>
<span
data-component="Gitlab"
data-props="{}"
/>
<span
data-component="Trans"
data-props="{}"
>
Source on GitLab
</span>
</a>
</li>
<li>
<a
data-testid="privacy-link"
href="/privacy"
>
<span
data-component="Trans"
data-props="{}"
>
Privacy Policy
</span>
</a>
</li>
<li>
<span
data-component="withI18nextTranslation(InstallPrompt)"
data-props="{}"
/>
</li>
<li
data-requires-js="true"
>
<span
data-component="withI18nextTranslation(LocaleSwitcher)"
data-props="{}"
/>
</li>
</ul>
</header>
</DocumentFragment>
`;
exports[`Header opening the Privacy Policy modal while holding meta key 1`] = `
<DocumentFragment>
<span
data-component="Modal"
data-props="{
\\"isOpen\\": false
}"
>
<span
data-component="withI18nextTranslation(PrivacyPolicy)"
data-props="{}"
/>
</span>
<header
class="header"
>
<h1>
<a
href="/"
>
Regexper
</a>
</h1>
<ul
class="list"
>
<li>
<a
href="https://gitlab.com/javallone/regexper-static"
rel="external noopener noreferrer"
target="_blank"
>
<span
data-component="Gitlab"
data-props="{}"
/>
<span
data-component="Trans"
data-props="{}"
>
Source on GitLab
</span>
</a>
</li>
<li>
<a
data-testid="privacy-link"
href="/privacy"
>
<span
data-component="Trans"
data-props="{}"
>
Privacy Policy
</span>
</a>
</li>
<li>
<span
data-component="withI18nextTranslation(InstallPrompt)"
data-props="{}"
/>
</li>
<li
data-requires-js="true"
>
<span
data-component="withI18nextTranslation(LocaleSwitcher)"
data-props="{}"
/>
</li>
</ul>
</header>
</DocumentFragment>
`;
exports[`Header opening the Privacy Policy modal while holding shift key 1`] = `
<DocumentFragment>
<span
data-component="Modal"
data-props="{
\\"isOpen\\": false
}"
>
<span
data-component="withI18nextTranslation(PrivacyPolicy)"
data-props="{}"
/>
</span>
<header
class="header"
>
<h1>
<a
href="/"
>
Regexper
</a>
</h1>
<ul
class="list"
>
<li>
<a
href="https://gitlab.com/javallone/regexper-static"
rel="external noopener noreferrer"
target="_blank"
>
<span
data-component="Gitlab"
data-props="{}"
/>
<span
data-component="Trans"
data-props="{}"
>
Source on GitLab
</span>
</a>
</li>
<li>
<a
data-testid="privacy-link"
href="/privacy"
>
<span
data-component="Trans"
data-props="{}"
>
Privacy Policy
</span>
</a>
</li>
<li>
<span
data-component="withI18nextTranslation(InstallPrompt)"
data-props="{}"
/>
</li>
<li
data-requires-js="true"
>
<span
data-component="withI18nextTranslation(LocaleSwitcher)"
data-props="{}"
/>
</li>
</ul>
</header>
</DocumentFragment>
`; `;
exports[`Header rendering 1`] = ` exports[`Header rendering 1`] = `
<Fragment> <DocumentFragment>
<Modal <span
ariaHideApp={true} data-component="Modal"
bodyOpenClassName="ReactModal__Body--open" data-props="{
closeTimeoutMS={0} \\"isOpen\\": false
isOpen={false} }"
onRequestClose={[Function]}
parentSelector={[Function]}
portalClassName="ReactModalPortal"
role="dialog"
shouldCloseOnEsc={true}
shouldCloseOnOverlayClick={true}
shouldFocusAfterRender={true}
shouldReturnFocusAfterClose={true}
> >
<withI18nextTranslation(PrivacyPolicy) <span
onClose={[Function]} data-component="withI18nextTranslation(PrivacyPolicy)"
data-props="{}"
/> />
</Modal> </span>
<header <header
className="header" class="header"
data-banner="testing" data-banner="testing"
> >
<h1> <h1>
<mockConstructor <a
to="/" href="/"
> >
Regexper Regexper
</mockConstructor> </a>
</h1> </h1>
<ul <ul
className="list" class="list"
> >
<li> <li>
<a <a
@ -256,71 +413,75 @@ exports[`Header rendering 1`] = `
rel="external noopener noreferrer" rel="external noopener noreferrer"
target="_blank" target="_blank"
> >
<Gitlab <span
color="currentColor" data-component="Gitlab"
size="24" data-props="{}"
/> />
<Trans> <span
data-component="Trans"
data-props="{}"
>
Source on GitLab Source on GitLab
</Trans> </span>
</a> </a>
</li> </li>
<li> <li>
<mockConstructor <a
onClick={[Function]} data-testid="privacy-link"
to="/privacy" href="/privacy"
>
<span
data-component="Trans"
data-props="{}"
> >
<Trans>
Privacy Policy Privacy Policy
</Trans> </span>
</mockConstructor> </a>
</li> </li>
<li> <li>
<withI18nextTranslation(InstallPrompt) /> <span
data-component="withI18nextTranslation(InstallPrompt)"
data-props="{}"
/>
</li> </li>
<li <li
data-requires-js={true} data-requires-js="true"
> >
<withI18nextTranslation(LocaleSwitcher) /> <span
data-component="withI18nextTranslation(LocaleSwitcher)"
data-props="{}"
/>
</li> </li>
</ul> </ul>
</header> </header>
</Fragment> </DocumentFragment>
`; `;
exports[`Header rendering with no banner 1`] = ` exports[`Header rendering with no banner 1`] = `
<Fragment> <DocumentFragment>
<Modal <span
ariaHideApp={true} data-component="Modal"
bodyOpenClassName="ReactModal__Body--open" data-props="{
closeTimeoutMS={0} \\"isOpen\\": false
isOpen={false} }"
onRequestClose={[Function]}
parentSelector={[Function]}
portalClassName="ReactModalPortal"
role="dialog"
shouldCloseOnEsc={true}
shouldCloseOnOverlayClick={true}
shouldFocusAfterRender={true}
shouldReturnFocusAfterClose={true}
> >
<withI18nextTranslation(PrivacyPolicy) <span
onClose={[Function]} data-component="withI18nextTranslation(PrivacyPolicy)"
data-props="{}"
/> />
</Modal> </span>
<header <header
className="header" class="header"
data-banner={null}
> >
<h1> <h1>
<mockConstructor <a
to="/" href="/"
> >
Regexper Regexper
</mockConstructor> </a>
</h1> </h1>
<ul <ul
className="list" class="list"
> >
<li> <li>
<a <a
@ -328,34 +489,46 @@ exports[`Header rendering with no banner 1`] = `
rel="external noopener noreferrer" rel="external noopener noreferrer"
target="_blank" target="_blank"
> >
<Gitlab <span
color="currentColor" data-component="Gitlab"
size="24" data-props="{}"
/> />
<Trans> <span
data-component="Trans"
data-props="{}"
>
Source on GitLab Source on GitLab
</Trans> </span>
</a> </a>
</li> </li>
<li> <li>
<mockConstructor <a
onClick={[Function]} data-testid="privacy-link"
to="/privacy" href="/privacy"
>
<span
data-component="Trans"
data-props="{}"
> >
<Trans>
Privacy Policy Privacy Policy
</Trans> </span>
</mockConstructor> </a>
</li> </li>
<li> <li>
<withI18nextTranslation(InstallPrompt) /> <span
data-component="withI18nextTranslation(InstallPrompt)"
data-props="{}"
/>
</li> </li>
<li <li
data-requires-js={true} data-requires-js="true"
> >
<withI18nextTranslation(LocaleSwitcher) /> <span
data-component="withI18nextTranslation(LocaleSwitcher)"
data-props="{}"
/>
</li> </li>
</ul> </ul>
</header> </header>
</Fragment> </DocumentFragment>
`; `;

View File

@ -64,7 +64,10 @@ class Header extends React.PureComponent {
</a> </a>
</li> </li>
<li> <li>
<Link to="/privacy" onClick={ this.handleOpen }> <Link to="/privacy"
data-testid="privacy-link"
onClick={ this.handleOpen }
>
<Trans>Privacy Policy</Trans> <Trans>Privacy Policy</Trans>
</Link> </Link>
</li> </li>

View File

@ -1,60 +1,62 @@
jest.mock('react-modal', () =>
require('__mocks__/component-mock')('react-modal'));
jest.mock('react-feather/dist/icons/gitlab', () =>
require('__mocks__/component-mock')('react-feather/dist/icons/gitlab'));
jest.mock('components/LocaleSwitcher', () =>
require('__mocks__/component-mock')('components/LocaleSwitcher'));
jest.mock('components/InstallPrompt', () =>
require('__mocks__/component-mock')('components/InstallPrompt'));
jest.mock('components/PrivacyPolicy', () =>
require('__mocks__/component-mock')('components/PrivacyPolicy'));
import React from 'react'; import React from 'react';
import { shallow } from 'enzyme'; import { render, fireEvent } from 'react-testing-library';
import { Header } from 'components/Header'; import { Header } from 'components/Header';
describe('Header', () => { describe('Header', () => {
test('rendering', () => { test('rendering', () => {
const component = shallow( const { asFragment } = render(
<Header banner="testing" /> <Header banner="testing" />
); );
expect(component).toMatchSnapshot(); expect(asFragment()).toMatchSnapshot();
}); });
test('rendering with no banner', () => { test('rendering with no banner', () => {
const component = shallow( const { asFragment } = render(
<Header banner={ false } /> <Header banner={ false } />
); );
expect(component).toMatchSnapshot(); expect(asFragment()).toMatchSnapshot();
}); });
test('opening the Privacy Policy modal', () => { test('opening the Privacy Policy modal', () => {
const component = shallow( const { asFragment, getByTestId } = render(
<Header banner={ false } /> <Header banner={ false } />
); );
const eventObj = { preventDefault: jest.fn() }; const event = new MouseEvent('click', { bubbles: true });
jest.spyOn(event, 'preventDefault');
component.instance().handleOpen(eventObj); fireEvent(getByTestId('privacy-link'), event);
expect(eventObj.preventDefault).toHaveBeenCalled(); expect(event.preventDefault).toHaveBeenCalled();
expect(component).toMatchSnapshot(); expect(asFragment()).toMatchSnapshot();
}); });
['shift', 'ctrl', 'alt', 'meta'].forEach(key => { ['shift', 'ctrl', 'alt', 'meta'].forEach(key => {
test(`opening the Privacy Policy modal while holding ${ key } key`, () => { test(`opening the Privacy Policy modal while holding ${ key } key`, () => {
const component = shallow( const { asFragment, getByTestId } = render(
<Header banner={ false } /> <Header banner={ false } />
); );
const eventObj = { preventDefault: jest.fn() }; const event = new MouseEvent('click', {
bubbles: true,
component.instance().handleOpen({ [key + 'Key']: true, ...eventObj }); [key + 'Key']: true
expect(eventObj.preventDefault).not.toHaveBeenCalled();
expect(component.state('showModal')).toEqual(false);
}); });
jest.spyOn(event, 'preventDefault');
fireEvent(getByTestId('privacy-link'), event);
expect(event.preventDefault).not.toHaveBeenCalled();
expect(asFragment()).toMatchSnapshot();
}); });
test('closing the Privacy Policy modal', () => {
const component = shallow(
<Header banner={ false } />
);
component.setState({ showModal: true });
expect(component).toMatchSnapshot();
component.instance().handleClose();
expect(component).toMatchSnapshot();
}); });
}); });

View File

@ -1,16 +1,57 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP // Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`InstallPrompt rendering 1`] = `""`; exports[`InstallPrompt accepting install prompt 1`] = `
<DocumentFragment>
<a
data-testid="install"
href="#install"
>
<span
data-component="Trans"
data-props="{}"
>
Add to Home Screen
</span>
</a>
</DocumentFragment>
`;
exports[`InstallPrompt rendering after an install prompt has been requested 1`] = `""`; exports[`InstallPrompt accepting install prompt 2`] = `<DocumentFragment />`;
exports[`InstallPrompt rejecting install prompt 1`] = `
<DocumentFragment>
<a
data-testid="install"
href="#install"
>
<span
data-component="Trans"
data-props="{}"
>
Add to Home Screen
</span>
</a>
</DocumentFragment>
`;
exports[`InstallPrompt rejecting install prompt 2`] = `<DocumentFragment />`;
exports[`InstallPrompt rendering 1`] = `<DocumentFragment />`;
exports[`InstallPrompt rendering after an install prompt has been requested 1`] = `<DocumentFragment />`;
exports[`InstallPrompt rendering after an install prompt has been requested 2`] = ` exports[`InstallPrompt rendering after an install prompt has been requested 2`] = `
<a <DocumentFragment>
<a
data-testid="install"
href="#install" href="#install"
onClick={[Function]} >
> <span
<Trans> data-component="Trans"
data-props="{}"
>
Add to Home Screen Add to Home Screen
</Trans> </span>
</a> </a>
</DocumentFragment>
`; `;

View File

@ -43,7 +43,10 @@ class InstallPrompt extends React.PureComponent {
return null; return null;
} }
return <a href="#install" onClick={ this.handleInstall }> return <a href="#install"
data-testid="install"
onClick={ this.handleInstall }
>
<Trans>Add to Home Screen</Trans> <Trans>Add to Home Screen</Trans>
</a>; </a>;
} }

View File

@ -1,88 +1,86 @@
import React from 'react'; import React from 'react';
import { shallow } from 'enzyme'; import { render, fireEvent } from 'react-testing-library';
import { InstallPrompt } from 'components/InstallPrompt'; import { InstallPrompt } from 'components/InstallPrompt';
describe('InstallPrompt', () => { describe('InstallPrompt', () => {
test('rendering', () => { test('rendering', () => {
const component = shallow( const { asFragment } = render(
<InstallPrompt /> <InstallPrompt />
); );
expect(component).toMatchSnapshot(); expect(asFragment()).toMatchSnapshot();
}); });
test('rendering after an install prompt has been requested', () => { test('rendering after an install prompt has been requested', () => {
const component = shallow( const { asFragment } = render(
<InstallPrompt /> <InstallPrompt />
); );
expect(component).toMatchSnapshot(); expect(asFragment()).toMatchSnapshot();
component.instance().handleInstallPrompt({ const event = new Event('beforeinstallprompt', {
prompt: jest.fn() prompt: jest.fn()
}); });
fireEvent(window, event);
expect(component).toMatchSnapshot(); expect(asFragment()).toMatchSnapshot();
}); });
test('adding and removing event listener', () => { test('removing event listener', () => {
jest.spyOn(window, 'addEventListener'); jest.spyOn(window, 'addEventListener');
jest.spyOn(window, 'removeEventListener'); jest.spyOn(window, 'removeEventListener');
const component = shallow( const { unmount } = render(
<InstallPrompt /> <InstallPrompt />
); );
const handleInstallPrompt = component.instance().handleInstallPrompt;
expect(window.addEventListener).toHaveBeenCalledWith( unmount();
'beforeinstallprompt',
handleInstallPrompt);
component.unmount();
expect(window.removeEventListener).toHaveBeenCalledWith( expect(window.removeEventListener).toHaveBeenCalledWith(
'beforeinstallprompt', 'beforeinstallprompt',
handleInstallPrompt); expect.any(Function));
}); });
test('accepting install prompt', async () => { test('accepting install prompt', async () => {
const component = shallow( const { asFragment, getByTestId } = render(
<InstallPrompt /> <InstallPrompt />
); );
const promptObj = { const promptEvent = new Event('beforeinstallprompt');
prompt: jest.fn(), promptEvent.prompt = jest.fn();
userChoice: Promise.resolve() promptEvent.userChoice = Promise.resolve();
}; const clickEvent = new MouseEvent('click', { bubbles: true });
const eventObj = { preventDefault: jest.fn() }; jest.spyOn(clickEvent, 'preventDefault');
component.instance().handleInstallPrompt(promptObj); fireEvent(window, promptEvent);
component.find('a').simulate('click', eventObj); expect(asFragment()).toMatchSnapshot();
fireEvent(getByTestId('install'), clickEvent);
// Allow async code to run // Allow async code to run
await new Promise(resolve => setTimeout(resolve)); await new Promise(resolve => setTimeout(resolve));
expect(eventObj.preventDefault).toHaveBeenCalled(); expect(clickEvent.preventDefault).toHaveBeenCalled();
expect(promptObj.prompt).toHaveBeenCalled(); expect(promptEvent.prompt).toHaveBeenCalled();
expect(component.state('installPrompt')).toBeNull(); expect(asFragment()).toMatchSnapshot();
}); });
test('rejecting install prompt', async () => { test('rejecting install prompt', async () => {
const component = shallow( const { asFragment, getByTestId } = render(
<InstallPrompt /> <InstallPrompt />
); );
const promptObj = { const promptEvent = new Event('beforeinstallprompt');
prompt: jest.fn(), promptEvent.prompt = jest.fn();
userChoice: Promise.reject() promptEvent.userChoice = Promise.reject();
}; const clickEvent = new MouseEvent('click', { bubbles: true });
const eventObj = { preventDefault: jest.fn() }; jest.spyOn(clickEvent, 'preventDefault');
component.instance().handleInstallPrompt(promptObj); fireEvent(window, promptEvent);
component.find('a').simulate('click', eventObj); expect(asFragment()).toMatchSnapshot();
fireEvent(getByTestId('install'), clickEvent);
// Allow async code to run // Allow async code to run
await new Promise(resolve => setTimeout(resolve)); await new Promise(resolve => setTimeout(resolve));
expect(eventObj.preventDefault).toHaveBeenCalled(); expect(clickEvent.preventDefault).toHaveBeenCalled();
expect(promptObj.prompt).toHaveBeenCalled(); expect(promptEvent.prompt).toHaveBeenCalled();
expect(component.state('installPrompt')).toBeNull(); expect(asFragment()).toMatchSnapshot();
}); });
}); });

View File

@ -1,26 +1,30 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP // Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Layout rendering 1`] = ` exports[`Layout rendering 1`] = `
<SentryBoundary> <DocumentFragment>
<noscript> <span
<style data-component="SentryBoundary"
type="text/css" data-props="{}"
> >
<noscript />
[data-requires-js] { <span
display: none !important; data-component="withI18nextTranslation(Header)"
} data-props="{
\\"banner\\": \\"Test Banner\\"
</style> }"
</noscript>
<withI18nextTranslation(Header)
banner="Test Banner"
/> />
<SentryBoundary> <span
data-component="SentryBoundary"
data-props="{}"
>
Example content Example content
</SentryBoundary> </span>
<withI18nextTranslation(Footer) <span
buildId="test-buildid" data-component="withI18nextTranslation(Footer)"
data-props="{
\\"buildId\\": \\"test-buildid\\"
}"
/> />
</SentryBoundary> </span>
</DocumentFragment>
`; `;

View File

@ -1,15 +1,22 @@
jest.mock('components/SentryBoundary', () =>
require('__mocks__/component-mock')('components/SentryBoundary'));
jest.mock('components/Header', () =>
require('__mocks__/component-mock')('components/Header'));
jest.mock('components/Footer', () =>
require('__mocks__/component-mock')('components/Footer'));
import React from 'react'; import React from 'react';
import { shallow } from 'enzyme'; import { render } from 'react-testing-library';
import { Layout } from 'components/Layout'; import { Layout } from 'components/Layout';
describe('Layout', () => { describe('Layout', () => {
test('rendering', () => { test('rendering', () => {
const component = shallow( const { asFragment } = render(
<Layout banner="Test Banner" buildId="test-buildid"> <Layout banner="Test Banner" buildId="test-buildid">
Example content Example content
</Layout> </Layout>
); );
expect(component).toMatchSnapshot(); expect(asFragment()).toMatchSnapshot();
}); });
}); });

View File

@ -1,23 +1,17 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP // Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Loader rendering 1`] = ` exports[`Loader rendering 1`] = `
<Loader <DocumentFragment>
t={[Function]}
>
<div <div
className="loader" class="loader"
>
<Loader
color="currentColor"
size="24"
> >
<svg <svg
fill="none" fill="none"
height="24" height="24"
stroke="currentColor" stroke="currentColor"
strokeLinecap="round" stroke-linecap="round"
strokeLinejoin="round" stroke-linejoin="round"
strokeWidth="2" stroke-width="2"
viewBox="0 0 24 24" viewBox="0 0 24 24"
width="24" width="24"
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
@ -71,12 +65,11 @@ exports[`Loader rendering 1`] = `
y2="4.93" y2="4.93"
/> />
</svg> </svg>
</Loader>
<div <div
className="message" class="message"
> >
TRANSLATE(Loading...) TRANSLATE(Loading...)
</div> </div>
</div> </div>
</Loader> </DocumentFragment>
`; `;

View File

@ -1,5 +1,5 @@
import React from 'react'; import React from 'react';
import { mount } from 'enzyme'; import { render } from 'react-testing-library';
import { mockT } from 'i18n'; import { mockT } from 'i18n';
import { Loader } from 'components/Loader'; import { Loader } from 'components/Loader';
@ -8,9 +8,9 @@ describe('Loader', () => {
test('rendering', () => { test('rendering', () => {
// Using full rendering here since styles for this depend on the structure // Using full rendering here since styles for this depend on the structure
// of the SVG. // of the SVG.
const component = mount( const { asFragment } = render(
<Loader t={ mockT } /> <Loader t={ mockT } />
); );
expect(component).toMatchSnapshot(); expect(asFragment()).toMatchSnapshot();
}); });
}); });

View File

@ -1,34 +1,36 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP // Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`LocaleSwitcher rendering 1`] = ` exports[`LocaleSwitcher rendering 1`] = `
<label> <DocumentFragment>
<Trans> <label>
<span
data-component="Trans"
data-props="{}"
>
Language Language
</Trans> </span>
<div <div
className="switcher" class="switcher"
> >
<select <select
onChange={[Function]} data-testid="language-select"
value="en"
> >
<option <option
key="en"
value="en" value="en"
> >
English English
</option> </option>
<option <option
key="other"
value="other" value="other"
> >
Other Other
</option> </option>
</select> </select>
<ChevronsDown <span
color="currentColor" data-component="ChevronsDown"
size="24" data-props="{}"
/> />
</div> </div>
</label> </label>
</DocumentFragment>
`; `;

View File

@ -38,7 +38,10 @@ export class LocaleSwitcher extends React.PureComponent {
return <label> return <label>
<Trans>Language</Trans> <Trans>Language</Trans>
<div className={ style.switcher }> <div className={ style.switcher }>
<select value={ current } onChange={ this.handleSelectChange }> <select data-testid="language-select"
value={ current }
onChange={ this.handleSelectChange }
>
{ locales.map(locale => ( { locales.map(locale => (
<option value={ locale.code } key={ locale.code }> <option value={ locale.code } key={ locale.code }>
{ locale.name } { locale.name }

View File

@ -1,5 +1,9 @@
jest.mock('react-feather/dist/icons/chevrons-down', () =>
require('__mocks__/component-mock')(
'react-feather/dist/icons/chevrons-down'));
import React from 'react'; import React from 'react';
import { shallow } from 'enzyme'; import { render, fireEvent } from 'react-testing-library';
import i18n from 'i18n'; import i18n from 'i18n';
import { LocaleSwitcher } from 'components/LocaleSwitcher'; import { LocaleSwitcher } from 'components/LocaleSwitcher';
@ -9,44 +13,47 @@ jest.mock('./locale-to-available', () => jest.fn(() => 'en'));
describe('LocaleSwitcher', () => { describe('LocaleSwitcher', () => {
test('rendering', () => { test('rendering', () => {
const component = shallow( const { asFragment } = render(
<LocaleSwitcher /> <LocaleSwitcher />
); );
expect(component).toMatchSnapshot(); expect(asFragment()).toMatchSnapshot();
}); });
test('changing language', () => { test('changing language', () => {
jest.spyOn(i18n, 'changeLanguage'); jest.spyOn(i18n, 'changeLanguage');
const component = shallow( const { getByTestId } = render(
<LocaleSwitcher /> <LocaleSwitcher />
); );
const selectInput = component.find('select'); const event = new Event('change', { bubbles: true });
selectInput.value = 'other'; const select = getByTestId('language-select');
selectInput.simulate('change', { target: { value: 'other' } }); select.value = 'other';
fireEvent(select, event);
expect(i18n.changeLanguage).toHaveBeenCalledWith('other'); expect(i18n.changeLanguage).toHaveBeenCalledWith('other');
}); });
test('interface update from language change', () => { test('interface update from language change', () => {
const component = shallow( const { getByTestId } = render(
<LocaleSwitcher /> <LocaleSwitcher />
); );
expect(component.find('select').prop('value')).toEqual('en'); expect(getByTestId('language-select').value).toEqual('en');
i18n.emit('languageChanged', 'other'); i18n.emit('languageChanged', 'other');
expect(component.find('select').prop('value')).toEqual('other'); expect(getByTestId('language-select').value).toEqual('other');
}); });
test('disconnecting event handler on unmount', () => { test('disconnecting event handler on unmount', () => {
const component = shallow( const { unmount } = render(
<LocaleSwitcher /> <LocaleSwitcher />
); );
jest.spyOn(component, 'setState'); jest.spyOn(i18n, 'off');
component.unmount(); unmount();
i18n.emit('languageChanged', 'other'); expect(i18n.off).toHaveBeenCalledWith(
expect(component.setState).not.toHaveBeenCalled(); 'languageChanged',
expect.any(Function));
}); });
}); });

View File

@ -1,99 +1,105 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP // Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Message rendering 1`] = ` exports[`Message rendering 1`] = `
<div <DocumentFragment>
className="message"
>
<div <div
className="header" class="message"
>
<div
class="header"
> >
<h2> <h2>
Testing Testing
</h2> </h2>
</div> </div>
<div <div
className="content" class="content"
> >
<p> <p>
Message content Message content
</p> </p>
</div> </div>
</div> </div>
</DocumentFragment>
`; `;
exports[`Message rendering with a close button 1`] = ` exports[`Message rendering with a close button 1`] = `
<div <DocumentFragment>
className="message"
>
<div <div
className="header" class="message"
>
<div
class="header"
> >
<h2> <h2>
Testing Testing
</h2> </h2>
<button <button>
onClick={[MockFunction]} <span
> data-component="XSquare"
<XSquare data-props="{}"
color="currentColor"
size="24"
/> />
Close Close
</button> </button>
</div> </div>
<div <div
className="content" class="content"
> >
<p> <p>
Message content Message content
</p> </p>
</div> </div>
</div> </div>
</DocumentFragment>
`; `;
exports[`Message rendering with icon 1`] = ` exports[`Message rendering with icon 1`] = `
<div <DocumentFragment>
className="message"
>
<div <div
className="header" class="message"
> >
<Icon /> <div
class="header"
>
Sample icon SVG
<h2> <h2>
Testing Testing
</h2> </h2>
</div> </div>
<div <div
className="content" class="content"
> >
<p> <p>
Message content Message content
</p> </p>
</div> </div>
</div> </div>
</DocumentFragment>
`; `;
exports[`Message rendering with type 1`] = ` exports[`Message rendering with type 1`] = `
<div <DocumentFragment>
className="message error"
>
<div <div
className="header" class="message error"
> >
<AlertOctagon <div
color="currentColor" class="header"
size="24" >
<span
data-component="AlertOctagon"
data-props="{}"
/> />
<h2> <h2>
Testing Testing
</h2> </h2>
</div> </div>
<div <div
className="content" class="content"
> >
<p> <p>
Message content Message content
</p> </p>
</div> </div>
</div> </div>
</DocumentFragment>
`; `;

View File

@ -1,43 +1,56 @@
jest.mock('react-feather/dist/icons/info', () =>
require('__mocks__/component-mock')('react-feather/dist/icons/info'));
jest.mock('react-feather/dist/icons/alert-octagon', () =>
require('__mocks__/component-mock')(
'react-feather/dist/icons/alert-octagon'
));
jest.mock('react-feather/dist/icons/alert-triangle', () =>
require('__mocks__/component-mock')(
'react-feather/dist/icons/alert-triangle'
));
jest.mock('react-feather/dist/icons/x-square', () =>
require('__mocks__/component-mock')('react-feather/dist/icons/x-square'));
import React from 'react'; import React from 'react';
import { shallow } from 'enzyme'; import { render } from 'react-testing-library';
import Message from 'components/Message'; import Message from 'components/Message';
describe('Message', () => { describe('Message', () => {
test('rendering', () => { test('rendering', () => {
const component = shallow( const { asFragment } = render(
<Message heading="Testing"> <Message heading="Testing">
<p>Message content</p> <p>Message content</p>
</Message> </Message>
); );
expect(component).toMatchSnapshot(); expect(asFragment()).toMatchSnapshot();
}); });
test('rendering with icon', () => { test('rendering with icon', () => {
const Icon = () => 'Sample icon SVG'; const Icon = () => 'Sample icon SVG';
const component = shallow( const { asFragment } = render(
<Message heading="Testing" icon={ Icon }> <Message heading="Testing" icon={ Icon }>
<p>Message content</p> <p>Message content</p>
</Message> </Message>
); );
expect(component).toMatchSnapshot(); expect(asFragment()).toMatchSnapshot();
}); });
test('rendering with type', () => { test('rendering with type', () => {
const component = shallow( const { asFragment } = render(
<Message heading="Testing" type="error"> <Message heading="Testing" type="error">
<p>Message content</p> <p>Message content</p>
</Message> </Message>
); );
expect(component).toMatchSnapshot(); expect(asFragment()).toMatchSnapshot();
}); });
test('rendering with a close button', () => { test('rendering with a close button', () => {
const component = shallow( const { asFragment } = render(
<Message heading="Testing" onClose={ jest.fn() }> <Message heading="Testing" onClose={ jest.fn() }>
<p>Message content</p> <p>Message content</p>
</Message> </Message>
); );
expect(component).toMatchSnapshot(); expect(asFragment()).toMatchSnapshot();
}); });
}); });

View File

@ -1,31 +1,32 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP // Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Metadata rendering 1`] = ` exports[`Metadata rendering 1`] = `
<HelmetWrapper <DocumentFragment>
defer={true} <span
encodeSpecialCharacters={true} data-component="HelmetWrapper"
htmlAttributes={ data-props="{
Object { \\"htmlAttributes\\": {
"lang": "test-lang", \\"lang\\": \\"test-lang\\"
} }
} }"
> >
<title> <title>
Regexper Regexper
</title> </title>
</HelmetWrapper> </span>
</DocumentFragment>
`; `;
exports[`Metadata rendering with a title and description 1`] = ` exports[`Metadata rendering with a title and description 1`] = `
<HelmetWrapper <DocumentFragment>
defer={true} <span
encodeSpecialCharacters={true} data-component="HelmetWrapper"
htmlAttributes={ data-props="{
Object { \\"htmlAttributes\\": {
"lang": "test-lang", \\"lang\\": \\"test-lang\\"
} }
} }"
> >
<title> <title>
Regexper - Testing Regexper - Testing
</title> </title>
@ -33,5 +34,6 @@ exports[`Metadata rendering with a title and description 1`] = `
content="Test description" content="Test description"
name="description" name="description"
/> />
</HelmetWrapper> </span>
</DocumentFragment>
`; `;

View File

@ -1,5 +1,13 @@
jest.mock('react-helmet', () => {
const helmet = jest.requireActual('react-helmet');
return {
...helmet,
Helmet: require('__mocks__/component-mock').buildMock(helmet.Helmet)
};
});
import React from 'react'; import React from 'react';
import { shallow } from 'enzyme'; import { render } from 'react-testing-library';
import { Metadata } from 'components/Metadata'; import { Metadata } from 'components/Metadata';
@ -9,19 +17,19 @@ const commonProps = {
describe('Metadata', () => { describe('Metadata', () => {
test('rendering', () => { test('rendering', () => {
const component = shallow( const { asFragment } = render(
<Metadata { ...commonProps } /> <Metadata { ...commonProps } />
); );
expect(component).toMatchSnapshot(); expect(asFragment()).toMatchSnapshot();
}); });
test('rendering with a title and description', () => { test('rendering with a title and description', () => {
const component = shallow( const { asFragment } = render(
<Metadata <Metadata
title="Testing" title="Testing"
description="Test description" description="Test description"
{ ...commonProps } /> { ...commonProps } />
); );
expect(component).toMatchSnapshot(); expect(asFragment()).toMatchSnapshot();
}); });
}); });

View File

@ -1,13 +1,19 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP // Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`PrivacyPolicy rendering 1`] = ` exports[`PrivacyPolicy rendering 1`] = `
<Message <DocumentFragment>
heading="TRANSLATE(Privacy Policy)" <span
onClose={[MockFunction]} data-component="Message"
type="info" data-props="{
> \\"type\\": \\"info\\",
<Trans \\"heading\\": \\"TRANSLATE(Privacy Policy)\\"
i18nKey="Privacy policy copy" }"
>
<span
data-component="Trans"
data-props="{
\\"i18nKey\\": \\"Privacy policy copy\\"
}"
> >
<p> <p>
Regexper and the tools used to create it are all open source. If you are concerned that the JavaScript being delivered is in any way malicious, please inspect the source in the Regexper and the tools used to create it are all open source. If you are concerned that the JavaScript being delivered is in any way malicious, please inspect the source in the
@ -51,6 +57,7 @@ exports[`PrivacyPolicy rendering 1`] = `
<p> <p>
Regexper is not supported by ad revenue or sales of any kind. Regexper is not supported by ad revenue or sales of any kind.
</p> </p>
</Trans> </span>
</Message> </span>
</DocumentFragment>
`; `;

View File

@ -1,14 +1,17 @@
jest.mock('components/Message', () =>
require('__mocks__/component-mock')('components/Message'));
import React from 'react'; import React from 'react';
import { shallow } from 'enzyme'; import { render } from 'react-testing-library';
import { mockT } from 'i18n'; import { mockT } from 'i18n';
import { PrivacyPolicy } from 'components/PrivacyPolicy'; import { PrivacyPolicy } from 'components/PrivacyPolicy';
describe('PrivacyPolicy', () => { describe('PrivacyPolicy', () => {
test('rendering', () => { test('rendering', () => {
const component = shallow( const { asFragment } = render(
<PrivacyPolicy onClose={ jest.fn() } t={ mockT } /> <PrivacyPolicy onClose={ jest.fn() } t={ mockT } />
); );
expect(component).toMatchSnapshot(); expect(asFragment()).toMatchSnapshot();
}); });
}); });

View File

@ -1,155 +1,510 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP // Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Render debugging 1`] = ` exports[`Render debugging 1`] = `
<div <DocumentFragment>
className="render" <div
> class="render"
<SVG >
onReflow={[Function]} <svg
style="background-color: rgb(255, 255, 255);"
viewBox="0 0 "
xmlns="http://www.w3.org/2000/svg"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
>
<metadata>
<rdf:rdf>
<cc:license
rdf:about="http://creativecommons.org/licenses/by/3.0/"
>
<cc:permits
rdf:resource="http://creativecommons.org/ns#Reproduction"
/>
<cc:permits
rdf:resource="http://creativecommons.org/ns#Distribution"
/>
<cc:requires
rdf:resource="http://creativecommons.org/ns#Notice"
/>
<cc:requires
rdf:resource="http://creativecommons.org/ns#Attribution"
/>
<cc:permits
rdf:resource="http://creativecommons.org/ns#DerivativeWorks"
/>
</cc:license>
</rdf:rdf>
</metadata>
<g
transform="translate(10 10)"
>
<span
data-component="Text"
data-props="{}"
> >
<Text>
Example Example
</Text> </span>
<rect <rect
height={50} height="50"
style={ style="fill: transparent; stroke: red; stroke-width: 1px; stroke-dasharray: 2,2; opacity: 0.5;"
Object { width="100"
"fill": "transparent",
"opacity": 0.5,
"stroke": "red",
"strokeDasharray": "2,2",
"strokeWidth": "1px",
}
}
width={100}
/> />
<circle <circle
cx={5} cx="5"
cy={10} cy="10"
r="3" r="3"
style={ style="fill: red; opacity: 0.5;"
Object {
"fill": "red",
"opacity": 0.5,
}
}
/> />
<circle <circle
cx={95} cx="95"
cy={10} cy="10"
r="3" r="3"
style={ style="fill: red; opacity: 0.5;"
Object {
"fill": "red",
"opacity": 0.5,
}
}
/> />
</SVG> </g>
</div> </svg>
</div>
</DocumentFragment>
`; `;
exports[`Render types Box 1`] = ` exports[`Render types Box 1`] = `
<div <DocumentFragment>
className="render" <div
> class="render"
<SVG
onReflow={[Function]}
> >
<Box <svg
padding={5} style="background-color: rgb(255, 255, 255);"
radius={3} viewBox="0 0 "
xmlns="http://www.w3.org/2000/svg"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
>
<metadata>
<rdf:rdf>
<cc:license
rdf:about="http://creativecommons.org/licenses/by/3.0/"
>
<cc:permits
rdf:resource="http://creativecommons.org/ns#Reproduction"
/>
<cc:permits
rdf:resource="http://creativecommons.org/ns#Distribution"
/>
<cc:requires
rdf:resource="http://creativecommons.org/ns#Notice"
/>
<cc:requires
rdf:resource="http://creativecommons.org/ns#Attribution"
/>
<cc:permits
rdf:resource="http://creativecommons.org/ns#DerivativeWorks"
/>
</cc:license>
</rdf:rdf>
</metadata>
<g
transform="translate(10 10)"
>
<span
data-component="Box"
data-props="{}"
>
<span
data-component="Text"
data-props="{}"
> >
<Text>
Example Example
</Text> </span>
</Box> </span>
</SVG> </g>
</div> </svg>
</div>
</DocumentFragment>
`; `;
exports[`Render types HorizontalLayout 1`] = ` exports[`Render types HorizontalLayout 1`] = `
<div <DocumentFragment>
className="render" <div
> class="render"
<SVG
onReflow={[Function]}
> >
<HorizontalLayout <svg
spacing={10} style="background-color: rgb(255, 255, 255);"
withConnectors={false} viewBox="0 0 "
xmlns="http://www.w3.org/2000/svg"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
>
<metadata>
<rdf:rdf>
<cc:license
rdf:about="http://creativecommons.org/licenses/by/3.0/"
>
<cc:permits
rdf:resource="http://creativecommons.org/ns#Reproduction"
/>
<cc:permits
rdf:resource="http://creativecommons.org/ns#Distribution"
/>
<cc:requires
rdf:resource="http://creativecommons.org/ns#Notice"
/>
<cc:requires
rdf:resource="http://creativecommons.org/ns#Attribution"
/>
<cc:permits
rdf:resource="http://creativecommons.org/ns#DerivativeWorks"
/>
</cc:license>
</rdf:rdf>
</metadata>
<g
transform="translate(10 10)"
>
<span
data-component="HorizontalLayout"
data-props="{}"
>
<span
data-component="Text"
data-props="{}"
> >
<Text>
Example Example
</Text> </span>
<Text> <span
data-component="Text"
data-props="{}"
>
Another Example Another Example
</Text> </span>
</HorizontalLayout> </span>
</SVG> </g>
</div> </svg>
</div>
</DocumentFragment>
`; `;
exports[`Render types Loop 1`] = ` exports[`Render types Loop 1`] = `
<div <DocumentFragment>
className="render" <div
> class="render"
<SVG >
onReflow={[Function]} <svg
style="background-color: rgb(255, 255, 255);"
viewBox="0 0 "
xmlns="http://www.w3.org/2000/svg"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
>
<metadata>
<rdf:rdf>
<cc:license
rdf:about="http://creativecommons.org/licenses/by/3.0/"
>
<cc:permits
rdf:resource="http://creativecommons.org/ns#Reproduction"
/>
<cc:permits
rdf:resource="http://creativecommons.org/ns#Distribution"
/>
<cc:requires
rdf:resource="http://creativecommons.org/ns#Notice"
/>
<cc:requires
rdf:resource="http://creativecommons.org/ns#Attribution"
/>
<cc:permits
rdf:resource="http://creativecommons.org/ns#DerivativeWorks"
/>
</cc:license>
</rdf:rdf>
</metadata>
<g
transform="translate(10 10)"
>
<span
data-component="Loop"
data-props="{}"
>
<span
data-component="Text"
data-props="{}"
> >
<Loop>
<Text>
Example Example
</Text> </span>
</Loop> </span>
</SVG> </g>
</div> </svg>
</div>
</DocumentFragment>
`; `;
exports[`Render types Pin 1`] = ` exports[`Render types Pin 1`] = `
<div <DocumentFragment>
className="render" <div
> class="render"
<SVG
onReflow={[Function]}
> >
<Pin /> <svg
</SVG> style="background-color: rgb(255, 255, 255);"
</div> viewBox="0 0 "
xmlns="http://www.w3.org/2000/svg"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
>
<metadata>
<rdf:rdf>
<cc:license
rdf:about="http://creativecommons.org/licenses/by/3.0/"
>
<cc:permits
rdf:resource="http://creativecommons.org/ns#Reproduction"
/>
<cc:permits
rdf:resource="http://creativecommons.org/ns#Distribution"
/>
<cc:requires
rdf:resource="http://creativecommons.org/ns#Notice"
/>
<cc:requires
rdf:resource="http://creativecommons.org/ns#Attribution"
/>
<cc:permits
rdf:resource="http://creativecommons.org/ns#DerivativeWorks"
/>
</cc:license>
</rdf:rdf>
</metadata>
<g
transform="translate(10 10)"
>
<span
data-component="Pin"
data-props="{}"
/>
</g>
</svg>
</div>
</DocumentFragment>
`; `;
exports[`Render types Text 1`] = ` exports[`Render types Text 1`] = `
<div <DocumentFragment>
className="render" <div
> class="render"
<SVG >
onReflow={[Function]} <svg
style="background-color: rgb(255, 255, 255);"
viewBox="0 0 "
xmlns="http://www.w3.org/2000/svg"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
>
<metadata>
<rdf:rdf>
<cc:license
rdf:about="http://creativecommons.org/licenses/by/3.0/"
>
<cc:permits
rdf:resource="http://creativecommons.org/ns#Reproduction"
/>
<cc:permits
rdf:resource="http://creativecommons.org/ns#Distribution"
/>
<cc:requires
rdf:resource="http://creativecommons.org/ns#Notice"
/>
<cc:requires
rdf:resource="http://creativecommons.org/ns#Attribution"
/>
<cc:permits
rdf:resource="http://creativecommons.org/ns#DerivativeWorks"
/>
</cc:license>
</rdf:rdf>
</metadata>
<g
transform="translate(10 10)"
>
<span
data-component="Text"
data-props="{}"
> >
<Text>
Example Example
</Text> </span>
</SVG> </g>
</div> </svg>
</div>
</DocumentFragment>
`; `;
exports[`Render types VerticalLayout 1`] = ` exports[`Render types VerticalLayout 1`] = `
<div <DocumentFragment>
className="render" <div
> class="render"
<SVG
onReflow={[Function]}
> >
<VerticalLayout <svg
spacing={10} style="background-color: rgb(255, 255, 255);"
withConnectors={false} viewBox="0 0 "
xmlns="http://www.w3.org/2000/svg"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
>
<metadata>
<rdf:rdf>
<cc:license
rdf:about="http://creativecommons.org/licenses/by/3.0/"
>
<cc:permits
rdf:resource="http://creativecommons.org/ns#Reproduction"
/>
<cc:permits
rdf:resource="http://creativecommons.org/ns#Distribution"
/>
<cc:requires
rdf:resource="http://creativecommons.org/ns#Notice"
/>
<cc:requires
rdf:resource="http://creativecommons.org/ns#Attribution"
/>
<cc:permits
rdf:resource="http://creativecommons.org/ns#DerivativeWorks"
/>
</cc:license>
</rdf:rdf>
</metadata>
<g
transform="translate(10 10)"
>
<span
data-component="VerticalLayout"
data-props="{}"
>
<span
data-component="Text"
data-props="{}"
> >
<Text>
Example Example
</Text> </span>
<Text> <span
data-component="Text"
data-props="{}"
>
Another Example Another Example
</Text> </span>
</VerticalLayout> </span>
</SVG> </g>
</div> </svg>
</div>
</DocumentFragment>
`; `;

View File

@ -1,15 +1,28 @@
jest.mock('rendering/Box', () =>
require('__mocks__/component-mock')('rendering/Box'));
jest.mock('rendering/HorizontalLayout', () =>
require('__mocks__/component-mock')('rendering/HorizontalLayout'));
jest.mock('rendering/Loop', () =>
require('__mocks__/component-mock')('rendering/Loop'));
jest.mock('rendering/Pin', () =>
require('__mocks__/component-mock')('rendering/Pin'));
jest.mock('rendering/Text', () =>
require('__mocks__/component-mock')('rendering/Text'));
jest.mock('rendering/VerticalLayout', () =>
require('__mocks__/component-mock')('rendering/VerticalLayout'));
import React from 'react'; import React from 'react';
import { shallow } from 'enzyme'; import { render } from 'react-testing-library';
import Render from 'components/Render'; import Render from 'components/Render';
const testType = (name, item) => { const testType = (name, item) => {
test(name, () => { test(name, () => {
const data = { type: 'SVG', children: [item] }; const data = { type: 'SVG', children: [item] };
const component = shallow( const { asFragment } = render(
<Render data={ data } onRender={ jest.fn() }/> <Render data={ data } onRender={ jest.fn() }/>
); );
expect(component).toMatchSnapshot(); expect(asFragment()).toMatchSnapshot();
}); });
}; };
@ -34,10 +47,10 @@ describe('Render', () => {
} }
] ]
}; };
const component = shallow( const { asFragment } = render(
<Render data={ data } onRender={ jest.fn() }/> <Render data={ data } onRender={ jest.fn() }/>
); );
expect(component).toMatchSnapshot(); expect(asFragment()).toMatchSnapshot();
}); });
describe('types', () => { describe('types', () => {

View File

@ -1,7 +1,22 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP // Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`SentryBoundary error handling 1`] = `<Child />`; exports[`SentryBoundary error handling 1`] = `
<DocumentFragment>
Example content
</DocumentFragment>
`;
exports[`SentryBoundary error handling 2`] = `<withI18nextTranslation(SentryError) />`; exports[`SentryBoundary error handling 2`] = `
<DocumentFragment>
<span
data-component="withI18nextTranslation(SentryError)"
data-props="{}"
/>
</DocumentFragment>
`;
exports[`SentryBoundary rendering 1`] = `"Example content"`; exports[`SentryBoundary rendering 1`] = `
<DocumentFragment>
Example content
</DocumentFragment>
`;

View File

@ -1,41 +1,53 @@
jest.mock('@sentry/browser'); jest.mock('@sentry/browser');
jest.mock('components/SentryError', () =>
require('__mocks__/component-mock')('components/SentryError'));
import React from 'react'; import React from 'react';
import { shallow } from 'enzyme'; import { render } from 'react-testing-library';
import * as Sentry from '@sentry/browser'; import * as Sentry from '@sentry/browser';
import SentryBoundary from 'components/SentryBoundary'; import SentryBoundary from 'components/SentryBoundary';
describe('SentryBoundary', () => { describe('SentryBoundary', () => {
test('rendering', () => { test('rendering', () => {
const component = shallow( const { asFragment } = render(
<SentryBoundary> <SentryBoundary>
Example content Example content
</SentryBoundary> </SentryBoundary>
); );
expect(component).toMatchSnapshot(); expect(asFragment()).toMatchSnapshot();
}); });
test('error handling', () => { test('error handling', () => {
const Child = () => 'Example content'; // Hide React's console logging about the error
const component = shallow( jest.spyOn(console, 'error').mockImplementation(() => {});
const error =new Error('Example error');
const Child = ({ shouldThrow }) => {
if (shouldThrow) {
throw error;
}
return 'Example content';
};
const { asFragment, rerender } = render(
<SentryBoundary> <SentryBoundary>
<Child /> <Child shouldThrow={ false } />
</SentryBoundary> </SentryBoundary>
); );
expect(component).toMatchSnapshot(); expect(asFragment()).toMatchSnapshot();
const error = new Error('Example error'); rerender(
component.find('Child').simulateError(error); <SentryBoundary>
// NOTE: Enzyme doesn't call getDerivedStateFromError yet, so we have to <Child shouldThrow={ true } />
// set the state manually </SentryBoundary>
component.setState(SentryBoundary.getDerivedStateFromError(error)); );
const scope = { setExtra: jest.fn() }; const scope = { setExtra: jest.fn() };
expect(Sentry.withScope).toHaveBeenCalled(); expect(Sentry.withScope).toHaveBeenCalled();
Sentry.withScope.mock.calls[0][0](scope); Sentry.withScope.mock.calls[0][0](scope);
expect(Sentry.captureException).toHaveBeenCalledWith(error); expect(Sentry.captureException).toHaveBeenCalledWith(error);
expect(component).toMatchSnapshot(); expect(asFragment()).toMatchSnapshot();
}); });
}); });

View File

@ -1,21 +1,29 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP // Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`SentryError rendering 1`] = ` exports[`SentryError rendering 1`] = `
<Message <DocumentFragment>
heading="TRANSLATE(An error has occurred)" <span
type="error" data-component="Message"
> data-props="{
\\"type\\": \\"error\\",
\\"heading\\": \\"TRANSLATE(An error has occurred)\\"
}"
>
<p> <p>
<Trans> <span
data-component="Trans"
data-props="{}"
>
This error has been logged. You may also This error has been logged. You may also
<a <a
data-testid="error-report"
href="#error-report" href="#error-report"
onClick={[Function]}
> >
fill out a report fill out a report
</a> </a>
. .
</Trans> </span>
</p> </p>
</Message> </span>
</DocumentFragment>
`; `;

View File

@ -16,7 +16,9 @@ const reportError = event => {
export const SentryError = ({ t }) => ( export const SentryError = ({ t }) => (
<Message type="error" heading={ t('An error has occurred') }> <Message type="error" heading={ t('An error has occurred') }>
<p> <p>
<Trans>This error has been logged. You may also <a href="#error-report" <Trans>This error has been logged. You may also <a
href="#error-report"
data-testid="error-report"
onClick={ reportError }>fill out a report</a>.</Trans> onClick={ reportError }>fill out a report</a>.</Trans>
</p> </p>
</Message> </Message>

View File

@ -1,7 +1,10 @@
jest.mock('@sentry/browser'); jest.mock('@sentry/browser');
jest.mock('components/Message', () =>
require('__mocks__/component-mock')('components/Message'));
import React from 'react'; import React from 'react';
import { shallow } from 'enzyme'; import { render, fireEvent } from 'react-testing-library';
import * as Sentry from '@sentry/browser'; import * as Sentry from '@sentry/browser';
import { mockT } from 'i18n'; import { mockT } from 'i18n';
@ -9,34 +12,36 @@ import { SentryError } from 'components/SentryError';
describe('SentryError', () => { describe('SentryError', () => {
test('rendering', () => { test('rendering', () => {
const component = shallow( const { asFragment } = render(
<SentryError t={ mockT }/> <SentryError t={ mockT }/>
); );
expect(component).toMatchSnapshot(); expect(asFragment()).toMatchSnapshot();
}); });
describe('error reporting', () => { describe('error reporting', () => {
test('fill out a report when an event has been logged', () => { test('fill out a report when an event has been logged', () => {
Sentry.lastEventId.mockReturnValue(1); Sentry.lastEventId.mockReturnValue(1);
const component = shallow( const { getByTestId } = render(
<SentryError t={ mockT } /> <SentryError t={ mockT } />
); );
const eventObj = { preventDefault: jest.fn() }; const event = new MouseEvent('click', { bubbles: true });
component.find('a').simulate('click', eventObj); jest.spyOn(event, 'preventDefault');
fireEvent(getByTestId('error-report'), event);
expect(eventObj.preventDefault).toHaveBeenCalled(); expect(event.preventDefault).toHaveBeenCalled();
expect(Sentry.showReportDialog).toHaveBeenCalled(); expect(Sentry.showReportDialog).toHaveBeenCalled();
}); });
test('fill out a report when an event has not been logged', () => { test('fill out a report when an event has not been logged', () => {
Sentry.lastEventId.mockReturnValue(false); Sentry.lastEventId.mockReturnValue(false);
const component = shallow( const { getByTestId } = render(
<SentryError t={ mockT } /> <SentryError t={ mockT } />
); );
const eventObj = { preventDefault: jest.fn() }; const event = new MouseEvent('click', { bubbles: true });
component.find('a').simulate('click', eventObj); jest.spyOn(event, 'preventDefault');
fireEvent(getByTestId('error-report'), event);
expect(eventObj.preventDefault).toHaveBeenCalled(); expect(event.preventDefault).toHaveBeenCalled();
expect(Sentry.showReportDialog).not.toHaveBeenCalled(); expect(Sentry.showReportDialog).not.toHaveBeenCalled();
}); });
}); });

View File

@ -1,14 +1,19 @@
jest.mock('components/Metadata', () =>
require('__mocks__/component-mock')('components/Metadata'));
jest.mock('components/Message', () =>
require('__mocks__/component-mock')('components/Message'));
import React from 'react'; import React from 'react';
import { shallow } from 'enzyme'; import { render } from 'react-testing-library';
import { mockT } from 'i18n'; import { mockT } from 'i18n';
import { ErrorPage } from 'pages/404'; import { ErrorPage } from 'pages/404';
describe('Error Page', () => { describe('Error Page', () => {
test('rendering', () => { test('rendering', () => {
const component = shallow( const { asFragment } = render(
<ErrorPage t={ mockT } /> <ErrorPage t={ mockT } />
); );
expect(component).toMatchSnapshot(); expect(asFragment()).toMatchSnapshot();
}); });
}); });

View File

@ -1,19 +1,28 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP // Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Error Page rendering 1`] = ` exports[`Error Page rendering 1`] = `
<Fragment> <DocumentFragment>
<withI18nextTranslation(Metadata) <span
title="TRANSLATE(Page Not Found)" data-component="withI18nextTranslation(Metadata)"
data-props="{
\\"title\\": \\"TRANSLATE(Page Not Found)\\"
}"
/> />
<Message <span
heading="TRANSLATE(404 Page Not Found)" data-component="Message"
type="error" data-props="{
\\"type\\": \\"error\\",
\\"heading\\": \\"TRANSLATE(404 Page Not Found)\\"
}"
> >
<p> <p>
<Trans> <span
data-component="Trans"
data-props="{}"
>
The page you have requested could not be found. The page you have requested could not be found.
</Trans> </span>
</p> </p>
</Message> </span>
</Fragment> </DocumentFragment>
`; `;

View File

@ -1,89 +1,61 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP // Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Index Page rendering 1`] = ` exports[`Index Page rendering 1`] = `
<Fragment> <DocumentFragment>
<withI18nextTranslation(Metadata) <span
description="Test description" data-component="withI18nextTranslation(Metadata)"
data-props="{
\\"description\\": \\"Test description\\"
}"
/> />
<noscript> <noscript />
<Message <span
heading="JavaScript Required" data-component="withI18nextTranslation(App)"
type="error" data-props="{
> \\"syntaxList\\": [
<p> {
You need JavaScript to use Regexper. \\"id\\": \\"testJS\\",
</p> \\"name\\": \\"Testing JS\\"
<p>
If you have concerns regarding the use of tracking code on Regexper, please see the
<mockConstructor
to="/privacy"
>
Privacy Policy
</mockConstructor>
.
</p>
</Message>
</noscript>
<withI18nextTranslation(App)
expr=""
permalinkUrl={null}
syntax="testJs"
syntaxList={
Array [
Object {
"id": "testJS",
"name": "Testing JS",
}, },
Object { {
"id": "other", \\"id\\": \\"other\\",
"name": "Other", \\"name\\": \\"Other\\"
},
]
} }
],
\\"syntax\\": \\"testJs\\",
\\"expr\\": \\"\\",
\\"permalinkUrl\\": null
}"
/> />
</Fragment> </DocumentFragment>
`; `;
exports[`Index Page rendering with an expression on the URL 1`] = ` exports[`Index Page rendering with an expression on the URL 1`] = `
<Fragment> <DocumentFragment>
<withI18nextTranslation(Metadata) <span
description="Test description" data-component="withI18nextTranslation(Metadata)"
data-props="{
\\"description\\": \\"Test description\\"
}"
/> />
<noscript> <noscript />
<Message <span
heading="JavaScript Required" data-component="withI18nextTranslation(App)"
type="error" data-props="{
> \\"syntaxList\\": [
<p> {
You need JavaScript to use Regexper. \\"id\\": \\"testJS\\",
</p> \\"name\\": \\"Testing JS\\"
<p>
If you have concerns regarding the use of tracking code on Regexper, please see the
<mockConstructor
to="/privacy"
>
Privacy Policy
</mockConstructor>
.
</p>
</Message>
</noscript>
<withI18nextTranslation(App)
expr="testing"
permalinkUrl="http://example.com"
syntax="test"
syntaxList={
Array [
Object {
"id": "testJS",
"name": "Testing JS",
}, },
Object { {
"id": "other", \\"id\\": \\"other\\",
"name": "Other", \\"name\\": \\"Other\\"
},
]
} }
],
\\"syntax\\": \\"test\\",
\\"expr\\": \\"testing\\",
\\"permalinkUrl\\": \\"http://example.com\\"
}"
/> />
</Fragment> </DocumentFragment>
`; `;

View File

@ -1,10 +1,16 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP // Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Privacy Page rendering 1`] = ` exports[`Privacy Page rendering 1`] = `
<Fragment> <DocumentFragment>
<withI18nextTranslation(Metadata) <span
title="TRANSLATE(Privacy Policy)" data-component="withI18nextTranslation(Metadata)"
data-props="{
\\"title\\": \\"TRANSLATE(Privacy Policy)\\"
}"
/> />
<withI18nextTranslation(PrivacyPolicy) /> <span
</Fragment> data-component="withI18nextTranslation(PrivacyPolicy)"
data-props="{}"
/>
</DocumentFragment>
`; `;

View File

@ -1,5 +1,12 @@
jest.mock('components/Metadata', () =>
require('__mocks__/component-mock')('components/Metadata'));
jest.mock('components/Message', () =>
require('__mocks__/component-mock')('components/Message'));
jest.mock('components/App', () =>
require('__mocks__/component-mock')('components/App'));
import React from 'react'; import React from 'react';
import { shallow } from 'enzyme'; import { render } from 'react-testing-library';
import { IndexPage } from 'pages/index'; import { IndexPage } from 'pages/index';
@ -18,19 +25,19 @@ const queryResult = {
describe('Index Page', () => { describe('Index Page', () => {
test('rendering', () => { test('rendering', () => {
const component = shallow( const { asFragment } = render(
<IndexPage location={{ hash: '' }} data={ queryResult } /> <IndexPage location={{ hash: '' }} data={ queryResult } />
); );
expect(component).toMatchSnapshot(); expect(asFragment()).toMatchSnapshot();
}); });
test('rendering with an expression on the URL', () => { test('rendering with an expression on the URL', () => {
const component = shallow( const { asFragment } = render(
<IndexPage location={{ <IndexPage location={{
hash: '#syntax=test&expr=testing', hash: '#syntax=test&expr=testing',
href: 'http://example.com' href: 'http://example.com'
}} data={ queryResult } /> }} data={ queryResult } />
); );
expect(component).toMatchSnapshot(); expect(asFragment()).toMatchSnapshot();
}); });
}); });

View File

@ -1,14 +1,19 @@
jest.mock('components/Metadata', () =>
require('__mocks__/component-mock')('components/Metadata'));
jest.mock('components/PrivacyPolicy', () =>
require('__mocks__/component-mock')('components/PrivacyPolicy'));
import React from 'react'; import React from 'react';
import { shallow } from 'enzyme'; import { render } from 'react-testing-library';
import { mockT } from 'i18n'; import { mockT } from 'i18n';
import { PrivacyPage } from 'pages/privacy'; import { PrivacyPage } from 'pages/privacy';
describe('Privacy Page', () => { describe('Privacy Page', () => {
test('rendering', () => { test('rendering', () => {
const component = shallow( const { asFragment } = render(
<PrivacyPage t={ mockT } /> <PrivacyPage t={ mockT } />
); );
expect(component).toMatchSnapshot(); expect(asFragment()).toMatchSnapshot();
}); });
}); });

View File

@ -156,74 +156,65 @@ Object {
`; `;
exports[`Box rendering 1`] = ` exports[`Box rendering 1`] = `
<Fragment> <DocumentFragment>
<svg>
<rect <rect
rx={3} rx="3"
ry={3} ry="3"
/> />
<g> <g>
Example Example
</g> </g>
</Fragment> </svg>
</DocumentFragment>
`; `;
exports[`Box rendering with a corner radius 1`] = ` exports[`Box rendering with a corner radius 1`] = `
<Fragment> <DocumentFragment>
<svg>
<rect <rect
rx={5} rx="5"
ry={5} ry="5"
/> />
<g> <g>
Example Example
</g> </g>
</Fragment> </svg>
</DocumentFragment>
`; `;
exports[`Box rendering with a label 1`] = ` exports[`Box rendering with a label 1`] = `
<Fragment> <DocumentFragment>
<svg>
<rect <rect
rx={3} rx="3"
ry={3} ry="3"
/> />
<text <text
style={ style="font-size: 12px; font-family: Arial;"
Object {
"fontFamily": "Arial",
"fontSize": "12px",
}
}
> >
Test box Test box
</text> </text>
<g> <g>
Example Example
</g> </g>
</Fragment> </svg>
</DocumentFragment>
`; `;
exports[`Box rendering with props from layout 1`] = ` exports[`Box rendering with props from layout 1`] = `
<Fragment> <DocumentFragment>
<svg>
<rect <rect
height={50} height="50"
rx={3} rx="3"
ry={3} ry="3"
style={ style="fill: #dae9e5; stroke-width: 1px; stroke: #6b6659;"
Object {
"fill": "#dae9e5",
"stroke": "#6b6659",
"strokeWidth": "1px",
}
}
transform="RECT TRANSFORM" transform="RECT TRANSFORM"
width={100} width="100"
/> />
<text <text
style={ style="font-size: 12px; font-family: Arial;"
Object {
"fontFamily": "Arial",
"fontSize": "12px",
}
}
transform="LABEL TRANSFORM" transform="LABEL TRANSFORM"
> >
Test box Test box
@ -233,97 +224,81 @@ exports[`Box rendering with props from layout 1`] = `
> >
Example Example
</g> </g>
</Fragment> </svg>
</DocumentFragment>
`; `;
exports[`Box themes rendering a "anchor" Box 1`] = ` exports[`Box themes rendering a "anchor" Box 1`] = `
<Fragment> <DocumentFragment>
<svg>
<rect <rect
rx={3} rx="3"
ry={3} ry="3"
style={ style="fill: #6b6659;"
Object {
"fill": "#6b6659",
}
}
/> />
<g> <g>
Example Example
</g> </g>
</Fragment> </svg>
</DocumentFragment>
`; `;
exports[`Box themes rendering a "capture" Box 1`] = ` exports[`Box themes rendering a "capture" Box 1`] = `
<Fragment> <DocumentFragment>
<svg>
<rect <rect
rx={3} rx="3"
ry={3} ry="3"
style={ style="fill-opacity: 0; stroke-width: 2px; stroke: #908c83; stroke-dasharray: 6,2;"
Object {
"fillOpacity": 0,
"stroke": "#908c83",
"strokeDasharray": "6,2",
"strokeWidth": "2px",
}
}
/> />
<g> <g>
Example Example
</g> </g>
</Fragment> </svg>
</DocumentFragment>
`; `;
exports[`Box themes rendering a "charClass" Box 1`] = ` exports[`Box themes rendering a "charClass" Box 1`] = `
<Fragment> <DocumentFragment>
<svg>
<rect <rect
rx={3} rx="3"
ry={3} ry="3"
style={ style="fill: #cbcbba;"
Object {
"fill": "#cbcbba",
}
}
/> />
<g> <g>
Example Example
</g> </g>
</Fragment> </svg>
</DocumentFragment>
`; `;
exports[`Box themes rendering a "escape" Box 1`] = ` exports[`Box themes rendering a "escape" Box 1`] = `
<Fragment> <DocumentFragment>
<svg>
<rect <rect
rx={3} rx="3"
ry={3} ry="3"
style={ style="fill: #bada55; stroke-width: 1px; stroke: #6b6659;"
Object {
"fill": "#bada55",
"stroke": "#6b6659",
"strokeWidth": "1px",
}
}
/> />
<g> <g>
Example Example
</g> </g>
</Fragment> </svg>
</DocumentFragment>
`; `;
exports[`Box themes rendering a "literal" Box 1`] = ` exports[`Box themes rendering a "literal" Box 1`] = `
<Fragment> <DocumentFragment>
<svg>
<rect <rect
rx={3} rx="3"
ry={3} ry="3"
style={ style="fill: #dae9e5; stroke-width: 1px; stroke: #6b6659;"
Object {
"fill": "#dae9e5",
"stroke": "#6b6659",
"strokeWidth": "1px",
}
}
/> />
<g> <g>
Example Example
</g> </g>
</Fragment> </svg>
</DocumentFragment>
`; `;

View File

@ -1,7 +1,7 @@
jest.mock('rendering/getbbox', () => jest.fn()); jest.mock('rendering/getbbox', () => jest.fn());
import React from 'react'; import React from 'react';
import { shallow } from 'enzyme'; import { render } from 'react-testing-library';
import getBBox from 'rendering/getbbox'; import getBBox from 'rendering/getbbox';
@ -9,24 +9,30 @@ import Box, { layout } from 'rendering/Box';
describe('Box', () => { describe('Box', () => {
test('rendering', () => { test('rendering', () => {
const component = shallow( const { asFragment } = render(
<svg>
<Box>Example</Box> <Box>Example</Box>
</svg>
); );
expect(component).toMatchSnapshot(); expect(asFragment()).toMatchSnapshot();
}); });
test('rendering with a corner radius', () => { test('rendering with a corner radius', () => {
const component = shallow( const { asFragment } = render(
<svg>
<Box radius={ 5 }>Example</Box> <Box radius={ 5 }>Example</Box>
</svg>
); );
expect(component).toMatchSnapshot(); expect(asFragment()).toMatchSnapshot();
}); });
test('rendering with a label', () => { test('rendering with a label', () => {
const component = shallow( const { asFragment } = render(
<svg>
<Box label="Test box">Example</Box> <Box label="Test box">Example</Box>
</svg>
); );
expect(component).toMatchSnapshot(); expect(asFragment()).toMatchSnapshot();
}); });
test('rendering with props from layout', () => { test('rendering with props from layout', () => {
@ -39,46 +45,58 @@ describe('Box', () => {
labelTransform: 'LABEL TRANSFORM', labelTransform: 'LABEL TRANSFORM',
contentTransform: 'CONTENT TRANSFORM' contentTransform: 'CONTENT TRANSFORM'
}; };
const component = shallow( const { asFragment } = render(
<svg>
<Box { ...props }>Example</Box> <Box { ...props }>Example</Box>
</svg>
); );
expect(component).toMatchSnapshot(); expect(asFragment()).toMatchSnapshot();
}); });
describe('themes', () => { describe('themes', () => {
test('rendering a "literal" Box', () => { test('rendering a "literal" Box', () => {
const component = shallow( const { asFragment } = render(
<svg>
<Box theme="literal">Example</Box> <Box theme="literal">Example</Box>
</svg>
); );
expect(component).toMatchSnapshot(); expect(asFragment()).toMatchSnapshot();
}); });
test('rendering a "escape" Box', () => { test('rendering a "escape" Box', () => {
const component = shallow( const { asFragment } = render(
<svg>
<Box theme="escape">Example</Box> <Box theme="escape">Example</Box>
</svg>
); );
expect(component).toMatchSnapshot(); expect(asFragment()).toMatchSnapshot();
}); });
test('rendering a "charClass" Box', () => { test('rendering a "charClass" Box', () => {
const component = shallow( const { asFragment } = render(
<svg>
<Box theme="charClass">Example</Box> <Box theme="charClass">Example</Box>
</svg>
); );
expect(component).toMatchSnapshot(); expect(asFragment()).toMatchSnapshot();
}); });
test('rendering a "capture" Box', () => { test('rendering a "capture" Box', () => {
const component = shallow( const { asFragment } = render(
<svg>
<Box theme="capture">Example</Box> <Box theme="capture">Example</Box>
</svg>
); );
expect(component).toMatchSnapshot(); expect(asFragment()).toMatchSnapshot();
}); });
test('rendering a "anchor" Box', () => { test('rendering a "anchor" Box', () => {
const component = shallow( const { asFragment } = render(
<svg>
<Box theme="anchor">Example</Box> <Box theme="anchor">Example</Box>
</svg>
); );
expect(component).toMatchSnapshot(); expect(asFragment()).toMatchSnapshot();
}); });
}); });

View File

@ -11,15 +11,13 @@ Object {
`; `;
exports[`Pin rendering 1`] = ` exports[`Pin rendering 1`] = `
<circle <DocumentFragment>
r={5} <svg>
style={ <circle
Object { r="5"
"fill": "#6b6659", style="fill: #6b6659; stroke-width: 2px; stroke: #000;"
"stroke": "#000",
"strokeWidth": "2px",
}
}
transform="translate(5 5)" transform="translate(5 5)"
/> />
</svg>
</DocumentFragment>
`; `;

View File

@ -1,14 +1,16 @@
import React from 'react'; import React from 'react';
import { shallow } from 'enzyme'; import { render } from 'react-testing-library';
import Pin, { layout } from 'rendering/Pin'; import Pin, { layout } from 'rendering/Pin';
describe('Pin', () => { describe('Pin', () => {
test('rendering', () => { test('rendering', () => {
const component = shallow( const { asFragment } = render(
<svg>
<Pin/> <Pin/>
</svg>
); );
expect(component).toMatchSnapshot(); expect(asFragment()).toMatchSnapshot();
}); });
test('layout', () => { test('layout', () => {

View File

@ -24,38 +24,60 @@ Object {
`; `;
exports[`SVG rendering 1`] = ` exports[`SVG rendering 1`] = `
<svg <DocumentFragment>
height={20} <svg
style={ height="20"
Object { style="background-color: rgb(255, 255, 255);"
"backgroundColor": "#fff",
}
}
viewBox="0 0 100 20" viewBox="0 0 100 20"
width={100} width="100"
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
xmlns:cc="http://creativecommons.org/ns#" xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
> >
<metadata <metadata>
dangerouslySetInnerHTML={ <rdf:rdf>
Object {
"__html": "<rdf:rdf>
<cc:license rdf:about=\\"http://creativecommons.org/licenses/by/3.0/\\"> <cc:license
<cc:permits rdf:resource=\\"http://creativecommons.org/ns#Reproduction\\"></cc:permits> rdf:about="http://creativecommons.org/licenses/by/3.0/"
<cc:permits rdf:resource=\\"http://creativecommons.org/ns#Distribution\\"></cc:permits> >
<cc:requires rdf:resource=\\"http://creativecommons.org/ns#Notice\\"></cc:requires>
<cc:requires rdf:resource=\\"http://creativecommons.org/ns#Attribution\\"></cc:requires>
<cc:permits rdf:resource=\\"http://creativecommons.org/ns#DerivativeWorks\\"></cc:permits> <cc:permits
</cc:license> rdf:resource="http://creativecommons.org/ns#Reproduction"
</rdf:rdf>",
}
}
/> />
<cc:permits
rdf:resource="http://creativecommons.org/ns#Distribution"
/>
<cc:requires
rdf:resource="http://creativecommons.org/ns#Notice"
/>
<cc:requires
rdf:resource="http://creativecommons.org/ns#Attribution"
/>
<cc:permits
rdf:resource="http://creativecommons.org/ns#DerivativeWorks"
/>
</cc:license>
</rdf:rdf>
</metadata>
<g <g
transform="translate(10 10)" transform="translate(10 10)"
> >
Content Content
</g> </g>
</svg> </svg>
</DocumentFragment>
`; `;

View File

@ -1,14 +1,14 @@
import React from 'react'; import React from 'react';
import { shallow } from 'enzyme'; import { render } from 'react-testing-library';
import SVG, { layout } from 'rendering/SVG'; import SVG, { layout } from 'rendering/SVG';
describe('SVG', () => { describe('SVG', () => {
test('rendering', () => { test('rendering', () => {
const component = shallow( const { asFragment } = render(
<SVG width={ 100 } height={ 20 }>Content</SVG> <SVG width={ 100 } height={ 20 }>Content</SVG>
); );
expect(component).toMatchSnapshot(); expect(asFragment()).toMatchSnapshot();
}); });
test('layout', () => { test('layout', () => {

View File

@ -18,47 +18,38 @@ Object {
`; `;
exports[`Text positioning text 1`] = ` exports[`Text positioning text 1`] = `
<text <DocumentFragment>
style={ <svg>
Object { <text
"fontFamily": "Arial", style="font-size: 16px; font-family: Arial;"
"fontSize": "16px",
}
}
transform="translate(1 2)" transform="translate(1 2)"
> >
Example Example
</text> </text>
</svg>
</DocumentFragment>
`; `;
exports[`Text rendering 1`] = ` exports[`Text rendering 1`] = `
<text <DocumentFragment>
style={ <svg>
Object { <text
"fontFamily": "Arial", style="font-size: 16px; font-family: Arial;"
"fontSize": "16px", >
}
}
>
Example Example
</text> </text>
</svg>
</DocumentFragment>
`; `;
exports[`Text rendering quoted text 1`] = ` exports[`Text rendering quoted text 1`] = `
<text <DocumentFragment>
style={ <svg>
Object { <text
"fontFamily": "Arial", style="font-size: 16px; font-family: Arial;"
"fontSize": "16px", >
}
}
>
<tspan <tspan
style={ style="fill: #908c83;"
Object {
"fill": "#908c83",
}
}
> >
</tspan> </tspan>
@ -66,27 +57,23 @@ exports[`Text rendering quoted text 1`] = `
Example Example
</tspan> </tspan>
<tspan <tspan
style={ style="fill: #908c83;"
Object {
"fill": "#908c83",
}
}
> >
</tspan> </tspan>
</text> </text>
</svg>
</DocumentFragment>
`; `;
exports[`Text rendering with a theme 1`] = ` exports[`Text rendering with a theme 1`] = `
<text <DocumentFragment>
style={ <svg>
Object { <text
"fill": "#fff", style="font-size: 16px; font-family: Arial; fill: #fff;"
"fontFamily": "Arial", >
"fontSize": "16px",
}
}
>
Example Example
</text> </text>
</svg>
</DocumentFragment>
`; `;

View File

@ -1,35 +1,43 @@
import React from 'react'; import React from 'react';
import { shallow } from 'enzyme'; import { render } from 'react-testing-library';
import Text, { layout } from 'rendering/Text'; import Text, { layout } from 'rendering/Text';
describe('Text', () => { describe('Text', () => {
test('rendering', () => { test('rendering', () => {
const component = shallow( const { asFragment } = render(
<svg>
<Text>Example</Text> <Text>Example</Text>
</svg>
); );
expect(component).toMatchSnapshot(); expect(asFragment()).toMatchSnapshot();
}); });
test('positioning text', () => { test('positioning text', () => {
const component = shallow( const { asFragment } = render(
<svg>
<Text transform="translate(1 2)">Example</Text> <Text transform="translate(1 2)">Example</Text>
</svg>
); );
expect(component).toMatchSnapshot(); expect(asFragment()).toMatchSnapshot();
}); });
test('rendering with a theme', () => { test('rendering with a theme', () => {
const component = shallow( const { asFragment } = render(
<svg>
<Text theme="anchor">Example</Text> <Text theme="anchor">Example</Text>
</svg>
); );
expect(component).toMatchSnapshot(); expect(asFragment()).toMatchSnapshot();
}); });
test('rendering quoted text', () => { test('rendering quoted text', () => {
const component = shallow( const { asFragment } = render(
<svg>
<Text quoted={ true }>Example</Text> <Text quoted={ true }>Example</Text>
</svg>
); );
expect(component).toMatchSnapshot(); expect(asFragment()).toMatchSnapshot();
}); });
test('layout', () => { test('layout', () => {

244
yarn.lock
View File

@ -700,7 +700,7 @@
"@babel/plugin-transform-react-jsx-self" "^7.0.0" "@babel/plugin-transform-react-jsx-self" "^7.0.0"
"@babel/plugin-transform-react-jsx-source" "^7.0.0" "@babel/plugin-transform-react-jsx-source" "^7.0.0"
"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2": "@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.3.4":
version "7.4.2" version "7.4.2"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.4.2.tgz#f5ab6897320f16decd855eed70b705908a313fe8" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.4.2.tgz#f5ab6897320f16decd855eed70b705908a313fe8"
integrity sha512-7Bl2rALb7HpvXFL7TETNzKSAeBVCPHELzc0C//9FCxN8nsiueWSJBqaF+2oIJScyILStASR/Cx5WMkXGYTiJFA== integrity sha512-7Bl2rALb7HpvXFL7TETNzKSAeBVCPHELzc0C//9FCxN8nsiueWSJBqaF+2oIJScyILStASR/Cx5WMkXGYTiJFA==
@ -1077,6 +1077,11 @@
"@sentry/types" "4.5.3" "@sentry/types" "4.5.3"
tslib "^1.9.3" tslib "^1.9.3"
"@sheerun/mutationobserver-shim@^0.3.2":
version "0.3.2"
resolved "https://registry.yarnpkg.com/@sheerun/mutationobserver-shim/-/mutationobserver-shim-0.3.2.tgz#8013f2af54a2b7d735f71560ff360d3a8176a87b"
integrity sha512-vTCdPp/T/Q3oSqwHmZ5Kpa9oI7iLtGl3RQaA/NyLHikvcrPxACkkKVr/XzkSPJWXHRhKGzVvb0urJsbMlRxi1Q==
"@sindresorhus/is@^0.7.0": "@sindresorhus/is@^0.7.0":
version "0.7.0" version "0.7.0"
resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.7.0.tgz#9a06f4f137ee84d7df0460c1fdb1135ffa6c50fd" resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.7.0.tgz#9a06f4f137ee84d7df0460c1fdb1135ffa6c50fd"
@ -1655,11 +1660,6 @@ array-equal@^1.0.0:
resolved "https://registry.yarnpkg.com/array-equal/-/array-equal-1.0.0.tgz#8c2a5ef2472fd9ea742b04c77a75093ba2757c93" resolved "https://registry.yarnpkg.com/array-equal/-/array-equal-1.0.0.tgz#8c2a5ef2472fd9ea742b04c77a75093ba2757c93"
integrity sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM= 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-filter@~0.0.0: array-filter@~0.0.0:
version "0.0.1" version "0.0.1"
resolved "https://registry.yarnpkg.com/array-filter/-/array-filter-0.0.1.tgz#7da8cf2e26628ed732803581fd21f67cacd2eeec" resolved "https://registry.yarnpkg.com/array-filter/-/array-filter-0.0.1.tgz#7da8cf2e26628ed732803581fd21f67cacd2eeec"
@ -1720,15 +1720,6 @@ array-unique@^0.3.2:
resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428"
integrity sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg= integrity sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=
array.prototype.flat@^1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.2.1.tgz#812db8f02cad24d3fab65dd67eabe3b8903494a4"
integrity sha512-rVqIs330nLJvfC7JqYvEWwqVr5QjYF1ib02i3YJtR/fICO6527Tjpc/e4Mvmxh3GIePPreRXMdaGyC99YphWEw==
dependencies:
define-properties "^1.1.2"
es-abstract "^1.10.0"
function-bind "^1.1.1"
arraybuffer.slice@~0.0.7: arraybuffer.slice@~0.0.7:
version "0.0.7" version "0.0.7"
resolved "https://registry.yarnpkg.com/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz#3bbc4275dd584cc1b10809b89d4e8b63a69e7675" resolved "https://registry.yarnpkg.com/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz#3bbc4275dd584cc1b10809b89d4e8b63a69e7675"
@ -3923,11 +3914,6 @@ diffie-hellman@^5.0.0:
miller-rabin "^4.0.0" miller-rabin "^4.0.0"
randombytes "^2.0.0" randombytes "^2.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: dns-equal@^1.0.0:
version "1.0.0" version "1.0.0"
resolved "https://registry.yarnpkg.com/dns-equal/-/dns-equal-1.0.0.tgz#b39e7f1da6eb0a75ba9c17324b34753c47e0654d" resolved "https://registry.yarnpkg.com/dns-equal/-/dns-equal-1.0.0.tgz#b39e7f1da6eb0a75ba9c17324b34753c47e0654d"
@ -3992,6 +3978,16 @@ dom-serializer@0, dom-serializer@~0.1.0:
domelementtype "^1.3.0" domelementtype "^1.3.0"
entities "^1.1.1" entities "^1.1.1"
dom-testing-library@^3.13.1:
version "3.18.2"
resolved "https://registry.yarnpkg.com/dom-testing-library/-/dom-testing-library-3.18.2.tgz#07d65166743ad3299b7bee5b488e9622c31241bc"
integrity sha512-+nYUgGhHarrCY8kLVmyHlgM+IGwBXXrYsWIJB6vpAx2ne9WFgKfwMGcOkkTKQhuAro0sP6RIuRGfm5NF3+ccmQ==
dependencies:
"@babel/runtime" "^7.3.4"
"@sheerun/mutationobserver-shim" "^0.3.2"
pretty-format "^24.5.0"
wait-for-expect "^1.1.0"
dom-walk@^0.1.0: dom-walk@^0.1.0:
version "0.1.1" version "0.1.1"
resolved "https://registry.yarnpkg.com/dom-walk/-/dom-walk-0.1.1.tgz#672226dc74c8f799ad35307df936aba11acd6018" resolved "https://registry.yarnpkg.com/dom-walk/-/dom-walk-0.1.1.tgz#672226dc74c8f799ad35307df936aba11acd6018"
@ -4210,64 +4206,6 @@ envinfo@^5.8.1:
resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-5.12.1.tgz#83068c33e0972eb657d6bc69a6df30badefb46ef" resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-5.12.1.tgz#83068c33e0972eb657d6bc69a6df30badefb46ef"
integrity sha512-pwdo0/G3CIkQ0y6PCXq4RdkvId2elvtPCJMG0konqlrfkWQbf1DWeH9K2b/cvu2YgGvPPTOnonZxXM1gikFu1w== integrity sha512-pwdo0/G3CIkQ0y6PCXq4RdkvId2elvtPCJMG0konqlrfkWQbf1DWeH9K2b/cvu2YgGvPPTOnonZxXM1gikFu1w==
enzyme-adapter-react-16@^1.7.1:
version "1.11.2"
resolved "https://registry.yarnpkg.com/enzyme-adapter-react-16/-/enzyme-adapter-react-16-1.11.2.tgz#8efeafb27e96873a5492fdef3f423693182eb9d4"
integrity sha512-2ruTTCPRb0lPuw/vKTXGVZVBZqh83MNDnakMhzxhpJcIbneEwNy2Cv0KvL97pl57/GOazJHflWNLjwWhex5AAA==
dependencies:
enzyme-adapter-utils "^1.10.1"
object.assign "^4.1.0"
object.values "^1.1.0"
prop-types "^15.7.2"
react-is "^16.8.4"
react-test-renderer "^16.0.0-0"
semver "^5.6.0"
enzyme-adapter-utils@^1.10.1:
version "1.10.1"
resolved "https://registry.yarnpkg.com/enzyme-adapter-utils/-/enzyme-adapter-utils-1.10.1.tgz#58264efa19a7befdbf964fb7981a108a5452ac96"
integrity sha512-oasinhhLoBuZsIkTe8mx0HiudtfErUtG0Ooe1FOplu/t4c9rOmyG5gtrBASK6u4whHIRWvv0cbZMElzNTR21SA==
dependencies:
function.prototype.name "^1.1.0"
object.assign "^4.1.0"
object.fromentries "^2.0.0"
prop-types "^15.7.2"
semver "^5.6.0"
enzyme-to-json@^3.3.5:
version "3.3.5"
resolved "https://registry.yarnpkg.com/enzyme-to-json/-/enzyme-to-json-3.3.5.tgz#f8eb82bd3d5941c9d8bc6fd9140030777d17d0af"
integrity sha512-DmH1wJ68HyPqKSYXdQqB33ZotwfUhwQZW3IGXaNXgR69Iodaoj8TF/D9RjLdz4pEhGq2Tx2zwNUIjBuqoZeTgA==
dependencies:
lodash "^4.17.4"
enzyme@^3.8.0:
version "3.9.0"
resolved "https://registry.yarnpkg.com/enzyme/-/enzyme-3.9.0.tgz#2b491f06ca966eb56b6510068c7894a7e0be3909"
integrity sha512-JqxI2BRFHbmiP7/UFqvsjxTirWoM1HfeaJrmVSZ9a1EADKkZgdPcAuISPMpoUiHlac9J4dYt81MC5BBIrbJGMg==
dependencies:
array.prototype.flat "^1.2.1"
cheerio "^1.0.0-rc.2"
function.prototype.name "^1.1.0"
has "^1.0.3"
html-element-map "^1.0.0"
is-boolean-object "^1.0.0"
is-callable "^1.1.4"
is-number-object "^1.0.3"
is-regex "^1.0.4"
is-string "^1.0.4"
is-subset "^0.1.1"
lodash.escape "^4.0.1"
lodash.isequal "^4.5.0"
object-inspect "^1.6.0"
object-is "^1.0.1"
object.assign "^4.1.0"
object.entries "^1.0.4"
object.values "^1.0.4"
raf "^3.4.0"
rst-selector-parser "^2.2.3"
string.prototype.trim "^1.1.2"
eol@^0.8.1: eol@^0.8.1:
version "0.8.1" version "0.8.1"
resolved "https://registry.yarnpkg.com/eol/-/eol-0.8.1.tgz#defc3224990c7eca73bb34461a56cf9dc24761d0" resolved "https://registry.yarnpkg.com/eol/-/eol-0.8.1.tgz#defc3224990c7eca73bb34461a56cf9dc24761d0"
@ -4294,7 +4232,7 @@ error-stack-parser@^2.0.0:
dependencies: dependencies:
stackframe "^1.0.4" stackframe "^1.0.4"
es-abstract@^1.10.0, es-abstract@^1.11.0, es-abstract@^1.12.0, es-abstract@^1.5.0, es-abstract@^1.5.1, es-abstract@^1.7.0: es-abstract@^1.11.0, es-abstract@^1.12.0, es-abstract@^1.5.1, es-abstract@^1.7.0:
version "1.13.0" version "1.13.0"
resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.13.0.tgz#ac86145fdd5099d8dd49558ccba2eaf9b88e24e9" resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.13.0.tgz#ac86145fdd5099d8dd49558ccba2eaf9b88e24e9"
integrity sha512-vDZfg/ykNxQVwup/8E1BZhVzFfBxs9NqMzGcvIJrqg5k2/5Za2bWo40dK2J1pgLngZ7c+Shh8lwYtLGyrwPutg== integrity sha512-vDZfg/ykNxQVwup/8E1BZhVzFfBxs9NqMzGcvIJrqg5k2/5Za2bWo40dK2J1pgLngZ7c+Shh8lwYtLGyrwPutg==
@ -5341,20 +5279,11 @@ fsevents@^1.2.7:
nan "^2.9.2" nan "^2.9.2"
node-pre-gyp "^0.10.0" node-pre-gyp "^0.10.0"
function-bind@^1.0.2, function-bind@^1.1.1: function-bind@^1.1.1:
version "1.1.1" version "1.1.1"
resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d"
integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==
function.prototype.name@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/function.prototype.name/-/function.prototype.name-1.1.0.tgz#8bd763cc0af860a859cc5d49384d74b932cd2327"
integrity sha512-Bs0VRrTz4ghD8pTmbJQD1mZ8A/mN0ur/jGz+A6FBxPDUPkm1tNfF6bhTYPA7i7aF4lZJVr+OXTNNrnnIl58Wfg==
dependencies:
define-properties "^1.1.2"
function-bind "^1.1.1"
is-callable "^1.1.3"
functional-red-black-tree@^1.0.1: functional-red-black-tree@^1.0.1:
version "1.0.1" version "1.0.1"
resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327"
@ -6239,13 +6168,6 @@ html-comment-regex@^1.1.0:
resolved "https://registry.yarnpkg.com/html-comment-regex/-/html-comment-regex-1.1.2.tgz#97d4688aeb5c81886a364faa0cad1dda14d433a7" resolved "https://registry.yarnpkg.com/html-comment-regex/-/html-comment-regex-1.1.2.tgz#97d4688aeb5c81886a364faa0cad1dda14d433a7"
integrity sha512-P+M65QY2JQ5Y0G9KKdlDpo0zK+/OHptU5AaBwUfAIDJZk1MYf32Frm84EcOytfJE0t5JvkAnKlmjsXDnWzCJmQ== integrity sha512-P+M65QY2JQ5Y0G9KKdlDpo0zK+/OHptU5AaBwUfAIDJZk1MYf32Frm84EcOytfJE0t5JvkAnKlmjsXDnWzCJmQ==
html-element-map@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/html-element-map/-/html-element-map-1.0.0.tgz#19a41940225153ecdfead74f8509154ff1cdc18b"
integrity sha512-/SP6aOiM5Ai9zALvCxDubIeez0LvG3qP7R9GcRDnJEP/HBmv0A8A9K0o8+HFudcFt46+i921ANjzKsjPjb7Enw==
dependencies:
array-filter "^1.0.0"
html-encoding-sniffer@^1.0.2: html-encoding-sniffer@^1.0.2:
version "1.0.2" version "1.0.2"
resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz#e70d84b94da53aa375e11fe3a351be6642ca46f8" resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz#e70d84b94da53aa375e11fe3a351be6642ca46f8"
@ -6701,11 +6623,6 @@ is-binary-path@^1.0.0:
dependencies: dependencies:
binary-extensions "^1.0.0" binary-extensions "^1.0.0"
is-boolean-object@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.0.0.tgz#98f8b28030684219a95f375cfbd88ce3405dff93"
integrity sha1-mPiygDBoQhmpXzdc+9iM40Bd/5M=
is-buffer@^1.1.5, is-buffer@~1.1.1: is-buffer@^1.1.5, is-buffer@~1.1.1:
version "1.1.6" version "1.1.6"
resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be"
@ -6723,7 +6640,7 @@ is-builtin-module@^3.0.0:
dependencies: dependencies:
builtin-modules "^3.0.0" builtin-modules "^3.0.0"
is-callable@^1.1.3, is-callable@^1.1.4: is-callable@^1.1.4:
version "1.1.4" version "1.1.4"
resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.4.tgz#1e1adf219e1eeb684d691f9d6a05ff0d30a24d75" resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.4.tgz#1e1adf219e1eeb684d691f9d6a05ff0d30a24d75"
integrity sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA== integrity sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==
@ -6857,11 +6774,6 @@ is-npm@^1.0.0:
resolved "https://registry.yarnpkg.com/is-npm/-/is-npm-1.0.0.tgz#f2fb63a65e4905b406c86072765a1a4dc793b9f4" resolved "https://registry.yarnpkg.com/is-npm/-/is-npm-1.0.0.tgz#f2fb63a65e4905b406c86072765a1a4dc793b9f4"
integrity sha1-8vtjpl5JBbQGyGBydloaTceTufQ= integrity sha1-8vtjpl5JBbQGyGBydloaTceTufQ=
is-number-object@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.3.tgz#f265ab89a9f445034ef6aff15a8f00b00f551799"
integrity sha1-8mWrian0RQNO9q/xWo8AsA9VF5k=
is-number@^3.0.0: is-number@^3.0.0:
version "3.0.0" version "3.0.0"
resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195"
@ -6971,16 +6883,6 @@ is-stream@^1.0.0, is-stream@^1.0.1, is-stream@^1.1.0:
resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44"
integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ= integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ=
is-string@^1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.4.tgz#cc3a9b69857d621e963725a24caeec873b826e64"
integrity sha1-zDqbaYV9Yh6WNyWiTK7shzuCbmQ=
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: is-svg@^3.0.0:
version "3.0.0" version "3.0.0"
resolved "https://registry.yarnpkg.com/is-svg/-/is-svg-3.0.0.tgz#9321dbd29c212e5ca99c4fa9794c714bcafa2f75" resolved "https://registry.yarnpkg.com/is-svg/-/is-svg-3.0.0.tgz#9321dbd29c212e5ca99c4fa9794c714bcafa2f75"
@ -7963,11 +7865,6 @@ lodash._shimkeys@~2.4.1:
dependencies: dependencies:
lodash._objecttypes "~2.4.1" lodash._objecttypes "~2.4.1"
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.every@^4.6.0: lodash.every@^4.6.0:
version "4.6.0" version "4.6.0"
resolved "https://registry.yarnpkg.com/lodash.every/-/lodash.every-4.6.0.tgz#eb89984bebc4364279bb3aefbbd1ca19bfa6c6a7" resolved "https://registry.yarnpkg.com/lodash.every/-/lodash.every-4.6.0.tgz#eb89984bebc4364279bb3aefbbd1ca19bfa6c6a7"
@ -8008,11 +7905,6 @@ lodash.isboolean@^3.0.3:
resolved "https://registry.yarnpkg.com/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz#6c2e171db2a257cd96802fd43b01b20d5f5870f6" resolved "https://registry.yarnpkg.com/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz#6c2e171db2a257cd96802fd43b01b20d5f5870f6"
integrity sha1-bC4XHbKiV82WgC/UOwGyDV9YcPY= integrity sha1-bC4XHbKiV82WgC/UOwGyDV9YcPY=
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.isinteger@^4.0.4: lodash.isinteger@^4.0.4:
version "4.0.4" version "4.0.4"
resolved "https://registry.yarnpkg.com/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz#619c0af3d03f8b04c31f5882840b77b11cd68343" resolved "https://registry.yarnpkg.com/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz#619c0af3d03f8b04c31f5882840b77b11cd68343"
@ -8552,11 +8444,6 @@ moment@^2.21.0:
resolved "https://registry.yarnpkg.com/moment/-/moment-2.24.0.tgz#0d055d53f5052aa653c9f6eb68bb5d12bf5c2b5b" resolved "https://registry.yarnpkg.com/moment/-/moment-2.24.0.tgz#0d055d53f5052aa653c9f6eb68bb5d12bf5c2b5b"
integrity sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg== 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==
morgan@^1.8.2: morgan@^1.8.2:
version "1.9.1" version "1.9.1"
resolved "https://registry.yarnpkg.com/morgan/-/morgan-1.9.1.tgz#0a8d16734a1d9afbc824b99df87e738e58e2da59" resolved "https://registry.yarnpkg.com/morgan/-/morgan-1.9.1.tgz#0a8d16734a1d9afbc824b99df87e738e58e2da59"
@ -8670,17 +8557,6 @@ ncp@1.0.x:
resolved "https://registry.yarnpkg.com/ncp/-/ncp-1.0.1.tgz#d15367e5cb87432ba117d2bf80fdf45aecfb4246" resolved "https://registry.yarnpkg.com/ncp/-/ncp-1.0.1.tgz#d15367e5cb87432ba117d2bf80fdf45aecfb4246"
integrity sha1-0VNn5cuHQyuhF9K/gP30Wuz7QkY= integrity sha1-0VNn5cuHQyuhF9K/gP30Wuz7QkY=
nearley@^2.7.10:
version "2.16.0"
resolved "https://registry.yarnpkg.com/nearley/-/nearley-2.16.0.tgz#77c297d041941d268290ec84b739d0ee297e83a7"
integrity sha512-Tr9XD3Vt/EujXbZBv6UAHYoLUSMQAxSsTnm9K3koXzjzNWY195NqALeyrzLZBKzAkL3gl92BcSogqrHjD8QuUg==
dependencies:
commander "^2.19.0"
moo "^0.4.3"
railroad-diagrams "^1.0.0"
randexp "0.4.6"
semver "^5.4.1"
needle@^2.2.1: needle@^2.2.1:
version "2.2.4" version "2.2.4"
resolved "https://registry.yarnpkg.com/needle/-/needle-2.2.4.tgz#51931bff82533b1928b7d1d69e01f1b00ffd2a4e" resolved "https://registry.yarnpkg.com/needle/-/needle-2.2.4.tgz#51931bff82533b1928b7d1d69e01f1b00ffd2a4e"
@ -8987,16 +8863,6 @@ object-hash@^1.1.4:
resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-1.3.1.tgz#fde452098a951cb145f039bb7d455449ddc126df" resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-1.3.1.tgz#fde452098a951cb145f039bb7d455449ddc126df"
integrity sha512-OSuu/pU4ENM9kmREg0BdNrUDIl1heYa4mBZacJc+vVWz4GtAwu7jO8s4AIt2aGRUTqxykpWzI3Oqnsm13tTMDA== integrity sha512-OSuu/pU4ENM9kmREg0BdNrUDIl1heYa4mBZacJc+vVWz4GtAwu7jO8s4AIt2aGRUTqxykpWzI3Oqnsm13tTMDA==
object-inspect@^1.6.0:
version "1.6.0"
resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.6.0.tgz#c70b6cbf72f274aab4c34c0c82f5167bf82cf15b"
integrity sha512-GJzfBZ6DgDAmnuaM3104jR4s1Myxr3Y3zfIyN4z3UdqN69oSRacNK8UhnobDdC+7J2AHCjGwxQubNJfE70SXXQ==
object-is@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.0.1.tgz#0aa60ec9989a0b3ed795cf4d06f62cf1ad6539b6"
integrity sha1-CqYOyZiaCz7Xlc9NBvYs8a1lObY=
object-keys@^1.0.11, object-keys@^1.0.12: object-keys@^1.0.11, object-keys@^1.0.12:
version "1.1.0" version "1.1.0"
resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.0.tgz#11bd22348dd2e096a045ab06f6c85bcc340fa032" resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.0.tgz#11bd22348dd2e096a045ab06f6c85bcc340fa032"
@ -9024,16 +8890,6 @@ object.assign@^4.1.0:
has-symbols "^1.0.0" has-symbols "^1.0.0"
object-keys "^1.0.11" object-keys "^1.0.11"
object.entries@^1.0.4:
version "1.1.0"
resolved "https://registry.yarnpkg.com/object.entries/-/object.entries-1.1.0.tgz#2024fc6d6ba246aee38bdb0ffd5cfbcf371b7519"
integrity sha512-l+H6EQ8qzGRxbkHOd5I/aHRhHDKoQXQ8g0BYt4uSweQU1/J6dZUOyWh9a2Vky35YCKjzmgxOzta2hH6kf9HuXA==
dependencies:
define-properties "^1.1.3"
es-abstract "^1.12.0"
function-bind "^1.1.1"
has "^1.0.3"
object.fromentries@^2.0.0: object.fromentries@^2.0.0:
version "2.0.0" version "2.0.0"
resolved "https://registry.yarnpkg.com/object.fromentries/-/object.fromentries-2.0.0.tgz#49a543d92151f8277b3ac9600f1e930b189d30ab" resolved "https://registry.yarnpkg.com/object.fromentries/-/object.fromentries-2.0.0.tgz#49a543d92151f8277b3ac9600f1e930b189d30ab"
@ -9059,7 +8915,7 @@ object.pick@^1.3.0:
dependencies: dependencies:
isobject "^3.0.1" isobject "^3.0.1"
object.values@^1.0.4, object.values@^1.1.0: object.values@^1.1.0:
version "1.1.0" version "1.1.0"
resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.0.tgz#bf6810ef5da3e5325790eaaa2be213ea84624da9" resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.0.tgz#bf6810ef5da3e5325790eaaa2be213ea84624da9"
integrity sha512-8mf0nKLAoFX6VlNVdhGj31SVYpaNFtUnuoOXWyFEstsWRgU837AK+JYM0iAxwkSzGRbwn8cbFmgbyxj1j4VbXg== integrity sha512-8mf0nKLAoFX6VlNVdhGj31SVYpaNFtUnuoOXWyFEstsWRgU837AK+JYM0iAxwkSzGRbwn8cbFmgbyxj1j4VbXg==
@ -10405,7 +10261,7 @@ prop-types@^15.5.10, prop-types@^15.5.4:
loose-envify "^1.3.1" loose-envify "^1.3.1"
object-assign "^4.1.1" object-assign "^4.1.1"
prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.2: prop-types@^15.6.1, prop-types@^15.6.2:
version "15.7.2" version "15.7.2"
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5" resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5"
integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ== integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==
@ -10541,26 +10397,6 @@ querystringify@^2.0.0:
resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-2.1.1.tgz#60e5a5fd64a7f8bfa4d2ab2ed6fdf4c85bad154e" resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-2.1.1.tgz#60e5a5fd64a7f8bfa4d2ab2ed6fdf4c85bad154e"
integrity sha512-w7fLxIRCRT7U8Qu53jQnJyPkYZIaR4n5151KMfcJlO/A9397Wxb1amJvROTK6TOnp7PfoAmg/qXiNHI+08jRfA== integrity sha512-w7fLxIRCRT7U8Qu53jQnJyPkYZIaR4n5151KMfcJlO/A9397Wxb1amJvROTK6TOnp7PfoAmg/qXiNHI+08jRfA==
raf@^3.4.0:
version "3.4.1"
resolved "https://registry.yarnpkg.com/raf/-/raf-3.4.1.tgz#0742e99a4a6552f445d73e3ee0328af0ff1ede39"
integrity sha512-Sq4CW4QhwOHE8ucn6J34MqtZCeWFP2aQSmrlroYgqAV1PjStIhJXxYuTgUIfkEk7zTLjmIjLmU5q+fbD1NnOJA==
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=
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: randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5:
version "2.1.0" version "2.1.0"
resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a"
@ -10683,7 +10519,7 @@ react-i18next@^10.5.3:
"@babel/runtime" "^7.3.1" "@babel/runtime" "^7.3.1"
html-parse-stringify2 "2.0.1" html-parse-stringify2 "2.0.1"
react-is@^16.7.0, react-is@^16.8.1, react-is@^16.8.4, react-is@^16.8.5: react-is@^16.7.0, react-is@^16.8.1, react-is@^16.8.4:
version "16.8.5" version "16.8.5"
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.8.5.tgz#c54ac229dd66b5afe0de5acbe47647c3da692ff8" resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.8.5.tgz#c54ac229dd66b5afe0de5acbe47647c3da692ff8"
integrity sha512-sudt2uq5P/2TznPV4Wtdi+Lnq3yaYW8LfvPKLM9BKD8jJNBkxMVyB0C9/GmVhLw7Jbdmndk/73n7XQGeN9A3QQ== integrity sha512-sudt2uq5P/2TznPV4Wtdi+Lnq3yaYW8LfvPKLM9BKD8jJNBkxMVyB0C9/GmVhLw7Jbdmndk/73n7XQGeN9A3QQ==
@ -10711,15 +10547,13 @@ react-side-effect@^1.1.0:
exenv "^1.2.1" exenv "^1.2.1"
shallowequal "^1.0.1" shallowequal "^1.0.1"
react-test-renderer@^16.0.0-0: react-testing-library@^6.0.2:
version "16.8.5" version "6.0.2"
resolved "https://registry.yarnpkg.com/react-test-renderer/-/react-test-renderer-16.8.5.tgz#4cba7a8aad73f7e8a0bc4379a0fe21632886a563" resolved "https://registry.yarnpkg.com/react-testing-library/-/react-testing-library-6.0.2.tgz#afd7ddaa174e21cf672605e4e4f6f8156c4c9ef9"
integrity sha512-/pFpHYQH4f35OqOae/DgOCXJDxBqD3K3akVfDhLgR0qYHoHjnICI/XS9QDwIhbrOFHWL7okVW9kKMaHuKvt2ng== integrity sha512-hWJIixR/jxJBnemcWI5O2JCMXlwoIpgF1IEUF8EYNEADORSZ9fs8rEJu4ygqyC53l3QOowkNb8D+eF5kGT3srg==
dependencies: dependencies:
object-assign "^4.1.1" "@babel/runtime" "^7.3.1"
prop-types "^15.6.2" dom-testing-library "^3.13.1"
react-is "^16.8.5"
scheduler "^0.13.5"
react@^16.7.0: react@^16.7.0:
version "16.8.5" version "16.8.5"
@ -11254,14 +11088,6 @@ router@^1.3.1:
setprototypeof "1.1.0" setprototypeof "1.1.0"
utils-merge "1.0.1" utils-merge "1.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@^3.6.2: rsvp@^3.6.2:
version "3.6.2" version "3.6.2"
resolved "https://registry.yarnpkg.com/rsvp/-/rsvp-3.6.2.tgz#2e96491599a96cde1b515d5674a8f7a91452926a" resolved "https://registry.yarnpkg.com/rsvp/-/rsvp-3.6.2.tgz#2e96491599a96cde1b515d5674a8f7a91452926a"
@ -12073,15 +11899,6 @@ string-width@^3.0.0:
is-fullwidth-code-point "^2.0.0" is-fullwidth-code-point "^2.0.0"
strip-ansi "^5.1.0" strip-ansi "^5.1.0"
string.prototype.trim@^1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/string.prototype.trim/-/string.prototype.trim-1.1.2.tgz#d04de2c89e137f4d7d206f086b5ed2fae6be8cea"
integrity sha1-0E3iyJ4Tf019IG8Ia17S+ua+jOo=
dependencies:
define-properties "^1.1.2"
es-abstract "^1.5.0"
function-bind "^1.0.2"
string_decoder@^1.0.0, string_decoder@^1.1.1: string_decoder@^1.0.0, string_decoder@^1.1.1:
version "1.2.0" version "1.2.0"
resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.2.0.tgz#fe86e738b19544afe70469243b2a1ee9240eae8d" resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.2.0.tgz#fe86e738b19544afe70469243b2a1ee9240eae8d"
@ -12948,6 +12765,11 @@ w3c-hr-time@^1.0.1:
dependencies: dependencies:
browser-process-hrtime "^0.1.2" browser-process-hrtime "^0.1.2"
wait-for-expect@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/wait-for-expect/-/wait-for-expect-1.1.0.tgz#6607375c3f79d32add35cd2c87ce13f351a3d453"
integrity sha512-vQDokqxyMyknfX3luCDn16bSaRcOyH6gGuUXMIbxBLeTo6nWuEWYqMTT9a+44FmW8c2m6TRWBdNvBBjA1hwEKg==
walker@~1.0.5: walker@~1.0.5:
version "1.0.7" version "1.0.7"
resolved "https://registry.yarnpkg.com/walker/-/walker-1.0.7.tgz#2f7f9b8fd10d677262b18a884e28d19618e028fb" resolved "https://registry.yarnpkg.com/walker/-/walker-1.0.7.tgz#2f7f9b8fd10d677262b18a884e28d19618e028fb"