diff --git a/tests/utils/TestInput.js b/__test_utils__/TestInput.js similarity index 58% rename from tests/utils/TestInput.js rename to __test_utils__/TestInput.js index 0ea84ba0..2655e494 100644 --- a/tests/utils/TestInput.js +++ b/__test_utils__/TestInput.js @@ -1,15 +1,23 @@ import React from 'react'; -import Formsy, { withFormsy } from './../..'; +import Formsy, { withFormsy } from '../lib'; class TestInput extends React.Component { static defaultProps = { type: 'text' }; updateValue = event => { - this.props.setValue(event.target[this.props.type === 'checkbox' ? 'checked' : 'value']); + this.props.setValue( + event.target[this.props.type === 'checkbox' ? 'checked' : 'value'], + ); }; render() { - return ; + return ( + + ); } } diff --git a/tests/utils/TestInputHoc.js b/__test_utils__/TestInputHoc.js similarity index 82% rename from tests/utils/TestInputHoc.js rename to __test_utils__/TestInputHoc.js index d9668def..f59a63ec 100644 --- a/tests/utils/TestInputHoc.js +++ b/__test_utils__/TestInputHoc.js @@ -1,5 +1,5 @@ import React from 'react'; -import Formsy, { withFormsy } from './../..'; +import Formsy, { withFormsy } from '../lib'; class TestComponent extends React.Component { methodOnWrappedInstance = param => { diff --git a/tests/utils/immediate.js b/__test_utils__/immediate.js similarity index 100% rename from tests/utils/immediate.js rename to __test_utils__/immediate.js diff --git a/tests/Element-spec.js b/__tests__/Element-spec.js similarity index 66% rename from tests/Element-spec.js rename to __tests__/Element-spec.js index 8956a3ad..a1d87194 100644 --- a/tests/Element-spec.js +++ b/__tests__/Element-spec.js @@ -4,11 +4,11 @@ import PureRenderMixin from 'react-addons-pure-render-mixin'; import sinon from 'sinon'; import Formsy, { withFormsy } from './..'; -import TestInput, { InputFactory } from './utils/TestInput'; -import immediate from './utils/immediate'; +import TestInput, { InputFactory } from '../__test_utils__/TestInput'; +import immediate from '../__test_utils__/immediate'; -export default { - 'should pass down correct value prop after using setValue()': function(test) { +describe('Element', () => { + it('should pass down correct value prop after using setValue()', () => { const form = TestUtils.renderIntoDocument( @@ -16,21 +16,25 @@ export default { ); const input = TestUtils.findRenderedDOMComponentWithTag(form, 'INPUT'); - test.equal(input.value, 'foo'); + expect(input.value).toEqual('foo'); TestUtils.Simulate.change(input, { target: { value: 'foobar' } }); - test.equal(input.value, 'foobar'); + expect(input.value).toEqual('foobar'); + }); - test.done(); - }, - - 'withFormsy: should only set the value and not validate when calling setValue(val, false)': function(test) { + it('withFormsy: should only set the value and not validate when calling setValue(val, false)', () => { const Input = withFormsy( class TestInput extends React.Component { updateValue = event => { this.props.setValue(event.target.value, false); }; render() { - return ; + return ( + + ); } }, ); @@ -41,16 +45,18 @@ export default { ); const inputComponent = TestUtils.findRenderedComponentWithType(form, Input); const setStateSpy = sinon.spy(inputComponent, 'setState'); - const inputElement = TestUtils.findRenderedDOMComponentWithTag(form, 'INPUT'); + const inputElement = TestUtils.findRenderedDOMComponentWithTag( + form, + 'INPUT', + ); - test.equal(setStateSpy.called, false); + expect(setStateSpy.called).toEqual(false); TestUtils.Simulate.change(inputElement, { target: { value: 'foobar' } }); - test.equal(setStateSpy.calledOnce, true); - test.equal(setStateSpy.calledWithExactly({ value: 'foobar' }), true); - test.done(); - }, + expect(setStateSpy.calledOnce).toEqual(true); + expect(setStateSpy.calledWithExactly({ value: 'foobar' })).toEqual(true); + }); - 'should set back to pristine value when running reset': function(test) { + it('should set back to pristine value when running reset', () => { let reset = null; const Input = InputFactory({ componentDidMount: function() { @@ -66,12 +72,10 @@ export default { const input = TestUtils.findRenderedDOMComponentWithTag(form, 'INPUT'); TestUtils.Simulate.change(input, { target: { value: 'foobar' } }); reset(); - test.equal(input.value, 'foo'); + expect(input.value).toEqual('foo'); + }); - test.done(); - }, - - 'should return error message passed when calling getErrorMessage()': function(test) { + it('should return error message passed when calling getErrorMessage()', () => { let errorMessage = null; const Input = InputFactory({ componentDidMount: function() { @@ -80,16 +84,19 @@ export default { }); TestUtils.renderIntoDocument( - + , ); - test.equal(errorMessage, 'Has to be email'); - - test.done(); - }, + expect(errorMessage).toEqual('Has to be email'); + }); - 'should return true or false when calling isValid() depending on valid state': function(test) { + it('should return true or false when calling isValid() depending on valid state', () => { let isValid = null; const Input = InputFactory({ componentWillReceiveProps: function(nextProps) { @@ -102,15 +109,13 @@ export default { , ); - test.equal(isValid, false); + expect(isValid).toEqual(false); const input = TestUtils.findRenderedDOMComponentWithTag(form, 'INPUT'); TestUtils.Simulate.change(input, { target: { value: 'foo@foo.com' } }); - test.equal(isValid, true); + expect(isValid).toEqual(true); + }); - test.done(); - }, - - 'should return true or false when calling isRequired() depending on passed required attribute': function(test) { + it('should return true or false when calling isRequired() depending on passed required attribute', () => { const isRequireds = []; const Input = InputFactory({ componentDidMount: function() { @@ -125,16 +130,12 @@ export default { , ); - test.equal(isRequireds[0], false); - test.equal(isRequireds[1], true); - test.equal(isRequireds[2], true); - - test.done(); - }, + expect(isRequireds[0]).toEqual(false); + expect(isRequireds[1]).toEqual(true); + expect(isRequireds[2]).toEqual(true); + }); - 'should return true or false when calling showRequired() depending on input being empty and required is passed, or not': function( - test, - ) { + it('should return true or false when calling showRequired() depending on input being empty and required is passed, or not', () => { const showRequireds = []; const Input = InputFactory({ componentDidMount: function() { @@ -149,14 +150,12 @@ export default { , ); - test.equal(showRequireds[0], false); - test.equal(showRequireds[1], true); - test.equal(showRequireds[2], false); - - test.done(); - }, + expect(showRequireds[0]).toEqual(false); + expect(showRequireds[1]).toEqual(true); + expect(showRequireds[2]).toEqual(false); + }); - 'should return true or false when calling isPristine() depending on input has been "touched" or not': function(test) { + it('should return true or false when calling isPristine() depending on input has been "touched" or not', () => { const Input = InputFactory(); const form = TestUtils.renderIntoDocument( @@ -164,15 +163,13 @@ export default { , ); - test.equal(form.inputs[0].isPristine(), true); + expect(form.inputs[0].isPristine()).toEqual(true); const input = TestUtils.findRenderedDOMComponentWithTag(form, 'INPUT'); TestUtils.Simulate.change(input, { target: { value: 'foo' } }); - test.equal(form.inputs[0].isPristine(), false); + expect(form.inputs[0].isPristine()).toEqual(false); + }); - test.done(); - }, - - 'should allow an undefined value to be updated to a value': function(test) { + it('should allow an undefined value to be updated to a value', () => { class TestForm extends React.Component { state = { value: undefined }; changeValue = () => { @@ -193,12 +190,11 @@ export default { form.changeValue(); const input = TestUtils.findRenderedDOMComponentWithTag(form, 'INPUT'); immediate(() => { - test.equal(input.value, 'foo'); - test.done(); + expect(input.value).toEqual('foo'); }); - }, + }); - 'should be able to test a values validity': function(test) { + it('should be able to test a values validity', () => { class TestForm extends React.Component { render() { return ( @@ -211,12 +207,11 @@ export default { const form = TestUtils.renderIntoDocument(); const input = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(input.isValidValue('foo@bar.com'), true); - test.equal(input.isValidValue('foo@bar'), false); - test.done(); - }, + expect(input.isValidValue('foo@bar.com')).toEqual(true); + expect(input.isValidValue('foo@bar')).toEqual(false); + }); - 'should be able to use an object as validations property': function(test) { + it('should be able to use an object as validations property', () => { class TestForm extends React.Component { render() { return ( @@ -234,13 +229,11 @@ export default { const form = TestUtils.renderIntoDocument(); const input = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(input.isValidValue('foo@bar.com'), true); - test.equal(input.isValidValue('foo@bar'), false); - - test.done(); - }, + expect(input.isValidValue('foo@bar.com')).toEqual(true); + expect(input.isValidValue('foo@bar')).toEqual(false); + }); - 'should be able to pass complex values to a validation rule': function(test) { + it('should be able to pass complex values to a validation rule', () => { class TestForm extends React.Component { render() { return ( @@ -258,16 +251,17 @@ export default { } const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), true); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(true); const input = TestUtils.findRenderedDOMComponentWithTag(form, 'INPUT'); TestUtils.Simulate.change(input, { target: { value: 'bar' } }); - test.equal(inputComponent.isValid(), false); - - test.done(); - }, + expect(inputComponent.isValid()).toEqual(false); + }); - 'should be able to run a function to validate': function(test) { + it('should be able to run a function to validate', () => { class TestForm extends React.Component { customValidationA(values, value) { return value === 'foo'; @@ -298,20 +292,19 @@ export default { } const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.scryRenderedComponentsWithType(form, TestInput); - test.equal(inputComponent[0].isValid(), true); - test.equal(inputComponent[1].isValid(), true); + const inputComponent = TestUtils.scryRenderedComponentsWithType( + form, + TestInput, + ); + expect(inputComponent[0].isValid()).toEqual(true); + expect(inputComponent[1].isValid()).toEqual(true); const input = TestUtils.scryRenderedDOMComponentsWithTag(form, 'INPUT'); TestUtils.Simulate.change(input[0], { target: { value: 'bar' } }); - test.equal(inputComponent[0].isValid(), false); - test.equal(inputComponent[1].isValid(), false); + expect(inputComponent[0].isValid()).toEqual(false); + expect(inputComponent[1].isValid()).toEqual(false); + }); - test.done(); - }, - - 'should not override error messages with error messages passed by form if passed eror messages is an empty object': function( - test, - ) { + it('should not override error messages with error messages passed by form if passed eror messages is an empty object', () => { class TestForm extends React.Component { render() { return ( @@ -331,13 +324,14 @@ export default { } const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.getErrorMessage(), 'bar3'); - - test.done(); - }, + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.getErrorMessage()).toEqual('bar3'); + }); - 'should override all error messages with error messages passed by form': function(test) { + it('should override all error messages with error messages passed by form', () => { class TestForm extends React.Component { render() { return ( @@ -357,13 +351,14 @@ export default { } const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.getErrorMessage(), 'bar'); - - test.done(); - }, + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.getErrorMessage()).toEqual('bar'); + }); - 'should override validation rules with required rules': function(test) { + it('should override validation rules with required rules', () => { class TestForm extends React.Component { render() { return ( @@ -386,13 +381,14 @@ export default { } const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.getErrorMessage(), 'bar3'); - - test.done(); - }, + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.getErrorMessage()).toEqual('bar3'); + }); - 'should fall back to default error message when non exist in validationErrors map': function(test) { + it('should fall back to default error message when non exist in validationErrors map', () => { class TestForm extends React.Component { render() { return ( @@ -412,13 +408,14 @@ export default { } const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.getErrorMessage(), 'bar1'); - - test.done(); - }, + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.getErrorMessage()).toEqual('bar1'); + }); - 'should not be valid if it is required and required rule is true': function(test) { + it('should not be valid if it is required and required rule is true', () => { class TestForm extends React.Component { render() { return ( @@ -430,13 +427,14 @@ export default { } const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), false); - - test.done(); - }, + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(false); + }); - 'should return the validationError if the field is invalid and required rule is true': function(test) { + it('should return the validationError if the field is invalid and required rule is true', () => { class TestForm extends React.Component { render() { return ( @@ -448,14 +446,15 @@ export default { } const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), false); - test.equal(inputComponent.getErrorMessage(), 'Field is required'); - - test.done(); - }, + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(false); + expect(inputComponent.getErrorMessage()).toEqual('Field is required'); + }); - 'should handle objects and arrays as values': function(test) { + it('should handle objects and arrays as values', () => { class TestForm extends React.Component { state = { foo: { foo: 'bar' }, @@ -478,13 +477,11 @@ export default { }); const inputs = TestUtils.scryRenderedComponentsWithType(form, TestInput); - test.deepEqual(inputs[0].getValue(), { foo: 'foo' }); - test.deepEqual(inputs[1].getValue(), ['bar']); - - test.done(); - }, + expect(inputs[0].getValue()).toEqual({ foo: 'foo' }); + expect(inputs[1].getValue()).toEqual(['bar']); + }); - 'should handle isFormDisabled with dynamic inputs': function(test) { + it('should handle isFormDisabled with dynamic inputs', () => { class TestForm extends React.Component { state = { bool: true }; flip = () => { @@ -495,7 +492,11 @@ export default { render() { return ( - {this.state.bool ? : } + {this.state.bool ? ( + + ) : ( + + )} ); } @@ -503,17 +504,15 @@ export default { const form = TestUtils.renderIntoDocument(); const input = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(input.isFormDisabled(), true); + expect(input.isFormDisabled()).toEqual(true); form.flip(); - test.equal(input.isFormDisabled(), false); + expect(input.isFormDisabled()).toEqual(false); + }); - test.done(); - }, - - 'should allow for dot notation in name which maps to a deep object': function(test) { + it('should allow for dot notation in name which maps to a deep object', () => { class TestForm extends React.Component { onSubmit(model) { - test.deepEqual(model, { foo: { bar: 'foo', test: 'test' } }); + expect(model).toEqual({ foo: { bar: 'foo', test: 'test' } }); } render() { return ( @@ -526,18 +525,16 @@ export default { } const form = TestUtils.renderIntoDocument(); - test.expect(1); + expect(true).toBe(true); const formEl = TestUtils.findRenderedDOMComponentWithTag(form, 'form'); TestUtils.Simulate.submit(formEl); + }); - test.done(); - }, - - 'should allow for application/x-www-form-urlencoded syntax and convert to object': function(test) { + it('should allow for application/x-www-form-urlencoded syntax and convert to object', () => { class TestForm extends React.Component { onSubmit(model) { - test.deepEqual(model, { foo: ['foo', 'bar'] }); + expect(model).toEqual({ foo: ['foo', 'bar'] }); } render() { return ( @@ -550,15 +547,13 @@ export default { } const form = TestUtils.renderIntoDocument(); - test.expect(1); + expect(true).toBe(true); const formEl = TestUtils.findRenderedDOMComponentWithTag(form, 'form'); TestUtils.Simulate.submit(formEl); + }); - test.done(); - }, - - 'input should rendered once with PureRenderMixin': function(test) { + it('input should rendered once with PureRenderMixin', () => { var renderSpy = sinon.spy(); const Input = InputFactory({ @@ -567,7 +562,13 @@ export default { }, render: function() { renderSpy(); - return ; + return ( + + ); }, }); @@ -577,12 +578,10 @@ export default { , ); - test.equal(renderSpy.calledOnce, true); + expect(renderSpy.calledOnce).toEqual(true); + }); - test.done(); - }, - - 'input should call shouldComponentUpdate with correct value': function(test) { + it('input should call shouldComponentUpdate with correct value', () => { var renderSpy = sinon.spy(); const Input = InputFactory({ @@ -591,7 +590,13 @@ export default { }, render: function() { renderSpy(); - return ; + return ( + + ); }, }); @@ -603,27 +608,25 @@ export default { const input = TestUtils.findRenderedDOMComponentWithTag(form, 'INPUT'); - test.equal(renderSpy.calledOnce, true); + expect(renderSpy.calledOnce).toEqual(true); TestUtils.Simulate.change(input, { target: { value: 'fooz' } }); - test.equal(input.value, 'fooz'); - test.equal(renderSpy.calledTwice, true); - - test.done(); - }, + expect(input.value).toEqual('fooz'); + expect(renderSpy.calledTwice).toEqual(true); + }); - 'binds all necessary methods': function(test) { + it('binds all necessary methods', () => { const onInputRef = input => { - ['isValidValue', 'resetValue', 'setValidations', 'setValue'].forEach(fnName => { - const fn = input[fnName]; - try { - fn(); - } catch (e) { - throw new Error(`Method '${fnName}' isn't bound.`); - } - }); - - test.done(); + ['isValidValue', 'resetValue', 'setValidations', 'setValue'].forEach( + fnName => { + const fn = input[fnName]; + try { + fn(); + } catch (e) { + throw new Error(`Method '${fnName}' isn't bound.`); + } + }, + ); }; TestUtils.renderIntoDocument( @@ -631,5 +634,5 @@ export default { , ); - }, -}; + }); +}); diff --git a/__tests__/Formsy-spec.js b/__tests__/Formsy-spec.js new file mode 100755 index 00000000..0edddb0a --- /dev/null +++ b/__tests__/Formsy-spec.js @@ -0,0 +1,814 @@ +import React from 'react'; +import ReactDOM from 'react-dom'; +import TestUtils from 'react-dom/test-utils'; + +import Formsy, { addValidationRule } from './..'; +import TestInput from '../__test_utils__/TestInput'; +import TestInputHoc from '../__test_utils__/TestInputHoc'; +import immediate from '../__test_utils__/immediate'; +import sinon from 'sinon'; + +describe('Setting up a form', () => { + it('should expose the users DOM node through an innerRef prop', () => { + class TestForm extends React.Component { + render() { + return ( + + { + this.name = c; + }} + /> + + ); + } + } + + const form = TestUtils.renderIntoDocument(); + const input = form.name; + expect(input.methodOnWrappedInstance('foo')).toEqual('foo'); + }); + + it('should render a form into the document', () => { + const form = TestUtils.renderIntoDocument(); + expect(ReactDOM.findDOMNode(form).tagName).toEqual('FORM'); + }); + + it('should set a class name if passed', () => { + const form = TestUtils.renderIntoDocument( + , + ); + expect(ReactDOM.findDOMNode(form).className).toEqual('foo'); + }); + + it('should allow for null/undefined children', () => { + let model = null; + class TestForm extends React.Component { + render() { + return ( + (model = formModel)}> +

Test

+ {null} + {undefined} + +
+ ); + } + } + + const form = TestUtils.renderIntoDocument(); + immediate(() => { + TestUtils.Simulate.submit(ReactDOM.findDOMNode(form)); + expect(model).toEqual({ name: 'foo' }); + }); + }); + + it('should allow for inputs being added dynamically', () => { + const inputs = []; + let forceUpdate = null; + let model = null; + class TestForm extends React.Component { + componentWillMount() { + forceUpdate = this.forceUpdate.bind(this); + } + render() { + return ( + (model = formModel)}>{inputs} + ); + } + } + const form = TestUtils.renderIntoDocument(); + + // Wait before adding the input + setTimeout(() => { + inputs.push(); + + forceUpdate(() => { + // Wait for next event loop, as that does the form + immediate(() => { + TestUtils.Simulate.submit(ReactDOM.findDOMNode(form)); + test.ok('test' in model); + }); + }); + }, 10); + }); + + it('should allow dynamically added inputs to update the form-model', () => { + const inputs = []; + let forceUpdate = null; + let model = null; + class TestForm extends React.Component { + componentWillMount() { + forceUpdate = this.forceUpdate.bind(this); + } + render() { + return ( + (model = formModel)}>{inputs} + ); + } + } + const form = TestUtils.renderIntoDocument(); + + // Wait before adding the input + immediate(() => { + inputs.push(); + + forceUpdate(() => { + // Wait for next event loop, as that does the form + immediate(() => { + TestUtils.Simulate.change( + TestUtils.findRenderedDOMComponentWithTag(form, 'INPUT'), + { + target: { value: 'foo' }, + }, + ); + TestUtils.Simulate.submit(ReactDOM.findDOMNode(form)); + expect(model.test).toEqual('foo'); + }); + }); + }); + }); + + it('should allow a dynamically updated input to update the form-model', () => { + let forceUpdate = null; + let model = null; + + class TestForm extends React.Component { + componentWillMount() { + forceUpdate = this.forceUpdate.bind(this); + } + render() { + const input = ; + + return ( + (model = formModel)}>{input} + ); + } + } + let form = TestUtils.renderIntoDocument(); + + // Wait before changing the input + immediate(() => { + form = TestUtils.renderIntoDocument(); + + forceUpdate(() => { + // Wait for next event loop, as that does the form + immediate(() => { + TestUtils.Simulate.submit(ReactDOM.findDOMNode(form)); + expect(model.test).toEqual('bar'); + }); + }); + }); + }); +}); + +describe('validations', () => { + it('should run when the input changes', () => { + const runRule = sinon.spy(); + const notRunRule = sinon.spy(); + + addValidationRule('runRule', runRule); + addValidationRule('notRunRule', notRunRule); + + const form = TestUtils.renderIntoDocument( + + + , + ); + + const input = TestUtils.findRenderedDOMComponentWithTag(form, 'input'); + TestUtils.Simulate.change(ReactDOM.findDOMNode(input), { + target: { value: 'bar' }, + }); + expect(runRule.calledWith({ one: 'bar' })).toBe(true); + expect(notRunRule.called).toEqual(false); + }); + + it('should allow the validation to be changed', () => { + const ruleA = sinon.spy(); + const ruleB = sinon.spy(); + addValidationRule('ruleA', ruleA); + addValidationRule('ruleB', ruleB); + + class TestForm extends React.Component { + constructor(props) { + super(props); + this.state = { rule: 'ruleA' }; + } + changeRule = () => { + this.setState({ + rule: 'ruleB', + }); + }; + render() { + return ( + + + + ); + } + } + + const form = TestUtils.renderIntoDocument(); + form.changeRule(); + const input = TestUtils.findRenderedDOMComponentWithTag(form, 'input'); + TestUtils.Simulate.change(ReactDOM.findDOMNode(input), { + target: { value: 'bar' }, + }); + expect(ruleB.calledWith({ one: 'bar' })).toBe(true); + }); + + it('should invalidate a form if dynamically inserted input is invalid', () => { + const isInValidSpy = sinon.spy(); + + class TestForm extends React.Component { + constructor(props) { + super(props); + this.state = { showSecondInput: false }; + } + addInput = () => { + this.setState({ + showSecondInput: true, + }); + }; + render() { + return ( + + + {this.state.showSecondInput ? ( + + ) : null} + + ); + } + } + + const form = TestUtils.renderIntoDocument(); + + expect(form.refs.formsy.state.isValid).toEqual(true); + form.addInput(); + + immediate(() => { + expect(isInValidSpy.called).toEqual(true); + }); + }); + + it('should validate a form when removing an invalid input', () => { + const isValidSpy = sinon.spy(); + + class TestForm extends React.Component { + constructor(props) { + super(props); + this.state = { showSecondInput: true }; + } + removeInput() { + this.setState({ + showSecondInput: false, + }); + } + render() { + return ( + + + {this.state.showSecondInput ? ( + + ) : null} + + ); + } + } + + const form = TestUtils.renderIntoDocument(); + + expect(form.refs.formsy.state.isValid).toEqual(false); + form.removeInput(); + + immediate(() => { + expect(isValidSpy.called).toEqual(true); + }); + }); + + it('runs multiple validations', () => { + const ruleA = sinon.spy(); + const ruleB = sinon.spy(); + addValidationRule('ruleA', ruleA); + addValidationRule('ruleB', ruleB); + + const form = TestUtils.renderIntoDocument( + + + , + ); + + const input = TestUtils.findRenderedDOMComponentWithTag(form, 'input'); + TestUtils.Simulate.change(ReactDOM.findDOMNode(input), { + target: { value: 'bar' }, + }); + expect(ruleA.calledWith({ one: 'bar' })).toBe(true); + expect(ruleB.calledWith({ one: 'bar' })).toBe(true); + }); +}); + +describe('onChange', () => { + it('should not trigger onChange when form is mounted', () => { + const hasChanged = sinon.spy(); + class TestForm extends React.Component { + render() { + return ; + } + } + TestUtils.renderIntoDocument(); + expect(hasChanged.called).toEqual(false); + }); + + it('should trigger onChange once when form element is changed', () => { + const hasChanged = sinon.spy(); + const form = TestUtils.renderIntoDocument( + + + , + ); + TestUtils.Simulate.change( + TestUtils.findRenderedDOMComponentWithTag(form, 'INPUT'), + { target: { value: 'bar' } }, + ); + expect(hasChanged.calledOnce).toEqual(true); + }); + + it('should trigger onChange once when new input is added to form', () => { + const hasChanged = sinon.spy(); + class TestForm extends React.Component { + state = { + showInput: false, + }; + addInput() { + this.setState({ + showInput: true, + }); + } + render() { + return ( + + {this.state.showInput ? : null} + + ); + } + } + + const form = TestUtils.renderIntoDocument(); + form.addInput(); + immediate(() => { + expect(hasChanged.calledOnce).toEqual(true); + }); + }); + + it('onChange should honor dot notation transformations', () => { + const hasChanged = sinon.spy(); + class TestForm extends React.Component { + state = { + showInput: false, + }; + addInput() { + this.setState({ + showInput: true, + }); + } + render() { + return ( + + {this.state.showInput ? ( + + ) : null} + + ); + } + } + + const form = TestUtils.renderIntoDocument(); + form.addInput(); + immediate(() => { + expect(hasChanged.args[0][0]).toEqual({ parent: { child: 'test' } }); + }); + }); +}); + +describe('Update a form', () => { + it('should allow elements to check if the form is disabled', () => { + class TestForm extends React.Component { + state = { disabled: true }; + enableForm() { + this.setState({ disabled: false }); + } + render() { + return ( + + + + ); + } + } + + const form = TestUtils.renderIntoDocument(); + const input = TestUtils.findRenderedComponentWithType(form, TestInput); + expect(input.isFormDisabled()).toEqual(true); + + form.enableForm(); + immediate(() => { + expect(input.isFormDisabled()).toEqual(false); + }); + }); + + it('should be possible to pass error state of elements by changing an errors attribute', () => { + class TestForm extends React.Component { + state = { validationErrors: { foo: 'bar' } }; + onChange = values => { + this.setState( + values.foo + ? { validationErrors: {} } + : { validationErrors: { foo: 'bar' } }, + ); + }; + render() { + return ( + + + + ); + } + } + const form = TestUtils.renderIntoDocument(); + + // Wait for update + immediate(() => { + const input = TestUtils.findRenderedComponentWithType(form, TestInput); + expect(input.getErrorMessage()).toEqual('bar'); + input.setValue('gotValue'); + + // Wait for update + immediate(() => { + expect(input.getErrorMessage()).toEqual(null); + }); + }); + }); + + it('should trigger an onValidSubmit when submitting a valid form', () => { + let isCalled = sinon.spy(); + class TestForm extends React.Component { + render() { + return ( + + + + ); + } + } + const form = TestUtils.renderIntoDocument(); + const FoundForm = TestUtils.findRenderedComponentWithType(form, TestForm); + TestUtils.Simulate.submit(ReactDOM.findDOMNode(FoundForm)); + expect(isCalled.called).toEqual(true); + }); + + it('should trigger an onInvalidSubmit when submitting an invalid form', () => { + let isCalled = sinon.spy(); + class TestForm extends React.Component { + render() { + return ( + + + + ); + } + } + const form = TestUtils.renderIntoDocument(); + + const FoundForm = TestUtils.findRenderedComponentWithType(form, TestForm); + TestUtils.Simulate.submit(ReactDOM.findDOMNode(FoundForm)); + expect(isCalled.called).toEqual(true); + }); +}); + +describe('value === false', () => { + it('should call onSubmit correctly', () => { + const onSubmit = sinon.spy(); + class TestForm extends React.Component { + render() { + return ( + + + + + ); + } + } + + const form = TestUtils.renderIntoDocument(); + TestUtils.Simulate.submit(ReactDOM.findDOMNode(form)); + expect(onSubmit.calledWith({ foo: false })).toEqual(true); + }); + + it('should allow dynamic changes to false', () => { + const onSubmit = sinon.spy(); + class TestForm extends React.Component { + state = { + value: true, + }; + changeValue() { + this.setState({ + value: false, + }); + } + render() { + return ( + + + + + ); + } + } + + const form = TestUtils.renderIntoDocument(); + form.changeValue(); + TestUtils.Simulate.submit(ReactDOM.findDOMNode(form)); + expect(onSubmit.calledWith({ foo: false })).toEqual(true); + }); + + it('should say the form is submitted', () => { + class TestForm extends React.Component { + render() { + return ( + + + + + ); + } + } + const form = TestUtils.renderIntoDocument(); + const input = TestUtils.findRenderedComponentWithType(form, TestInput); + expect(input.isFormSubmitted()).toEqual(false); + TestUtils.Simulate.submit(ReactDOM.findDOMNode(form)); + expect(input.isFormSubmitted()).toEqual(true); + }); + + it('should be able to reset the form to its pristine state', () => { + class TestForm extends React.Component { + state = { + value: true, + }; + changeValue() { + this.setState({ + value: false, + }); + } + render() { + return ( + + + + + ); + } + } + const form = TestUtils.renderIntoDocument(); + const input = TestUtils.findRenderedComponentWithType(form, TestInput); + const formsyForm = TestUtils.findRenderedComponentWithType(form, Formsy); + expect(input.getValue()).toEqual(true); + form.changeValue(); + expect(input.getValue()).toEqual(false); + formsyForm.reset(); + expect(input.getValue()).toEqual(true); + }); + + it('should be able to reset the form using custom data', () => { + class TestForm extends React.Component { + state = { + value: true, + }; + changeValue() { + this.setState({ + value: false, + }); + } + render() { + return ( + + + + + ); + } + } + const form = TestUtils.renderIntoDocument(); + const input = TestUtils.findRenderedComponentWithType(form, TestInput); + const formsyForm = TestUtils.findRenderedComponentWithType(form, Formsy); + + expect(input.getValue()).toEqual(true); + form.changeValue(); + expect(input.getValue()).toEqual(false); + formsyForm.reset({ + foo: 'bar', + }); + expect(input.getValue()).toEqual('bar'); + }); +}); + +describe('.reset()', () => { + it('should be able to reset the form to empty values', () => { + class TestForm extends React.Component { + render() { + return ( + + + + + ); + } + } + const form = TestUtils.renderIntoDocument(); + const input = TestUtils.findRenderedComponentWithType(form, TestInput); + const formsyForm = TestUtils.findRenderedComponentWithType(form, Formsy); + + formsyForm.reset({ + foo: '', + }); + expect(input.getValue()).toEqual(''); + }); +}); + +describe('.isChanged()', () => { + it('initially returns false', () => { + const hasOnChanged = sinon.spy(); + const form = TestUtils.renderIntoDocument( + + + , + ); + expect(form.isChanged()).toEqual(false); + expect(hasOnChanged.called).toEqual(false); + }); + + it('returns true when changed', () => { + const hasOnChanged = sinon.spy(); + const form = TestUtils.renderIntoDocument( + + + , + ); + const input = TestUtils.findRenderedDOMComponentWithTag(form, 'input'); + TestUtils.Simulate.change(ReactDOM.findDOMNode(input), { + target: { value: 'bar' }, + }); + expect(form.isChanged()).toEqual(true); + expect(hasOnChanged.calledWith({ one: 'bar' })).toEqual(true); + }); + + it('returns false if changes are undone', () => { + const hasOnChanged = sinon.spy(); + const form = TestUtils.renderIntoDocument( + + + , + ); + const input = TestUtils.findRenderedDOMComponentWithTag(form, 'input'); + TestUtils.Simulate.change(ReactDOM.findDOMNode(input), { + target: { value: 'bar' }, + }); + expect(hasOnChanged.calledWith({ one: 'bar' })).toBe(true); + + TestUtils.Simulate.change(ReactDOM.findDOMNode(input), { + target: { value: 'foo' }, + }); + expect(form.isChanged()).toEqual(false); + expect(hasOnChanged.calledWith({ one: 'foo' })).toBe(true); + }); +}); + +describe('form valid state', () => { + it('should allow to be changed with updateInputsWithError', () => { + class TestForm extends React.Component { + state = { isValid: true }; + onValidSubmit = (model, reset, updateInputsWithError) => { + updateInputsWithError({ foo: 'bar' }, true); + }; + onValid = () => { + this.setState({ isValid: true }); + }; + onInvalid = () => { + this.setState({ isValid: false }); + }; + render() { + return ( + + + + ); + } + } + const form = TestUtils.renderIntoDocument(); + + // Wait for update + immediate(() => { + expect(form.state.isValid).toEqual(true); + TestUtils.Simulate.submit(ReactDOM.findDOMNode(form)); + + // Wait for update + immediate(() => { + expect(form.state.isValid).toEqual(false); + }); + }); + }); + + it('should be false when validationErrors is not empty', () => { + class TestForm extends React.Component { + state = { validationErrors: {}, isValid: true }; + setValidationErrors = empty => { + this.setState( + !empty + ? { validationErrors: { foo: 'bar' } } + : { validationErrors: {} }, + ); + }; + onValid = () => { + this.setState({ isValid: true }); + }; + onInvalid = () => { + this.setState({ isValid: false }); + }; + render() { + return ( + + + + ); + } + } + const form = TestUtils.renderIntoDocument(); + + // Wait for update + immediate(() => { + expect(form.state.isValid).toEqual(true); + form.setValidationErrors(); + + // Wait for update + immediate(() => { + expect(form.state.isValid).toEqual(false); + }); + }); + }); + + it('should be true when validationErrors is not empty and preventExternalInvalidation is true', () => { + class TestForm extends React.Component { + state = { validationErrors: {}, isValid: true }; + setValidationErrors = empty => { + this.setState( + !empty + ? { validationErrors: { foo: 'bar' } } + : { validationErrors: {} }, + ); + }; + onValid = () => { + this.setState({ isValid: true }); + }; + onInvalid = () => { + this.setState({ isValid: false }); + }; + render() { + return ( + + + + ); + } + } + const form = TestUtils.renderIntoDocument(); + + // Wait for update + immediate(() => { + expect(form.state.isValid).toEqual(true); + form.setValidationErrors(); + + // Wait for update + immediate(() => { + expect(form.state.isValid).toEqual(true); + }); + }); + }); +}); diff --git a/__tests__/Rules-equals-spec.js b/__tests__/Rules-equals-spec.js new file mode 100644 index 00000000..d1fe3aac --- /dev/null +++ b/__tests__/Rules-equals-spec.js @@ -0,0 +1,84 @@ +import React from 'react'; +import TestUtils from 'react-dom/test-utils'; +import immediate from '../__test_utils__/immediate'; + +import Formsy from './..'; +import { InputFactory } from '../__test_utils__/TestInput'; + +const TestInput = InputFactory({ + render: function() { + return ; + }, +}); + +class TestForm extends React.Component { + render() { + return ( + + + + ); + } +} + +describe('equals', () => { + it('should pass when the value is equal', () => { + const form = TestUtils.renderIntoDocument(); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(true); + }); + + it('should fail when the value is not equal', () => { + const form = TestUtils.renderIntoDocument(); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(false); + }); + + it('should pass with an empty string', () => { + const form = TestUtils.renderIntoDocument(); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(true); + }); + + it('should pass with an undefined', () => { + const form = TestUtils.renderIntoDocument( + , + ); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(true); + }); + + it('should pass with a null', () => { + const form = TestUtils.renderIntoDocument(); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(true); + }); + + it('should fail with a number', () => { + const form = TestUtils.renderIntoDocument(); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(false); + }); +}); diff --git a/__tests__/Rules-isAlpha-spec.js b/__tests__/Rules-isAlpha-spec.js new file mode 100644 index 00000000..d91363da --- /dev/null +++ b/__tests__/Rules-isAlpha-spec.js @@ -0,0 +1,96 @@ +import React from 'react'; +import TestUtils from 'react-dom/test-utils'; + +import Formsy from './..'; +import { InputFactory } from '../__test_utils__/TestInput'; + +const TestInput = InputFactory({ + render: function() { + return ; + }, +}); + +class TestForm extends React.Component { + render() { + return ( + + + + ); + } +} + +describe('isAlpha', () => { + it('should pass with a default value', () => { + const form = TestUtils.renderIntoDocument(); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(true); + }); + + it('should pass with a string is only latin letters', () => { + const form = TestUtils.renderIntoDocument( + , + ); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(true); + }); + + it('should fail with a string with numbers', () => { + const form = TestUtils.renderIntoDocument( + , + ); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(false); + }); + + it('should pass with an undefined', () => { + const form = TestUtils.renderIntoDocument( + , + ); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(true); + }); + + it('should pass with a null', () => { + const form = TestUtils.renderIntoDocument(); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(true); + }); + + it('should pass with an empty string', () => { + const form = TestUtils.renderIntoDocument(); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(true); + }); + + it('should fail with a number', () => { + const form = TestUtils.renderIntoDocument(); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(false); + }); +}); diff --git a/__tests__/Rules-isAlphanumeric-spec.js b/__tests__/Rules-isAlphanumeric-spec.js new file mode 100644 index 00000000..827a1205 --- /dev/null +++ b/__tests__/Rules-isAlphanumeric-spec.js @@ -0,0 +1,106 @@ +import React from 'react'; +import TestUtils from 'react-dom/test-utils'; + +import Formsy from './..'; +import { InputFactory } from '../__test_utils__/TestInput'; + +const TestInput = InputFactory({ + render() { + return ; + }, +}); + +class TestForm extends React.Component { + render() { + return ( + + + + ); + } +} + +describe('isAlphanumeric', () => { + it('should pass with a default value', () => { + const form = TestUtils.renderIntoDocument(); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(true); + }); + + it('should pass with a string is only latin letters', () => { + const form = TestUtils.renderIntoDocument( + , + ); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(true); + }); + + it('should fail with a string with numbers', () => { + const form = TestUtils.renderIntoDocument( + , + ); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(true); + }); + + it('should pass with an undefined', () => { + const form = TestUtils.renderIntoDocument( + , + ); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(true); + }); + + it('should pass with a null', () => { + const form = TestUtils.renderIntoDocument(); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(true); + }); + + it('should pass with an empty string', () => { + const form = TestUtils.renderIntoDocument(); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(true); + }); + + it('should pass with a number', () => { + const form = TestUtils.renderIntoDocument(); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(true); + }); + + it('should fail with a non alpha and number symbols', () => { + const value = '!@#$%^&*()'; + const form = TestUtils.renderIntoDocument(); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(false); + }); +}); diff --git a/__tests__/Rules-isEmail-spec.js b/__tests__/Rules-isEmail-spec.js new file mode 100644 index 00000000..479794c1 --- /dev/null +++ b/__tests__/Rules-isEmail-spec.js @@ -0,0 +1,105 @@ +import React from 'react'; +import TestUtils from 'react-dom/test-utils'; + +import Formsy from './..'; +import { InputFactory } from '../__test_utils__/TestInput'; + +const TestInput = InputFactory({ + render() { + return ; + }, +}); + +class TestForm extends React.Component { + render() { + return ( + + + + ); + } +} + +describe('isEmail', () => { + it('should pass with a default value', () => { + const form = TestUtils.renderIntoDocument(); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(true); + }); + + it('should fail with "foo"', () => { + const form = TestUtils.renderIntoDocument(); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(false); + }); + + it('should pass with "foo@foo.com"', () => { + const form = TestUtils.renderIntoDocument( + , + ); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(true); + }); + + it('should pass with new long domains', () => { + const form = TestUtils.renderIntoDocument( + , + ); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(true); + }); + + it('should pass with an undefined', () => { + const form = TestUtils.renderIntoDocument( + , + ); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(true); + }); + + it('should pass with a null', () => { + const form = TestUtils.renderIntoDocument(); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(true); + }); + + it('should pass with an empty string', () => { + const form = TestUtils.renderIntoDocument(); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(true); + }); + + it('should fail with a number', () => { + const form = TestUtils.renderIntoDocument(); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(false); + }); +}); diff --git a/__tests__/Rules-isEmptyString-spec.js b/__tests__/Rules-isEmptyString-spec.js new file mode 100644 index 00000000..fca3f07e --- /dev/null +++ b/__tests__/Rules-isEmptyString-spec.js @@ -0,0 +1,92 @@ +import React from 'react'; +import TestUtils from 'react-dom/test-utils'; + +import Formsy from './..'; +import { InputFactory } from '../__test_utils__/TestInput'; + +const TestInput = InputFactory({ + render() { + return ; + }, +}); + +class TestForm extends React.Component { + render() { + return ( + + + + ); + } +} + +describe('isEmptyString', () => { + it('should pass with a default value', () => { + const form = TestUtils.renderIntoDocument(); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(false); + }); + + it('should fail with non-empty string', () => { + const form = TestUtils.renderIntoDocument(); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(false); + }); + + it('should pass with an empty string', () => { + const form = TestUtils.renderIntoDocument(); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(true); + }); + + it('should fail with undefined', () => { + const form = TestUtils.renderIntoDocument( + , + ); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(false); + }); + + it('should fail with null', () => { + const form = TestUtils.renderIntoDocument(); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(false); + }); + + it('should fail with a number', () => { + const form = TestUtils.renderIntoDocument(); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(false); + }); + + it('should fail with a zero', () => { + const form = TestUtils.renderIntoDocument(); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(false); + }); +}); diff --git a/__tests__/Rules-isExisty-spec.js b/__tests__/Rules-isExisty-spec.js new file mode 100644 index 00000000..fb79ab4d --- /dev/null +++ b/__tests__/Rules-isExisty-spec.js @@ -0,0 +1,92 @@ +import React from 'react'; +import TestUtils from 'react-dom/test-utils'; + +import Formsy from './..'; +import { InputFactory } from '../__test_utils__/TestInput'; + +const TestInput = InputFactory({ + render() { + return ; + }, +}); + +class TestForm extends React.Component { + render() { + return ( + + + + ); + } +} + +describe('isExisty', () => { + it('should pass with a default value', () => { + const form = TestUtils.renderIntoDocument(); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(false); + }); + + it('should pass with a string', () => { + const form = TestUtils.renderIntoDocument(); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(true); + }); + + it('should pass with an empty string', () => { + const form = TestUtils.renderIntoDocument(); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(true); + }); + + it('should fail with undefined', () => { + const form = TestUtils.renderIntoDocument( + , + ); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(false); + }); + + it('should fail with null', () => { + const form = TestUtils.renderIntoDocument(); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(false); + }); + + it('should pass with a number', () => { + const form = TestUtils.renderIntoDocument(); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(true); + }); + + it('should pass with a zero', () => { + const form = TestUtils.renderIntoDocument(); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(true); + }); +}); diff --git a/__tests__/Rules-isFloat-spec.js b/__tests__/Rules-isFloat-spec.js new file mode 100644 index 00000000..4d10923d --- /dev/null +++ b/__tests__/Rules-isFloat-spec.js @@ -0,0 +1,132 @@ +import React from 'react'; +import TestUtils from 'react-dom/test-utils'; + +import Formsy from './..'; +import { InputFactory } from '../__test_utils__/TestInput'; + +const TestInput = InputFactory({ + render() { + return ; + }, +}); + +class TestForm extends React.Component { + render() { + return ( + + + + ); + } +} + +describe('isFloat', () => { + it('should pass with a default value', () => { + const form = TestUtils.renderIntoDocument(); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(true); + }); + + it('should pass with an empty string', () => { + const form = TestUtils.renderIntoDocument(); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(true); + }); + + it('should fail with a string', () => { + const form = TestUtils.renderIntoDocument(); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(false); + }); + + it('should pass with a number as string', () => { + const form = TestUtils.renderIntoDocument(); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(true); + }); + + it('should fail string with digits', () => { + const form = TestUtils.renderIntoDocument( + , + ); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(false); + }); + + it('should pass with an int', () => { + const form = TestUtils.renderIntoDocument(); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(true); + }); + + it('should pass with a float', () => { + const form = TestUtils.renderIntoDocument( + , + ); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(true); + }); + + it('should pass with a float in science notation', () => { + const form = TestUtils.renderIntoDocument(); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(true); + }); + + it('should pass with undefined', () => { + const form = TestUtils.renderIntoDocument( + , + ); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(true); + }); + + it('should pass with null', () => { + const form = TestUtils.renderIntoDocument(); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(true); + }); + + it('should pass with a zero', () => { + const form = TestUtils.renderIntoDocument(); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(true); + }); +}); diff --git a/__tests__/Rules-isInt-spec.js b/__tests__/Rules-isInt-spec.js new file mode 100644 index 00000000..9fe9b0f6 --- /dev/null +++ b/__tests__/Rules-isInt-spec.js @@ -0,0 +1,132 @@ +import React from 'react'; +import TestUtils from 'react-dom/test-utils'; + +import Formsy from './..'; +import { InputFactory } from '../__test_utils__/TestInput'; + +const TestInput = InputFactory({ + render() { + return ; + }, +}); + +class TestForm extends React.Component { + render() { + return ( + + + + ); + } +} + +describe('isInt', () => { + it('should pass with a default value', () => { + const form = TestUtils.renderIntoDocument(); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(true); + }); + + it('should pass with an empty string', () => { + const form = TestUtils.renderIntoDocument(); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(true); + }); + + it('should fail with a string', () => { + const form = TestUtils.renderIntoDocument(); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(false); + }); + + it('should pass with a number as string', () => { + const form = TestUtils.renderIntoDocument(); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(true); + }); + + it('should fail string with digits', () => { + const form = TestUtils.renderIntoDocument( + , + ); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(false); + }); + + it('should pass with an int', () => { + const form = TestUtils.renderIntoDocument(); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(true); + }); + + it('should fail with a float', () => { + const form = TestUtils.renderIntoDocument( + , + ); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(false); + }); + + it('should fail with a float in science notation', () => { + const form = TestUtils.renderIntoDocument(); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(false); + }); + + it('should pass with undefined', () => { + const form = TestUtils.renderIntoDocument( + , + ); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(true); + }); + + it('should pass with null', () => { + const form = TestUtils.renderIntoDocument(); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(true); + }); + + it('should pass with a zero', () => { + const form = TestUtils.renderIntoDocument(); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(true); + }); +}); diff --git a/__tests__/Rules-isLength-spec.js b/__tests__/Rules-isLength-spec.js new file mode 100644 index 00000000..ebd20e8e --- /dev/null +++ b/__tests__/Rules-isLength-spec.js @@ -0,0 +1,201 @@ +import React from 'react'; +import TestUtils from 'react-dom/test-utils'; + +import Formsy from './..'; +import { InputFactory } from '../__test_utils__/TestInput'; + +const TestInput = InputFactory({ + render() { + return ; + }, +}); + +class TestForm extends React.Component { + render() { + return ( + + + + ); + } +} + +describe('isLength:3', () => { + it('should pass with a default value', () => { + const form = TestUtils.renderIntoDocument(); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(true); + }); + + it('should fail with a string too small', () => { + const form = TestUtils.renderIntoDocument( + , + ); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(false); + }); + + it('should fail with a string too long', () => { + const form = TestUtils.renderIntoDocument( + , + ); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(false); + }); + + it('should pass with matching length', () => { + const form = TestUtils.renderIntoDocument( + , + ); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(true); + }); + + it('should pass with undefined', () => { + const form = TestUtils.renderIntoDocument( + , + ); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(true); + }); + + it('should pass with null', () => { + const form = TestUtils.renderIntoDocument( + , + ); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(true); + }); + + it('should pass with empty string', () => { + const form = TestUtils.renderIntoDocument( + , + ); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(true); + }); + + it('should fail with a number', () => { + const form = TestUtils.renderIntoDocument( + , + ); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(false); + }); +}); + +describe('isLength:0', () => { + it('should pass with a default value', () => { + const form = TestUtils.renderIntoDocument(); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(true); + }); + + it('should fail with a string too small', () => { + const form = TestUtils.renderIntoDocument( + , + ); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(false); + }); + + it('should fail with a string too long', () => { + const form = TestUtils.renderIntoDocument( + , + ); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(false); + }); + + it('should pass with matching length', () => { + const form = TestUtils.renderIntoDocument( + , + ); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(true); + }); + + it('should pass with undefined', () => { + const form = TestUtils.renderIntoDocument( + , + ); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(true); + }); + + it('should pass with null', () => { + const form = TestUtils.renderIntoDocument( + , + ); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(true); + }); + + it('should pass with empty string', () => { + const form = TestUtils.renderIntoDocument( + , + ); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(true); + }); + + it('should fail with a number', () => { + const form = TestUtils.renderIntoDocument( + , + ); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(false); + }); +}); diff --git a/__tests__/Rules-isNumeric-spec.js b/__tests__/Rules-isNumeric-spec.js new file mode 100644 index 00000000..fc6a0cb5 --- /dev/null +++ b/__tests__/Rules-isNumeric-spec.js @@ -0,0 +1,132 @@ +import React from 'react'; +import TestUtils from 'react-dom/test-utils'; + +import Formsy from './..'; +import { InputFactory } from '../__test_utils__/TestInput'; + +const TestInput = InputFactory({ + render() { + return ; + }, +}); + +class TestForm extends React.Component { + render() { + return ( + + + + ); + } +} + +describe('isNumeric', () => { + it('should pass with a default value', () => { + const form = TestUtils.renderIntoDocument(); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(true); + }); + + it('should pass with an empty string', () => { + const form = TestUtils.renderIntoDocument(); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(true); + }); + + it('should fail with an unempty string', () => { + const form = TestUtils.renderIntoDocument(); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(false); + }); + + it('should pass with a number as string', () => { + const form = TestUtils.renderIntoDocument(); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(true); + }); + + it('should fail with a number as string with not digits', () => { + const form = TestUtils.renderIntoDocument( + , + ); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(false); + }); + + it('should pass with an int', () => { + const form = TestUtils.renderIntoDocument(); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(true); + }); + + it('should pass with a float', () => { + const form = TestUtils.renderIntoDocument( + , + ); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(true); + }); + + it('should fail with a float in science notation', () => { + const form = TestUtils.renderIntoDocument(); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(false); + }); + + it('should pass with an undefined', () => { + const form = TestUtils.renderIntoDocument( + , + ); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(true); + }); + + it('should pass with a null', () => { + const form = TestUtils.renderIntoDocument(); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(true); + }); + + it('should pass with a zero', () => { + const form = TestUtils.renderIntoDocument(); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(true); + }); +}); diff --git a/__tests__/Rules-isUrl-spec.js b/__tests__/Rules-isUrl-spec.js new file mode 100644 index 00000000..deb03941 --- /dev/null +++ b/__tests__/Rules-isUrl-spec.js @@ -0,0 +1,94 @@ +import React from 'react'; +import TestUtils from 'react-dom/test-utils'; + +import Formsy from './..'; +import { InputFactory } from '../__test_utils__/TestInput'; + +const TestInput = InputFactory({ + render() { + return ; + }, +}); + +class TestForm extends React.Component { + render() { + return ( + + + + ); + } +} + +describe('isUrl', () => { + it('should pass with default value', () => { + const form = TestUtils.renderIntoDocument(); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(true); + }); + + it('should fail with "foo"', () => { + const form = TestUtils.renderIntoDocument(); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(false); + }); + + it('should pass with "https://www.google.com/"', () => { + const form = TestUtils.renderIntoDocument( + , + ); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(true); + }); + + it('should pass with an undefined', () => { + const form = TestUtils.renderIntoDocument( + , + ); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(true); + }); + + it('should pass with a null', () => { + const form = TestUtils.renderIntoDocument(); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(true); + }); + + it('should fail with a number', () => { + const form = TestUtils.renderIntoDocument(); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(false); + }); + + it('should pass with an empty string', () => { + const form = TestUtils.renderIntoDocument(); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(true); + }); +}); diff --git a/__tests__/Rules-isWords-spec.js b/__tests__/Rules-isWords-spec.js new file mode 100644 index 00000000..3a49789f --- /dev/null +++ b/__tests__/Rules-isWords-spec.js @@ -0,0 +1,94 @@ +import React from 'react'; +import TestUtils from 'react-dom/test-utils'; + +import Formsy from './..'; +import { InputFactory } from '../__test_utils__/TestInput'; + +const TestInput = InputFactory({ + render() { + return ; + }, +}); + +class TestForm extends React.Component { + render() { + return ( + + + + ); + } +} + +describe('isWord', () => { + it('should pass with a default value', () => { + const form = TestUtils.renderIntoDocument(); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(true); + }); + + it('should pass with a 1 word', () => { + const form = TestUtils.renderIntoDocument(); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(true); + }); + + it('should pass with 2 words', () => { + const form = TestUtils.renderIntoDocument( + , + ); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(true); + }); + + it('should fail with a string with numbers', () => { + const form = TestUtils.renderIntoDocument(); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(false); + }); + + it('should pass with an undefined', () => { + const form = TestUtils.renderIntoDocument( + , + ); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(true); + }); + + it('should pass with a null', () => { + const form = TestUtils.renderIntoDocument(); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(true); + }); + + it('should fail with a number', () => { + const form = TestUtils.renderIntoDocument(); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(false); + }); +}); diff --git a/__tests__/Rules-maxLength-spec.js b/__tests__/Rules-maxLength-spec.js new file mode 100644 index 00000000..60468a33 --- /dev/null +++ b/__tests__/Rules-maxLength-spec.js @@ -0,0 +1,101 @@ +import React from 'react'; +import TestUtils from 'react-dom/test-utils'; + +import Formsy from './..'; +import { InputFactory } from '../__test_utils__/TestInput'; + +const TestInput = InputFactory({ + render() { + return ; + }, +}); + +class TestForm extends React.Component { + render() { + return ( + + + + ); + } +} + +describe('maxLength', () => { + it('should pass with a default value', () => { + const form = TestUtils.renderIntoDocument(); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(true); + }); + + it("should pass when a string's length is smaller", () => { + const form = TestUtils.renderIntoDocument(); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(true); + }); + + it("should pass when a string's length is equal", () => { + const form = TestUtils.renderIntoDocument(); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(true); + }); + + it("should fail when a string's length is bigger", () => { + const form = TestUtils.renderIntoDocument(); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(false); + }); + + it('should pass with empty string', () => { + const form = TestUtils.renderIntoDocument(); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(true); + }); + + it('should pass with an undefined', () => { + const form = TestUtils.renderIntoDocument( + , + ); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(true); + }); + + it('should pass with a null', () => { + const form = TestUtils.renderIntoDocument(); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(true); + }); + + it('should fail with a number', () => { + const form = TestUtils.renderIntoDocument(); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(false); + }); +}); diff --git a/__tests__/Rules-minLength-spec.js b/__tests__/Rules-minLength-spec.js new file mode 100644 index 00000000..c87b9248 --- /dev/null +++ b/__tests__/Rules-minLength-spec.js @@ -0,0 +1,168 @@ +import React from 'react'; +import TestUtils from 'react-dom/test-utils'; + +import Formsy from './..'; +import { InputFactory } from '../__test_utils__/TestInput'; + +const TestInput = InputFactory({ + render() { + return ; + }, +}); + +class TestForm extends React.Component { + render() { + return ( + + + + ); + } +} + +describe('minLength:3', () => { + it('should pass with a default value', () => { + const form = TestUtils.renderIntoDocument(); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(true); + }); + + it("should pass when a string's length is bigger", () => { + const form = TestUtils.renderIntoDocument( + , + ); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(true); + }); + + it("should fail when a string's length is smaller", () => { + const form = TestUtils.renderIntoDocument( + , + ); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(false); + }); + + it('should pass with empty string', () => { + const form = TestUtils.renderIntoDocument( + , + ); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(true); + }); + + it('should pass with an undefined', () => { + const form = TestUtils.renderIntoDocument( + , + ); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(true); + }); + + it('should pass with a null', () => { + const form = TestUtils.renderIntoDocument( + , + ); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(true); + }); + + it('should fail with a number', () => { + const form = TestUtils.renderIntoDocument( + , + ); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(false); + }); +}); + +describe('minLength:0', () => { + it('should pass with a default value', () => { + const form = TestUtils.renderIntoDocument(); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(true); + }); + + it("should pass when a string's length is bigger", () => { + const form = TestUtils.renderIntoDocument( + , + ); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(true); + }); + + it('should pass with empty string', () => { + const form = TestUtils.renderIntoDocument( + , + ); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(true); + }); + + it('should pass with an undefined', () => { + const form = TestUtils.renderIntoDocument( + , + ); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(true); + }); + + it('should pass with a null', () => { + const form = TestUtils.renderIntoDocument( + , + ); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(true); + }); + + it('should fail with a number', () => { + const form = TestUtils.renderIntoDocument( + , + ); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + TestInput, + ); + expect(inputComponent.isValid()).toEqual(false); + }); +}); diff --git a/__tests__/Utils-spec.js b/__tests__/Utils-spec.js new file mode 100644 index 00000000..19940766 --- /dev/null +++ b/__tests__/Utils-spec.js @@ -0,0 +1,31 @@ +import utils from './../src/utils.js'; + +describe('Utils', () => { + it('should check equality of objects and arrays', () => { + const objA = { foo: 'bar' }; + const objB = { foo: 'bar' }; + const objC = [{ foo: ['bar'] }]; + const objD = [{ foo: ['bar'] }]; + const objE = undefined; + const objF = undefined; + const objG = null; + const objH = null; + + expect(utils.isSame(objA, objB)).toBe(true); + expect(utils.isSame(objC, objD)).toBe(true); + expect(utils.isSame(objA, objD)).toBe(false); + + expect(utils.isSame(objE, objF)).toBe(true); + expect(utils.isSame(objA, objF)).toBe(false); + expect(utils.isSame(objE, objA)).toBe(false); + + expect(utils.isSame(objG, objH)).toBe(true); + expect(utils.isSame(objA, objH)).toBe(false); + expect(utils.isSame(objC, objH)).toBe(false); + expect(utils.isSame(objG, objA)).toBe(false); + + expect(utils.isSame(() => {}, () => {})).toBe(true); + expect(utils.isSame(objA, () => {})).toBe(false); + expect(utils.isSame(() => {}, objA)).toBe(false); + }); +}); diff --git a/tests/Validation-spec.js b/__tests__/Validation-spec.js similarity index 57% rename from tests/Validation-spec.js rename to __tests__/Validation-spec.js index 27a1895e..5715a277 100644 --- a/tests/Validation-spec.js +++ b/__tests__/Validation-spec.js @@ -2,8 +2,8 @@ import React from 'react'; import TestUtils from 'react-dom/test-utils'; import Formsy, { withFormsy } from './..'; -import { InputFactory } from './utils/TestInput'; -import immediate from './utils/immediate'; +import { InputFactory } from '../__test_utils__/TestInput'; +import immediate from '../__test_utils__/immediate'; import sinon from 'sinon'; class MyTest extends React.Component { @@ -14,57 +14,73 @@ class MyTest extends React.Component { }; render() { - return ; + return ( + + ); } } const FormsyTest = withFormsy(MyTest); -export default { - 'should reset only changed form element when external error is passed': function(test) { +describe('Validation', () => { + it('should reset only changed form element when external error is passed', () => { const form = TestUtils.renderIntoDocument( - invalidate({ foo: 'bar', bar: 'foo' })}> + + invalidate({ foo: 'bar', bar: 'foo' }) + } + > , ); const input = TestUtils.scryRenderedDOMComponentsWithTag(form, 'INPUT')[0]; - const inputComponents = TestUtils.scryRenderedComponentsWithType(form, FormsyTest); + const inputComponents = TestUtils.scryRenderedComponentsWithType( + form, + FormsyTest, + ); form.submit(); - test.equal(inputComponents[0].isValid(), false); - test.equal(inputComponents[1].isValid(), false); + expect(inputComponents[0].isValid()).toEqual(false); + expect(inputComponents[1].isValid()).toEqual(false); TestUtils.Simulate.change(input, { target: { value: 'bar' } }); immediate(() => { - test.equal(inputComponents[0].isValid(), true); - test.equal(inputComponents[1].isValid(), false); - test.done(); + expect(inputComponents[0].isValid()).toEqual(true); + expect(inputComponents[1].isValid()).toEqual(false); }); - }, + }); - 'should let normal validation take over when component with external error is changed': function(test) { + it('should let normal validation take over when component with external error is changed', () => { const form = TestUtils.renderIntoDocument( - invalidate({ foo: 'bar' })}> + invalidate({ foo: 'bar' })} + > , ); const input = TestUtils.findRenderedDOMComponentWithTag(form, 'INPUT'); - const inputComponent = TestUtils.findRenderedComponentWithType(form, FormsyTest); + const inputComponent = TestUtils.findRenderedComponentWithType( + form, + FormsyTest, + ); form.submit(); - test.equal(inputComponent.isValid(), false); + expect(inputComponent.isValid()).toEqual(false); TestUtils.Simulate.change(input, { target: { value: 'bar' } }); immediate(() => { - test.equal(inputComponent.getValue(), 'bar'); - test.equal(inputComponent.isValid(), false); - test.done(); + expect(inputComponent.getValue()).toEqual('bar'); + expect(inputComponent.isValid()).toEqual(false); }); - }, + }); - 'should trigger an onValid handler, if passed, when form is valid': function(test) { + it('should trigger an onValid handler, if passed, when form is valid', () => { const onValid = sinon.spy(); const onInvalid = sinon.spy(); @@ -74,12 +90,11 @@ export default { , ); - test.equal(onValid.called, true); - test.equal(onInvalid.called, false); - test.done(); - }, + expect(onValid.called).toEqual(true); + expect(onInvalid.called).toEqual(false); + }); - 'should trigger an onInvalid handler, if passed, when form is invalid': function(test) { + it('should trigger an onInvalid handler, if passed, when form is invalid', () => { const onValid = sinon.spy(); const onInvalid = sinon.spy(); @@ -89,12 +104,11 @@ export default { , ); - test.equal(onValid.called, false); - test.equal(onInvalid.called, true); - test.done(); - }, + expect(onValid.called).toEqual(false); + expect(onInvalid.called).toEqual(true); + }); - 'should trigger the `onInvalid` handler if a required element receives `null` as the value': function(test) { + it('should trigger the `onInvalid` handler if a required element receives `null` as the value', () => { const onValid = sinon.spy(); const onInvalid = sinon.spy(); @@ -104,12 +118,11 @@ export default { , ); - test.equal(onValid.called, false); - test.equal(onInvalid.called, true); - test.done(); - }, + expect(onValid.called).toEqual(false); + expect(onInvalid.called).toEqual(true); + }); - 'should be able to use provided validate function': function(test) { + it('should be able to use provided validate function', () => { let isValid = false; const CustomInput = InputFactory({ componentDidMount: function() { @@ -123,15 +136,18 @@ export default { ); const input = TestUtils.findRenderedDOMComponentWithTag(form, 'INPUT'); - test.equal(isValid, true); - test.done(); - }, + expect(isValid).toEqual(true); + }); - 'should provide invalidate callback on onValidSubmit': function(test) { + it('should provide invalidate callback on onValidSubmit', () => { class TestForm extends React.Component { render() { return ( - invalidate({ foo: 'bar' })}> + + invalidate({ foo: 'bar' }) + } + > ); @@ -143,15 +159,18 @@ export default { const formEl = TestUtils.findRenderedDOMComponentWithTag(form, 'form'); const input = TestUtils.findRenderedComponentWithType(form, FormsyTest); TestUtils.Simulate.submit(formEl); - test.equal(input.isValid(), false); - test.done(); - }, + expect(input.isValid()).toEqual(false); + }); - 'should provide invalidate callback on onInvalidSubmit': function(test) { + it('should provide invalidate callback on onInvalidSubmit', () => { class TestForm extends React.Component { render() { return ( - invalidate({ foo: 'bar' })}> + + invalidate({ foo: 'bar' }) + } + > ); @@ -162,16 +181,17 @@ export default { const formEl = TestUtils.findRenderedDOMComponentWithTag(form, 'form'); const input = TestUtils.findRenderedComponentWithType(form, FormsyTest); TestUtils.Simulate.submit(formEl); - test.equal(input.getErrorMessage(), 'bar'); - - test.done(); - }, + expect(input.getErrorMessage()).toEqual('bar'); + }); - 'should not invalidate inputs on external errors with preventExternalInvalidation prop': function(test) { + it('should not invalidate inputs on external errors with preventExternalInvalidation prop', () => { class TestForm extends React.Component { render() { return ( - invalidate({ foo: 'bar' })}> + invalidate({ foo: 'bar' })} + > ); @@ -182,15 +202,16 @@ export default { const formEl = TestUtils.findRenderedDOMComponentWithTag(form, 'form'); const input = TestUtils.findRenderedComponentWithType(form, FormsyTest); TestUtils.Simulate.submit(formEl); - test.equal(input.isValid(), true); - test.done(); - }, + expect(input.isValid()).toEqual(true); + }); - 'should invalidate inputs on external errors without preventExternalInvalidation prop': function(test) { + it('should invalidate inputs on external errors without preventExternalInvalidation prop', () => { class TestForm extends React.Component { render() { return ( - invalidate({ foo: 'bar' })}> + invalidate({ foo: 'bar' })} + > ); @@ -201,7 +222,6 @@ export default { const formEl = TestUtils.findRenderedDOMComponentWithTag(form, 'form'); const input = TestUtils.findRenderedComponentWithType(form, FormsyTest); TestUtils.Simulate.submit(formEl); - test.equal(input.isValid(), false); - test.done(); - }, -}; + expect(input.isValid()).toEqual(false); + }); +}); diff --git a/package.json b/package.json index 57502fa7..da6f8d8d 100644 --- a/package.json +++ b/package.json @@ -39,7 +39,7 @@ "format": "prettier --write src/**/* tests/**/* tests/*", "lint": "eslint src/**/*.js", "prepublish": "rm -Rf ./lib && babel ./src/ -d ./lib/", - "test": "babel-node testrunner", + "test": "jest", "version": "npm run build && git add lib && git add release && npm run changelog && git add CHANGELOG.md" }, "dependencies": { @@ -54,6 +54,7 @@ "@babel/preset-env": "^7.4.5", "@babel/preset-react": "^7.0.0", "babel-eslint": "^10.0.2", + "babel-jest": "^24.8.0", "babel-loader": "^8.0.6", "eslint": "^4.14.0", "eslint-config-airbnb": "^16.1.0", @@ -62,6 +63,7 @@ "eslint-plugin-jsx-a11y": "^6.0.3", "eslint-plugin-react": "^7.5.1", "husky": "^2.4.1", + "jest": "^24.8.0", "jsdom": "^11.5.1", "nodeunit": "^0.11.1", "np": "^5.0.2", diff --git a/testrunner.js b/testrunner.js deleted file mode 100644 index bd5be23d..00000000 --- a/testrunner.js +++ /dev/null @@ -1,21 +0,0 @@ -import testrunner from 'nodeunit/lib/reporters/default'; -import { jsdom } from 'jsdom/lib/old-api'; - -global.document = jsdom(); -global.window = global.document.defaultView; -global.navigator = global.window.navigator; - -testrunner.run(['tests'], { - error_prefix: '\u001B[31m', - error_suffix: '\u001B[39m', - ok_prefix: '\u001B[32m', - ok_suffix: '\u001B[39m', - bold_prefix: '\u001B[1m', - bold_suffix: '\u001B[22m', - assertion_prefix: '\u001B[35m', - assertion_suffix: '\u001B[39m', -}, (err) => { - if (err) { - process.exit(1); - } -}); diff --git a/tests/Formsy-spec.js b/tests/Formsy-spec.js deleted file mode 100755 index 2ce84024..00000000 --- a/tests/Formsy-spec.js +++ /dev/null @@ -1,792 +0,0 @@ -import React from 'react'; -import ReactDOM from 'react-dom'; -import TestUtils from 'react-dom/test-utils'; - -import Formsy, { addValidationRule } from './..'; -import TestInput from './utils/TestInput'; -import TestInputHoc from './utils/TestInputHoc'; -import immediate from './utils/immediate'; -import sinon from 'sinon'; - -export default { - 'Setting up a form': { - 'should expose the users DOM node through an innerRef prop': function(test) { - class TestForm extends React.Component { - render() { - return ( - - { - this.name = c; - }} - /> - - ); - } - } - - const form = TestUtils.renderIntoDocument(); - const input = form.name; - test.equal(input.methodOnWrappedInstance('foo'), 'foo'); - - test.done(); - }, - - 'should render a form into the document': function(test) { - const form = TestUtils.renderIntoDocument(); - test.equal(ReactDOM.findDOMNode(form).tagName, 'FORM'); - - test.done(); - }, - - 'should set a class name if passed': function(test) { - const form = TestUtils.renderIntoDocument(); - test.equal(ReactDOM.findDOMNode(form).className, 'foo'); - - test.done(); - }, - - 'should allow for null/undefined children': function(test) { - let model = null; - class TestForm extends React.Component { - render() { - return ( - (model = formModel)}> -

Test

- {null} - {undefined} - -
- ); - } - } - - const form = TestUtils.renderIntoDocument(); - immediate(() => { - TestUtils.Simulate.submit(ReactDOM.findDOMNode(form)); - test.deepEqual(model, { name: 'foo' }); - test.done(); - }); - }, - - 'should allow for inputs being added dynamically': function(test) { - const inputs = []; - let forceUpdate = null; - let model = null; - class TestForm extends React.Component { - componentWillMount() { - forceUpdate = this.forceUpdate.bind(this); - } - render() { - return (model = formModel)}>{inputs}; - } - } - const form = TestUtils.renderIntoDocument(); - - // Wait before adding the input - setTimeout(() => { - inputs.push(); - - forceUpdate(() => { - // Wait for next event loop, as that does the form - immediate(() => { - TestUtils.Simulate.submit(ReactDOM.findDOMNode(form)); - test.ok('test' in model); - test.done(); - }); - }); - }, 10); - }, - - 'should allow dynamically added inputs to update the form-model': function(test) { - const inputs = []; - let forceUpdate = null; - let model = null; - class TestForm extends React.Component { - componentWillMount() { - forceUpdate = this.forceUpdate.bind(this); - } - render() { - return (model = formModel)}>{inputs}; - } - } - const form = TestUtils.renderIntoDocument(); - - // Wait before adding the input - immediate(() => { - inputs.push(); - - forceUpdate(() => { - // Wait for next event loop, as that does the form - immediate(() => { - TestUtils.Simulate.change(TestUtils.findRenderedDOMComponentWithTag(form, 'INPUT'), { - target: { value: 'foo' }, - }); - TestUtils.Simulate.submit(ReactDOM.findDOMNode(form)); - test.equal(model.test, 'foo'); - test.done(); - }); - }); - }); - }, - - 'should allow a dynamically updated input to update the form-model': function(test) { - let forceUpdate = null; - let model = null; - - class TestForm extends React.Component { - componentWillMount() { - forceUpdate = this.forceUpdate.bind(this); - } - render() { - const input = ; - - return (model = formModel)}>{input}; - } - } - let form = TestUtils.renderIntoDocument(); - - // Wait before changing the input - immediate(() => { - form = TestUtils.renderIntoDocument(); - - forceUpdate(() => { - // Wait for next event loop, as that does the form - immediate(() => { - TestUtils.Simulate.submit(ReactDOM.findDOMNode(form)); - test.equal(model.test, 'bar'); - test.done(); - }); - }); - }); - }, - }, - - validations: { - 'should run when the input changes': function(test) { - const runRule = sinon.spy(); - const notRunRule = sinon.spy(); - - addValidationRule('runRule', runRule); - addValidationRule('notRunRule', notRunRule); - - const form = TestUtils.renderIntoDocument( - - - , - ); - - const input = TestUtils.findRenderedDOMComponentWithTag(form, 'input'); - TestUtils.Simulate.change(ReactDOM.findDOMNode(input), { target: { value: 'bar' } }); - test.equal(runRule.calledWith({ one: 'bar' }, 'bar', true), true); - test.equal(notRunRule.called, false); - - test.done(); - }, - - 'should allow the validation to be changed': function(test) { - const ruleA = sinon.spy(); - const ruleB = sinon.spy(); - addValidationRule('ruleA', ruleA); - addValidationRule('ruleB', ruleB); - - class TestForm extends React.Component { - constructor(props) { - super(props); - this.state = { rule: 'ruleA' }; - } - changeRule = () => { - this.setState({ - rule: 'ruleB', - }); - }; - render() { - return ( - - - - ); - } - } - - const form = TestUtils.renderIntoDocument(); - form.changeRule(); - const input = TestUtils.findRenderedDOMComponentWithTag(form, 'input'); - TestUtils.Simulate.change(ReactDOM.findDOMNode(input), { target: { value: 'bar' } }); - test.equal(ruleB.calledWith({ one: 'bar' }, 'bar', true), true); - - test.done(); - }, - - 'should invalidate a form if dynamically inserted input is invalid': function(test) { - const isInValidSpy = sinon.spy(); - - class TestForm extends React.Component { - constructor(props) { - super(props); - this.state = { showSecondInput: false }; - } - addInput = () => { - this.setState({ - showSecondInput: true, - }); - }; - render() { - return ( - - - {this.state.showSecondInput ? : null} - - ); - } - } - - const form = TestUtils.renderIntoDocument(); - - test.equal(form.refs.formsy.state.isValid, true); - form.addInput(); - - immediate(() => { - test.equal(isInValidSpy.called, true); - test.done(); - }); - }, - - 'should validate a form when removing an invalid input': function(test) { - const isValidSpy = sinon.spy(); - - class TestForm extends React.Component { - constructor(props) { - super(props); - this.state = { showSecondInput: true }; - } - removeInput() { - this.setState({ - showSecondInput: false, - }); - } - render() { - return ( - - - {this.state.showSecondInput ? : null} - - ); - } - } - - const form = TestUtils.renderIntoDocument(); - - test.equal(form.refs.formsy.state.isValid, false); - form.removeInput(); - - immediate(() => { - test.equal(isValidSpy.called, true); - test.done(); - }); - }, - - 'runs multiple validations': function(test) { - const ruleA = sinon.spy(); - const ruleB = sinon.spy(); - addValidationRule('ruleA', ruleA); - addValidationRule('ruleB', ruleB); - - const form = TestUtils.renderIntoDocument( - - - , - ); - - const input = TestUtils.findRenderedDOMComponentWithTag(form, 'input'); - TestUtils.Simulate.change(ReactDOM.findDOMNode(input), { target: { value: 'bar' } }); - test.equal(ruleA.calledWith({ one: 'bar' }, 'bar', true), true); - test.equal(ruleB.calledWith({ one: 'bar' }, 'bar', true), true); - test.done(); - }, - }, - - 'should not trigger onChange when form is mounted': function(test) { - const hasChanged = sinon.spy(); - class TestForm extends React.Component { - render() { - return ; - } - } - TestUtils.renderIntoDocument(); - test.equal(hasChanged.called, false); - test.done(); - }, - - 'should trigger onChange once when form element is changed': function(test) { - const hasChanged = sinon.spy(); - const form = TestUtils.renderIntoDocument( - - - , - ); - TestUtils.Simulate.change(TestUtils.findRenderedDOMComponentWithTag(form, 'INPUT'), { target: { value: 'bar' } }); - test.equal(hasChanged.calledOnce, true); - test.done(); - }, - - 'should trigger onChange once when new input is added to form': function(test) { - const hasChanged = sinon.spy(); - class TestForm extends React.Component { - state = { - showInput: false, - }; - addInput() { - this.setState({ - showInput: true, - }); - } - render() { - return {this.state.showInput ? : null}; - } - } - - const form = TestUtils.renderIntoDocument(); - form.addInput(); - immediate(() => { - test.equal(hasChanged.calledOnce, true); - test.done(); - }); - }, - - 'onChange should honor dot notation transformations': function(test) { - const hasChanged = sinon.spy(); - class TestForm extends React.Component { - state = { - showInput: false, - }; - addInput() { - this.setState({ - showInput: true, - }); - } - render() { - return ( - - {this.state.showInput ? : null} - - ); - } - } - - const form = TestUtils.renderIntoDocument(); - form.addInput(); - immediate(() => { - test.deepEqual(hasChanged.args[0][0], { parent: { child: 'test' } }); - test.done(); - }); - }, - - 'Update a form': { - 'should allow elements to check if the form is disabled': function(test) { - class TestForm extends React.Component { - state = { disabled: true }; - enableForm() { - this.setState({ disabled: false }); - } - render() { - return ( - - - - ); - } - } - - const form = TestUtils.renderIntoDocument(); - const input = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(input.isFormDisabled(), true); - - form.enableForm(); - immediate(() => { - test.equal(input.isFormDisabled(), false); - test.done(); - }); - }, - - 'should be possible to pass error state of elements by changing an errors attribute': function(test) { - class TestForm extends React.Component { - state = { validationErrors: { foo: 'bar' } }; - onChange = values => { - this.setState(values.foo ? { validationErrors: {} } : { validationErrors: { foo: 'bar' } }); - }; - render() { - return ( - - - - ); - } - } - const form = TestUtils.renderIntoDocument(); - - // Wait for update - immediate(() => { - const input = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(input.getErrorMessage(), 'bar'); - input.setValue('gotValue'); - - // Wait for update - immediate(() => { - test.equal(input.getErrorMessage(), null); - test.done(); - }); - }); - }, - - 'should trigger an onValidSubmit when submitting a valid form': function(test) { - let isCalled = sinon.spy(); - class TestForm extends React.Component { - render() { - return ( - - - - ); - } - } - const form = TestUtils.renderIntoDocument(); - const FoundForm = TestUtils.findRenderedComponentWithType(form, TestForm); - TestUtils.Simulate.submit(ReactDOM.findDOMNode(FoundForm)); - test.equal(isCalled.called, true); - test.done(); - }, - - 'should trigger an onInvalidSubmit when submitting an invalid form': function(test) { - let isCalled = sinon.spy(); - class TestForm extends React.Component { - render() { - return ( - - - - ); - } - } - const form = TestUtils.renderIntoDocument(); - - const FoundForm = TestUtils.findRenderedComponentWithType(form, TestForm); - TestUtils.Simulate.submit(ReactDOM.findDOMNode(FoundForm)); - test.equal(isCalled.called, true); - - test.done(); - }, - }, - - 'value === false': { - 'should call onSubmit correctly': function(test) { - const onSubmit = sinon.spy(); - class TestForm extends React.Component { - render() { - return ( - - - - - ); - } - } - - const form = TestUtils.renderIntoDocument(); - TestUtils.Simulate.submit(ReactDOM.findDOMNode(form)); - test.equal(onSubmit.calledWith({ foo: false }), true); - test.done(); - }, - - 'should allow dynamic changes to false': function(test) { - const onSubmit = sinon.spy(); - class TestForm extends React.Component { - state = { - value: true, - }; - changeValue() { - this.setState({ - value: false, - }); - } - render() { - return ( - - - - - ); - } - } - - const form = TestUtils.renderIntoDocument(); - form.changeValue(); - TestUtils.Simulate.submit(ReactDOM.findDOMNode(form)); - test.equal(onSubmit.calledWith({ foo: false }), true); - test.done(); - }, - - 'should say the form is submitted': function(test) { - class TestForm extends React.Component { - render() { - return ( - - - - - ); - } - } - const form = TestUtils.renderIntoDocument(); - const input = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(input.isFormSubmitted(), false); - TestUtils.Simulate.submit(ReactDOM.findDOMNode(form)); - test.equal(input.isFormSubmitted(), true); - test.done(); - }, - - 'should be able to reset the form to its pristine state': function(test) { - class TestForm extends React.Component { - state = { - value: true, - }; - changeValue() { - this.setState({ - value: false, - }); - } - render() { - return ( - - - - - ); - } - } - const form = TestUtils.renderIntoDocument(); - const input = TestUtils.findRenderedComponentWithType(form, TestInput); - const formsyForm = TestUtils.findRenderedComponentWithType(form, Formsy); - test.equal(input.getValue(), true); - form.changeValue(); - test.equal(input.getValue(), false); - formsyForm.reset(); - test.equal(input.getValue(), true); - - test.done(); - }, - - 'should be able to reset the form using custom data': function(test) { - class TestForm extends React.Component { - state = { - value: true, - }; - changeValue() { - this.setState({ - value: false, - }); - } - render() { - return ( - - - - - ); - } - } - const form = TestUtils.renderIntoDocument(); - const input = TestUtils.findRenderedComponentWithType(form, TestInput); - const formsyForm = TestUtils.findRenderedComponentWithType(form, Formsy); - - test.equal(input.getValue(), true); - form.changeValue(); - test.equal(input.getValue(), false); - formsyForm.reset({ - foo: 'bar', - }); - test.equal(input.getValue(), 'bar'); - test.done(); - }, - }, - - 'should be able to reset the form to empty values': function(test) { - class TestForm extends React.Component { - render() { - return ( - - - - - ); - } - } - const form = TestUtils.renderIntoDocument(); - const input = TestUtils.findRenderedComponentWithType(form, TestInput); - const formsyForm = TestUtils.findRenderedComponentWithType(form, Formsy); - - formsyForm.reset({ - foo: '', - }); - test.equal(input.getValue(), ''); - test.done(); - }, - - '.isChanged()': { - 'initially returns false': function(test) { - const hasOnChanged = sinon.spy(); - const form = TestUtils.renderIntoDocument( - - - , - ); - test.equal(form.isChanged(), false); - test.equal(hasOnChanged.called, false); - test.done(); - }, - - 'returns true when changed': function(test) { - const hasOnChanged = sinon.spy(); - const form = TestUtils.renderIntoDocument( - - - , - ); - const input = TestUtils.findRenderedDOMComponentWithTag(form, 'input'); - TestUtils.Simulate.change(ReactDOM.findDOMNode(input), { target: { value: 'bar' } }); - test.equal(form.isChanged(), true); - test.equal(hasOnChanged.calledWith({ one: 'bar' }), true); - test.done(); - }, - - 'returns false if changes are undone': function(test) { - const hasOnChanged = sinon.spy(); - const form = TestUtils.renderIntoDocument( - - - , - ); - const input = TestUtils.findRenderedDOMComponentWithTag(form, 'input'); - TestUtils.Simulate.change(ReactDOM.findDOMNode(input), { target: { value: 'bar' } }); - test.equal(hasOnChanged.calledWith({ one: 'bar' }, true), true); - - TestUtils.Simulate.change(ReactDOM.findDOMNode(input), { target: { value: 'foo' } }); - test.equal(form.isChanged(), false); - test.equal(hasOnChanged.calledWith({ one: 'foo' }, false), true); - test.done(); - }, - }, - - 'form valid state': { - 'should allow to be changed with updateInputsWithError': function(test) { - class TestForm extends React.Component { - state = { isValid: true }; - onValidSubmit = (model, reset, updateInputsWithError) => { - updateInputsWithError({ foo: 'bar' }, true); - }; - onValid = () => { - this.setState({ isValid: true }); - }; - onInvalid = () => { - this.setState({ isValid: false }); - }; - render() { - return ( - - - - ); - } - } - const form = TestUtils.renderIntoDocument(); - - // Wait for update - immediate(() => { - test.equal(form.state.isValid, true); - TestUtils.Simulate.submit(ReactDOM.findDOMNode(form)); - - // Wait for update - immediate(() => { - test.equal(form.state.isValid, false); - test.done(); - }); - }); - }, - - 'should be false when validationErrors is not empty': function(test) { - class TestForm extends React.Component { - state = { validationErrors: {}, isValid: true }; - setValidationErrors = empty => { - this.setState(!empty ? { validationErrors: { foo: 'bar' } } : { validationErrors: {} }); - }; - onValid = () => { - this.setState({ isValid: true }); - }; - onInvalid = () => { - this.setState({ isValid: false }); - }; - render() { - return ( - - - - ); - } - } - const form = TestUtils.renderIntoDocument(); - - // Wait for update - immediate(() => { - test.equal(form.state.isValid, true); - form.setValidationErrors(); - - // Wait for update - immediate(() => { - test.equal(form.state.isValid, false); - test.done(); - }); - }); - }, - }, - - 'should be true when validationErrors is not empty and preventExternalInvalidation is true': function(test) { - class TestForm extends React.Component { - state = { validationErrors: {}, isValid: true }; - setValidationErrors = empty => { - this.setState(!empty ? { validationErrors: { foo: 'bar' } } : { validationErrors: {} }); - }; - onValid = () => { - this.setState({ isValid: true }); - }; - onInvalid = () => { - this.setState({ isValid: false }); - }; - render() { - return ( - - - - ); - } - } - const form = TestUtils.renderIntoDocument(); - - // Wait for update - immediate(() => { - test.equal(form.state.isValid, true); - form.setValidationErrors(); - - // Wait for update - immediate(() => { - test.equal(form.state.isValid, true); - test.done(); - }); - }); - }, -}; diff --git a/tests/Rules-equals-spec.js b/tests/Rules-equals-spec.js deleted file mode 100644 index 148232ca..00000000 --- a/tests/Rules-equals-spec.js +++ /dev/null @@ -1,66 +0,0 @@ -import React from 'react'; -import TestUtils from 'react-dom/test-utils'; -import immediate from './utils/immediate'; - -import Formsy from './..'; -import { InputFactory } from './utils/TestInput'; - -const TestInput = InputFactory({ - render: function() { - return ; - }, -}); - -class TestForm extends React.Component { - render() { - return ( - - - - ); - } -} - -export default { - 'should pass when the value is equal': function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), true); - test.done(); - }, - - 'should fail when the value is not equal': function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), false); - test.done(); - }, - - 'should pass with an empty string': function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), true); - test.done(); - }, - - 'should pass with an undefined': function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), true); - test.done(); - }, - - 'should pass with a null': function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), true); - test.done(); - }, - - 'should fail with a number': function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), false); - test.done(); - }, -}; diff --git a/tests/Rules-isAlpha-spec.js b/tests/Rules-isAlpha-spec.js deleted file mode 100644 index d51f36a5..00000000 --- a/tests/Rules-isAlpha-spec.js +++ /dev/null @@ -1,72 +0,0 @@ -import React from 'react'; -import TestUtils from 'react-dom/test-utils'; - -import Formsy from './..'; -import { InputFactory } from './utils/TestInput'; - -const TestInput = InputFactory({ - render: function() { - return ; - }, -}); - -class TestForm extends React.Component { - render() { - return ( - - - - ); - } -} - -export default { - 'should pass with a default value': function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), true); - test.done(); - }, - - 'should pass with a string is only latin letters': function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), true); - test.done(); - }, - - 'should fail with a string with numbers': function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), false); - test.done(); - }, - - 'should pass with an undefined': function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), true); - test.done(); - }, - - 'should pass with a null': function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), true); - test.done(); - }, - - 'should pass with an empty string': function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), true); - test.done(); - }, - - 'should fail with a number': function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), false); - test.done(); - }, -}; diff --git a/tests/Rules-isAlphanumeric-spec.js b/tests/Rules-isAlphanumeric-spec.js deleted file mode 100644 index d4ca996f..00000000 --- a/tests/Rules-isAlphanumeric-spec.js +++ /dev/null @@ -1,80 +0,0 @@ -import React from 'react'; -import TestUtils from 'react-dom/test-utils'; - -import Formsy from './..'; -import { InputFactory } from './utils/TestInput'; - -const TestInput = InputFactory({ - render() { - return ; - }, -}); - -class TestForm extends React.Component { - render() { - return ( - - - - ); - } -} - -export default { - 'should pass with a default value': function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), true); - test.done(); - }, - - 'should pass with a string is only latin letters': function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), true); - test.done(); - }, - - 'should fail with a string with numbers': function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), true); - test.done(); - }, - - 'should pass with an undefined': function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), true); - test.done(); - }, - - 'should pass with a null': function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), true); - test.done(); - }, - - 'should pass with an empty string': function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), true); - test.done(); - }, - - 'should pass with a number': function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), true); - test.done(); - }, - - 'should fail with a non alpha and number symbols': function(test) { - const value = '!@#$%^&*()'; - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), false); - test.done(); - }, -}; diff --git a/tests/Rules-isEmail-spec.js b/tests/Rules-isEmail-spec.js deleted file mode 100644 index 8665d3b4..00000000 --- a/tests/Rules-isEmail-spec.js +++ /dev/null @@ -1,79 +0,0 @@ -import React from 'react'; -import TestUtils from 'react-dom/test-utils'; - -import Formsy from './..'; -import { InputFactory } from './utils/TestInput'; - -const TestInput = InputFactory({ - render() { - return ; - }, -}); - -class TestForm extends React.Component { - render() { - return ( - - - - ); - } -} - -export default { - 'should pass with a default value': function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), true); - test.done(); - }, - - 'should fail with "foo"': function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), false); - test.done(); - }, - - 'should pass with "foo@foo.com"': function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), true); - test.done(); - }, - - 'should pass with new long domains': function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), true); - test.done(); - }, - - 'should pass with an undefined': function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), true); - test.done(); - }, - - 'should pass with a null': function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), true); - test.done(); - }, - - 'should pass with an empty string': function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), true); - test.done(); - }, - - 'should fail with a number': function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), false); - test.done(); - }, -}; diff --git a/tests/Rules-isEmptyString-spec.js b/tests/Rules-isEmptyString-spec.js deleted file mode 100644 index 706eb13e..00000000 --- a/tests/Rules-isEmptyString-spec.js +++ /dev/null @@ -1,72 +0,0 @@ -import React from 'react'; -import TestUtils from 'react-dom/test-utils'; - -import Formsy from './..'; -import { InputFactory } from './utils/TestInput'; - -const TestInput = InputFactory({ - render() { - return ; - }, -}); - -class TestForm extends React.Component { - render() { - return ( - - - - ); - } -} - -export default { - 'should pass with a default value': function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), false); - test.done(); - }, - - 'should fail with non-empty string': function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), false); - test.done(); - }, - - 'should pass with an empty string': function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), true); - test.done(); - }, - - 'should fail with undefined': function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), false); - test.done(); - }, - - 'should fail with null': function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), false); - test.done(); - }, - - 'should fail with a number': function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), false); - test.done(); - }, - - 'should fail with a zero': function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), false); - test.done(); - }, -}; diff --git a/tests/Rules-isExisty-spec.js b/tests/Rules-isExisty-spec.js deleted file mode 100644 index 65653b45..00000000 --- a/tests/Rules-isExisty-spec.js +++ /dev/null @@ -1,72 +0,0 @@ -import React from 'react'; -import TestUtils from 'react-dom/test-utils'; - -import Formsy from './..'; -import { InputFactory } from './utils/TestInput'; - -const TestInput = InputFactory({ - render() { - return ; - }, -}); - -class TestForm extends React.Component { - render() { - return ( - - - - ); - } -} - -export default { - 'should pass with a default value': function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), false); - test.done(); - }, - - 'should pass with a string': function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), true); - test.done(); - }, - - 'should pass with an empty string': function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), true); - test.done(); - }, - - 'should fail with undefined': function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), false); - test.done(); - }, - - 'should fail with null': function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), false); - test.done(); - }, - - 'should pass with a number': function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), true); - test.done(); - }, - - 'should pass with a zero': function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), true); - test.done(); - }, -}; diff --git a/tests/Rules-isFloat-spec.js b/tests/Rules-isFloat-spec.js deleted file mode 100644 index 71ca530f..00000000 --- a/tests/Rules-isFloat-spec.js +++ /dev/null @@ -1,100 +0,0 @@ -import React from 'react'; -import TestUtils from 'react-dom/test-utils'; - -import Formsy from './..'; -import { InputFactory } from './utils/TestInput'; - -const TestInput = InputFactory({ - render() { - return ; - }, -}); - -class TestForm extends React.Component { - render() { - return ( - - - - ); - } -} - -export default { - 'should pass with a default value': function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), true); - test.done(); - }, - - 'should pass with an empty string': function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), true); - test.done(); - }, - - 'should fail with a string': function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), false); - test.done(); - }, - - 'should pass with a number as string': function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), true); - test.done(); - }, - - 'should fail string with digits': function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), false); - test.done(); - }, - - 'should pass with an int': function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), true); - test.done(); - }, - - 'should pass with a float': function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), true); - test.done(); - }, - - 'should pass with a float in science notation': function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), true); - test.done(); - }, - - 'should pass with undefined': function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), true); - test.done(); - }, - - 'should pass with null': function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), true); - test.done(); - }, - - 'should pass with a zero': function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), true); - test.done(); - }, -}; diff --git a/tests/Rules-isInt-spec.js b/tests/Rules-isInt-spec.js deleted file mode 100644 index f54c6bdc..00000000 --- a/tests/Rules-isInt-spec.js +++ /dev/null @@ -1,100 +0,0 @@ -import React from 'react'; -import TestUtils from 'react-dom/test-utils'; - -import Formsy from './..'; -import { InputFactory } from './utils/TestInput'; - -const TestInput = InputFactory({ - render() { - return ; - }, -}); - -class TestForm extends React.Component { - render() { - return ( - - - - ); - } -} - -export default { - 'should pass with a default value': function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), true); - test.done(); - }, - - 'should pass with an empty string': function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), true); - test.done(); - }, - - 'should fail with a string': function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), false); - test.done(); - }, - - 'should pass with a number as string': function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), true); - test.done(); - }, - - 'should fail string with digits': function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), false); - test.done(); - }, - - 'should pass with an int': function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), true); - test.done(); - }, - - 'should fail with a float': function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), false); - test.done(); - }, - - 'should fail with a float in science notation': function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), false); - test.done(); - }, - - 'should pass with undefined': function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), true); - test.done(); - }, - - 'should pass with null': function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), true); - test.done(); - }, - - 'should pass with a zero': function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), true); - test.done(); - }, -}; diff --git a/tests/Rules-isLength-spec.js b/tests/Rules-isLength-spec.js deleted file mode 100644 index 27e1bc03..00000000 --- a/tests/Rules-isLength-spec.js +++ /dev/null @@ -1,139 +0,0 @@ -import React from 'react'; -import TestUtils from 'react-dom/test-utils'; - -import Formsy from './..'; -import { InputFactory } from './utils/TestInput'; - -const TestInput = InputFactory({ - render() { - return ; - }, -}); - -class TestForm extends React.Component { - render() { - return ( - - - - ); - } -} - -export default { - 'isLength:3': { - 'should pass with a default value': function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), true); - test.done(); - }, - - 'should fail with a string too small': function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), false); - test.done(); - }, - - 'should fail with a string too long': function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), false); - test.done(); - }, - - 'should pass with matching length': function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), true); - test.done(); - }, - - 'should pass with undefined': function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), true); - test.done(); - }, - - 'should pass with null': function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), true); - test.done(); - }, - - 'should pass with empty string': function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), true); - test.done(); - }, - - 'should fail with a number': function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), false); - test.done(); - }, - }, - - 'isLength:0': { - 'should pass with a default value': function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), true); - test.done(); - }, - - 'should fail with a string too small': function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), false); - test.done(); - }, - - 'should fail with a string too long': function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), false); - test.done(); - }, - - 'should pass with matching length': function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), true); - test.done(); - }, - - 'should pass with undefined': function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), true); - test.done(); - }, - - 'should pass with null': function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), true); - test.done(); - }, - - 'should pass with empty string': function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), true); - test.done(); - }, - - 'should fail with a number': function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), false); - test.done(); - }, - }, -}; diff --git a/tests/Rules-isNumeric-spec.js b/tests/Rules-isNumeric-spec.js deleted file mode 100644 index 4e376e92..00000000 --- a/tests/Rules-isNumeric-spec.js +++ /dev/null @@ -1,100 +0,0 @@ -import React from 'react'; -import TestUtils from 'react-dom/test-utils'; - -import Formsy from './..'; -import { InputFactory } from './utils/TestInput'; - -const TestInput = InputFactory({ - render() { - return ; - }, -}); - -class TestForm extends React.Component { - render() { - return ( - - - - ); - } -} - -export default { - 'should pass with a default value': function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), true); - test.done(); - }, - - 'should pass with an empty string': function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), true); - test.done(); - }, - - 'should fail with an unempty string': function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), false); - test.done(); - }, - - 'should pass with a number as string': function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), true); - test.done(); - }, - - 'should fail with a number as string with not digits': function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), false); - test.done(); - }, - - 'should pass with an int': function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), true); - test.done(); - }, - - 'should pass with a float': function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), true); - test.done(); - }, - - 'should fail with a float in science notation': function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), false); - test.done(); - }, - - 'should pass with an undefined': function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), true); - test.done(); - }, - - 'should pass with a null': function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), true); - test.done(); - }, - - 'should pass with a zero': function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), true); - test.done(); - }, -}; diff --git a/tests/Rules-isUrl-spec.js b/tests/Rules-isUrl-spec.js deleted file mode 100644 index afc28bee..00000000 --- a/tests/Rules-isUrl-spec.js +++ /dev/null @@ -1,72 +0,0 @@ -import React from 'react'; -import TestUtils from 'react-dom/test-utils'; - -import Formsy from './..'; -import { InputFactory } from './utils/TestInput'; - -const TestInput = InputFactory({ - render() { - return ; - }, -}); - -class TestForm extends React.Component { - render() { - return ( - - - - ); - } -} - -export default { - 'should pass with default value': function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), true); - test.done(); - }, - - 'should fail with "foo"': function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), false); - test.done(); - }, - - 'should pass with "https://www.google.com/"': function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), true); - test.done(); - }, - - 'should pass with an undefined': function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), true); - test.done(); - }, - - 'should pass with a null': function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), true); - test.done(); - }, - - 'should fail with a number': function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), false); - test.done(); - }, - - 'should pass with an empty string': function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), true); - test.done(); - }, -}; diff --git a/tests/Rules-isWords-spec.js b/tests/Rules-isWords-spec.js deleted file mode 100644 index 63439cba..00000000 --- a/tests/Rules-isWords-spec.js +++ /dev/null @@ -1,72 +0,0 @@ -import React from 'react'; -import TestUtils from 'react-dom/test-utils'; - -import Formsy from './..'; -import { InputFactory } from './utils/TestInput'; - -const TestInput = InputFactory({ - render() { - return ; - }, -}); - -class TestForm extends React.Component { - render() { - return ( - - - - ); - } -} - -export default { - 'should pass with a default value': function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), true); - test.done(); - }, - - 'should pass with a 1 word': function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), true); - test.done(); - }, - - 'should pass with 2 words': function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), true); - test.done(); - }, - - 'should fail with a string with numbers': function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), false); - test.done(); - }, - - 'should pass with an undefined': function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), true); - test.done(); - }, - - 'should pass with a null': function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), true); - test.done(); - }, - - 'should fail with a number': function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), false); - test.done(); - }, -}; diff --git a/tests/Rules-maxLength-spec.js b/tests/Rules-maxLength-spec.js deleted file mode 100644 index 181817c0..00000000 --- a/tests/Rules-maxLength-spec.js +++ /dev/null @@ -1,79 +0,0 @@ -import React from 'react'; -import TestUtils from 'react-dom/test-utils'; - -import Formsy from './..'; -import { InputFactory } from './utils/TestInput'; - -const TestInput = InputFactory({ - render() { - return ; - }, -}); - -class TestForm extends React.Component { - render() { - return ( - - - - ); - } -} - -export default { - 'should pass with a default value': function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), true); - test.done(); - }, - - "should pass when a string's length is smaller": function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), true); - test.done(); - }, - - "should pass when a string's length is equal": function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), true); - test.done(); - }, - - "should fail when a string's length is bigger": function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), false); - test.done(); - }, - - 'should pass with empty string': function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), true); - test.done(); - }, - - 'should pass with an undefined': function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), true); - test.done(); - }, - - 'should pass with a null': function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), true); - test.done(); - }, - - 'should fail with a number': function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), false); - test.done(); - }, -}; diff --git a/tests/Rules-minLength-spec.js b/tests/Rules-minLength-spec.js deleted file mode 100644 index f0d9ba95..00000000 --- a/tests/Rules-minLength-spec.js +++ /dev/null @@ -1,118 +0,0 @@ -import React from 'react'; -import TestUtils from 'react-dom/test-utils'; - -import Formsy from './..'; -import { InputFactory } from './utils/TestInput'; - -const TestInput = InputFactory({ - render() { - return ; - }, -}); - -class TestForm extends React.Component { - render() { - return ( - - - - ); - } -} - -export default { - 'minLength:3': { - 'should pass with a default value': function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), true); - test.done(); - }, - - "should pass when a string's length is bigger": function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), true); - test.done(); - }, - - "should fail when a string's length is smaller": function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), false); - test.done(); - }, - - 'should pass with empty string': function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), true); - test.done(); - }, - - 'should pass with an undefined': function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), true); - test.done(); - }, - - 'should pass with a null': function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), true); - test.done(); - }, - - 'should fail with a number': function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), false); - test.done(); - }, - }, - - 'minLength:0': { - 'should pass with a default value': function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), true); - test.done(); - }, - - "should pass when a string's length is bigger": function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), true); - test.done(); - }, - - 'should pass with empty string': function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), true); - test.done(); - }, - - 'should pass with an undefined': function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), true); - test.done(); - }, - - 'should pass with a null': function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), true); - test.done(); - }, - - 'should fail with a number': function(test) { - const form = TestUtils.renderIntoDocument(); - const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); - test.equal(inputComponent.isValid(), false); - test.done(); - }, - }, -}; diff --git a/tests/Utils-spec.js b/tests/Utils-spec.js deleted file mode 100644 index ca5c625d..00000000 --- a/tests/Utils-spec.js +++ /dev/null @@ -1,33 +0,0 @@ -import utils from './../src/utils.js'; - -export default { - 'should check equality of objects and arrays': function(test) { - const objA = { foo: 'bar' }; - const objB = { foo: 'bar' }; - const objC = [{ foo: ['bar'] }]; - const objD = [{ foo: ['bar'] }]; - const objE = undefined; - const objF = undefined; - const objG = null; - const objH = null; - - test.equal(utils.isSame(objA, objB), true); - test.equal(utils.isSame(objC, objD), true); - test.equal(utils.isSame(objA, objD), false); - - test.equal(utils.isSame(objE, objF), true); - test.equal(utils.isSame(objA, objF), false); - test.equal(utils.isSame(objE, objA), false); - - test.equal(utils.isSame(objG, objH), true); - test.equal(utils.isSame(objA, objH), false); - test.equal(utils.isSame(objC, objH), false); - test.equal(utils.isSame(objG, objA), false); - - test.equal(utils.isSame(() => {}, () => {}), true); - test.equal(utils.isSame(objA, () => {}), false); - test.equal(utils.isSame(() => {}, objA), false); - - test.done(); - }, -}; diff --git a/yarn.lock b/yarn.lock index 9df0d5e5..c533e61f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -26,7 +26,7 @@ dependencies: "@babel/highlight" "^7.0.0" -"@babel/core@^7.4.5": +"@babel/core@^7.1.0", "@babel/core@^7.4.5": version "7.4.5" resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.4.5.tgz#081f97e8ffca65a9b4b0fdc7e274e703f000c06a" integrity sha512-OvjIh6aqXtlsA8ujtGKfC7LYWksYSX8yQcM8Ay3LuvVeQ63lcOKgoZWVqcpFwkd29aYU9rVx7jxhfhiEDV9MZA== @@ -262,7 +262,7 @@ node-environment-flags "^1.0.5" v8flags "^3.1.1" -"@babel/parser@^7.0.0", "@babel/parser@^7.4.3", "@babel/parser@^7.4.4", "@babel/parser@^7.4.5": +"@babel/parser@^7.0.0", "@babel/parser@^7.1.0", "@babel/parser@^7.4.3", "@babel/parser@^7.4.4", "@babel/parser@^7.4.5": version "7.4.5" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.4.5.tgz#04af8d5d5a2b044a2a1bffacc1e5e6673544e872" integrity sha512-9mUqkL1FF5T7f0WDFfAoDdiMVPWsdD1gZYzSnaXsxUCUqzuch/8of9G3VUSNiZmMBoRxT3neyVsqeiL/ZPcjew== @@ -338,7 +338,7 @@ dependencies: "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-syntax-object-rest-spread@^7.2.0": +"@babel/plugin-syntax-object-rest-spread@^7.0.0", "@babel/plugin-syntax-object-rest-spread@^7.2.0": version "7.2.0" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.2.0.tgz#3b7a3e733510c57e820b9142a6579ac8b0dfad2e" integrity sha512-t0JKGgqk2We+9may3t0xDdmneaXmyxq0xieYcKHxIsrJO64n1OiMWNUtc5gQK1PA0NpdCRrtZp4z+IUaKugrSA== @@ -745,6 +745,160 @@ lodash "^4.17.11" to-fast-properties "^2.0.0" +"@cnakazawa/watch@^1.0.3": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@cnakazawa/watch/-/watch-1.0.3.tgz#099139eaec7ebf07a27c1786a3ff64f39464d2ef" + integrity sha512-r5160ogAvGyHsal38Kux7YYtodEKOj89RGb28ht1jh3SJb08VwRwAKKJL0bGb04Zd/3r9FL3BFIc3bBidYffCA== + dependencies: + exec-sh "^0.3.2" + minimist "^1.2.0" + +"@jest/console@^24.7.1": + version "24.7.1" + resolved "https://registry.yarnpkg.com/@jest/console/-/console-24.7.1.tgz#32a9e42535a97aedfe037e725bd67e954b459545" + integrity sha512-iNhtIy2M8bXlAOULWVTUxmnelTLFneTNEkHCgPmgd+zNwy9zVddJ6oS5rZ9iwoscNdT5mMwUd0C51v/fSlzItg== + dependencies: + "@jest/source-map" "^24.3.0" + chalk "^2.0.1" + slash "^2.0.0" + +"@jest/core@^24.8.0": + version "24.8.0" + resolved "https://registry.yarnpkg.com/@jest/core/-/core-24.8.0.tgz#fbbdcd42a41d0d39cddbc9f520c8bab0c33eed5b" + integrity sha512-R9rhAJwCBQzaRnrRgAdVfnglUuATXdwTRsYqs6NMdVcAl5euG8LtWDe+fVkN27YfKVBW61IojVsXKaOmSnqd/A== + dependencies: + "@jest/console" "^24.7.1" + "@jest/reporters" "^24.8.0" + "@jest/test-result" "^24.8.0" + "@jest/transform" "^24.8.0" + "@jest/types" "^24.8.0" + ansi-escapes "^3.0.0" + chalk "^2.0.1" + exit "^0.1.2" + graceful-fs "^4.1.15" + jest-changed-files "^24.8.0" + jest-config "^24.8.0" + jest-haste-map "^24.8.0" + jest-message-util "^24.8.0" + jest-regex-util "^24.3.0" + jest-resolve-dependencies "^24.8.0" + jest-runner "^24.8.0" + jest-runtime "^24.8.0" + jest-snapshot "^24.8.0" + jest-util "^24.8.0" + jest-validate "^24.8.0" + jest-watcher "^24.8.0" + micromatch "^3.1.10" + p-each-series "^1.0.0" + pirates "^4.0.1" + realpath-native "^1.1.0" + rimraf "^2.5.4" + strip-ansi "^5.0.0" + +"@jest/environment@^24.8.0": + version "24.8.0" + resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-24.8.0.tgz#0342261383c776bdd652168f68065ef144af0eac" + integrity sha512-vlGt2HLg7qM+vtBrSkjDxk9K0YtRBi7HfRFaDxoRtyi+DyVChzhF20duvpdAnKVBV6W5tym8jm0U9EfXbDk1tw== + dependencies: + "@jest/fake-timers" "^24.8.0" + "@jest/transform" "^24.8.0" + "@jest/types" "^24.8.0" + jest-mock "^24.8.0" + +"@jest/fake-timers@^24.8.0": + version "24.8.0" + resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-24.8.0.tgz#2e5b80a4f78f284bcb4bd5714b8e10dd36a8d3d1" + integrity sha512-2M4d5MufVXwi6VzZhJ9f5S/wU4ud2ck0kxPof1Iz3zWx6Y+V2eJrES9jEktB6O3o/oEyk+il/uNu9PvASjWXQw== + dependencies: + "@jest/types" "^24.8.0" + jest-message-util "^24.8.0" + jest-mock "^24.8.0" + +"@jest/reporters@^24.8.0": + version "24.8.0" + resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-24.8.0.tgz#075169cd029bddec54b8f2c0fc489fd0b9e05729" + integrity sha512-eZ9TyUYpyIIXfYCrw0UHUWUvE35vx5I92HGMgS93Pv7du+GHIzl+/vh8Qj9MCWFK/4TqyttVBPakWMOfZRIfxw== + dependencies: + "@jest/environment" "^24.8.0" + "@jest/test-result" "^24.8.0" + "@jest/transform" "^24.8.0" + "@jest/types" "^24.8.0" + chalk "^2.0.1" + exit "^0.1.2" + glob "^7.1.2" + istanbul-lib-coverage "^2.0.2" + istanbul-lib-instrument "^3.0.1" + istanbul-lib-report "^2.0.4" + istanbul-lib-source-maps "^3.0.1" + istanbul-reports "^2.1.1" + jest-haste-map "^24.8.0" + jest-resolve "^24.8.0" + jest-runtime "^24.8.0" + jest-util "^24.8.0" + jest-worker "^24.6.0" + node-notifier "^5.2.1" + slash "^2.0.0" + source-map "^0.6.0" + string-length "^2.0.0" + +"@jest/source-map@^24.3.0": + version "24.3.0" + resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-24.3.0.tgz#563be3aa4d224caf65ff77edc95cd1ca4da67f28" + integrity sha512-zALZt1t2ou8le/crCeeiRYzvdnTzaIlpOWaet45lNSqNJUnXbppUUFR4ZUAlzgDmKee4Q5P/tKXypI1RiHwgag== + dependencies: + callsites "^3.0.0" + graceful-fs "^4.1.15" + source-map "^0.6.0" + +"@jest/test-result@^24.8.0": + version "24.8.0" + resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-24.8.0.tgz#7675d0aaf9d2484caa65e048d9b467d160f8e9d3" + integrity sha512-+YdLlxwizlfqkFDh7Mc7ONPQAhA4YylU1s529vVM1rsf67vGZH/2GGm5uO8QzPeVyaVMobCQ7FTxl38QrKRlng== + dependencies: + "@jest/console" "^24.7.1" + "@jest/types" "^24.8.0" + "@types/istanbul-lib-coverage" "^2.0.0" + +"@jest/test-sequencer@^24.8.0": + version "24.8.0" + resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-24.8.0.tgz#2f993bcf6ef5eb4e65e8233a95a3320248cf994b" + integrity sha512-OzL/2yHyPdCHXEzhoBuq37CE99nkme15eHkAzXRVqthreWZamEMA0WoetwstsQBCXABhczpK03JNbc4L01vvLg== + dependencies: + "@jest/test-result" "^24.8.0" + jest-haste-map "^24.8.0" + jest-runner "^24.8.0" + jest-runtime "^24.8.0" + +"@jest/transform@^24.8.0": + version "24.8.0" + resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-24.8.0.tgz#628fb99dce4f9d254c6fd9341e3eea262e06fef5" + integrity sha512-xBMfFUP7TortCs0O+Xtez2W7Zu1PLH9bvJgtraN1CDST6LBM/eTOZ9SfwS/lvV8yOfcDpFmwf9bq5cYbXvqsvA== + dependencies: + "@babel/core" "^7.1.0" + "@jest/types" "^24.8.0" + babel-plugin-istanbul "^5.1.0" + chalk "^2.0.1" + convert-source-map "^1.4.0" + fast-json-stable-stringify "^2.0.0" + graceful-fs "^4.1.15" + jest-haste-map "^24.8.0" + jest-regex-util "^24.3.0" + jest-util "^24.8.0" + micromatch "^3.1.10" + realpath-native "^1.1.0" + slash "^2.0.0" + source-map "^0.6.1" + write-file-atomic "2.4.1" + +"@jest/types@^24.8.0": + version "24.8.0" + resolved "https://registry.yarnpkg.com/@jest/types/-/types-24.8.0.tgz#f31e25948c58f0abd8c845ae26fcea1491dea7ad" + integrity sha512-g17UxVr2YfBtaMUxn9u/4+siG1ptg9IGYAYwvpwn61nBg779RXnjE/m7CxYcIzEt0AbHZZAHSEZNhkE2WxURVg== + dependencies: + "@types/istanbul-lib-coverage" "^2.0.0" + "@types/istanbul-reports" "^1.1.1" + "@types/yargs" "^12.0.9" + "@samverschueren/stream-to-observable@^0.3.0": version "0.3.0" resolved "https://registry.yarnpkg.com/@samverschueren/stream-to-observable/-/stream-to-observable-0.3.0.tgz#ecdf48d532c58ea477acfcab80348424f8d0662f" @@ -793,6 +947,39 @@ dependencies: defer-to-connect "^1.0.1" +"@types/babel__core@^7.1.0": + version "7.1.2" + resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.2.tgz#608c74f55928033fce18b99b213c16be4b3d114f" + integrity sha512-cfCCrFmiGY/yq0NuKNxIQvZFy9kY/1immpSpTngOnyIbD4+eJOG5mxphhHDv3CHL9GltO4GcKr54kGBg3RNdbg== + dependencies: + "@babel/parser" "^7.1.0" + "@babel/types" "^7.0.0" + "@types/babel__generator" "*" + "@types/babel__template" "*" + "@types/babel__traverse" "*" + +"@types/babel__generator@*": + version "7.0.2" + resolved "https://registry.yarnpkg.com/@types/babel__generator/-/babel__generator-7.0.2.tgz#d2112a6b21fad600d7674274293c85dce0cb47fc" + integrity sha512-NHcOfab3Zw4q5sEE2COkpfXjoE7o+PmqD9DQW4koUT3roNxwziUdXGnRndMat/LJNUtePwn1TlP4do3uoe3KZQ== + dependencies: + "@babel/types" "^7.0.0" + +"@types/babel__template@*": + version "7.0.2" + resolved "https://registry.yarnpkg.com/@types/babel__template/-/babel__template-7.0.2.tgz#4ff63d6b52eddac1de7b975a5223ed32ecea9307" + integrity sha512-/K6zCpeW7Imzgab2bLkLEbz0+1JlFSrUMdw7KoIIu+IUdu51GWaBZpd3y1VXGVXzynvGa4DaIaxNZHiON3GXUg== + dependencies: + "@babel/parser" "^7.1.0" + "@babel/types" "^7.0.0" + +"@types/babel__traverse@*", "@types/babel__traverse@^7.0.6": + version "7.0.7" + resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.0.7.tgz#2496e9ff56196cc1429c72034e07eab6121b6f3f" + integrity sha512-CeBpmX1J8kWLcDEnI3Cl2Eo6RfbGvzUctA+CjZUhOKDFbLfcr7fc4usEqLNWetrlJd7RhAkyYe2czXop4fICpw== + dependencies: + "@babel/types" "^7.3.0" + "@types/events@*": version "3.0.0" resolved "https://registry.yarnpkg.com/@types/events/-/events-3.0.0.tgz#2862f3f58a9a7f7c3e78d79f130dd4d71c25c2a7" @@ -807,6 +994,26 @@ "@types/minimatch" "*" "@types/node" "*" +"@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0": + version "2.0.1" + resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.1.tgz#42995b446db9a48a11a07ec083499a860e9138ff" + integrity sha512-hRJD2ahnnpLgsj6KWMYSrmXkM3rm2Dl1qkx6IOFD5FnuNPXJIG5L0dhgKXCYTRMGzU4n0wImQ/xfmRc4POUFlg== + +"@types/istanbul-lib-report@*": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@types/istanbul-lib-report/-/istanbul-lib-report-1.1.1.tgz#e5471e7fa33c61358dd38426189c037a58433b8c" + integrity sha512-3BUTyMzbZa2DtDI2BkERNC6jJw2Mr2Y0oGI7mRxYNBPxppbtEK1F66u3bKwU2g+wxwWI7PAoRpJnOY1grJqzHg== + dependencies: + "@types/istanbul-lib-coverage" "*" + +"@types/istanbul-reports@^1.1.1": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@types/istanbul-reports/-/istanbul-reports-1.1.1.tgz#7a8cbf6a406f36c8add871625b278eaf0b0d255a" + integrity sha512-UpYjBi8xefVChsCoBpKShdxTllC9pwISirfoZsUa2AAdQg/Jd2KQGtSbw+ya7GPo7x/wAPlH6JBhKhAsXUEZNA== + dependencies: + "@types/istanbul-lib-coverage" "*" + "@types/istanbul-lib-report" "*" + "@types/minimatch@*": version "3.0.3" resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d" @@ -821,6 +1028,16 @@ resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz#e486d0d97396d79beedd0a6e33f4534ff6b4973e" integrity sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA== +"@types/stack-utils@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-1.0.1.tgz#0a851d3bd96498fa25c33ab7278ed3bd65f06c3e" + integrity sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw== + +"@types/yargs@^12.0.2", "@types/yargs@^12.0.9": + version "12.0.12" + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-12.0.12.tgz#45dd1d0638e8c8f153e87d296907659296873916" + integrity sha512-SOhuU4wNBxhhTHxYaiG5NY4HBhDIDnJF60GU+2LqHAdKKer86//e4yg69aENCtQ04n0ovz+tq2YPME5t5yp4pw== + JSONStream@^1.0.4: version "1.3.1" resolved "https://registry.yarnpkg.com/JSONStream/-/JSONStream-1.3.1.tgz#707f761e01dae9e16f1bcf93703b78c70966579a" @@ -938,7 +1155,7 @@ ansi-regex@^3.0.0: resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= -ansi-regex@^4.1.0: +ansi-regex@^4.0.0, ansi-regex@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997" integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg== @@ -1136,6 +1353,11 @@ ast-types-flow@0.0.7, ast-types-flow@^0.0.7: version "0.0.7" resolved "https://registry.yarnpkg.com/ast-types-flow/-/ast-types-flow-0.0.7.tgz#f70b735c6bca1a5c9c22d982c3e39e7feba3bdad" +astral-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9" + integrity sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg== + async-each@^1.0.0, async-each@^1.0.1: version "1.0.3" resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.3.tgz#b727dbf87d7651602f06f4d4ac387f47d91b0cbf" @@ -1202,6 +1424,19 @@ babel-eslint@^10.0.2: eslint-scope "3.7.1" eslint-visitor-keys "^1.0.0" +babel-jest@^24.8.0: + version "24.8.0" + resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-24.8.0.tgz#5c15ff2b28e20b0f45df43fe6b7f2aae93dba589" + integrity sha512-+5/kaZt4I9efoXzPlZASyK/lN9qdRKmmUav9smVc0ruPQD7IsfucQ87gpOE8mn2jbDuS6M/YOW6n3v9ZoIfgnw== + dependencies: + "@jest/transform" "^24.8.0" + "@jest/types" "^24.8.0" + "@types/babel__core" "^7.1.0" + babel-plugin-istanbul "^5.1.0" + babel-preset-jest "^24.6.0" + chalk "^2.4.2" + slash "^2.0.0" + babel-loader@^8.0.6: version "8.0.6" resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-8.0.6.tgz#e33bdb6f362b03f4bb141a0c21ab87c501b70dfb" @@ -1212,6 +1447,30 @@ babel-loader@^8.0.6: mkdirp "^0.5.1" pify "^4.0.1" +babel-plugin-istanbul@^5.1.0: + version "5.1.4" + resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-5.1.4.tgz#841d16b9a58eeb407a0ddce622ba02fe87a752ba" + integrity sha512-dySz4VJMH+dpndj0wjJ8JPs/7i1TdSPb1nRrn56/92pKOF9VKC1FMFJmMXjzlGGusnCAqujP6PBCiKq0sVA+YQ== + dependencies: + find-up "^3.0.0" + istanbul-lib-instrument "^3.3.0" + test-exclude "^5.2.3" + +babel-plugin-jest-hoist@^24.6.0: + version "24.6.0" + resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-24.6.0.tgz#f7f7f7ad150ee96d7a5e8e2c5da8319579e78019" + integrity sha512-3pKNH6hMt9SbOv0F3WVmy5CWQ4uogS3k0GY5XLyQHJ9EGpAT9XWkFd2ZiXXtkwFHdAHa5j7w7kfxSP5lAIwu7w== + dependencies: + "@types/babel__traverse" "^7.0.6" + +babel-preset-jest@^24.6.0: + version "24.6.0" + resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-24.6.0.tgz#66f06136eefce87797539c0d63f1769cc3915984" + integrity sha512-pdZqLEdmy1ZK5kyRUfvBb2IfTPb2BUvIJczlPspS8fWmBQslNNDBqVfh7BW5leOVJMDZKzjD8XEyABTk6gQ5yw== + dependencies: + "@babel/plugin-syntax-object-rest-spread" "^7.0.0" + babel-plugin-jest-hoist "^24.6.0" + balanced-match@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" @@ -1330,6 +1589,13 @@ browser-process-hrtime@^1.0.0: resolved "https://registry.yarnpkg.com/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz#3c9b4b7d782c8121e56f10106d84c0d0ffc94626" integrity sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow== +browser-resolve@^1.11.3: + version "1.11.3" + resolved "https://registry.yarnpkg.com/browser-resolve/-/browser-resolve-1.11.3.tgz#9b7cbb3d0f510e4cb86bdbd796124d28b5890af6" + integrity sha512-exDi1BYWB/6raKHmDTCicQfTkqwN5fioMFV4j8BsfMU4R2DK/QfZfK7kOVkmWCNANf0snkBzqGqAJBao9gZMdQ== + dependencies: + resolve "1.1.7" + browserify-aes@^1.0.0, browserify-aes@^1.0.4: version "1.1.1" resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.1.1.tgz#38b7ab55edb806ff2dcda1a7f1620773a477c49f" @@ -1391,6 +1657,13 @@ browserslist@^4.6.0, browserslist@^4.6.2: electron-to-chromium "^1.3.164" node-releases "^1.1.23" +bser@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/bser/-/bser-2.1.0.tgz#65fc784bf7f87c009b973c12db6546902fa9c7b5" + integrity sha512-8zsjWrQkkBoLK6uxASk1nJ2SKv97ltiGDo6A3wA0/yRPz+CwmEyDo0hUrhIuukG2JHpAl3bvFIixw2/3Hi0DOg== + dependencies: + node-int64 "^0.4.0" + buffer-from@^1.0.0: version "1.1.1" resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" @@ -1488,6 +1761,11 @@ callsites@^2.0.0: resolved "https://registry.yarnpkg.com/callsites/-/callsites-2.0.0.tgz#06eb84f00eea413da86affefacbffb36093b3c50" integrity sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA= +callsites@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" + integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== + camelcase-keys@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-2.1.0.tgz#308beeaffdf28119051efa1d932213c91b8f92e7" @@ -1528,6 +1806,13 @@ caniuse-lite@^1.0.30000975: resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000976.tgz#d30fe12662cb2a21e130d307db9907513ca830a2" integrity sha512-tleNB1IwPRqZiod6nUNum63xQCMN96BUO2JTeiwuRM7p9d616EHsMBjBWJMudX39qCaPuWY8KEWzMZq7A9XQMQ== +capture-exit@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/capture-exit/-/capture-exit-2.0.0.tgz#fb953bfaebeb781f62898239dabb426d08a509a4" + integrity sha512-PiT/hQmTonHhl/HFGN+Lx3JJUznrVYJ3+AQsnthneZbvW7x+f08Tk7yLJTLEOUvBTbduLeeBkxEaYXUOUrRq6g== + dependencies: + rsvp "^4.8.4" + capture-stack-trace@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/capture-stack-trace/-/capture-stack-trace-1.0.1.tgz#a6c0bbe1f38f3aa0b92238ecb6ff42c344d4135d" @@ -1683,6 +1968,15 @@ cliui@^3.2.0: strip-ansi "^3.0.1" wrap-ansi "^2.0.0" +cliui@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-4.1.0.tgz#348422dbe82d800b3022eef4f6ac10bf2e4d1b49" + integrity sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ== + dependencies: + string-width "^2.1.1" + strip-ansi "^4.0.0" + wrap-ansi "^2.0.0" + cliui@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/cliui/-/cliui-5.0.0.tgz#deefcfdb2e800784aa34f46fa08e06851c7bbbc5" @@ -1875,7 +2169,7 @@ conventional-commits-parser@^3.0.2: through2 "^3.0.0" trim-off-newlines "^1.0.0" -convert-source-map@^1.1.0, convert-source-map@^1.6.0: +convert-source-map@^1.1.0, convert-source-map@^1.4.0, convert-source-map@^1.6.0: version "1.6.0" resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.6.0.tgz#51b537a8c43e0f04dec1993bffcdd504e758ac20" integrity sha512-eFu7XigvxdZ1ETfbgPBohgyQ/Z++C0eEhTor0qRwBw9unw+L0/6V8wkSuGgzdThkiS5lSpdptOQPD8Ak40a+7A== @@ -2237,6 +2531,16 @@ detect-libc@^1.0.2: resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" integrity sha1-+hN8S9aY7fVc1c0CrFWfkaTEups= +detect-newline@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-2.1.0.tgz#f41f1c10be4b00e87b5f13da680759f2c5bfd3e2" + integrity sha1-9B8cEL5LAOh7XxPaaAdZ8sW/0+I= + +diff-sequences@^24.3.0: + version "24.3.0" + resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-24.3.0.tgz#0f20e8a1df1abddaf4d9c226680952e64118b975" + integrity sha512-xLqpez+Zj9GKSnPWS0WZw1igGocZ+uua8+y+5dDNTT934N3QuY1sp2LkHzwiaYQGz60hMq0pjAshdeXm5VUOEw== + diff@^1.3.2: version "1.4.0" resolved "https://registry.yarnpkg.com/diff/-/diff-1.4.0.tgz#7f28d2eb9ee7b15a97efd89ce63dcfdaa3ccbabf" @@ -2692,6 +2996,11 @@ evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3: md5.js "^1.3.4" safe-buffer "^5.1.1" +exec-sh@^0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/exec-sh/-/exec-sh-0.3.2.tgz#6738de2eb7c8e671d0366aea0b0db8c6f7d7391b" + integrity sha512-9sLAvzhI5nc8TpuQUh4ahMdCrWT00wPWz7j47/emR5+2qEfoZP5zzUXvx+vdx+H6ohhnsYC31iX04QLYJK8zTg== + execa@^0.7.0: version "0.7.0" resolved "https://registry.yarnpkg.com/execa/-/execa-0.7.0.tgz#944becd34cc41ee32a63a9faf27ad5a65fc59777" @@ -2730,6 +3039,11 @@ execa@^1.0.0: signal-exit "^3.0.0" strip-eof "^1.0.0" +exit@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c" + integrity sha1-BjJjj42HfMghB9MKD/8aF8uhzQw= + expand-brackets@^0.1.4: version "0.1.5" resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-0.1.5.tgz#df07284e342a807cd733ac5af72411e581d1177b" @@ -2757,6 +3071,18 @@ expand-range@^1.8.1: dependencies: fill-range "^2.1.0" +expect@^24.8.0: + version "24.8.0" + resolved "https://registry.yarnpkg.com/expect/-/expect-24.8.0.tgz#471f8ec256b7b6129ca2524b2a62f030df38718d" + integrity sha512-/zYvP8iMDrzaaxHVa724eJBCKqSHmO0FA7EDkBiRHxg6OipmMn1fN+C8T9L9K8yr7UONkOifu6+LLH+z76CnaA== + dependencies: + "@jest/types" "^24.8.0" + ansi-styles "^3.2.0" + jest-get-type "^24.8.0" + jest-matcher-utils "^24.8.0" + jest-message-util "^24.8.0" + jest-regex-util "^24.3.0" + extend-shallow@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" @@ -2842,6 +3168,13 @@ fast-levenshtein@~2.0.4: version "2.0.6" resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" +fb-watchman@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/fb-watchman/-/fb-watchman-2.0.0.tgz#54e9abf7dfa2f26cd9b1636c588c1afc05de5d58" + integrity sha1-VOmr99+i8mzZsWNsWIwa/AXeXVg= + dependencies: + bser "^2.0.0" + fbjs@^0.8.4: version "0.8.16" resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.16.tgz#5e67432f550dc41b572bf55847b8aca64e5337db" @@ -3179,7 +3512,7 @@ glob-parent@^3.1.0: is-glob "^3.1.0" path-dirname "^1.0.0" -glob@^7.0.0, glob@^7.0.3, glob@^7.0.5, glob@^7.1.2, glob@^7.1.3: +glob@^7.0.0, glob@^7.0.3, glob@^7.0.5, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3: version "7.1.4" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.4.tgz#aa608a2f6c577ad357e1ae5a5c26d9a8d1969255" integrity sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A== @@ -3273,6 +3606,11 @@ graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2: resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e" integrity sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA== +growly@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/growly/-/growly-1.3.0.tgz#f10748cbe76af964b7c96c93c6bcc28af120c081" + integrity sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE= + handlebars@^4.1.0, handlebars@^4.1.2: version "4.1.2" resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.1.2.tgz#b6b37c1ced0306b221e094fc7aca3ec23b131b67" @@ -3512,6 +3850,14 @@ import-lazy@^2.1.0: resolved "https://registry.yarnpkg.com/import-lazy/-/import-lazy-2.1.0.tgz#05698e3d45c88e8d7e9d92cb0584e77f096f3e43" integrity sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM= +import-local@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/import-local/-/import-local-2.0.0.tgz#55070be38a5993cf18ef6db7e961f5bee5c5a09d" + integrity sha512-b6s04m3O+s3CGSbqDIyP4R6aAwAeYlVq9+WUWep6iHa8ETRf9yei1U48C5MmfJmV9AiLYYBKPMq/W+/WRpQmCQ== + dependencies: + pkg-dir "^3.0.0" + resolve-cwd "^2.0.0" + imurmurhash@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" @@ -3606,6 +3952,13 @@ invariant@^2.2.2: dependencies: loose-envify "^1.0.0" +invariant@^2.2.4: + version "2.2.4" + resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" + integrity sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA== + dependencies: + loose-envify "^1.0.0" + invert-kv@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6" @@ -3768,6 +4121,11 @@ is-fullwidth-code-point@^2.0.0: resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= +is-generator-fn@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-generator-fn/-/is-generator-fn-2.1.0.tgz#7d140adc389aaf3011a8f2a2a4cfa6faadffb118" + integrity sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ== + is-glob@^2.0.0, is-glob@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-2.0.1.tgz#d096f926a3ded5600f3fdfd91198cb0888c2d863" @@ -4013,7 +4371,7 @@ issue-regex@^2.0.0: resolved "https://registry.yarnpkg.com/issue-regex/-/issue-regex-2.0.0.tgz#bb1802490394f8083c7a6787247cbf975638ef5d" integrity sha512-flaQ/45dMqCYSMzBQI/h3bcto6T70uN7kjNnI8n3gQU6no5p+QcnMWBNXkraED0YvbUymxKaqdvgPa09RZQM5A== -istanbul-lib-coverage@^2.0.5: +istanbul-lib-coverage@^2.0.2, istanbul-lib-coverage@^2.0.5: version "2.0.5" resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz#675f0ab69503fad4b1d849f736baaca803344f49" integrity sha512-8aXznuEPCJvGnMSRft4udDRDtb1V3pkQkMMI5LI+6HuQz5oQ4J2UFn1H82raA3qJtyOLkkwVqICBQkjnGtn5mA== @@ -4025,7 +4383,7 @@ istanbul-lib-hook@^2.0.7: dependencies: append-transform "^1.0.0" -istanbul-lib-instrument@^3.3.0: +istanbul-lib-instrument@^3.0.1, istanbul-lib-instrument@^3.3.0: version "3.3.0" resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-3.3.0.tgz#a5f63d91f0bbc0c3e479ef4c5de027335ec6d630" integrity sha512-5nnIN4vo5xQZHdXno/YDXJ0G+I3dAm4XgzfSVTPLQpj/zAV2dV6Juy0yaf10/zrJOJeHoN3fraFe+XRq2bFVZA== @@ -4038,7 +4396,7 @@ istanbul-lib-instrument@^3.3.0: istanbul-lib-coverage "^2.0.5" semver "^6.0.0" -istanbul-lib-report@^2.0.8: +istanbul-lib-report@^2.0.4, istanbul-lib-report@^2.0.8: version "2.0.8" resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-2.0.8.tgz#5a8113cd746d43c4889eba36ab10e7d50c9b4f33" integrity sha512-fHBeG573EIihhAblwgxrSenp0Dby6tJMFR/HvlerBsrCTD5bkUuoNtn3gVh29ZCS824cGGBPn7Sg7cNk+2xUsQ== @@ -4047,7 +4405,7 @@ istanbul-lib-report@^2.0.8: make-dir "^2.1.0" supports-color "^6.1.0" -istanbul-lib-source-maps@^3.0.6: +istanbul-lib-source-maps@^3.0.1, istanbul-lib-source-maps@^3.0.6: version "3.0.6" resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-3.0.6.tgz#284997c48211752ec486253da97e3879defba8c8" integrity sha512-R47KzMtDJH6X4/YW9XTx+jrLnZnscW4VpNN+1PViSYTejLVPWv7oov+Duf8YQSPyVRUvueQqz1TcsC6mooZTXw== @@ -4058,13 +4416,365 @@ istanbul-lib-source-maps@^3.0.6: rimraf "^2.6.3" source-map "^0.6.1" -istanbul-reports@^2.2.4: +istanbul-reports@^2.1.1, istanbul-reports@^2.2.4: version "2.2.6" resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-2.2.6.tgz#7b4f2660d82b29303a8fe6091f8ca4bf058da1af" integrity sha512-SKi4rnMyLBKe0Jy2uUdx28h8oG7ph2PPuQPvIAh31d+Ci+lSiEu4C+h3oBPuJ9+mPKhOyW0M8gY4U5NM1WLeXA== dependencies: handlebars "^4.1.2" +jest-changed-files@^24.8.0: + version "24.8.0" + resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-24.8.0.tgz#7e7eb21cf687587a85e50f3d249d1327e15b157b" + integrity sha512-qgANC1Yrivsq+UrLXsvJefBKVoCsKB0Hv+mBb6NMjjZ90wwxCDmU3hsCXBya30cH+LnPYjwgcU65i6yJ5Nfuug== + dependencies: + "@jest/types" "^24.8.0" + execa "^1.0.0" + throat "^4.0.0" + +jest-cli@^24.8.0: + version "24.8.0" + resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-24.8.0.tgz#b075ac914492ed114fa338ade7362a301693e989" + integrity sha512-+p6J00jSMPQ116ZLlHJJvdf8wbjNbZdeSX9ptfHX06/MSNaXmKihQzx5vQcw0q2G6JsdVkUIdWbOWtSnaYs3yA== + dependencies: + "@jest/core" "^24.8.0" + "@jest/test-result" "^24.8.0" + "@jest/types" "^24.8.0" + chalk "^2.0.1" + exit "^0.1.2" + import-local "^2.0.0" + is-ci "^2.0.0" + jest-config "^24.8.0" + jest-util "^24.8.0" + jest-validate "^24.8.0" + prompts "^2.0.1" + realpath-native "^1.1.0" + yargs "^12.0.2" + +jest-config@^24.8.0: + version "24.8.0" + resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-24.8.0.tgz#77db3d265a6f726294687cbbccc36f8a76ee0f4f" + integrity sha512-Czl3Nn2uEzVGsOeaewGWoDPD8GStxCpAe0zOYs2x2l0fZAgPbCr3uwUkgNKV3LwE13VXythM946cd5rdGkkBZw== + dependencies: + "@babel/core" "^7.1.0" + "@jest/test-sequencer" "^24.8.0" + "@jest/types" "^24.8.0" + babel-jest "^24.8.0" + chalk "^2.0.1" + glob "^7.1.1" + jest-environment-jsdom "^24.8.0" + jest-environment-node "^24.8.0" + jest-get-type "^24.8.0" + jest-jasmine2 "^24.8.0" + jest-regex-util "^24.3.0" + jest-resolve "^24.8.0" + jest-util "^24.8.0" + jest-validate "^24.8.0" + micromatch "^3.1.10" + pretty-format "^24.8.0" + realpath-native "^1.1.0" + +jest-diff@^24.8.0: + version "24.8.0" + resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-24.8.0.tgz#146435e7d1e3ffdf293d53ff97e193f1d1546172" + integrity sha512-wxetCEl49zUpJ/bvUmIFjd/o52J+yWcoc5ZyPq4/W1LUKGEhRYDIbP1KcF6t+PvqNrGAFk4/JhtxDq/Nnzs66g== + dependencies: + chalk "^2.0.1" + diff-sequences "^24.3.0" + jest-get-type "^24.8.0" + pretty-format "^24.8.0" + +jest-docblock@^24.3.0: + version "24.3.0" + resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-24.3.0.tgz#b9c32dac70f72e4464520d2ba4aec02ab14db5dd" + integrity sha512-nlANmF9Yq1dufhFlKG9rasfQlrY7wINJbo3q01tu56Jv5eBU5jirylhF2O5ZBnLxzOVBGRDz/9NAwNyBtG4Nyg== + dependencies: + detect-newline "^2.1.0" + +jest-each@^24.8.0: + version "24.8.0" + resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-24.8.0.tgz#a05fd2bf94ddc0b1da66c6d13ec2457f35e52775" + integrity sha512-NrwK9gaL5+XgrgoCsd9svsoWdVkK4gnvyhcpzd6m487tXHqIdYeykgq3MKI1u4I+5Zf0tofr70at9dWJDeb+BA== + dependencies: + "@jest/types" "^24.8.0" + chalk "^2.0.1" + jest-get-type "^24.8.0" + jest-util "^24.8.0" + pretty-format "^24.8.0" + +jest-environment-jsdom@^24.8.0: + version "24.8.0" + resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-24.8.0.tgz#300f6949a146cabe1c9357ad9e9ecf9f43f38857" + integrity sha512-qbvgLmR7PpwjoFjM/sbuqHJt/NCkviuq9vus9NBn/76hhSidO+Z6Bn9tU8friecegbJL8gzZQEMZBQlFWDCwAQ== + dependencies: + "@jest/environment" "^24.8.0" + "@jest/fake-timers" "^24.8.0" + "@jest/types" "^24.8.0" + jest-mock "^24.8.0" + jest-util "^24.8.0" + jsdom "^11.5.1" + +jest-environment-node@^24.8.0: + version "24.8.0" + resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-24.8.0.tgz#d3f726ba8bc53087a60e7a84ca08883a4c892231" + integrity sha512-vIGUEScd1cdDgR6sqn2M08sJTRLQp6Dk/eIkCeO4PFHxZMOgy+uYLPMC4ix3PEfM5Au/x3uQ/5Tl0DpXXZsJ/Q== + dependencies: + "@jest/environment" "^24.8.0" + "@jest/fake-timers" "^24.8.0" + "@jest/types" "^24.8.0" + jest-mock "^24.8.0" + jest-util "^24.8.0" + +jest-get-type@^24.8.0: + version "24.8.0" + resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-24.8.0.tgz#a7440de30b651f5a70ea3ed7ff073a32dfe646fc" + integrity sha512-RR4fo8jEmMD9zSz2nLbs2j0zvPpk/KCEz3a62jJWbd2ayNo0cb+KFRxPHVhE4ZmgGJEQp0fosmNz84IfqM8cMQ== + +jest-haste-map@^24.8.0: + version "24.8.1" + resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-24.8.1.tgz#f39cc1d2b1d907e014165b4bd5a957afcb992982" + integrity sha512-SwaxMGVdAZk3ernAx2Uv2sorA7jm3Kx+lR0grp6rMmnY06Kn/urtKx1LPN2mGTea4fCT38impYT28FfcLUhX0g== + dependencies: + "@jest/types" "^24.8.0" + anymatch "^2.0.0" + fb-watchman "^2.0.0" + graceful-fs "^4.1.15" + invariant "^2.2.4" + jest-serializer "^24.4.0" + jest-util "^24.8.0" + jest-worker "^24.6.0" + micromatch "^3.1.10" + sane "^4.0.3" + walker "^1.0.7" + optionalDependencies: + fsevents "^1.2.7" + +jest-jasmine2@^24.8.0: + version "24.8.0" + resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-24.8.0.tgz#a9c7e14c83dd77d8b15e820549ce8987cc8cd898" + integrity sha512-cEky88npEE5LKd5jPpTdDCLvKkdyklnaRycBXL6GNmpxe41F0WN44+i7lpQKa/hcbXaQ+rc9RMaM4dsebrYong== + dependencies: + "@babel/traverse" "^7.1.0" + "@jest/environment" "^24.8.0" + "@jest/test-result" "^24.8.0" + "@jest/types" "^24.8.0" + chalk "^2.0.1" + co "^4.6.0" + expect "^24.8.0" + is-generator-fn "^2.0.0" + jest-each "^24.8.0" + jest-matcher-utils "^24.8.0" + jest-message-util "^24.8.0" + jest-runtime "^24.8.0" + jest-snapshot "^24.8.0" + jest-util "^24.8.0" + pretty-format "^24.8.0" + throat "^4.0.0" + +jest-leak-detector@^24.8.0: + version "24.8.0" + resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-24.8.0.tgz#c0086384e1f650c2d8348095df769f29b48e6980" + integrity sha512-cG0yRSK8A831LN8lIHxI3AblB40uhv0z+SsQdW3GoMMVcK+sJwrIIyax5tu3eHHNJ8Fu6IMDpnLda2jhn2pD/g== + dependencies: + pretty-format "^24.8.0" + +jest-matcher-utils@^24.8.0: + version "24.8.0" + resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-24.8.0.tgz#2bce42204c9af12bde46f83dc839efe8be832495" + integrity sha512-lex1yASY51FvUuHgm0GOVj7DCYEouWSlIYmCW7APSqB9v8mXmKSn5+sWVF0MhuASG0bnYY106/49JU1FZNl5hw== + dependencies: + chalk "^2.0.1" + jest-diff "^24.8.0" + jest-get-type "^24.8.0" + pretty-format "^24.8.0" + +jest-message-util@^24.8.0: + version "24.8.0" + resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-24.8.0.tgz#0d6891e72a4beacc0292b638685df42e28d6218b" + integrity sha512-p2k71rf/b6ns8btdB0uVdljWo9h0ovpnEe05ZKWceQGfXYr4KkzgKo3PBi8wdnd9OtNh46VpNIJynUn/3MKm1g== + dependencies: + "@babel/code-frame" "^7.0.0" + "@jest/test-result" "^24.8.0" + "@jest/types" "^24.8.0" + "@types/stack-utils" "^1.0.1" + chalk "^2.0.1" + micromatch "^3.1.10" + slash "^2.0.0" + stack-utils "^1.0.1" + +jest-mock@^24.8.0: + version "24.8.0" + resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-24.8.0.tgz#2f9d14d37699e863f1febf4e4d5a33b7fdbbde56" + integrity sha512-6kWugwjGjJw+ZkK4mDa0Df3sDlUTsV47MSrT0nGQ0RBWJbpODDQ8MHDVtGtUYBne3IwZUhtB7elxHspU79WH3A== + dependencies: + "@jest/types" "^24.8.0" + +jest-pnp-resolver@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/jest-pnp-resolver/-/jest-pnp-resolver-1.2.1.tgz#ecdae604c077a7fbc70defb6d517c3c1c898923a" + integrity sha512-pgFw2tm54fzgYvc/OHrnysABEObZCUNFnhjoRjaVOCN8NYc032/gVjPaHD4Aq6ApkSieWtfKAFQtmDKAmhupnQ== + +jest-regex-util@^24.3.0: + version "24.3.0" + resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-24.3.0.tgz#d5a65f60be1ae3e310d5214a0307581995227b36" + integrity sha512-tXQR1NEOyGlfylyEjg1ImtScwMq8Oh3iJbGTjN7p0J23EuVX1MA8rwU69K4sLbCmwzgCUbVkm0FkSF9TdzOhtg== + +jest-resolve-dependencies@^24.8.0: + version "24.8.0" + resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-24.8.0.tgz#19eec3241f2045d3f990dba331d0d7526acff8e0" + integrity sha512-hyK1qfIf/krV+fSNyhyJeq3elVMhK9Eijlwy+j5jqmZ9QsxwKBiP6qukQxaHtK8k6zql/KYWwCTQ+fDGTIJauw== + dependencies: + "@jest/types" "^24.8.0" + jest-regex-util "^24.3.0" + jest-snapshot "^24.8.0" + +jest-resolve@^24.8.0: + version "24.8.0" + resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-24.8.0.tgz#84b8e5408c1f6a11539793e2b5feb1b6e722439f" + integrity sha512-+hjSzi1PoRvnuOICoYd5V/KpIQmkAsfjFO71458hQ2Whi/yf1GDeBOFj8Gxw4LrApHsVJvn5fmjcPdmoUHaVKw== + dependencies: + "@jest/types" "^24.8.0" + browser-resolve "^1.11.3" + chalk "^2.0.1" + jest-pnp-resolver "^1.2.1" + realpath-native "^1.1.0" + +jest-runner@^24.8.0: + version "24.8.0" + resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-24.8.0.tgz#4f9ae07b767db27b740d7deffad0cf67ccb4c5bb" + integrity sha512-utFqC5BaA3JmznbissSs95X1ZF+d+4WuOWwpM9+Ak356YtMhHE/GXUondZdcyAAOTBEsRGAgH/0TwLzfI9h7ow== + dependencies: + "@jest/console" "^24.7.1" + "@jest/environment" "^24.8.0" + "@jest/test-result" "^24.8.0" + "@jest/types" "^24.8.0" + chalk "^2.4.2" + exit "^0.1.2" + graceful-fs "^4.1.15" + jest-config "^24.8.0" + jest-docblock "^24.3.0" + jest-haste-map "^24.8.0" + jest-jasmine2 "^24.8.0" + jest-leak-detector "^24.8.0" + jest-message-util "^24.8.0" + jest-resolve "^24.8.0" + jest-runtime "^24.8.0" + jest-util "^24.8.0" + jest-worker "^24.6.0" + source-map-support "^0.5.6" + throat "^4.0.0" + +jest-runtime@^24.8.0: + version "24.8.0" + resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-24.8.0.tgz#05f94d5b05c21f6dc54e427cd2e4980923350620" + integrity sha512-Mq0aIXhvO/3bX44ccT+czU1/57IgOMyy80oM0XR/nyD5zgBcesF84BPabZi39pJVA6UXw+fY2Q1N+4BiVUBWOA== + dependencies: + "@jest/console" "^24.7.1" + "@jest/environment" "^24.8.0" + "@jest/source-map" "^24.3.0" + "@jest/transform" "^24.8.0" + "@jest/types" "^24.8.0" + "@types/yargs" "^12.0.2" + chalk "^2.0.1" + exit "^0.1.2" + glob "^7.1.3" + graceful-fs "^4.1.15" + jest-config "^24.8.0" + jest-haste-map "^24.8.0" + jest-message-util "^24.8.0" + jest-mock "^24.8.0" + jest-regex-util "^24.3.0" + jest-resolve "^24.8.0" + jest-snapshot "^24.8.0" + jest-util "^24.8.0" + jest-validate "^24.8.0" + realpath-native "^1.1.0" + slash "^2.0.0" + strip-bom "^3.0.0" + yargs "^12.0.2" + +jest-serializer@^24.4.0: + version "24.4.0" + resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-24.4.0.tgz#f70c5918c8ea9235ccb1276d232e459080588db3" + integrity sha512-k//0DtglVstc1fv+GY/VHDIjrtNjdYvYjMlbLUed4kxrE92sIUewOi5Hj3vrpB8CXfkJntRPDRjCrCvUhBdL8Q== + +jest-snapshot@^24.8.0: + version "24.8.0" + resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-24.8.0.tgz#3bec6a59da2ff7bc7d097a853fb67f9d415cb7c6" + integrity sha512-5ehtWoc8oU9/cAPe6fez6QofVJLBKyqkY2+TlKTOf0VllBB/mqUNdARdcjlZrs9F1Cv+/HKoCS/BknT0+tmfPg== + dependencies: + "@babel/types" "^7.0.0" + "@jest/types" "^24.8.0" + chalk "^2.0.1" + expect "^24.8.0" + jest-diff "^24.8.0" + jest-matcher-utils "^24.8.0" + jest-message-util "^24.8.0" + jest-resolve "^24.8.0" + mkdirp "^0.5.1" + natural-compare "^1.4.0" + pretty-format "^24.8.0" + semver "^5.5.0" + +jest-util@^24.8.0: + version "24.8.0" + resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-24.8.0.tgz#41f0e945da11df44cc76d64ffb915d0716f46cd1" + integrity sha512-DYZeE+XyAnbNt0BG1OQqKy/4GVLPtzwGx5tsnDrFcax36rVE3lTA5fbvgmbVPUZf9w77AJ8otqR4VBbfFJkUZA== + dependencies: + "@jest/console" "^24.7.1" + "@jest/fake-timers" "^24.8.0" + "@jest/source-map" "^24.3.0" + "@jest/test-result" "^24.8.0" + "@jest/types" "^24.8.0" + callsites "^3.0.0" + chalk "^2.0.1" + graceful-fs "^4.1.15" + is-ci "^2.0.0" + mkdirp "^0.5.1" + slash "^2.0.0" + source-map "^0.6.0" + +jest-validate@^24.8.0: + version "24.8.0" + resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-24.8.0.tgz#624c41533e6dfe356ffadc6e2423a35c2d3b4849" + integrity sha512-+/N7VOEMW1Vzsrk3UWBDYTExTPwf68tavEPKDnJzrC6UlHtUDU/fuEdXqFoHzv9XnQ+zW6X3qMZhJ3YexfeLDA== + dependencies: + "@jest/types" "^24.8.0" + camelcase "^5.0.0" + chalk "^2.0.1" + jest-get-type "^24.8.0" + leven "^2.1.0" + pretty-format "^24.8.0" + +jest-watcher@^24.8.0: + version "24.8.0" + resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-24.8.0.tgz#58d49915ceddd2de85e238f6213cef1c93715de4" + integrity sha512-SBjwHt5NedQoVu54M5GEx7cl7IGEFFznvd/HNT8ier7cCAx/Qgu9ZMlaTQkvK22G1YOpcWBLQPFSImmxdn3DAw== + dependencies: + "@jest/test-result" "^24.8.0" + "@jest/types" "^24.8.0" + "@types/yargs" "^12.0.9" + ansi-escapes "^3.0.0" + chalk "^2.0.1" + jest-util "^24.8.0" + string-length "^2.0.0" + +jest-worker@^24.6.0: + version "24.6.0" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-24.6.0.tgz#7f81ceae34b7cde0c9827a6980c35b7cdc0161b3" + integrity sha512-jDwgW5W9qGNvpI1tNnvajh0a5IE/PuGLFmHk6aR/BZFz8tSgGw17GsDPXAJ6p91IvYDjOw8GpFbvvZGAK+DPQQ== + dependencies: + merge-stream "^1.0.1" + supports-color "^6.1.0" + +jest@^24.8.0: + version "24.8.0" + resolved "https://registry.yarnpkg.com/jest/-/jest-24.8.0.tgz#d5dff1984d0d1002196e9b7f12f75af1b2809081" + integrity sha512-o0HM90RKFRNWmAWvlyV8i5jGZ97pFwkeVoGvPW1EtLTgJc2+jcuqcbbqcSZLE/3f2S5pt0y2ZBETuhpWNl1Reg== + dependencies: + import-local "^2.0.0" + jest-cli "^24.8.0" + js-levenshtein@^1.1.3: version "1.1.6" resolved "https://registry.yarnpkg.com/js-levenshtein/-/js-levenshtein-1.1.6.tgz#c6cee58eb3550372df8deb85fad5ce66ce01d59d" @@ -4239,6 +4949,11 @@ kind-of@^6.0.0, kind-of@^6.0.2: resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.2.tgz#01146b36a6218e64e58f3a8d66de5d7fc6f6d051" integrity sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA== +kleur@^3.0.2: + version "3.0.3" + resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e" + integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w== + latest-version@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/latest-version/-/latest-version-3.1.0.tgz#a205383fea322b33b5ae3b18abee0dc2f356ee15" @@ -4273,6 +4988,11 @@ left-pad@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/left-pad/-/left-pad-1.2.0.tgz#d30a73c6b8201d8f7d8e7956ba9616087a68e0ee" +leven@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/leven/-/leven-2.1.0.tgz#c2e7a9f772094dee9d34202ae8acce4687875580" + integrity sha1-wuep93IJTe6dNCAq6KzORoeHVYA= + levn@^0.3.0, levn@~0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" @@ -4522,6 +5242,13 @@ make-error@^1.1.1: resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.5.tgz#efe4e81f6db28cadd605c70f29c831b58ef776c8" integrity sha512-c3sIjNUow0+8swNwVpqoH4YCShKNFkMaw6oH1mNS2haDZQqkeZFlHS3dhoeEbKKmJB4vXpJucU6oH75aDYeE9g== +makeerror@1.0.x: + version "1.0.11" + resolved "https://registry.yarnpkg.com/makeerror/-/makeerror-1.0.11.tgz#e01a5c9109f2af79660e4e8b9587790184f5a96c" + integrity sha1-4BpckQnyr3lmDk6LlYd5AYT1qWw= + dependencies: + tmpl "1.0.x" + map-age-cleaner@^0.1.1: version "0.1.3" resolved "https://registry.yarnpkg.com/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz#7d583a7306434c055fe474b0f45078e6e1b4b92a" @@ -4637,6 +5364,13 @@ merge-source-map@^1.1.0: dependencies: source-map "^0.6.1" +merge-stream@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-1.0.1.tgz#4041202d508a342ba00174008df0c251b8c135e1" + integrity sha1-QEEgLVCKNCugAXQAjfDCUbjBNeE= + dependencies: + readable-stream "^2.0.1" + micromatch@^2.1.5: version "2.3.11" resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-2.3.11.tgz#86677c97d1720b363431d04d0d15293bd38c1565" @@ -4737,7 +5471,7 @@ minimist@0.0.8: resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0= -minimist@^1.1.3, minimist@^1.2.0: +minimist@^1.1.1, minimist@^1.1.3, minimist@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" integrity sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ= @@ -4885,6 +5619,11 @@ node-fetch@^1.0.1: encoding "^0.1.11" is-stream "^1.0.1" +node-int64@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" + integrity sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs= + node-libs-browser@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/node-libs-browser/-/node-libs-browser-2.0.0.tgz#a3a59ec97024985b46e958379646f96c4b616646" @@ -4918,6 +5657,17 @@ node-modules-regexp@^1.0.0: resolved "https://registry.yarnpkg.com/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz#8d9dbe28964a4ac5712e9131642107c71e90ec40" integrity sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA= +node-notifier@^5.2.1: + version "5.4.0" + resolved "https://registry.yarnpkg.com/node-notifier/-/node-notifier-5.4.0.tgz#7b455fdce9f7de0c63538297354f3db468426e6a" + integrity sha512-SUDEb+o71XR5lXSTyivXd9J7fCloE3SyP4lSgt3lU2oSANiox+SxlNRGPjDKrwU1YN3ix2KN/VGGCg0t01rttQ== + dependencies: + growly "^1.3.0" + is-wsl "^1.1.0" + semver "^5.5.0" + shellwords "^0.1.1" + which "^1.3.0" + node-pre-gyp@^0.12.0: version "0.12.0" resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.12.0.tgz#39ba4bb1439da030295f899e3b520b7785766149" @@ -5251,7 +6001,7 @@ os-locale@^2.0.0: lcid "^1.0.0" mem "^1.1.0" -os-locale@^3.1.0: +os-locale@^3.0.0, os-locale@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-3.1.0.tgz#a802a6ee17f24c10483ab9935719cef4ed16bf1a" integrity sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q== @@ -5307,6 +6057,13 @@ p-defer@^1.0.0: resolved "https://registry.yarnpkg.com/p-defer/-/p-defer-1.0.0.tgz#9f6eb182f6c9aa8cd743004a7d4f96b196b0fb0c" integrity sha1-n26xgvbJqozXQwBKfU+WsZaw+ww= +p-each-series@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-each-series/-/p-each-series-1.0.0.tgz#930f3d12dd1f50e7434457a22cd6f04ac6ad7f71" + integrity sha1-kw89Et0fUOdDRFeiLNbwSsatf3E= + dependencies: + p-reduce "^1.0.0" + p-finally@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" @@ -5364,6 +6121,11 @@ p-memoize@^3.1.0: mem "^4.3.0" mimic-fn "^2.1.0" +p-reduce@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-reduce/-/p-reduce-1.0.0.tgz#18c2b0dd936a4690a529f8231f58a0fdb6a47dfa" + integrity sha1-GMKw3ZNqRpClKfgjH1ig/bakffo= + p-timeout@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-3.1.0.tgz#198c1f503bb973e9b9727177a276c80afd6851f3" @@ -5567,7 +6329,7 @@ pinkie@^2.0.0: resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" integrity sha1-clVrgM+g1IqXToDnckjoDtT3+HA= -pirates@^4.0.0: +pirates@^4.0.0, pirates@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.1.tgz#643a92caf894566f91b2b986d2c66950a8e2fb87" integrity sha512-WuNqLTbMI3tmfef2TKxlQmAiLHKtFhlsCZnPIpuv2Ow0RDVO8lfy1Opf4NUzlMXLjPl+Men7AuVdX6TA+s+uGA== @@ -5639,6 +6401,16 @@ prettier@^1.18.2: resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.18.2.tgz#6823e7c5900017b4bd3acf46fe9ac4b4d7bda9ea" integrity sha512-OeHeMc0JhFE9idD4ZdtNibzY0+TPHSpSSb9h8FqtP+YnoZZ1sl8Vc9b1sasjfymH3SonAF4QcA2+mzHPhMvIiw== +pretty-format@^24.8.0: + version "24.8.0" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-24.8.0.tgz#8dae7044f58db7cb8be245383b565a963e3c27f2" + integrity sha512-P952T7dkrDEplsR+TuY7q3VXDae5Sr7zmQb12JU/NDQa/3CH7/QW0yvqLcGN6jL+zQFKaoJcPc+yJxMTGmosqw== + dependencies: + "@jest/types" "^24.8.0" + ansi-regex "^4.0.0" + ansi-styles "^3.2.0" + react-is "^16.8.4" + pretty-quick@^1.11.1: version "1.11.1" resolved "https://registry.yarnpkg.com/pretty-quick/-/pretty-quick-1.11.1.tgz#462ffa2b93d24c05b7a0c3a001e08601a0c55ee4" @@ -5679,6 +6451,14 @@ promise@^7.1.1: dependencies: asap "~2.0.3" +prompts@^2.0.1: + version "2.1.0" + resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.1.0.tgz#bf90bc71f6065d255ea2bdc0fe6520485c1b45db" + integrity sha512-+x5TozgqYdOwWsQFZizE/Tra3fKvAoy037kOyU6cgz84n8f6zxngLOV4O32kTwt9FcLCxAqw0P/c8rOr9y+Gfg== + dependencies: + kleur "^3.0.2" + sisteransi "^1.0.0" + prop-types@^15.5.10, prop-types@^15.6.2, prop-types@^15.7.2: version "15.7.2" resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5" @@ -5813,7 +6593,7 @@ react-addons-test-utils@^15.6.0: prop-types "^15.6.2" scheduler "^0.13.6" -react-is@^16.8.1: +react-is@^16.8.1, react-is@^16.8.4: version "16.8.6" resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.8.6.tgz#5bbc1e2d29141c9fbdfed456343fe2bc430a6a16" integrity sha512-aUk3bHfZ2bRSVFFbbeVS4i+lNPZr3/WM5jT2J5omUVV1zzcs1nAaf3l51ctA5FFvCRbhrH0bdAsRRQddFJZPtA== @@ -5946,6 +6726,13 @@ readdirp@^2.0.0, readdirp@^2.2.1: micromatch "^3.1.10" readable-stream "^2.0.2" +realpath-native@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/realpath-native/-/realpath-native-1.1.0.tgz#2003294fea23fb0672f2476ebe22fcf498a2d65c" + integrity sha512-wlgPA6cCIIg9gKz0fgAPjnzh4yR/LnXovwuo9hvyGvx3h8nX4+/iLZplfUWasXpqD8BdnGnP5njOFjkUwPzvjA== + dependencies: + util.promisify "^1.0.0" + redent@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/redent/-/redent-1.0.0.tgz#cf916ab1fd5f1f16dfb20822dd6ec7f730c2afde" @@ -6175,6 +6962,13 @@ require-uncached@^1.0.3: caller-path "^0.1.0" resolve-from "^1.0.0" +resolve-cwd@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-2.0.0.tgz#00a9f7387556e27038eae232caa372a6a59b665a" + integrity sha1-AKn3OHVW4nA46uIyyqNypqWbZlo= + dependencies: + resolve-from "^3.0.0" + resolve-from@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-1.0.1.tgz#26cbfe935d1aeeeabb29bc3fe5aeb01e93d44226" @@ -6194,6 +6988,11 @@ resolve-url@^0.2.1: resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= +resolve@1.1.7: + version "1.1.7" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b" + integrity sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs= + resolve@^1.10.0, resolve@^1.10.1, resolve@^1.11.0, resolve@^1.5.0: version "1.11.0" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.11.0.tgz#4014870ba296176b86343d50b60f3b50609ce232" @@ -6233,7 +7032,7 @@ right-align@^0.1.1: dependencies: align-text "^0.1.1" -rimraf@^2.2.8, rimraf@^2.6.1, rimraf@^2.6.2, rimraf@^2.6.3: +rimraf@^2.2.8, rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6.2, rimraf@^2.6.3: version "2.6.3" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" integrity sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA== @@ -6253,6 +7052,11 @@ ripemd160@^2.0.0, ripemd160@^2.0.1: hash-base "^2.0.0" inherits "^2.0.1" +rsvp@^4.8.4: + version "4.8.5" + resolved "https://registry.yarnpkg.com/rsvp/-/rsvp-4.8.5.tgz#c8f155311d167f68f21e168df71ec5b083113734" + integrity sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA== + run-async@^2.2.0: version "2.3.0" resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.3.0.tgz#0371ab4ae0bdd720d4166d7dfda64ff7a445a6c0" @@ -6309,6 +7113,21 @@ safe-regex@^1.1.0: resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== +sane@^4.0.3: + version "4.1.0" + resolved "https://registry.yarnpkg.com/sane/-/sane-4.1.0.tgz#ed881fd922733a6c461bc189dc2b6c006f3ffded" + integrity sha512-hhbzAgTIX8O7SHfp2c8/kREfEn4qO/9q8C9beyY6+tvZ87EpoZ3i1RIEvp27YBswnNbY9mWd6paKVmKbAgLfZA== + dependencies: + "@cnakazawa/watch" "^1.0.3" + anymatch "^2.0.0" + capture-exit "^2.0.0" + exec-sh "^0.3.2" + execa "^1.0.0" + fb-watchman "^2.0.0" + micromatch "^3.1.4" + minimist "^1.1.1" + walker "~1.0.5" + sax@^1.2.1, sax@^1.2.4: version "1.2.4" resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" @@ -6405,6 +7224,11 @@ shebang-regex@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" +shellwords@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/shellwords/-/shellwords-0.1.1.tgz#d6b9181c1a48d397324c84871efbcfc73fc0654b" + integrity sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww== + signal-exit@^3.0.0, signal-exit@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" @@ -6423,6 +7247,11 @@ sinon@^7.3.2: nise "^1.4.10" supports-color "^5.5.0" +sisteransi@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.0.tgz#77d9622ff909080f1c19e5f4a1df0c1b0a27b88c" + integrity sha512-N+z4pHB4AmUv0SjveWRd6q1Nj5w62m5jodv+GD8lvmbY/83T/rpbJGZOnK5T149OldDj4Db07BSv9xY4K6NTPQ== + slash@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/slash/-/slash-2.0.0.tgz#de552851a1759df3a8f206535442f5ec4ddeab44" @@ -6598,7 +7427,7 @@ sshpk@^1.7.0: safer-buffer "^2.0.2" tweetnacl "~0.14.0" -stack-utils@^1.0.2: +stack-utils@^1.0.1, stack-utils@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-1.0.2.tgz#33eba3897788558bebfc2db059dc158ec36cebb8" integrity sha512-MTX+MeG5U994cazkjd/9KNAapsHnibjMLnfXodlkXw76JEea0UiNzrqidzo1emMwk7w5Qhc9jd4Bn9TBb1MFwA== @@ -6649,6 +7478,14 @@ stream-http@^2.3.1: to-arraybuffer "^1.0.0" xtend "^4.0.0" +string-length@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/string-length/-/string-length-2.0.0.tgz#d40dbb686a3ace960c1cffca562bf2c45f8363ed" + integrity sha1-1A27aGo6zpYMHP/KVivyxF+DY+0= + dependencies: + astral-regex "^1.0.0" + strip-ansi "^4.0.0" + string-width@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" @@ -6948,6 +7785,11 @@ text-table@~0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" +throat@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/throat/-/throat-4.1.0.tgz#89037cbc92c56ab18926e6ba4cbb200e15672a6a" + integrity sha1-iQN8vJLFarGJJua6TLsgDhVnKmo= + through2@^2.0.0, through2@^2.0.2: version "2.0.3" resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.3.tgz#0004569b37c7c74ba39c43f3ced78d1ad94140be" @@ -6988,6 +7830,11 @@ tmp@^0.0.33: dependencies: os-tmpdir "~1.0.2" +tmpl@1.0.x: + version "1.0.4" + resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.4.tgz#23640dd7b42d00433911140820e5cf440e521dd1" + integrity sha1-I2QN17QtAEM5ERQIIOXPRA5SHdE= + to-arraybuffer@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz#7d229b1fcc637e466ca081180836a7aabff83f43" @@ -7291,6 +8138,14 @@ util-deprecate@^1.0.1, util-deprecate@~1.0.1: resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= +util.promisify@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/util.promisify/-/util.promisify-1.0.0.tgz#440f7165a459c9a16dc145eb8e72f35687097030" + integrity sha512-i+6qA2MPhvoKLuxnJNpXAGhg7HphQOSUq2LKMZD0m15EiskXUkMvKdF4Uui0WYeCUGea+o2cw/ZuwehtfsrNkA== + dependencies: + define-properties "^1.1.2" + object.getownpropertydescriptors "^2.0.3" + util@0.10.3, util@^0.10.3: version "0.10.3" resolved "https://registry.yarnpkg.com/util/-/util-0.10.3.tgz#7afb1afe50805246489e3db7fe0ed379336ac0f9" @@ -7347,6 +8202,13 @@ vm-browserify@0.0.4: dependencies: indexof "0.0.1" +walker@^1.0.7, walker@~1.0.5: + version "1.0.7" + resolved "https://registry.yarnpkg.com/walker/-/walker-1.0.7.tgz#2f7f9b8fd10d677262b18a884e28d19618e028fb" + integrity sha1-L3+bj9ENZ3JisYqITijRlhjgKPs= + dependencies: + makeerror "1.0.x" + watchpack@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-1.4.0.tgz#4a1472bcbb952bd0a9bb4036801f954dfb39faac" @@ -7489,6 +8351,15 @@ wrappy@1: resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= +write-file-atomic@2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-2.4.1.tgz#d0b05463c188ae804396fd5ab2a370062af87529" + integrity sha512-TGHFeZEZMnv+gBFRfjAcxL5bPHrsGKtnb4qsFAws7/vlh+QfwAaySIw4AXP9ZskTTh5GWu3FLuJhsWVdiJPGvg== + dependencies: + graceful-fs "^4.1.11" + imurmurhash "^0.1.4" + signal-exit "^3.0.2" + write-file-atomic@^2.0.0, write-file-atomic@^2.4.2: version "2.4.3" resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-2.4.3.tgz#1fd2e9ae1df3e75b8d8c367443c692d4ca81f481" @@ -7523,7 +8394,7 @@ y18n@^3.2.1: resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.1.tgz#6d15fba884c08679c0d77e88e7759e811e07fa41" integrity sha1-bRX7qITAhnnA136I53WegR4H+kE= -y18n@^4.0.0: +"y18n@^3.2.1 || ^4.0.0", y18n@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b" integrity sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w== @@ -7548,6 +8419,14 @@ yargs-parser@^10.0.0: dependencies: camelcase "^4.1.0" +yargs-parser@^11.1.1: + version "11.1.1" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-11.1.1.tgz#879a0865973bca9f6bab5cbdf3b1c67ec7d3bcf4" + integrity sha512-C6kB/WJDiaxONLJQnF8ccx9SEeoTTLek8RVbaOIsrAUS8VrBEXfmeSnCZxygc+XC2sNMBIwOOnfcxiynjHsVSQ== + dependencies: + camelcase "^5.0.0" + decamelize "^1.2.0" + yargs-parser@^13.0.0, yargs-parser@^13.1.0: version "13.1.1" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.1.1.tgz#d26058532aa06d365fe091f6a1fc06b2f7e5eca0" @@ -7562,6 +8441,24 @@ yargs-parser@^7.0.0: dependencies: camelcase "^4.1.0" +yargs@^12.0.2: + version "12.0.5" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-12.0.5.tgz#05f5997b609647b64f66b81e3b4b10a368e7ad13" + integrity sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw== + dependencies: + cliui "^4.0.0" + decamelize "^1.2.0" + find-up "^3.0.0" + get-caller-file "^1.0.1" + os-locale "^3.0.0" + require-directory "^2.1.1" + require-main-filename "^1.0.1" + set-blocking "^2.0.0" + string-width "^2.0.0" + which-module "^2.0.0" + y18n "^3.2.1 || ^4.0.0" + yargs-parser "^11.1.1" + yargs@^13.2.2: version "13.2.4" resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.2.4.tgz#0b562b794016eb9651b98bd37acf364aa5d6dc83"