Refactored tests and made React 0.14 friendly
This commit is contained in:
commit
2846f0fadd
|
|
@ -1,3 +1,4 @@
|
|||
.DS_Store
|
||||
build
|
||||
node_modules
|
||||
lib
|
||||
|
|
|
|||
|
|
@ -1,6 +1,4 @@
|
|||
language: node_js
|
||||
node_js:
|
||||
- 'iojs'
|
||||
- '0.12'
|
||||
- '0.11'
|
||||
- '0.10'
|
||||
|
|
|
|||
79
API.md
79
API.md
|
|
@ -35,6 +35,8 @@
|
|||
- [isFormSubmitted()](#isformsubmitted)
|
||||
- [validate](#validate)
|
||||
- [formNoValidate](#formnovalidate)
|
||||
- [Formsy.HOC](#formsyhoc)
|
||||
- [Formsy.Decorator](#formsydecorator)
|
||||
- [Formsy.addValidationRule](#formsyaddvalidationrule)
|
||||
- [Validators](#validators)
|
||||
|
||||
|
|
@ -109,7 +111,7 @@ var Form = React.createClass({
|
|||
```html
|
||||
<Formsy.Form onSubmit={this.showFormLoader}></Formsy.Form>
|
||||
```
|
||||
Takes a function to run when the submit button has been clicked.
|
||||
Takes a function to run when the submit button has been clicked.
|
||||
|
||||
The first argument is the data of the form. The second argument will reset the form. The third argument will invalidate the form by taking an object that maps to inputs. This is useful for server side validation. E.g. `{email: "This email is taken"}`. Resetting or invalidating the form will cause **setState** to run on the form element component.
|
||||
|
||||
|
|
@ -226,12 +228,12 @@ The message that will show when the form input component is invalid. It will be
|
|||
|
||||
#### <a name="validationerrors">validationErrors</a>
|
||||
```html
|
||||
<MyInputComponent
|
||||
name="email"
|
||||
<MyInputComponent
|
||||
name="email"
|
||||
validations={{
|
||||
isEmail: true,
|
||||
maxLength: 50
|
||||
}}
|
||||
}}
|
||||
validationErrors={{
|
||||
isEmail: 'You have to type valid email',
|
||||
maxLength: 'You can not type in more than 50 characters'
|
||||
|
|
@ -404,7 +406,7 @@ var MyInput = React.createClass({
|
|||
}
|
||||
});
|
||||
```
|
||||
Returns true if the required property has been passed.
|
||||
Returns true if the required property has been passed.
|
||||
|
||||
#### <a name="showrequired">showRequired()</a>
|
||||
```javascript
|
||||
|
|
@ -424,7 +426,7 @@ var MyInput = React.createClass({
|
|||
}
|
||||
});
|
||||
```
|
||||
Lets you check if the form input component should indicate if it is a required field. This happens when the form input component value is empty and the required prop has been passed.
|
||||
Lets you check if the form input component should indicate if it is a required field. This happens when the form input component value is empty and the required prop has been passed.
|
||||
|
||||
#### <a name="showerror">showError()</a>
|
||||
```javascript
|
||||
|
|
@ -539,6 +541,41 @@ var MyInput = React.createClass({
|
|||
});
|
||||
```
|
||||
|
||||
### <a name="formsyhoc">Formsy.HOC</a>
|
||||
The same methods as the mixin are exposed to the HOC version of the element component, though through the `props`, not on the instance.
|
||||
```js
|
||||
import {HOC} from 'formsy-react';
|
||||
|
||||
class MyInput extends React.Component {
|
||||
render() {
|
||||
return (
|
||||
<div>
|
||||
<input value={this.props.getValue()} onChange={(e) => this.props.setValue(e.target.value)}/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
};
|
||||
export default HOC(MyInput);
|
||||
```
|
||||
|
||||
### <a name="formsydecorator">Formsy.Decorator</a>
|
||||
The same methods as the mixin are exposed to the decorator version of the element component, though through the `props`, not on the instance.
|
||||
```js
|
||||
import {Decorator as FormsyElement} from 'formsy-react';
|
||||
|
||||
@FormsyElement()
|
||||
class MyInput extends React.Component {
|
||||
render() {
|
||||
return (
|
||||
<div>
|
||||
<input value={this.props.getValue()} onChange={(e) => this.props.setValue(e.target.value)}/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
};
|
||||
export default MyInput
|
||||
```
|
||||
|
||||
### <a name="formsyaddvalidationrule">Formsy.addValidationRule(name, ruleFunc)</a>
|
||||
An example:
|
||||
```javascript
|
||||
|
|
@ -622,18 +659,36 @@ Returns true if the value is the boolean true
|
|||
```
|
||||
Returns true if the value is the boolean false
|
||||
|
||||
**isNumeric**
|
||||
```html
|
||||
<MyInputComponent name="foo" validations="isNumeric"/>
|
||||
```
|
||||
Returns true if string only contains numbers
|
||||
|
||||
**isAlpha**
|
||||
```html
|
||||
<MyInputComponent name="foo" validations="isAlpha"/>
|
||||
```
|
||||
Returns true if string is only letters
|
||||
|
||||
**isNumeric**
|
||||
```html
|
||||
<MyInputComponent name="foo" validations="isNumeric"/>
|
||||
```
|
||||
Returns true if string only contains numbers. Examples: 42; -3.14
|
||||
|
||||
**isAlphanumeric**
|
||||
```html
|
||||
<MyInputComponent name="foo" validations="isAlphanumeric"/>
|
||||
```
|
||||
Returns true if string only contains letters or numbers
|
||||
|
||||
**isInt**
|
||||
```html
|
||||
<MyInputComponent name="foo" validations="isInt"/>
|
||||
```
|
||||
Returns true if string represents integer value. Examples: 42; -12; 0
|
||||
|
||||
**isFloat**
|
||||
```html
|
||||
<MyInputComponent name="foo" validations="isFloat"/>
|
||||
```
|
||||
Returns true if string represents float value. Examples: 42; -3.14; 1e3
|
||||
|
||||
**isWords**
|
||||
```html
|
||||
<MyInputComponent name="foo" validations="isWords"/>
|
||||
|
|
|
|||
17
README.md
17
README.md
|
|
@ -11,7 +11,7 @@ A form input builder and validator for React JS
|
|||
### From version 0.12.0 Formsy only supports React 0.13.1 and up
|
||||
|
||||
## <a name="background">Background</a>
|
||||
I wrote an article on forms and validation with React JS, [Nailing that validation with React JS](http://christianalfoni.github.io/javascript/2014/10/22/nailing-that-validation-with-reactjs.html), the result of that was this extension.
|
||||
I wrote an article on forms and validation with React JS, [Nailing that validation with React JS](http://christianalfoni.github.io/javascript/2014/10/22/nailing-that-validation-with-reactjs.html), the result of that was this extension.
|
||||
|
||||
The main concept is that forms, inputs and validation is done very differently across developers and projects. This extension to React JS aims to be that "sweet spot" between flexibility and reusability.
|
||||
|
||||
|
|
@ -21,12 +21,15 @@ The main concept is that forms, inputs and validation is done very differently a
|
|||
|
||||
2. Add validation rules and use them with simple syntax
|
||||
|
||||
3. Use handlers for different states of your form. Ex. "onSubmit", "onError", "onValid" etc.
|
||||
3. Use handlers for different states of your form. Ex. "onSubmit", "onError", "onValid" etc.
|
||||
|
||||
4. Server validation errors automatically binds to the correct form input component
|
||||
4. Pass external errors to the form to invalidate elements
|
||||
|
||||
5. You can dynamically add form elements to your form and they will register/unregister to the form
|
||||
|
||||
## Default elements
|
||||
You can look at examples in this repo or use the [formsy-react-components](https://github.com/twisty/formsy-react-components) project to use bootstrap with formsy-react.
|
||||
|
||||
## Install
|
||||
|
||||
1. Download from this REPO and use globally (Formsy) or with requirejs
|
||||
|
|
@ -91,7 +94,7 @@ This code results in a form with a submit button that will run the `submit` meth
|
|||
// Add the Formsy Mixin
|
||||
mixins: [Formsy.Mixin],
|
||||
|
||||
// setValue() will set the value of the component, which in
|
||||
// setValue() will set the value of the component, which in
|
||||
// turn will validate it and the rest of the form
|
||||
changeValue: function (event) {
|
||||
this.setValue(event.currentTarget.value);
|
||||
|
|
@ -99,9 +102,9 @@ This code results in a form with a submit button that will run the `submit` meth
|
|||
render: function () {
|
||||
|
||||
// Set a specific className based on the validation
|
||||
// state of this component. showRequired() is true
|
||||
// when the value is empty and the required prop is
|
||||
// passed to the input. showError() is true when the
|
||||
// state of this component. showRequired() is true
|
||||
// when the value is empty and the required prop is
|
||||
// passed to the input. showError() is true when the
|
||||
// value typed is invalid
|
||||
var className = this.showRequired() ? 'required' : this.showError() ? 'error' : null;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "formsy-react",
|
||||
"version": "0.14.1",
|
||||
"version": "0.16.0",
|
||||
"description": "A form input builder and validator for React JS",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
|
|
|||
|
|
@ -1,37 +1,55 @@
|
|||
var React = require('react');
|
||||
var ReactDOM = require('react-dom');
|
||||
var Formsy = require('./../src/main.js');
|
||||
|
||||
var Input = React.createClass({
|
||||
|
||||
mixins: [Formsy.Mixin],
|
||||
|
||||
onChange: function (event) {
|
||||
this.props.setValue(event.currentTarget.value);
|
||||
},
|
||||
render: function () {
|
||||
return (
|
||||
<div>
|
||||
{this.showError()}
|
||||
{this.getErrorMessage()}
|
||||
<input disabled={this.isFormDisabled()} />
|
||||
{this.props.showRequired() ? 'required' : ''}
|
||||
<input disabled={this.props.isFormDisabled()} value={this.props.getValue()} onChange={this.onChange}/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
var FormApp = React.createClass({
|
||||
componentDidMount: function () {
|
||||
this.refs.form.updateInputsWithError({
|
||||
'foo.bar': 'hmmm'
|
||||
Input = Formsy.HOC(Input);
|
||||
|
||||
var SomeComp = React.createClass({
|
||||
getInitialState: function () {
|
||||
return {
|
||||
isRequired: false
|
||||
};
|
||||
},
|
||||
toggleRequired: function () {
|
||||
this.setState({
|
||||
isRequired: !this.state.isRequired
|
||||
});
|
||||
},
|
||||
render: function () {
|
||||
return (
|
||||
<div>
|
||||
<Input name="foo[0]" value={''} validations="isEmail" validationError="No email" required={this.state.isRequired}/>
|
||||
<button onClick={this.toggleRequired}>Test</button>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
});
|
||||
|
||||
var FormApp = React.createClass({
|
||||
onSubmit: function (model) {
|
||||
console.log('model', model);
|
||||
},
|
||||
render: function () {
|
||||
return (
|
||||
<Formsy.Form ref="form" onInvalid={this.onInvalid}>
|
||||
<Input name="foo.bar" />
|
||||
<Formsy.Form ref="form" onSubmit={this.onSubmit}>
|
||||
<SomeComp/>
|
||||
</Formsy.Form>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
React.render(<FormApp />, document.getElementById('app'));
|
||||
ReactDOM.render(<FormApp />, document.getElementById('app'));
|
||||
|
|
|
|||
|
|
@ -29,4 +29,8 @@ If it is not helped try update your node.js and npm.
|
|||
|
||||
2. [**Custom Validation**](custom-validation)
|
||||
|
||||
One field with added validation rule (`Formsy.addValidationRule`) and one field with dynamically added validation and error messages.
|
||||
One field with added validation rule (`Formsy.addValidationRule`) and one field with dynamically added validation and error messages.
|
||||
|
||||
3. [**Reset Values**](reset-values)
|
||||
|
||||
Reset text input, checkbox and select to their pristine values.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,43 @@
|
|||
import React from 'react';
|
||||
import Formsy from 'formsy-react';
|
||||
|
||||
const MyInput = React.createClass({
|
||||
|
||||
// Add the Formsy Mixin
|
||||
mixins: [Formsy.Mixin],
|
||||
|
||||
// setValue() will set the value of the component, which in
|
||||
// turn will validate it and the rest of the form
|
||||
changeValue(event) {
|
||||
this.setValue(event.currentTarget[this.props.type === 'checkbox' ? 'checked' : 'value']);
|
||||
},
|
||||
render() {
|
||||
|
||||
// Set a specific className based on the validation
|
||||
// state of this component. showRequired() is true
|
||||
// when the value is empty and the required prop is
|
||||
// passed to the input. showError() is true when the
|
||||
// value typed is invalid
|
||||
const className = this.props.className + ' ' + (this.showRequired() ? 'required' : this.showError() ? 'error' : null);
|
||||
|
||||
// An error message is returned ONLY if the component is invalid
|
||||
// or the server has returned an error message
|
||||
const errorMessage = this.getErrorMessage();
|
||||
|
||||
return (
|
||||
<div className='form-group'>
|
||||
<label htmlFor={this.props.name}>{this.props.title}</label>
|
||||
<input
|
||||
type={this.props.type || 'text'}
|
||||
name={this.props.name}
|
||||
onChange={this.changeValue}
|
||||
value={this.getValue()}
|
||||
checked={this.props.type === 'checkbox' && this.getValue() ? 'checked' : null}
|
||||
/>
|
||||
<span className='validation-error'>{errorMessage}</span>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
export default MyInput;
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
import React from 'react';
|
||||
import Formsy from 'formsy-react';
|
||||
|
||||
const MySelect = React.createClass({
|
||||
mixins: [Formsy.Mixin],
|
||||
|
||||
changeValue(event) {
|
||||
this.setValue(event.currentTarget.value);
|
||||
},
|
||||
|
||||
render() {
|
||||
const className = this.props.className + ' ' + (this.showRequired() ? 'required' : this.showError() ? 'error' : null);
|
||||
const errorMessage = this.getErrorMessage();
|
||||
|
||||
const options = this.props.options.map((option, i) => (
|
||||
<option key={option.title+option.value} value={option.value}>
|
||||
{option.title}
|
||||
</option>
|
||||
));
|
||||
|
||||
return (
|
||||
<div className='form-group'>
|
||||
<label htmlFor={this.props.name}>{this.props.title}</label>
|
||||
<select name={this.props.name} onChange={this.changeValue} value={this.getValue()}>
|
||||
{options}
|
||||
</select>
|
||||
<span className='validation-error'>{errorMessage}</span>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
export default MySelect;
|
||||
|
|
@ -1,9 +1,12 @@
|
|||
var React = require('react');
|
||||
var Formsy = require('formsy-react');
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import Formsy from 'formsy-react';
|
||||
|
||||
var currentYear = new Date().getFullYear();
|
||||
import MyInput from './../components/Input';
|
||||
|
||||
var validators = {
|
||||
const currentYear = new Date().getFullYear();
|
||||
|
||||
const validators = {
|
||||
time: {
|
||||
regexp: /^(([0-1]?[0-9])|([2][0-3])):([0-5]?[0-9])(:([0-5]?[0-9]))?$/,
|
||||
message: 'Not valid time'
|
||||
|
|
@ -18,79 +21,56 @@ var validators = {
|
|||
}
|
||||
};
|
||||
|
||||
Formsy.addValidationRule('isYearOfBirth', function (values, value) {
|
||||
Formsy.addValidationRule('isYearOfBirth', (values, value) => {
|
||||
value = parseInt(value);
|
||||
if (typeof value !== 'number' || value !== value) {
|
||||
if (typeof value !== 'number') {
|
||||
return false;
|
||||
}
|
||||
return value < currentYear && value > currentYear - 130;
|
||||
});
|
||||
|
||||
var App = React.createClass({
|
||||
submit: function (data) {
|
||||
const App = React.createClass({
|
||||
submit(data) {
|
||||
alert(JSON.stringify(data, null, 4));
|
||||
},
|
||||
render: function () {
|
||||
render() {
|
||||
return (
|
||||
<Formsy.Form onSubmit={this.submit} className="custom-validation">
|
||||
<MyOwnInput name="year" title="Year of Birth" type="number" validations="isYearOfBirth" validationError="Please type your year of birth" />
|
||||
<DynamicInput name="dynamic" title="..." type="text" />
|
||||
<MyInput name="year" title="Year of Birth" type="number" validations="isYearOfBirth" validationError="Please type your year of birth" />
|
||||
<DynamicInput name="dynamic" title="..." />
|
||||
<button type="submit">Submit</button>
|
||||
</Formsy.Form>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
var MyOwnInput = React.createClass({
|
||||
const DynamicInput = React.createClass({
|
||||
mixins: [Formsy.Mixin],
|
||||
changeValue: function (event) {
|
||||
getInitialState() {
|
||||
return { validationType: 'time' };
|
||||
},
|
||||
changeValue(event) {
|
||||
this.setValue(event.currentTarget.value);
|
||||
},
|
||||
render: function () {
|
||||
var className = this.props.className + ' ' + (this.showError() ? 'error' : null);
|
||||
var errorMessage = this.getErrorMessage();
|
||||
|
||||
return (
|
||||
<div className='form-group'>
|
||||
<label htmlFor={this.props.name}>{this.props.title}</label>
|
||||
<input type={this.props.type || 'text'} name={this.props.name} onChange={this.changeValue} value={this.getValue()}/>
|
||||
<span className='validation-error'>{errorMessage}</span>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
var DynamicInput = React.createClass({
|
||||
mixins: [Formsy.Mixin],
|
||||
getInitialState: function() {
|
||||
return {
|
||||
validationType: 'time'
|
||||
};
|
||||
},
|
||||
changeValue: function (event) {
|
||||
this.setValue(event.currentTarget.value);
|
||||
},
|
||||
changeValidation: function(validationType) {
|
||||
this.setState({
|
||||
validationType: validationType
|
||||
});
|
||||
changeValidation(validationType) {
|
||||
this.setState({ validationType: validationType });
|
||||
this.setValue(this.getValue());
|
||||
},
|
||||
validate: function () {
|
||||
var value = this.getValue();
|
||||
return value === '' ? true : validators[this.state.validationType].regexp.test(value);
|
||||
validate() {
|
||||
const value = this.getValue();
|
||||
return value !== '' ? validators[this.state.validationType].regexp.test(value) : true;
|
||||
},
|
||||
getCustomErrorMessage: function() {
|
||||
getCustomErrorMessage() {
|
||||
return this.showError() ? validators[this.state.validationType].message : '';
|
||||
},
|
||||
render: function () {
|
||||
var className = this.props.className + ' ' + (this.showError() ? 'error' : null);
|
||||
var errorMessage = this.getCustomErrorMessage();
|
||||
render() {
|
||||
const className = this.props.className + ' ' + (this.showError() ? 'error' : null);
|
||||
const errorMessage = this.getCustomErrorMessage();
|
||||
|
||||
return (
|
||||
<div className='form-group'>
|
||||
<label htmlFor={this.props.name}>{this.props.title}</label>
|
||||
<input type={this.props.type || 'text'} name={this.props.name} onChange={this.changeValue} value={this.getValue()}/>
|
||||
<input type='text' name={this.props.name} onChange={this.changeValue} value={this.getValue()}/>
|
||||
<span className='validation-error'>{errorMessage}</span>
|
||||
<Validations validationType={this.state.validationType} changeValidation={this.changeValidation}/>
|
||||
</div>
|
||||
|
|
@ -98,26 +78,27 @@ var DynamicInput = React.createClass({
|
|||
}
|
||||
});
|
||||
|
||||
var Validations = React.createClass({
|
||||
changeValidation: function(e) {
|
||||
const Validations = React.createClass({
|
||||
changeValidation(e) {
|
||||
this.props.changeValidation(e.target.value);
|
||||
},
|
||||
render: function() {
|
||||
render() {
|
||||
const { validationType } = this.props;
|
||||
return (
|
||||
<fieldset onChange={this.changeValidation}>
|
||||
<legend>Validation Type</legend>
|
||||
<div>
|
||||
<input name='validationType' type='radio' value='time' checked={this.props.validationType === 'time'}/>Time
|
||||
<input name='validationType' type='radio' value='time' defaultChecked={validationType === 'time'}/>Time
|
||||
</div>
|
||||
<div>
|
||||
<input name='validationType' type='radio' value='decimal' checked={this.props.validationType === 'decimal'}/>Decimal
|
||||
<input name='validationType' type='radio' value='decimal' defaultChecked={validationType === 'decimal'}/>Decimal
|
||||
</div>
|
||||
<div>
|
||||
<input name='validationType' type='radio' value='binary' checked={this.props.validationType === 'binary'}/>Binary
|
||||
<input name='validationType' type='radio' value='binary' defaultChecked={validationType === 'binary'}/>Binary
|
||||
</div>
|
||||
</fieldset>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
React.render(<App/>, document.getElementById('example'));
|
||||
ReactDOM.render(<App/>, document.getElementById('example'));
|
||||
|
|
|
|||
|
|
@ -38,7 +38,8 @@ form {
|
|||
.form-group input[type='text'],
|
||||
.form-group input[type='email'],
|
||||
.form-group input[type='number'],
|
||||
.form-group input[type='password'] {
|
||||
.form-group input[type='password'],
|
||||
.form-group select {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 34px;
|
||||
|
|
@ -62,4 +63,11 @@ form {
|
|||
button {
|
||||
padding: 10px 15px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
}
|
||||
|
||||
.buttons button {
|
||||
margin-left: 10px;
|
||||
}
|
||||
.buttons button:first-child {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
<ul>
|
||||
<li><a href="login/index.html">Login Page</a></li>
|
||||
<li><a href="custom-validation/index.html">Custom Validation</a></li>
|
||||
<li><a href="reset-values/index.html">Reset Values</a></li>
|
||||
</ul>
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
|
|
|
|||
|
|
@ -1,65 +1,31 @@
|
|||
var React = require('react');
|
||||
var Formsy = require('formsy-react');
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import { Form } from 'formsy-react';
|
||||
|
||||
var App = React.createClass({
|
||||
getInitialState: function() {
|
||||
import MyInput from './../components/Input';
|
||||
|
||||
const App = React.createClass({
|
||||
getInitialState() {
|
||||
return { canSubmit: false };
|
||||
},
|
||||
submit: function (data) {
|
||||
submit(data) {
|
||||
alert(JSON.stringify(data, null, 4));
|
||||
},
|
||||
enableButton: function () {
|
||||
this.setState({
|
||||
canSubmit: true
|
||||
});
|
||||
enableButton() {
|
||||
this.setState({ canSubmit: true });
|
||||
},
|
||||
disableButton: function () {
|
||||
this.setState({
|
||||
canSubmit: false
|
||||
});
|
||||
disableButton() {
|
||||
this.setState({ canSubmit: false });
|
||||
},
|
||||
render: function () {
|
||||
render() {
|
||||
return (
|
||||
<Formsy.Form onSubmit={this.submit} onValid={this.enableButton} onInvalid={this.disableButton} className="login">
|
||||
<MyOwnInput name="email" title="Email" validations="isEmail" validationError="This is not a valid email" required />
|
||||
<MyOwnInput name="password" title="Password" type="password" required />
|
||||
<Form onSubmit={this.submit} onValid={this.enableButton} onInvalid={this.disableButton} className="login">
|
||||
<MyInput name="email" title="Email" validations="isEmail" validationError="This is not a valid email" required />
|
||||
<MyInput name="password" title="Password" type="password" required />
|
||||
<button type="submit" disabled={!this.state.canSubmit}>Submit</button>
|
||||
</Formsy.Form>
|
||||
</Form>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
var MyOwnInput = React.createClass({
|
||||
|
||||
// Add the Formsy Mixin
|
||||
mixins: [Formsy.Mixin],
|
||||
|
||||
// setValue() will set the value of the component, which in
|
||||
// turn will validate it and the rest of the form
|
||||
changeValue: function (event) {
|
||||
this.setValue(event.currentTarget.value);
|
||||
},
|
||||
render: function () {
|
||||
|
||||
// Set a specific className based on the validation
|
||||
// state of this component. showRequired() is true
|
||||
// when the value is empty and the required prop is
|
||||
// passed to the input. showError() is true when the
|
||||
// value typed is invalid
|
||||
var className = this.props.className + ' ' + (this.showRequired() ? 'required' : this.showError() ? 'error' : null);
|
||||
|
||||
// An error message is returned ONLY if the component is invalid
|
||||
// or the server has returned an error message
|
||||
var errorMessage = this.getErrorMessage();
|
||||
|
||||
return (
|
||||
<div className='form-group'>
|
||||
<label htmlFor={this.props.name}>{this.props.title}</label>
|
||||
<input type={this.props.type || 'text'} name={this.props.name} onChange={this.changeValue} value={this.getValue()}/>
|
||||
<span className='validation-error'>{errorMessage}</span>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
React.render(<App/>, document.getElementById('example'));
|
||||
ReactDOM.render(<App/>, document.getElementById('example'));
|
||||
|
|
|
|||
|
|
@ -0,0 +1,4 @@
|
|||
.form {
|
||||
width: 400px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import { Form } from 'formsy-react';
|
||||
|
||||
import MyInput from './../components/Input';
|
||||
import MySelect from './../components/Select';
|
||||
|
||||
const user = {
|
||||
name: 'Sam',
|
||||
free: true,
|
||||
hair: 'brown'
|
||||
};
|
||||
|
||||
const App = React.createClass({
|
||||
submit(data) {
|
||||
alert(JSON.stringify(data, null, 4));
|
||||
},
|
||||
resetForm() {
|
||||
this.refs.form.reset();
|
||||
},
|
||||
render() {
|
||||
return (
|
||||
<Formsy.Form ref="form" onSubmit={this.submit} className="form">
|
||||
<MyInput name="name" title="Name" value={user.name} />
|
||||
<MyInput name="free" title="Free to hire" type="checkbox" value={user.free} />
|
||||
<MySelect name="hair" title="Hair" value={user.hair}
|
||||
options={[
|
||||
{ value: "black", title: "Black" },
|
||||
{ value: "brown", title: "Brown" },
|
||||
{ value: "blonde", title: "Blonde" },
|
||||
{ value: "red", title: "Red" }
|
||||
]}
|
||||
/>
|
||||
|
||||
<div className="buttons">
|
||||
<button type="reset" onClick={this.resetForm}>Reset</button>
|
||||
<button type="submit">Submit</button>
|
||||
</div>
|
||||
</Formsy.Form>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
ReactDOM.render(<App/>, document.getElementById('example'));
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Reset Values</title>
|
||||
<link href="../global.css" rel="stylesheet"/>
|
||||
<link href="app.css" rel="stylesheet"/>
|
||||
</head>
|
||||
<body>
|
||||
<h1 class="breadcrumbs"><a href="../index.html">Formsy React Examples</a> / Reset Values</h1>
|
||||
<div id="example"/>
|
||||
<script src="/__build__/shared.js"></script>
|
||||
<script src="/__build__/reset-values.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -11,7 +11,7 @@ module.exports = {
|
|||
devtool: 'inline-source-map',
|
||||
|
||||
entry: fs.readdirSync(__dirname).reduce(function (entries, dir) {
|
||||
var isDraft = dir.charAt(0) === '_';
|
||||
var isDraft = dir.charAt(0) === '_' || dir.indexOf('components') >= 0;
|
||||
|
||||
if (!isDraft && isDirectory(path.join(__dirname, dir))) {
|
||||
entries[dir] = path.join(__dirname, dir, 'app.js');
|
||||
|
|
|
|||
22
package.json
22
package.json
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "formsy-react",
|
||||
"version": "0.14.1",
|
||||
"version": "0.16.0",
|
||||
"description": "A form input builder and validator for React JS",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
|
@ -15,8 +15,9 @@
|
|||
"scripts": {
|
||||
"start": "webpack-dev-server --content-base build",
|
||||
"deploy": "NODE_ENV=production webpack -p --config webpack.production.config.js",
|
||||
"test": "node testrunner",
|
||||
"examples": "webpack-dev-server --config examples/webpack.config.js --content-base examples"
|
||||
"test": "babel-node testrunner",
|
||||
"examples": "webpack-dev-server --config examples/webpack.config.js --content-base examples",
|
||||
"prepublish": "babel ./src/ -d ./lib/"
|
||||
},
|
||||
"author": "Christian Alfoni",
|
||||
"license": "MIT",
|
||||
|
|
@ -27,17 +28,24 @@
|
|||
"validation",
|
||||
"react-component"
|
||||
],
|
||||
"dependencies": {
|
||||
"form-data-to-object": "^0.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"babel": "^5.6.4",
|
||||
"babel-core": "^5.1.11",
|
||||
"babel-loader": "^5.0.0",
|
||||
"jasmine-node": "^1.14.5",
|
||||
"jsdom": "^3.1.2",
|
||||
"react": "^0.13.1",
|
||||
"jsdom": "^6.5.1",
|
||||
"lolex": "^1.3.2",
|
||||
"nodeunit": "^0.9.1",
|
||||
"react": "^0.14.0-rc1",
|
||||
"react-addons-test-utils": "^0.14.0-rc1",
|
||||
"react-dom": "^0.14.0-rc1",
|
||||
"sinon": "^1.17.1",
|
||||
"webpack": "^1.7.3",
|
||||
"webpack-dev-server": "^1.7.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "0.13.x"
|
||||
"react": "^0.14.0-rc1"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -1,593 +0,0 @@
|
|||
var React = require('react/addons');
|
||||
var TestUtils = React.addons.TestUtils;
|
||||
var Formsy = require('./../src/main.js');
|
||||
|
||||
describe('Element', function() {
|
||||
|
||||
it('should return passed and setValue() value when using getValue()', function () {
|
||||
|
||||
var TestInput = React.createClass({
|
||||
mixins: [Formsy.Mixin],
|
||||
updateValue: function (event) {
|
||||
this.setValue(event.target.value);
|
||||
},
|
||||
render: function () {
|
||||
return <input value={this.getValue()} onChange={this.updateValue}/>
|
||||
}
|
||||
});
|
||||
var form = TestUtils.renderIntoDocument(
|
||||
<Formsy.Form>
|
||||
<TestInput name="foo" value="foo"/>
|
||||
</Formsy.Form>
|
||||
);
|
||||
|
||||
var input = TestUtils.findRenderedDOMComponentWithTag(form, 'INPUT');
|
||||
expect(input.getDOMNode().value).toBe('foo');
|
||||
TestUtils.Simulate.change(input, {target: {value: 'foobar'}});
|
||||
expect(input.getDOMNode().value).toBe('foobar');
|
||||
|
||||
});
|
||||
|
||||
it('should set back to pristine value when running reset', function () {
|
||||
|
||||
var reset = null;
|
||||
var TestInput = React.createClass({
|
||||
mixins: [Formsy.Mixin],
|
||||
componentDidMount: function () {
|
||||
reset = this.resetValue;
|
||||
},
|
||||
updateValue: function (event) {
|
||||
this.setValue(event.target.value);
|
||||
},
|
||||
render: function () {
|
||||
return <input value={this.getValue()} onChange={this.updateValue}/>
|
||||
}
|
||||
});
|
||||
var form = TestUtils.renderIntoDocument(
|
||||
<Formsy.Form>
|
||||
<TestInput name="foo" value="foo"/>
|
||||
</Formsy.Form>
|
||||
);
|
||||
|
||||
var input = TestUtils.findRenderedDOMComponentWithTag(form, 'INPUT');
|
||||
TestUtils.Simulate.change(input, {target: {value: 'foobar'}});
|
||||
reset();
|
||||
expect(input.getDOMNode().value).toBe('foo');
|
||||
|
||||
});
|
||||
|
||||
it('should return error message passed when calling getErrorMessage()', function () {
|
||||
|
||||
var getErrorMessage = null;
|
||||
var TestInput = React.createClass({
|
||||
mixins: [Formsy.Mixin],
|
||||
componentDidMount: function () {
|
||||
getErrorMessage = this.getErrorMessage;
|
||||
},
|
||||
updateValue: function (event) {
|
||||
this.setValue(event.target.value);
|
||||
},
|
||||
render: function () {
|
||||
return <input value={this.getValue()} onChange={this.updateValue}/>
|
||||
}
|
||||
});
|
||||
var form = TestUtils.renderIntoDocument(
|
||||
<Formsy.Form>
|
||||
<TestInput name="foo" value="foo" validations="isEmail" validationError="Has to be email"/>
|
||||
</Formsy.Form>
|
||||
);
|
||||
|
||||
expect(getErrorMessage()).toBe('Has to be email');
|
||||
|
||||
});
|
||||
|
||||
it('should return true or false when calling isValid() depending on valid state', function () {
|
||||
|
||||
var isValid = null;
|
||||
var TestInput = React.createClass({
|
||||
mixins: [Formsy.Mixin],
|
||||
componentDidMount: function () {
|
||||
isValid = this.isValid;
|
||||
},
|
||||
updateValue: function (event) {
|
||||
this.setValue(event.target.value);
|
||||
},
|
||||
render: function () {
|
||||
return <input value={this.getValue()} onChange={this.updateValue}/>
|
||||
}
|
||||
});
|
||||
var form = TestUtils.renderIntoDocument(
|
||||
<Formsy.Form url="/users">
|
||||
<TestInput name="foo" value="foo" validations="isEmail"/>
|
||||
</Formsy.Form>
|
||||
);
|
||||
|
||||
expect(isValid()).toBe(false);
|
||||
var input = TestUtils.findRenderedDOMComponentWithTag(form, 'INPUT');
|
||||
TestUtils.Simulate.change(input, {target: {value: 'foo@foo.com'}});
|
||||
expect(isValid()).toBe(true);
|
||||
|
||||
});
|
||||
|
||||
it('should return true or false when calling isRequired() depending on passed required attribute', function () {
|
||||
|
||||
var isRequireds = [];
|
||||
var TestInput = React.createClass({
|
||||
mixins: [Formsy.Mixin],
|
||||
componentDidMount: function () {
|
||||
isRequireds.push(this.isRequired);
|
||||
},
|
||||
updateValue: function (event) {
|
||||
this.setValue(event.target.value);
|
||||
},
|
||||
render: function () {
|
||||
return <input value={this.getValue()} onChange={this.updateValue}/>
|
||||
}
|
||||
});
|
||||
var form = TestUtils.renderIntoDocument(
|
||||
<Formsy.Form url="/users">
|
||||
<TestInput name="foo" value=""/>
|
||||
<TestInput name="foo" value="" required/>
|
||||
<TestInput name="foo" value="foo" required="isLength:3"/>
|
||||
</Formsy.Form>
|
||||
);
|
||||
|
||||
expect(isRequireds[0]()).toBe(false);
|
||||
expect(isRequireds[1]()).toBe(true);
|
||||
expect(isRequireds[2]()).toBe(true);
|
||||
|
||||
});
|
||||
|
||||
it('should return true or false when calling showRequired() depending on input being empty and required is passed, or not', function () {
|
||||
|
||||
var showRequireds = [];
|
||||
var TestInput = React.createClass({
|
||||
mixins: [Formsy.Mixin],
|
||||
componentDidMount: function () {
|
||||
showRequireds.push(this.showRequired);
|
||||
},
|
||||
updateValue: function (event) {
|
||||
this.setValue(event.target.value);
|
||||
},
|
||||
render: function () {
|
||||
return <input value={this.getValue()} onChange={this.updateValue}/>
|
||||
}
|
||||
});
|
||||
var form = TestUtils.renderIntoDocument(
|
||||
<Formsy.Form url="/users">
|
||||
<TestInput name="A" value="foo"/>
|
||||
<TestInput name="B" value="" required/>
|
||||
<TestInput name="C" value=""/>
|
||||
</Formsy.Form>
|
||||
);
|
||||
|
||||
expect(showRequireds[0]()).toBe(false);
|
||||
expect(showRequireds[1]()).toBe(true);
|
||||
expect(showRequireds[2]()).toBe(false);
|
||||
|
||||
});
|
||||
|
||||
it('should return true or false when calling isPristine() depending on input has been "touched" or not', function () {
|
||||
|
||||
var isPristine = null;
|
||||
var TestInput = React.createClass({
|
||||
mixins: [Formsy.Mixin],
|
||||
componentDidMount: function () {
|
||||
isPristine = this.isPristine;
|
||||
},
|
||||
updateValue: function (event) {
|
||||
this.setValue(event.target.value);
|
||||
},
|
||||
render: function () {
|
||||
return <input value={this.getValue()} onChange={this.updateValue}/>
|
||||
}
|
||||
});
|
||||
var form = TestUtils.renderIntoDocument(
|
||||
<Formsy.Form url="/users">
|
||||
<TestInput name="A" value="foo"/>
|
||||
</Formsy.Form>
|
||||
);
|
||||
|
||||
expect(isPristine()).toBe(true);
|
||||
var input = TestUtils.findRenderedDOMComponentWithTag(form, 'INPUT');
|
||||
TestUtils.Simulate.change(input, {target: {value: 'foo'}});
|
||||
expect(isPristine()).toBe(false);
|
||||
|
||||
});
|
||||
|
||||
it('should allow an undefined value to be updated to a value', function (done) {
|
||||
var TestInput = React.createClass({
|
||||
mixins: [Formsy.Mixin],
|
||||
changeValue: function (event) {
|
||||
this.setValue(event.target.value);
|
||||
},
|
||||
render: function () {
|
||||
return <input value={this.getValue()} onChange={this.changeValue}/>
|
||||
}
|
||||
});
|
||||
var TestForm = React.createClass({
|
||||
getInitialState: function () {
|
||||
return {value: undefined};
|
||||
},
|
||||
changeValue: function () {
|
||||
this.setState({
|
||||
value: 'foo'
|
||||
});
|
||||
},
|
||||
render: function () {
|
||||
return (
|
||||
<Formsy.Form url="/users">
|
||||
<TestInput name="A" value={this.state.value}/>
|
||||
</Formsy.Form>
|
||||
);
|
||||
}
|
||||
});
|
||||
var form = TestUtils.renderIntoDocument(
|
||||
<TestForm/>
|
||||
);
|
||||
|
||||
form.changeValue();
|
||||
var input = TestUtils.findRenderedDOMComponentWithTag(form, 'INPUT');
|
||||
setTimeout(function () {
|
||||
expect(input.getDOMNode().value).toBe('foo');
|
||||
done();
|
||||
}, 0);
|
||||
});
|
||||
|
||||
it('should be able to test a values validity', function () {
|
||||
|
||||
var isInvalid = false;
|
||||
var TestInput = React.createClass({
|
||||
mixins: [Formsy.Mixin],
|
||||
render: function () {
|
||||
return <input/>
|
||||
}
|
||||
});
|
||||
var TestForm = React.createClass({
|
||||
render: function () {
|
||||
return (
|
||||
<Formsy.Form>
|
||||
<TestInput name="A" validations="isEmail"/>
|
||||
</Formsy.Form>
|
||||
);
|
||||
}
|
||||
});
|
||||
var form = TestUtils.renderIntoDocument(
|
||||
<TestForm/>
|
||||
);
|
||||
|
||||
var input = TestUtils.findRenderedComponentWithType(form, TestInput);
|
||||
expect(input.isValidValue('foo@bar.com')).toBe(true);
|
||||
expect(input.isValidValue('foo@bar')).toBe(false);
|
||||
|
||||
});
|
||||
|
||||
it('should be able to use an object as validations property', function () {
|
||||
|
||||
var TestInput = React.createClass({
|
||||
mixins: [Formsy.Mixin],
|
||||
render: function () {
|
||||
return <input/>
|
||||
}
|
||||
});
|
||||
var TestForm = React.createClass({
|
||||
render: function () {
|
||||
return (
|
||||
<Formsy.Form>
|
||||
<TestInput name="A" validations={{
|
||||
isEmail: true
|
||||
}}/>
|
||||
</Formsy.Form>
|
||||
);
|
||||
}
|
||||
});
|
||||
var form = TestUtils.renderIntoDocument(
|
||||
<TestForm/>
|
||||
);
|
||||
|
||||
var input = TestUtils.findRenderedComponentWithType(form, TestInput);
|
||||
expect(input.isValidValue('foo@bar.com')).toBe(true);
|
||||
expect(input.isValidValue('foo@bar')).toBe(false);
|
||||
});
|
||||
|
||||
it('should be able to pass complex values to a validation rule', function () {
|
||||
|
||||
var TestInput = React.createClass({
|
||||
mixins: [Formsy.Mixin],
|
||||
changeValue: function (event) {
|
||||
this.setValue(event.target.value);
|
||||
},
|
||||
render: function () {
|
||||
return <input value={this.getValue()} onChange={this.changeValue}/>
|
||||
}
|
||||
});
|
||||
var TestForm = React.createClass({
|
||||
render: function () {
|
||||
return (
|
||||
<Formsy.Form>
|
||||
<TestInput name="A" validations={{
|
||||
matchRegexp: /foo/
|
||||
}} value="foo"/>
|
||||
</Formsy.Form>
|
||||
);
|
||||
}
|
||||
});
|
||||
var form = TestUtils.renderIntoDocument(
|
||||
<TestForm/>
|
||||
);
|
||||
|
||||
var inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput);
|
||||
expect(inputComponent.isValid()).toBe(true);
|
||||
var input = TestUtils.findRenderedDOMComponentWithTag(form, 'INPUT');
|
||||
TestUtils.Simulate.change(input, {target: {value: 'bar'}});
|
||||
expect(inputComponent.isValid()).toBe(false);
|
||||
});
|
||||
|
||||
it('should be able to run a function to validate', function () {
|
||||
|
||||
var TestInput = React.createClass({
|
||||
mixins: [Formsy.Mixin],
|
||||
changeValue: function (event) {
|
||||
this.setValue(event.target.value);
|
||||
},
|
||||
render: function () {
|
||||
return <input value={this.getValue()} onChange={this.changeValue}/>
|
||||
}
|
||||
});
|
||||
var TestForm = React.createClass({
|
||||
customValidationA: function (values, value) {
|
||||
return value === 'foo';
|
||||
},
|
||||
customValidationB: function (values, value) {
|
||||
return value === 'foo' && values.A === 'foo';
|
||||
},
|
||||
render: function () {
|
||||
return (
|
||||
<Formsy.Form>
|
||||
<TestInput name="A" validations={{
|
||||
custom: this.customValidationA
|
||||
}} value="foo"/>
|
||||
<TestInput name="B" validations={{
|
||||
custom: this.customValidationB
|
||||
}} value="foo"/>
|
||||
</Formsy.Form>
|
||||
);
|
||||
}
|
||||
});
|
||||
var form = TestUtils.renderIntoDocument(
|
||||
<TestForm/>
|
||||
);
|
||||
|
||||
var inputComponent = TestUtils.scryRenderedComponentsWithType(form, TestInput);
|
||||
expect(inputComponent[0].isValid()).toBe(true);
|
||||
expect(inputComponent[1].isValid()).toBe(true);
|
||||
var input = TestUtils.scryRenderedDOMComponentsWithTag(form, 'INPUT');
|
||||
TestUtils.Simulate.change(input[0], {target: {value: 'bar'}});
|
||||
expect(inputComponent[0].isValid()).toBe(false);
|
||||
expect(inputComponent[1].isValid()).toBe(false);
|
||||
});
|
||||
|
||||
it('should override all error messages with error messages passed by form', function () {
|
||||
var TestInput = React.createClass({
|
||||
mixins: [Formsy.Mixin],
|
||||
render: function () {
|
||||
return <input/>
|
||||
}
|
||||
});
|
||||
var TestForm = React.createClass({
|
||||
render: function () {
|
||||
return (
|
||||
<Formsy.Form validationErrors={{A: 'bar'}}>
|
||||
<TestInput name="A" validations={{
|
||||
isEmail: true
|
||||
}} validationError="bar2" validationErrors={{isEmail: 'bar3'}} value="foo"/>
|
||||
</Formsy.Form>
|
||||
);
|
||||
}
|
||||
});
|
||||
var form = TestUtils.renderIntoDocument(
|
||||
<TestForm/>
|
||||
);
|
||||
|
||||
var inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput);
|
||||
expect(inputComponent.getErrorMessage()).toBe('bar');
|
||||
});
|
||||
|
||||
it('should override validation rules with required rules', function () {
|
||||
var TestInput = React.createClass({
|
||||
mixins: [Formsy.Mixin],
|
||||
render: function () {
|
||||
return <input/>
|
||||
}
|
||||
});
|
||||
var TestForm = React.createClass({
|
||||
render: function () {
|
||||
return (
|
||||
<Formsy.Form>
|
||||
<TestInput name="A"
|
||||
validations={{
|
||||
isEmail: true
|
||||
}}
|
||||
validationError="bar"
|
||||
validationErrors={{isEmail: 'bar2', isLength: 'bar3'}}
|
||||
value="f"
|
||||
required={{
|
||||
isLength: 1
|
||||
}}
|
||||
/>
|
||||
</Formsy.Form>
|
||||
);
|
||||
}
|
||||
});
|
||||
var form = TestUtils.renderIntoDocument(
|
||||
<TestForm/>
|
||||
);
|
||||
|
||||
var inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput);
|
||||
expect(inputComponent.getErrorMessage()).toBe('bar3');
|
||||
});
|
||||
|
||||
it('should fall back to default error message when non exist in validationErrors map', function () {
|
||||
var TestInput = React.createClass({
|
||||
mixins: [Formsy.Mixin],
|
||||
render: function () {
|
||||
return <input/>
|
||||
}
|
||||
});
|
||||
var TestForm = React.createClass({
|
||||
render: function () {
|
||||
return (
|
||||
<Formsy.Form>
|
||||
<TestInput name="A"
|
||||
validations={{
|
||||
isEmail: true
|
||||
}}
|
||||
validationError="bar"
|
||||
validationErrors={{foo: 'bar'}}
|
||||
value="foo"
|
||||
/>
|
||||
</Formsy.Form>
|
||||
);
|
||||
}
|
||||
});
|
||||
var form = TestUtils.renderIntoDocument(
|
||||
<TestForm/>
|
||||
);
|
||||
|
||||
var inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput);
|
||||
expect(inputComponent.getErrorMessage()).toBe('bar');
|
||||
});
|
||||
|
||||
it('should not be valid if it is required and required rule is true', function () {
|
||||
var TestInput = React.createClass({
|
||||
mixins: [Formsy.Mixin],
|
||||
render: function () {
|
||||
return <input/>
|
||||
}
|
||||
});
|
||||
var TestForm = React.createClass({
|
||||
render: function () {
|
||||
return (
|
||||
<Formsy.Form>
|
||||
<TestInput name="A"
|
||||
required
|
||||
/>
|
||||
</Formsy.Form>
|
||||
);
|
||||
}
|
||||
});
|
||||
var form = TestUtils.renderIntoDocument(
|
||||
<TestForm/>
|
||||
);
|
||||
|
||||
var inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput);
|
||||
expect(inputComponent.isValid()).toBe(false);
|
||||
});
|
||||
|
||||
it('should handle objects and arrays as values', function () {
|
||||
|
||||
var TestInput = React.createClass({
|
||||
mixins: [Formsy.Mixin],
|
||||
render: function () {
|
||||
return <div>{JSON.stringify(this.getValue())}</div>
|
||||
}
|
||||
});
|
||||
var TestForm = React.createClass({
|
||||
getInitialState: function () {
|
||||
return {
|
||||
foo: {foo: 'bar'},
|
||||
bar: ['foo']
|
||||
};
|
||||
},
|
||||
render: function () {
|
||||
return (
|
||||
<Formsy.Form>
|
||||
<TestInput name="foo" value={this.state.foo}/>
|
||||
<TestInput name="bar" value={this.state.bar}/>
|
||||
</Formsy.Form>
|
||||
);
|
||||
}
|
||||
});
|
||||
var form = TestUtils.renderIntoDocument(<TestForm/>);
|
||||
|
||||
form.setState({
|
||||
foo: {foo: 'foo'},
|
||||
bar: ['bar']
|
||||
});
|
||||
|
||||
var inputs = TestUtils.scryRenderedComponentsWithType(form, TestInput);
|
||||
expect(inputs[0].getValue()).toEqual({foo: 'foo'});
|
||||
expect(inputs[1].getValue()).toEqual(['bar']);
|
||||
|
||||
});
|
||||
|
||||
it('should handle isFormDisabled with dynamic inputs', function () {
|
||||
|
||||
var TestInput = React.createClass({
|
||||
mixins: [Formsy.Mixin],
|
||||
render: function () {
|
||||
return <input disabled={this.isFormDisabled()} />
|
||||
}
|
||||
});
|
||||
|
||||
var TestForm = React.createClass({
|
||||
getInitialState: function () {
|
||||
return {
|
||||
bool: true
|
||||
};
|
||||
},
|
||||
flip: function () {
|
||||
this.setState({
|
||||
bool: !this.state.bool
|
||||
});
|
||||
},
|
||||
render: function () {
|
||||
return (
|
||||
<Formsy.Form disabled={this.state.bool}>
|
||||
{this.state.bool ?
|
||||
<TestInput name="foo" /> :
|
||||
<TestInput name="bar" />
|
||||
}
|
||||
</Formsy.Form>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
var form = TestUtils.renderIntoDocument(<TestForm/>);
|
||||
var input = TestUtils.findRenderedComponentWithType(form, TestInput);
|
||||
expect(input.isFormDisabled()).toBe(true);
|
||||
form.flip();
|
||||
expect(input.isFormDisabled()).toBe(false);
|
||||
|
||||
});
|
||||
|
||||
it('should allow for dot notation in name which maps to a deep object', function () {
|
||||
|
||||
var TestInput = React.createClass({
|
||||
mixins: [Formsy.Mixin],
|
||||
render: function () {
|
||||
return <input/>
|
||||
}
|
||||
});
|
||||
|
||||
var TestForm = React.createClass({
|
||||
onSubmit: function (model) {
|
||||
expect(model).toEqual({foo: {bar: 'foo', test: 'test'}});
|
||||
},
|
||||
render: function () {
|
||||
return (
|
||||
<Formsy.Form>
|
||||
<TestInput name="foo.bar" value="foo"/>
|
||||
<TestInput name="foo.test" value="test"/>
|
||||
</Formsy.Form>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
var form = TestUtils.renderIntoDocument(<TestForm/>);
|
||||
var formEl = TestUtils.findRenderedDOMComponentWithTag(form, 'form');
|
||||
TestUtils.Simulate.submit(formEl);
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
|
@ -1,692 +0,0 @@
|
|||
var React = require('react/addons');
|
||||
var TestUtils = React.addons.TestUtils;
|
||||
var Formsy = require('./../src/main.js');
|
||||
|
||||
describe('Formsy', function () {
|
||||
|
||||
describe('Setting up a form', function () {
|
||||
|
||||
it('should render a form into the document', function () {
|
||||
var form = TestUtils.renderIntoDocument( <Formsy.Form></Formsy.Form>);
|
||||
expect(form.getDOMNode().tagName).toEqual('FORM');
|
||||
});
|
||||
|
||||
it('should set a class name if passed', function () {
|
||||
var form = TestUtils.renderIntoDocument( <Formsy.Form className="foo"></Formsy.Form>);
|
||||
expect(form.getDOMNode().className).toEqual('foo');
|
||||
});
|
||||
|
||||
it('should allow for null/undefined children', function (done) {
|
||||
var TestInput = React.createClass({
|
||||
mixins: [Formsy.Mixin],
|
||||
changeValue: function (event) {
|
||||
this.setValue(event.target.value);
|
||||
},
|
||||
render: function () {
|
||||
return <input value={this.getValue()} onChange={this.changeValue}/>
|
||||
}
|
||||
});
|
||||
|
||||
var model = null;
|
||||
var TestForm = React.createClass({
|
||||
onSubmit: function (formModel) {
|
||||
model = formModel;
|
||||
},
|
||||
render: function () {
|
||||
return (
|
||||
<Formsy.Form onSubmit={ this.onSubmit }>
|
||||
<h1>Test</h1>
|
||||
{ null }
|
||||
{ undefined }
|
||||
<TestInput name='name' value={ 'foo' } />
|
||||
</Formsy.Form>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
var form = TestUtils.renderIntoDocument(<TestForm/>);
|
||||
setTimeout(function () {
|
||||
TestUtils.Simulate.submit(form.getDOMNode());
|
||||
expect(model).toEqual({name: 'foo'});
|
||||
done();
|
||||
}, 10);
|
||||
});
|
||||
|
||||
it('should allow for inputs being added dynamically', function (done) {
|
||||
|
||||
var inputs = [];
|
||||
var forceUpdate = null;
|
||||
var model = null;
|
||||
var TestInput = React.createClass({
|
||||
mixins: [Formsy.Mixin],
|
||||
render: function () {
|
||||
return <div/>
|
||||
}
|
||||
});
|
||||
var TestForm = React.createClass({
|
||||
componentWillMount: function () {
|
||||
forceUpdate = this.forceUpdate.bind(this);
|
||||
},
|
||||
onSubmit: function (formModel) {
|
||||
model = formModel;
|
||||
},
|
||||
render: function () {
|
||||
return (
|
||||
<Formsy.Form onSubmit={this.onSubmit}>
|
||||
{inputs}
|
||||
</Formsy.Form>);
|
||||
}
|
||||
});
|
||||
var form = TestUtils.renderIntoDocument(
|
||||
<TestForm/>
|
||||
);
|
||||
|
||||
// Wait before adding the input
|
||||
setTimeout(function () {
|
||||
|
||||
inputs.push(<TestInput key={inputs.length} name="test" value=""/>);
|
||||
|
||||
forceUpdate(function () {
|
||||
// Wait for next event loop, as that does the form
|
||||
setTimeout(function () {
|
||||
TestUtils.Simulate.submit(form.getDOMNode());
|
||||
expect(model.test).toBeDefined();
|
||||
done();
|
||||
}, 0);
|
||||
|
||||
});
|
||||
|
||||
}, 10);
|
||||
|
||||
});
|
||||
|
||||
it('should allow dynamically added inputs to update the form-model', function (done) {
|
||||
|
||||
var inputs = [];
|
||||
var forceUpdate = null;
|
||||
var model = null;
|
||||
var TestInput = React.createClass({
|
||||
mixins: [Formsy.Mixin],
|
||||
changeValue: function (event) {
|
||||
this.setValue(event.target.value);
|
||||
},
|
||||
render: function () {
|
||||
return <input value={this.getValue()} onChange={this.changeValue}/>
|
||||
}
|
||||
});
|
||||
var TestForm = React.createClass({
|
||||
componentWillMount: function () {
|
||||
forceUpdate = this.forceUpdate.bind(this);
|
||||
},
|
||||
onSubmit: function (formModel) {
|
||||
model = formModel;
|
||||
},
|
||||
render: function () {
|
||||
return (
|
||||
<Formsy.Form onSubmit={this.onSubmit}>
|
||||
{inputs}
|
||||
</Formsy.Form>);
|
||||
}
|
||||
});
|
||||
var form = TestUtils.renderIntoDocument(
|
||||
<TestForm/>
|
||||
);
|
||||
|
||||
// Wait before adding the input
|
||||
setTimeout(function () {
|
||||
|
||||
inputs.push(<TestInput key={inputs.length} name="test"/>);
|
||||
|
||||
forceUpdate(function () {
|
||||
|
||||
// Wait for next event loop, as that does the form
|
||||
setTimeout(function () {
|
||||
TestUtils.Simulate.change(TestUtils.findRenderedDOMComponentWithTag(form, 'INPUT'), {target: {value: 'foo'}});
|
||||
TestUtils.Simulate.submit(form.getDOMNode());
|
||||
expect(model.test).toBe('foo');
|
||||
done();
|
||||
}, 0);
|
||||
|
||||
});
|
||||
|
||||
}, 0);
|
||||
|
||||
});
|
||||
|
||||
it('should allow a dynamically updated input to update the form-model', function (done) {
|
||||
|
||||
var forceUpdate = null;
|
||||
var model = null;
|
||||
var TestInput = React.createClass({
|
||||
mixins: [Formsy.Mixin],
|
||||
changeValue: function (event) {
|
||||
this.setValue(event.target.value);
|
||||
},
|
||||
render: function () {
|
||||
return <input value={this.getValue()} onChange={this.changeValue}/>
|
||||
}
|
||||
});
|
||||
|
||||
var input;
|
||||
var TestForm = React.createClass({
|
||||
componentWillMount: function () {
|
||||
forceUpdate = this.forceUpdate.bind(this);
|
||||
},
|
||||
onSubmit: function (formModel) {
|
||||
model = formModel;
|
||||
},
|
||||
render: function () {
|
||||
input = <TestInput name='test' value={ this.props.value } />;
|
||||
|
||||
return (
|
||||
<Formsy.Form onSubmit={this.onSubmit}>
|
||||
{input}
|
||||
</Formsy.Form>);
|
||||
}
|
||||
});
|
||||
var form = TestUtils.renderIntoDocument(<TestForm value='foo'/>);
|
||||
|
||||
// Wait before changing the input
|
||||
setTimeout(function () {
|
||||
form.setProps({value: 'bar'});
|
||||
|
||||
forceUpdate(function () {
|
||||
// Wait for next event loop, as that does the form
|
||||
setTimeout(function () {
|
||||
TestUtils.Simulate.submit(form.getDOMNode());
|
||||
expect(model.test).toBe('bar');
|
||||
done();
|
||||
}, 0);
|
||||
|
||||
});
|
||||
|
||||
}, 10);
|
||||
|
||||
});
|
||||
|
||||
describe('validations', function() {
|
||||
var CheckValid, onSubmit, OtherCheckValid;
|
||||
var isValid;
|
||||
|
||||
var TestInput = React.createClass({
|
||||
mixins: [Formsy.Mixin],
|
||||
changeValue: function (event) {
|
||||
this.setValue(event.target.value);
|
||||
},
|
||||
render: function () {
|
||||
return <input value={ this.getValue() } onChange={ this.changeValue } />
|
||||
}
|
||||
});
|
||||
|
||||
var TestForm = React.createClass({
|
||||
getDefaultProps: function() {
|
||||
return {
|
||||
inputs: [],
|
||||
};
|
||||
},
|
||||
render: function () {
|
||||
var builtInputs = [];
|
||||
var inputs = this.props.inputs;
|
||||
for (var i=0; i < inputs.length; i++) {
|
||||
var input = inputs[i];
|
||||
builtInputs.push(<TestInput { ...input } key={ input.name } />);
|
||||
}
|
||||
var _this = this;
|
||||
return <Formsy.Form
|
||||
onSubmit = { function(arg1) { onSubmit(arg1); } }
|
||||
onValid = { function() { isValid = true; } }
|
||||
onInvalid = { function() { isValid = false; } } >
|
||||
{ builtInputs }
|
||||
</Formsy.Form>;
|
||||
}
|
||||
});
|
||||
|
||||
beforeEach(function() {
|
||||
isValid = true;
|
||||
CheckValid = jasmine.createSpy('CheckValid');
|
||||
Formsy.addValidationRule('CheckValid', CheckValid);
|
||||
OtherCheckValid = jasmine.createSpy('CheckValid');
|
||||
Formsy.addValidationRule('OtherCheckValid', OtherCheckValid);
|
||||
onSubmit = jasmine.createSpy('onSubmit');
|
||||
});
|
||||
|
||||
it('should run when the input changes', function() {
|
||||
var form = TestUtils.renderIntoDocument(<TestForm inputs={ [{name: 'one', validations: 'CheckValid', value: 'foo'}] }/>);
|
||||
var input = TestUtils.findRenderedDOMComponentWithTag(form, 'input');
|
||||
TestUtils.Simulate.change(input.getDOMNode(), {target: {value: 'bar'}});
|
||||
expect(CheckValid).toHaveBeenCalledWith({one: 'bar'}, 'bar', true);
|
||||
expect(OtherCheckValid).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should allow the validation to be changed', function() {
|
||||
var form = TestUtils.renderIntoDocument(<TestForm inputs={ [{name: 'one', validations: 'CheckValid', value: 'foo'}] }/>);
|
||||
form.setProps({inputs: [{name: 'one', validations: 'OtherCheckValid', value: 'foo'}] });
|
||||
var input = TestUtils.findRenderedDOMComponentWithTag(form, 'input');
|
||||
TestUtils.Simulate.change(input.getDOMNode(), {target: {value: 'bar'}});
|
||||
expect(OtherCheckValid).toHaveBeenCalledWith({one: 'bar'}, 'bar', true);
|
||||
});
|
||||
|
||||
it('should invalidate a form if dynamically inserted input is invalid', function(done) {
|
||||
var form = TestUtils.renderIntoDocument(<TestForm inputs={ [{name: 'one', validations: 'isEmail', value: 'foo@bar.com'}] }/>);
|
||||
expect(isValid).toEqual(true);
|
||||
form.setProps({inputs: [
|
||||
{name: 'one', validations: 'isEmail', value: 'foo@bar.com'},
|
||||
{name: 'two', validations: 'isEmail', value: 'foo@bar'},
|
||||
]}, function() {
|
||||
setTimeout(function() {
|
||||
expect(isValid).toEqual(false);
|
||||
done();
|
||||
}, 0);
|
||||
});
|
||||
});
|
||||
|
||||
it('should validate a form when removing an invalid input', function(done) {
|
||||
var form = TestUtils.renderIntoDocument(<TestForm inputs={ [
|
||||
{name: 'one', validations: 'isEmail', value: 'foo@bar.com'},
|
||||
{name: 'two', validations: 'isEmail', value: 'foo@bar'},
|
||||
] } />);
|
||||
expect(isValid).toEqual(false);
|
||||
form.setProps({inputs: [{name: 'one', validations: 'isEmail', value: 'foo@bar.com'}]}, function() {
|
||||
setTimeout(function() {
|
||||
expect(isValid).toEqual(true);
|
||||
done();
|
||||
}, 0);
|
||||
});
|
||||
});
|
||||
|
||||
it('runs multiple validations', function() {
|
||||
var form = TestUtils.renderIntoDocument(<TestForm inputs={ [{name: 'one', validations: 'CheckValid,OtherCheckValid', value: 'foo'}] }/>);
|
||||
var input = TestUtils.findRenderedDOMComponentWithTag(form, 'input');
|
||||
TestUtils.Simulate.change(input.getDOMNode(), {target: {value: 'bar'}});
|
||||
expect(CheckValid).toHaveBeenCalledWith({one: 'bar'}, 'bar', true);
|
||||
expect(OtherCheckValid).toHaveBeenCalledWith({one: 'bar'}, 'bar', true);
|
||||
});
|
||||
});
|
||||
|
||||
it('should not trigger onChange when form is mounted', function () {
|
||||
var hasChanged = jasmine.createSpy('onChange');
|
||||
var TestForm = React.createClass({
|
||||
onChange: function () {
|
||||
hasChanged();
|
||||
},
|
||||
render: function () {
|
||||
return <Formsy.Form onChange={this.onChange}></Formsy.Form>;
|
||||
}
|
||||
});
|
||||
var form = TestUtils.renderIntoDocument(<TestForm/>);
|
||||
expect(hasChanged).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should trigger onChange when form element is changed', function () {
|
||||
var hasChanged = jasmine.createSpy('onChange');
|
||||
var MyInput = React.createClass({
|
||||
mixins: [Formsy.Mixin],
|
||||
onChange: function (event) {
|
||||
this.setValue(event.target.value);
|
||||
},
|
||||
render: function () {
|
||||
return <input value={this.getValue()} onChange={this.onChange}/>
|
||||
}
|
||||
});
|
||||
var TestForm = React.createClass({
|
||||
onChange: function () {
|
||||
hasChanged();
|
||||
},
|
||||
render: function () {
|
||||
return (
|
||||
<Formsy.Form onChange={this.onChange}>
|
||||
<MyInput name="foo"/>
|
||||
</Formsy.Form>
|
||||
);
|
||||
}
|
||||
});
|
||||
var form = TestUtils.renderIntoDocument(<TestForm/>);
|
||||
TestUtils.Simulate.change(TestUtils.findRenderedDOMComponentWithTag(form, 'INPUT'), {target: {value: 'bar'}});
|
||||
expect(hasChanged).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should trigger onChange when new input is added to form', function (done) {
|
||||
var hasChanged = jasmine.createSpy('onChange');
|
||||
var inputs = [];
|
||||
var forceUpdate = null;
|
||||
var TestInput = React.createClass({
|
||||
mixins: [Formsy.Mixin],
|
||||
changeValue: function (event) {
|
||||
this.setValue(event.target.value);
|
||||
},
|
||||
render: function () {
|
||||
return <input value={this.getValue()} onChange={this.changeValue}/>
|
||||
}
|
||||
});
|
||||
var TestForm = React.createClass({
|
||||
componentWillMount: function () {
|
||||
forceUpdate = this.forceUpdate.bind(this);
|
||||
},
|
||||
onChange: function () {
|
||||
hasChanged();
|
||||
},
|
||||
render: function () {
|
||||
return (
|
||||
<Formsy.Form onChange={this.onChange}>
|
||||
{inputs}
|
||||
</Formsy.Form>);
|
||||
}
|
||||
});
|
||||
var form = TestUtils.renderIntoDocument(
|
||||
<TestForm/>
|
||||
);
|
||||
|
||||
// Wait before adding the input
|
||||
inputs.push(<TestInput key={inputs.length} name='test'/>);
|
||||
|
||||
forceUpdate(function () {
|
||||
|
||||
// Wait for next event loop, as that does the form
|
||||
setTimeout(function () {
|
||||
expect(hasChanged).toHaveBeenCalled();
|
||||
done();
|
||||
}, 0);
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('Update a form', function () {
|
||||
|
||||
it('should allow elements to check if the form is disabled', function (done) {
|
||||
|
||||
var TestInput = React.createClass({
|
||||
mixins: [Formsy.Mixin],
|
||||
render: function () {
|
||||
return <input/>
|
||||
}
|
||||
});
|
||||
var TestForm = React.createClass({
|
||||
getInitialState: function () {
|
||||
return {disabled: true};
|
||||
},
|
||||
enableForm: function () {
|
||||
this.setState({
|
||||
disabled: false
|
||||
});
|
||||
},
|
||||
render: function () {
|
||||
return (
|
||||
<Formsy.Form onChange={this.onChange} disabled={this.state.disabled}>
|
||||
<TestInput name="foo"/>
|
||||
</Formsy.Form>);
|
||||
}
|
||||
});
|
||||
var form = TestUtils.renderIntoDocument(
|
||||
<TestForm/>
|
||||
);
|
||||
|
||||
var input = TestUtils.findRenderedComponentWithType(form, TestInput);
|
||||
expect(input.isFormDisabled()).toBe(true);
|
||||
form.enableForm();
|
||||
setTimeout(function () {
|
||||
expect(input.isFormDisabled()).toBe(false);
|
||||
done();
|
||||
}, 0);
|
||||
|
||||
});
|
||||
|
||||
it('should be possible to pass error state of elements by changing an errors attribute', function (done) {
|
||||
|
||||
var TestInput = React.createClass({
|
||||
mixins: [Formsy.Mixin],
|
||||
render: function () {
|
||||
return <input/>;
|
||||
}
|
||||
});
|
||||
var TestForm = React.createClass({
|
||||
getInitialState: function () {
|
||||
return {
|
||||
validationErrors: {
|
||||
foo: 'bar'
|
||||
}
|
||||
};
|
||||
},
|
||||
onChange: function (values) {
|
||||
if (values.foo) {
|
||||
this.setState({
|
||||
validationErrors: {}
|
||||
});
|
||||
} else {
|
||||
this.setState({
|
||||
validationErrors: {foo: 'bar'}
|
||||
});
|
||||
}
|
||||
},
|
||||
render: function () {
|
||||
return (
|
||||
<Formsy.Form onChange={this.onChange} validationErrors={this.state.validationErrors}>
|
||||
<TestInput name="foo"/>
|
||||
</Formsy.Form>);
|
||||
}
|
||||
});
|
||||
var form = TestUtils.renderIntoDocument(
|
||||
<TestForm/>
|
||||
);
|
||||
|
||||
// Wait for update
|
||||
setTimeout(function () {
|
||||
var input = TestUtils.findRenderedComponentWithType(form, TestInput);
|
||||
expect(input.getErrorMessage()).toBe('bar');
|
||||
input.setValue('gotValue');
|
||||
|
||||
// Wait for update
|
||||
setTimeout(function () {
|
||||
expect(input.getErrorMessage()).toBe(null);
|
||||
done();
|
||||
}, 0);
|
||||
}, 0);
|
||||
|
||||
});
|
||||
|
||||
|
||||
it('should trigger an onValidSubmit when submitting a valid form', function () {
|
||||
|
||||
var isCalled = false;
|
||||
var TestInput = React.createClass({
|
||||
mixins: [Formsy.Mixin],
|
||||
render: function () {
|
||||
return <input/>;
|
||||
}
|
||||
});
|
||||
var TestForm = React.createClass({
|
||||
onValidSubmit: function () {
|
||||
isCalled = true;
|
||||
},
|
||||
render: function () {
|
||||
return (
|
||||
<Formsy.Form onValidSubmit={this.onValidSubmit}>
|
||||
<TestInput name="foo" validations="isEmail" value="foo@bar.com"/>
|
||||
</Formsy.Form>);
|
||||
}
|
||||
});
|
||||
var form = TestUtils.renderIntoDocument(
|
||||
<TestForm/>
|
||||
);
|
||||
|
||||
var TestForm = TestUtils.findRenderedComponentWithType(form, TestForm);
|
||||
TestUtils.Simulate.submit(TestForm.getDOMNode());
|
||||
expect(isCalled).toBe(true);
|
||||
|
||||
});
|
||||
|
||||
it('should trigger an onInvalidSubmit when submitting an invalid form', function () {
|
||||
|
||||
var isCalled = false;
|
||||
var TestInput = React.createClass({
|
||||
mixins: [Formsy.Mixin],
|
||||
render: function () {
|
||||
return <input/>;
|
||||
}
|
||||
});
|
||||
var TestForm = React.createClass({
|
||||
onInvalidSubmit: function () {
|
||||
isCalled = true;
|
||||
},
|
||||
render: function () {
|
||||
return (
|
||||
<Formsy.Form onInvalidSubmit={this.onInvalidSubmit}>
|
||||
<TestInput name="foo" validations="isEmail" value="foo@bar"/>
|
||||
</Formsy.Form>);
|
||||
}
|
||||
});
|
||||
var form = TestUtils.renderIntoDocument(
|
||||
<TestForm/>
|
||||
);
|
||||
|
||||
var TestForm = TestUtils.findRenderedComponentWithType(form, TestForm);
|
||||
TestUtils.Simulate.submit(TestForm.getDOMNode());
|
||||
expect(isCalled).toBe(true);
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe("value === false", function() {
|
||||
var onSubmit;
|
||||
var TestInput = React.createClass({
|
||||
mixins: [Formsy.Mixin],
|
||||
getDefaultProps: function() {
|
||||
return {
|
||||
type: "text",
|
||||
};
|
||||
},
|
||||
changeValue: function() {
|
||||
this.setValue(e.target[this.props.type === "checkbox" ? "checked" : "value"]);
|
||||
},
|
||||
render: function () {
|
||||
return <input type={ this.props.type } value={ this.getValue() } onChange={ this.changeValue }/>
|
||||
}
|
||||
});
|
||||
|
||||
var TestForm = React.createClass({
|
||||
render: function () {
|
||||
return (
|
||||
<Formsy.Form onSubmit={ function(arg1) { onSubmit(arg1); } }>
|
||||
<TestInput name="foo" value={ this.props.value } type="checkbox" />
|
||||
<button type="submit">Save</button>
|
||||
</Formsy.Form>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
beforeEach(function() {
|
||||
onSubmit = jasmine.createSpy("onSubmit");
|
||||
});
|
||||
|
||||
it("should call onSubmit correctly", function() {
|
||||
var form = TestUtils.renderIntoDocument(<TestForm value={ false }/>);
|
||||
TestUtils.Simulate.submit(form.getDOMNode());
|
||||
expect(onSubmit).toHaveBeenCalledWith({foo: false});
|
||||
});
|
||||
|
||||
it("should allow dynamic changes to false", function() {
|
||||
var form = TestUtils.renderIntoDocument(<TestForm value={ true }/>);
|
||||
form.setProps({value: false});
|
||||
TestUtils.Simulate.submit(form.getDOMNode());
|
||||
expect(onSubmit).toHaveBeenCalledWith({foo: false});
|
||||
});
|
||||
|
||||
it("should say the form is submitted", function() {
|
||||
var form = TestUtils.renderIntoDocument(<TestForm value={ true }/>);
|
||||
var input = TestUtils.findRenderedComponentWithType(form, TestInput);
|
||||
expect(input.isFormSubmitted()).toBe(false);
|
||||
TestUtils.Simulate.submit(form.getDOMNode());
|
||||
expect(input.isFormSubmitted()).toBe(true);
|
||||
});
|
||||
|
||||
it("should be able to reset the form to its pristine state", function() {
|
||||
var form = TestUtils.renderIntoDocument(<TestForm value={ true }/>);
|
||||
var input = TestUtils.findRenderedComponentWithType(form, TestInput);
|
||||
var formsyForm = TestUtils.findRenderedComponentWithType(form, Formsy.Form);
|
||||
expect(input.getValue()).toBe(true);
|
||||
form.setProps({value: false});
|
||||
expect(input.getValue()).toBe(false);
|
||||
formsyForm.reset();
|
||||
expect(input.getValue()).toBe(true);
|
||||
});
|
||||
|
||||
it("should be able to reset the form using custom data", function() {
|
||||
var form = TestUtils.renderIntoDocument(<TestForm value={ true }/>);
|
||||
var input = TestUtils.findRenderedComponentWithType(form, TestInput);
|
||||
var formsyForm = TestUtils.findRenderedComponentWithType(form, Formsy.Form);
|
||||
expect(input.getValue()).toBe(true);
|
||||
form.setProps({value: false});
|
||||
expect(input.getValue()).toBe(false);
|
||||
formsyForm.reset({
|
||||
foo: 'bar'
|
||||
});
|
||||
expect(input.getValue()).toBe('bar');
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('.isChanged()', function() {
|
||||
var onChange;
|
||||
var TestInput = React.createClass({
|
||||
mixins: [Formsy.Mixin],
|
||||
changeValue: function (event) {
|
||||
this.setValue(event.target.value);
|
||||
},
|
||||
render: function () {
|
||||
return <input value={ this.getValue() } onChange={ this.changeValue } />
|
||||
}
|
||||
});
|
||||
|
||||
var TestForm = React.createClass({
|
||||
getDefaultProps: function() {
|
||||
return {
|
||||
inputs: [],
|
||||
};
|
||||
},
|
||||
render: function () {
|
||||
var builtInputs = [];
|
||||
var inputs = this.props.inputs;
|
||||
for (var i=0; i < inputs.length; i++) {
|
||||
var input = inputs[i];
|
||||
builtInputs.push(<TestInput { ...input } key={ input.name } />);
|
||||
}
|
||||
return <Formsy.Form ref='formsy' onChange={ onChange }>
|
||||
{ builtInputs }
|
||||
{ this.props.children }
|
||||
</Formsy.Form>;
|
||||
}
|
||||
});
|
||||
|
||||
beforeEach(function() {
|
||||
onChange = jasmine.createSpy("onChange");
|
||||
});
|
||||
|
||||
it('initially returns false', function() {
|
||||
var form = TestUtils.renderIntoDocument(<TestForm inputs={ [{name: 'one', value: 'foo'}] }/>);
|
||||
expect(form.refs.formsy.isChanged()).toEqual(false);
|
||||
expect(onChange).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('returns true when changed', function() {
|
||||
var form = TestUtils.renderIntoDocument(<TestForm inputs={ [{name: 'one', value: 'foo'}] }/>);
|
||||
var input = TestUtils.findRenderedDOMComponentWithTag(form, 'input');
|
||||
TestUtils.Simulate.change(input.getDOMNode(), {target: {value: 'bar'}});
|
||||
expect(form.refs.formsy.isChanged()).toEqual(true);
|
||||
expect(onChange).toHaveBeenCalledWith({one: 'bar'}, true);
|
||||
});
|
||||
|
||||
it('returns false if changes are undone', function() {
|
||||
var form = TestUtils.renderIntoDocument(<TestForm inputs={ [{name: 'one', value: 'foo'}] }/>);
|
||||
var input = TestUtils.findRenderedDOMComponentWithTag(form, 'input');
|
||||
TestUtils.Simulate.change(input.getDOMNode(), {target: {value: 'bar'}});
|
||||
expect(onChange).toHaveBeenCalledWith({one: 'bar'}, true);
|
||||
TestUtils.Simulate.change(input.getDOMNode(), {target: {value: 'foo'}});
|
||||
expect(form.refs.formsy.isChanged()).toEqual(false);
|
||||
expect(onChange).toHaveBeenCalledWith({one: 'foo'}, false);
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
|
@ -1,62 +0,0 @@
|
|||
var React = require('react/addons');
|
||||
var TestUtils = React.addons.TestUtils;
|
||||
var Formsy = require('./../src/main.js');
|
||||
|
||||
describe('Rules: equals', function() {
|
||||
var TestInput, isValid, form, input;
|
||||
|
||||
function pass(value) {
|
||||
return pass.length ? function () {
|
||||
TestUtils.Simulate.change(input, {target: {value: value}});
|
||||
expect(isValid).toBe(true);
|
||||
} : function () { expect(isValid).toBe(true); };
|
||||
}
|
||||
|
||||
function fail(value) {
|
||||
return fail.length ? function () {
|
||||
TestUtils.Simulate.change(input, {target: {value: value}});
|
||||
expect(isValid).toBe(false);
|
||||
} : function () { expect(isValid).toBe(false); };
|
||||
}
|
||||
|
||||
beforeEach(function() {
|
||||
TestInput = React.createClass({
|
||||
mixins: [Formsy.Mixin],
|
||||
updateValue: function (event) {
|
||||
this.setValue(event.target.value);
|
||||
},
|
||||
render: function () {
|
||||
isValid = this.isValid();
|
||||
return <input value={this.getValue()} onChange={this.updateValue}/>
|
||||
}
|
||||
});
|
||||
|
||||
form = TestUtils.renderIntoDocument(
|
||||
<Formsy.Form>
|
||||
<TestInput name="foo" validations="equals:myValue"/>
|
||||
</Formsy.Form>
|
||||
);
|
||||
|
||||
input = TestUtils.findRenderedDOMComponentWithTag(form, 'INPUT');
|
||||
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
TestInput = isValid = form = null;
|
||||
});
|
||||
|
||||
it('should pass with a default value', pass());
|
||||
|
||||
it('should fail when the value is not equal', fail('foo'));
|
||||
|
||||
it('should pass when the value is equal', pass('myValue'));
|
||||
|
||||
it('should pass with an empty string', pass(''));
|
||||
|
||||
it('should pass with an undefined', pass(undefined));
|
||||
|
||||
it('should pass with a null', pass(null));
|
||||
|
||||
it('should fail with a number', fail(42));
|
||||
|
||||
});
|
||||
|
|
@ -1,62 +0,0 @@
|
|||
var React = require('react/addons');
|
||||
var TestUtils = React.addons.TestUtils;
|
||||
var Formsy = require('./../src/main.js');
|
||||
|
||||
describe('Rules: isAlpha', function() {
|
||||
var TestInput, isValid, form, input;
|
||||
|
||||
function pass(value) {
|
||||
return pass.length ? function () {
|
||||
TestUtils.Simulate.change(input, {target: {value: value}});
|
||||
expect(isValid).toBe(true);
|
||||
} : function () { expect(isValid).toBe(true); };
|
||||
}
|
||||
|
||||
function fail(value) {
|
||||
return fail.length ? function () {
|
||||
TestUtils.Simulate.change(input, {target: {value: value}});
|
||||
expect(isValid).toBe(false);
|
||||
} : function () { expect(isValid).toBe(false); };
|
||||
}
|
||||
|
||||
beforeEach(function() {
|
||||
TestInput = React.createClass({
|
||||
mixins: [Formsy.Mixin],
|
||||
updateValue: function (event) {
|
||||
this.setValue(event.target.value);
|
||||
},
|
||||
render: function () {
|
||||
isValid = this.isValid();
|
||||
return <input value={this.getValue()} onChange={this.updateValue}/>
|
||||
}
|
||||
});
|
||||
|
||||
form = TestUtils.renderIntoDocument(
|
||||
<Formsy.Form>
|
||||
<TestInput name="foo" validations="isAlpha"/>
|
||||
</Formsy.Form>
|
||||
);
|
||||
|
||||
input = TestUtils.findRenderedDOMComponentWithTag(form, 'INPUT');
|
||||
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
TestInput = isValid = form = null;
|
||||
});
|
||||
|
||||
it('should pass with a default value', pass());
|
||||
|
||||
it('should pass with a string is only latin letters', pass('myValue'));
|
||||
|
||||
it('should fail with a string with numbers', fail('myValue 42'));
|
||||
|
||||
it('should pass with an undefined', pass(undefined));
|
||||
|
||||
it('should pass with a null', pass(null));
|
||||
|
||||
it('should pass with an empty string', pass(''));
|
||||
|
||||
it('should fail with a number', fail(42));
|
||||
|
||||
});
|
||||
|
|
@ -1,62 +0,0 @@
|
|||
var React = require('react/addons');
|
||||
var TestUtils = React.addons.TestUtils;
|
||||
var Formsy = require('./../src/main.js');
|
||||
|
||||
describe('Rules: isEmail', function() {
|
||||
var TestInput, isValid, form, input;
|
||||
|
||||
function pass(value) {
|
||||
return pass.length ? function () {
|
||||
TestUtils.Simulate.change(input, {target: {value: value}});
|
||||
expect(isValid).toBe(true);
|
||||
} : function () { expect(isValid).toBe(true); };
|
||||
}
|
||||
|
||||
function fail(value) {
|
||||
return fail.length ? function () {
|
||||
TestUtils.Simulate.change(input, {target: {value: value}});
|
||||
expect(isValid).toBe(false);
|
||||
} : function () { expect(isValid).toBe(false); };
|
||||
}
|
||||
|
||||
beforeEach(function() {
|
||||
TestInput = React.createClass({
|
||||
mixins: [Formsy.Mixin],
|
||||
updateValue: function (event) {
|
||||
this.setValue(event.target.value);
|
||||
},
|
||||
render: function () {
|
||||
isValid = this.isValid();
|
||||
return <input value={this.getValue()} onChange={this.updateValue}/>
|
||||
}
|
||||
});
|
||||
|
||||
form = TestUtils.renderIntoDocument(
|
||||
<Formsy.Form>
|
||||
<TestInput name="foo" value="foo" validations="isEmail"/>
|
||||
</Formsy.Form>
|
||||
);
|
||||
|
||||
input = TestUtils.findRenderedDOMComponentWithTag(form, 'INPUT');
|
||||
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
TestInput = isValid = form = null;
|
||||
});
|
||||
|
||||
it('should pass with a default value', pass());
|
||||
|
||||
it('should fail with "foo"', fail('foo'));
|
||||
|
||||
it('should pass with "foo@foo.com"', pass('foo@foo.com'));
|
||||
|
||||
it('should pass with an undefined', pass(undefined));
|
||||
|
||||
it('should pass with a null', pass(null));
|
||||
|
||||
it('should pass with an empty string', pass(''));
|
||||
|
||||
it('should fail with a number', fail(42));
|
||||
|
||||
});
|
||||
|
|
@ -1,62 +0,0 @@
|
|||
var React = require('react/addons');
|
||||
var TestUtils = React.addons.TestUtils;
|
||||
var Formsy = require('./../src/main.js');
|
||||
|
||||
describe('Rules: isEmptyString', function() {
|
||||
var TestInput, isValid, form, input;
|
||||
|
||||
function pass(value) {
|
||||
return pass.length ? function () {
|
||||
TestUtils.Simulate.change(input, {target: {value: value}});
|
||||
expect(isValid).toBe(true);
|
||||
} : function () { expect(isValid).toBe(true); };
|
||||
}
|
||||
|
||||
function fail(value) {
|
||||
return fail.length ? function () {
|
||||
TestUtils.Simulate.change(input, {target: {value: value}});
|
||||
expect(isValid).toBe(false);
|
||||
} : function () { expect(isValid).toBe(false); };
|
||||
}
|
||||
|
||||
beforeEach(function() {
|
||||
TestInput = React.createClass({
|
||||
mixins: [Formsy.Mixin],
|
||||
updateValue: function (event) {
|
||||
this.setValue(event.target.value);
|
||||
},
|
||||
render: function () {
|
||||
isValid = this.isValid();
|
||||
return <input value={this.getValue()} onChange={this.updateValue}/>
|
||||
}
|
||||
});
|
||||
|
||||
form = TestUtils.renderIntoDocument(
|
||||
<Formsy.Form>
|
||||
<TestInput name="foo" validations="isEmptyString"/>
|
||||
</Formsy.Form>
|
||||
);
|
||||
|
||||
input = TestUtils.findRenderedDOMComponentWithTag(form, 'INPUT');
|
||||
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
TestInput = isValid = form = null;
|
||||
});
|
||||
|
||||
it('should fail with a default value', fail());
|
||||
|
||||
it('should fail with non-empty string', fail('asd'));
|
||||
|
||||
it('should pass with an empty string', pass(''));
|
||||
|
||||
it('should fail with a undefined', fail(undefined));
|
||||
|
||||
it('should fail with a null', fail(null));
|
||||
|
||||
it('should fail with a number', fail(123));
|
||||
|
||||
it('should fail with a zero', fail(0));
|
||||
|
||||
});
|
||||
|
|
@ -1,62 +0,0 @@
|
|||
var React = require('react/addons');
|
||||
var TestUtils = React.addons.TestUtils;
|
||||
var Formsy = require('./../src/main.js');
|
||||
|
||||
describe('Rules: isExisty', function() {
|
||||
var TestInput, isValid, form, input;
|
||||
|
||||
function pass(value) {
|
||||
return pass.length ? function () {
|
||||
TestUtils.Simulate.change(input, {target: {value: value}});
|
||||
expect(isValid).toBe(true);
|
||||
} : function () { expect(isValid).toBe(true); };
|
||||
}
|
||||
|
||||
function fail(value) {
|
||||
return fail.length ? function () {
|
||||
TestUtils.Simulate.change(input, {target: {value: value}});
|
||||
expect(isValid).toBe(false);
|
||||
} : function () { expect(isValid).toBe(false); };
|
||||
}
|
||||
|
||||
beforeEach(function() {
|
||||
TestInput = React.createClass({
|
||||
mixins: [Formsy.Mixin],
|
||||
updateValue: function (event) {
|
||||
this.setValue(event.target.value);
|
||||
},
|
||||
render: function () {
|
||||
isValid = this.isValid();
|
||||
return <input value={this.getValue()} onChange={this.updateValue}/>
|
||||
}
|
||||
});
|
||||
|
||||
form = TestUtils.renderIntoDocument(
|
||||
<Formsy.Form>
|
||||
<TestInput name="foo" validations="isExisty"/>
|
||||
</Formsy.Form>
|
||||
);
|
||||
|
||||
input = TestUtils.findRenderedDOMComponentWithTag(form, 'INPUT');
|
||||
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
TestInput = isValid = form = null;
|
||||
});
|
||||
|
||||
it('should fail with a default value', fail());
|
||||
|
||||
it('should pass with a string', pass('myValue'));
|
||||
|
||||
it('should pass with an empty string', pass(''));
|
||||
|
||||
it('should fail with an undefined', fail(undefined));
|
||||
|
||||
it('should fail with a null', fail(null));
|
||||
|
||||
it('should pass with a number', pass(42));
|
||||
|
||||
it('should pass with a zero', pass(0));
|
||||
|
||||
});
|
||||
|
|
@ -1,95 +0,0 @@
|
|||
var React = require('react/addons');
|
||||
var TestUtils = React.addons.TestUtils;
|
||||
var Formsy = require('./../src/main.js');
|
||||
|
||||
describe('Rules: isLength', function() {
|
||||
var TestInput, isValid, form, input;
|
||||
|
||||
function pass(value) {
|
||||
return pass.length ? function () {
|
||||
TestUtils.Simulate.change(input, {target: {value: value}});
|
||||
expect(isValid).toBe(true);
|
||||
} : function () { expect(isValid).toBe(true); };
|
||||
}
|
||||
|
||||
function fail(value) {
|
||||
return fail.length ? function () {
|
||||
TestUtils.Simulate.change(input, {target: {value: value}});
|
||||
expect(isValid).toBe(false);
|
||||
} : function () { expect(isValid).toBe(false); };
|
||||
}
|
||||
|
||||
beforeEach(function() {
|
||||
TestInput = React.createClass({
|
||||
mixins: [Formsy.Mixin],
|
||||
updateValue: function (event) {
|
||||
this.setValue(event.target.value);
|
||||
},
|
||||
render: function () {
|
||||
isValid = this.isValid();
|
||||
return <input value={this.getValue()} onChange={this.updateValue}/>
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
TestInput = isValid = form = null;
|
||||
});
|
||||
|
||||
describe('isLength:3', function() {
|
||||
|
||||
beforeEach(function() {
|
||||
form = TestUtils.renderIntoDocument(
|
||||
<Formsy.Form>
|
||||
<TestInput name="foo" validations="isLength:3"/>
|
||||
</Formsy.Form>
|
||||
);
|
||||
|
||||
input = TestUtils.findRenderedDOMComponentWithTag(form, 'INPUT');
|
||||
});
|
||||
|
||||
it('should pass with a default value', pass());
|
||||
|
||||
it('should fail with a string too small', fail('hi'));
|
||||
|
||||
it('should fail with a string too long', fail('foo bar'));
|
||||
|
||||
it('should pass with the right length', pass('sup'));
|
||||
|
||||
it('should pass with an undefined', pass(undefined));
|
||||
|
||||
it('should pass with a null', pass(null));
|
||||
|
||||
it('should pass with an empty string', pass(''));
|
||||
|
||||
it('should fail with a number', fail(123));
|
||||
|
||||
});
|
||||
|
||||
describe('isLength:0', function() {
|
||||
|
||||
beforeEach(function() {
|
||||
form = TestUtils.renderIntoDocument(
|
||||
<Formsy.Form>
|
||||
<TestInput name="foo" validations="isLength:0"/>
|
||||
</Formsy.Form>
|
||||
);
|
||||
|
||||
input = TestUtils.findRenderedDOMComponentWithTag(form, 'INPUT');
|
||||
});
|
||||
|
||||
it('should pass with a default value', pass());
|
||||
|
||||
it('should fail with a string too long', fail('foo bar'));
|
||||
|
||||
it('should pass with an undefined', pass(undefined));
|
||||
|
||||
it('should pass with a null', pass(null));
|
||||
|
||||
it('should pass with an empty string', pass(''));
|
||||
|
||||
it('should fail with a number', fail(123));
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
|
@ -1,68 +0,0 @@
|
|||
var React = require('react/addons');
|
||||
var TestUtils = React.addons.TestUtils;
|
||||
var Formsy = require('./../src/main.js');
|
||||
|
||||
describe('Rules: isNumeric', function() {
|
||||
var TestInput, isValid, form, input;
|
||||
|
||||
function pass(value) {
|
||||
return pass.length ? function () {
|
||||
TestUtils.Simulate.change(input, {target: {value: value}});
|
||||
expect(isValid).toBe(true);
|
||||
} : function () { expect(isValid).toBe(true); };
|
||||
}
|
||||
|
||||
function fail(value) {
|
||||
return fail.length ? function () {
|
||||
TestUtils.Simulate.change(input, {target: {value: value}});
|
||||
expect(isValid).toBe(false);
|
||||
} : function () { expect(isValid).toBe(false); };
|
||||
}
|
||||
|
||||
beforeEach(function() {
|
||||
TestInput = React.createClass({
|
||||
mixins: [Formsy.Mixin],
|
||||
updateValue: function (event) {
|
||||
this.setValue(event.target.value);
|
||||
},
|
||||
render: function () {
|
||||
isValid = this.isValid();
|
||||
return <input value={this.getValue()} onChange={this.updateValue}/>
|
||||
}
|
||||
});
|
||||
|
||||
form = TestUtils.renderIntoDocument(
|
||||
<Formsy.Form>
|
||||
<TestInput name="foo" validations="isNumeric"/>
|
||||
</Formsy.Form>
|
||||
);
|
||||
|
||||
input = TestUtils.findRenderedDOMComponentWithTag(form, 'INPUT');
|
||||
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
TestInput = isValid = form = null;
|
||||
});
|
||||
|
||||
it('should pass with a default value', pass());
|
||||
|
||||
it('should pass with an empty string', pass(''));
|
||||
|
||||
it('should fail with an unempty string', fail('myValue'));
|
||||
|
||||
it('should pass with a number as string', pass('+42'));
|
||||
|
||||
it('should fail with a number as string with not digits', fail('42 as an answer'));
|
||||
|
||||
it('should pass with an int', pass(42));
|
||||
|
||||
it('should pass with a float', pass(Math.PI));
|
||||
|
||||
it('should pass with an undefined', pass(undefined));
|
||||
|
||||
it('should pass with a null', pass(null));
|
||||
|
||||
it('should pass with a zero', pass(0));
|
||||
|
||||
});
|
||||
|
|
@ -1,62 +0,0 @@
|
|||
var React = require('react/addons');
|
||||
var TestUtils = React.addons.TestUtils;
|
||||
var Formsy = require('./../src/main.js');
|
||||
|
||||
describe('Rules: isUrl', function() {
|
||||
var TestInput, isValid, form, input;
|
||||
|
||||
function pass(value) {
|
||||
return pass.length ? function () {
|
||||
TestUtils.Simulate.change(input, {target: {value: value}});
|
||||
expect(isValid).toBe(true);
|
||||
} : function () { expect(isValid).toBe(true); };
|
||||
}
|
||||
|
||||
function fail(value) {
|
||||
return fail.length ? function () {
|
||||
TestUtils.Simulate.change(input, {target: {value: value}});
|
||||
expect(isValid).toBe(false);
|
||||
} : function () { expect(isValid).toBe(false); };
|
||||
}
|
||||
|
||||
beforeEach(function() {
|
||||
TestInput = React.createClass({
|
||||
mixins: [Formsy.Mixin],
|
||||
updateValue: function (event) {
|
||||
this.setValue(event.target.value);
|
||||
},
|
||||
render: function () {
|
||||
isValid = this.isValid();
|
||||
return <input value={this.getValue()} onChange={this.updateValue}/>
|
||||
}
|
||||
});
|
||||
|
||||
form = TestUtils.renderIntoDocument(
|
||||
<Formsy.Form>
|
||||
<TestInput name="foo" value="foo" validations="isUrl"/>
|
||||
</Formsy.Form>
|
||||
);
|
||||
|
||||
input = TestUtils.findRenderedDOMComponentWithTag(form, 'INPUT');
|
||||
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
TestInput = isValid = form = null;
|
||||
});
|
||||
|
||||
it('should pass with a default value', pass());
|
||||
|
||||
it('should fail with "foo"', fail('foo'));
|
||||
|
||||
it('should pass with "https://www.google.com/"', pass('https://www.google.com/'));
|
||||
|
||||
it('should pass with an undefined', pass(undefined));
|
||||
|
||||
it('should pass with a null', pass(null));
|
||||
|
||||
it('should fail with a number', fail(42));
|
||||
|
||||
it('should pass with an empty string', pass(''));
|
||||
|
||||
});
|
||||
|
|
@ -1,62 +0,0 @@
|
|||
var React = require('react/addons');
|
||||
var TestUtils = React.addons.TestUtils;
|
||||
var Formsy = require('./../src/main.js');
|
||||
|
||||
describe('Rules: isWords', function() {
|
||||
var TestInput, isValid, form, input;
|
||||
|
||||
function pass(value) {
|
||||
return pass.length ? function () {
|
||||
TestUtils.Simulate.change(input, {target: {value: value}});
|
||||
expect(isValid).toBe(true);
|
||||
} : function () { expect(isValid).toBe(true); };
|
||||
}
|
||||
|
||||
function fail(value) {
|
||||
return fail.length ? function () {
|
||||
TestUtils.Simulate.change(input, {target: {value: value}});
|
||||
expect(isValid).toBe(false);
|
||||
} : function () { expect(isValid).toBe(false); };
|
||||
}
|
||||
|
||||
beforeEach(function() {
|
||||
TestInput = React.createClass({
|
||||
mixins: [Formsy.Mixin],
|
||||
updateValue: function (event) {
|
||||
this.setValue(event.target.value);
|
||||
},
|
||||
render: function () {
|
||||
isValid = this.isValid();
|
||||
return <input value={this.getValue()} onChange={this.updateValue}/>
|
||||
}
|
||||
});
|
||||
|
||||
form = TestUtils.renderIntoDocument(
|
||||
<Formsy.Form>
|
||||
<TestInput name="foo" validations="isWords"/>
|
||||
</Formsy.Form>
|
||||
);
|
||||
|
||||
input = TestUtils.findRenderedDOMComponentWithTag(form, 'INPUT');
|
||||
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
TestInput = isValid = form = null;
|
||||
});
|
||||
|
||||
it('should pass with a default value', pass());
|
||||
|
||||
it('should pass with a 1 word', pass('sup'));
|
||||
|
||||
it('should pass with 2 words', pass('sup dude'));
|
||||
|
||||
it('should fail with a string with numbers', fail('myValue 42'));
|
||||
|
||||
it('should pass with an undefined', pass(undefined));
|
||||
|
||||
it('should pass with a null', pass(null));
|
||||
|
||||
it('should fail with a number', fail(42));
|
||||
|
||||
});
|
||||
|
|
@ -1,64 +0,0 @@
|
|||
var React = require('react/addons');
|
||||
var TestUtils = React.addons.TestUtils;
|
||||
var Formsy = require('./../src/main.js');
|
||||
|
||||
describe('Rules: maxLength', function() {
|
||||
var TestInput, isValid, form, input;
|
||||
|
||||
function pass(value) {
|
||||
return pass.length ? function () {
|
||||
TestUtils.Simulate.change(input, {target: {value: value}});
|
||||
expect(isValid).toBe(true);
|
||||
} : function () { expect(isValid).toBe(true); };
|
||||
}
|
||||
|
||||
function fail(value) {
|
||||
return fail.length ? function () {
|
||||
TestUtils.Simulate.change(input, {target: {value: value}});
|
||||
expect(isValid).toBe(false);
|
||||
} : function () { expect(isValid).toBe(false); };
|
||||
}
|
||||
|
||||
beforeEach(function() {
|
||||
TestInput = React.createClass({
|
||||
mixins: [Formsy.Mixin],
|
||||
updateValue: function (event) {
|
||||
this.setValue(event.target.value);
|
||||
},
|
||||
render: function () {
|
||||
isValid = this.isValid();
|
||||
return <input value={this.getValue()} onChange={this.updateValue}/>
|
||||
}
|
||||
});
|
||||
|
||||
form = TestUtils.renderIntoDocument(
|
||||
<Formsy.Form>
|
||||
<TestInput name="foo" validations="maxLength:3"/>
|
||||
</Formsy.Form>
|
||||
);
|
||||
|
||||
input = TestUtils.findRenderedDOMComponentWithTag(form, 'INPUT');
|
||||
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
TestInput = isValid = form = null;
|
||||
});
|
||||
|
||||
it('should pass with a default value', pass());
|
||||
|
||||
it('should pass when a string\'s length is smaller', pass('hi'));
|
||||
|
||||
it('should pass when a string\'s length is equal', pass('bar'));
|
||||
|
||||
it('should fail when a string\'s length is bigger', fail('myValue'));
|
||||
|
||||
it('should pass with an empty string', pass(''));
|
||||
|
||||
it('should pass with an undefined', pass(undefined));
|
||||
|
||||
it('should pass with a null', pass(null));
|
||||
|
||||
it('should fail with a number', fail(123));
|
||||
|
||||
});
|
||||
|
|
@ -1,95 +0,0 @@
|
|||
var React = require('react/addons');
|
||||
var TestUtils = React.addons.TestUtils;
|
||||
var Formsy = require('./../src/main.js');
|
||||
|
||||
describe('Rules: minLength', function() {
|
||||
var TestInput, isValid, form, input;
|
||||
|
||||
function pass(value) {
|
||||
return pass.length ? function () {
|
||||
TestUtils.Simulate.change(input, {target: {value: value}});
|
||||
expect(isValid).toBe(true);
|
||||
} : function () { expect(isValid).toBe(true); };
|
||||
}
|
||||
|
||||
function fail(value) {
|
||||
return fail.length ? function () {
|
||||
TestUtils.Simulate.change(input, {target: {value: value}});
|
||||
expect(isValid).toBe(false);
|
||||
} : function () { expect(isValid).toBe(false); };
|
||||
}
|
||||
|
||||
beforeEach(function() {
|
||||
TestInput = React.createClass({
|
||||
mixins: [Formsy.Mixin],
|
||||
updateValue: function (event) {
|
||||
this.setValue(event.target.value);
|
||||
},
|
||||
render: function () {
|
||||
isValid = this.isValid();
|
||||
return <input value={this.getValue()} onChange={this.updateValue}/>
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
TestInput = isValid = form = null;
|
||||
});
|
||||
|
||||
describe('minLength:3', function() {
|
||||
|
||||
beforeEach(function() {
|
||||
form = TestUtils.renderIntoDocument(
|
||||
<Formsy.Form>
|
||||
<TestInput name="foo" validations="minLength:3"/>
|
||||
</Formsy.Form>
|
||||
);
|
||||
|
||||
input = TestUtils.findRenderedDOMComponentWithTag(form, 'INPUT');
|
||||
});
|
||||
|
||||
it('should pass with a default value', pass());
|
||||
|
||||
it('should fail when a string\'s length is smaller', fail('hi'));
|
||||
|
||||
it('should pass when a string\'s length is equal', pass('bar'));
|
||||
|
||||
it('should pass when a string\'s length is bigger', pass('myValue'));
|
||||
|
||||
it('should pass with an empty string', pass(''));
|
||||
|
||||
it('should pass with an undefined', pass(undefined));
|
||||
|
||||
it('should pass with a null', pass(null));
|
||||
|
||||
it('should fail with a number', fail(123));
|
||||
|
||||
});
|
||||
|
||||
describe('minLength:0', function() {
|
||||
|
||||
beforeEach(function() {
|
||||
form = TestUtils.renderIntoDocument(
|
||||
<Formsy.Form>
|
||||
<TestInput name="foo" validations="minLength:0"/>
|
||||
</Formsy.Form>
|
||||
);
|
||||
|
||||
input = TestUtils.findRenderedDOMComponentWithTag(form, 'INPUT');
|
||||
});
|
||||
|
||||
it('should pass with a default value', pass());
|
||||
|
||||
it('should pass when a string\'s length is bigger', pass('myValue'));
|
||||
|
||||
it('should pass with empty string', pass(''));
|
||||
|
||||
it('should pass with undefined', pass(undefined));
|
||||
|
||||
it('should pass with null', pass(null));
|
||||
|
||||
it('should fail with a number', fail(123));
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
|
@ -1,28 +0,0 @@
|
|||
var utils = require('./../src/utils.js');
|
||||
|
||||
describe('Utils', function() {
|
||||
|
||||
it('should check equality of objects and arrays', function () {
|
||||
var objA = { foo: 'bar' };
|
||||
var objB = { foo: 'bar' };
|
||||
var objC = [{ foo: ['bar'] }];
|
||||
var objD = [{ foo: ['bar'] }];
|
||||
var objE, objF;
|
||||
var objG = null;
|
||||
var 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(objG, objA)).toBe(false);
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
|
|
@ -1,281 +0,0 @@
|
|||
var React = require('react/addons');
|
||||
var TestUtils = React.addons.TestUtils;
|
||||
var Formsy = require('./../src/main.js');
|
||||
|
||||
describe('Validation', function() {
|
||||
|
||||
it('should reset only changed form element when external error is passed', function (done) {
|
||||
|
||||
var onSubmit = function (model, reset, invalidate) {
|
||||
invalidate({
|
||||
foo: 'bar',
|
||||
bar: 'foo'
|
||||
});
|
||||
}
|
||||
var TestInput = React.createClass({
|
||||
mixins: [Formsy.Mixin],
|
||||
updateValue: function (event) {
|
||||
this.setValue(event.target.value);
|
||||
},
|
||||
render: function () {
|
||||
return <input value={this.getValue()} onChange={this.updateValue}/>
|
||||
}
|
||||
});
|
||||
var form = TestUtils.renderIntoDocument(
|
||||
<Formsy.Form onSubmit={onSubmit}>
|
||||
<TestInput name="foo"/>
|
||||
<TestInput name="bar"/>
|
||||
</Formsy.Form>
|
||||
);
|
||||
|
||||
var input = TestUtils.scryRenderedDOMComponentsWithTag(form, 'INPUT')[0];
|
||||
var inputComponents = TestUtils.scryRenderedComponentsWithType(form, TestInput);
|
||||
|
||||
form.submit();
|
||||
expect(inputComponents[0].isValid()).toBe(false);
|
||||
expect(inputComponents[1].isValid()).toBe(false);
|
||||
TestUtils.Simulate.change(input, {target: {value: 'bar'}});
|
||||
setTimeout(function () {
|
||||
expect(inputComponents[0].isValid()).toBe(true);
|
||||
expect(inputComponents[1].isValid()).toBe(false);
|
||||
done();
|
||||
}, 0);
|
||||
});
|
||||
|
||||
it('should let normal validation take over when component with external error is changed', function (done) {
|
||||
|
||||
var onSubmit = function (model, reset, invalidate) {
|
||||
invalidate({
|
||||
foo: 'bar'
|
||||
});
|
||||
}
|
||||
var TestInput = React.createClass({
|
||||
mixins: [Formsy.Mixin],
|
||||
updateValue: function (event) {
|
||||
this.setValue(event.target.value);
|
||||
},
|
||||
render: function () {
|
||||
return <input value={this.getValue()} onChange={this.updateValue}/>
|
||||
}
|
||||
});
|
||||
var form = TestUtils.renderIntoDocument(
|
||||
<Formsy.Form onSubmit={onSubmit}>
|
||||
<TestInput name="foo" validations="isEmail"/>
|
||||
</Formsy.Form>
|
||||
);
|
||||
|
||||
var input = TestUtils.findRenderedDOMComponentWithTag(form, 'INPUT');
|
||||
var inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput);
|
||||
|
||||
form.submit();
|
||||
expect(inputComponent.isValid()).toBe(false);
|
||||
TestUtils.Simulate.change(input, {target: {value: 'bar'}});
|
||||
setTimeout(function () {
|
||||
expect(inputComponent.getValue()).toBe('bar');
|
||||
expect(inputComponent.isValid()).toBe(false);
|
||||
done();
|
||||
}, 0);
|
||||
});
|
||||
|
||||
it('should trigger an onValid handler, if passed, when form is valid', function () {
|
||||
|
||||
var onValid = jasmine.createSpy('valid');
|
||||
var TestInput = React.createClass({
|
||||
mixins: [Formsy.Mixin],
|
||||
updateValue: function (event) {
|
||||
this.setValue(event.target.value);
|
||||
},
|
||||
render: function () {
|
||||
return <input value={this.getValue()} onChange={this.updateValue}/>
|
||||
}
|
||||
});
|
||||
var form = TestUtils.renderIntoDocument(
|
||||
<Formsy.Form onValid={onValid}>
|
||||
<TestInput name="foo" required/>
|
||||
</Formsy.Form>
|
||||
);
|
||||
|
||||
var input = TestUtils.findRenderedDOMComponentWithTag(form, 'INPUT');
|
||||
TestUtils.Simulate.change(input, {target: {value: 'foo'}});
|
||||
expect(onValid).toHaveBeenCalled();
|
||||
|
||||
});
|
||||
|
||||
it('should trigger an onInvalid handler, if passed, when form is invalid', function () {
|
||||
|
||||
var onInvalid = jasmine.createSpy('invalid');
|
||||
var TestInput = React.createClass({
|
||||
mixins: [Formsy.Mixin],
|
||||
updateValue: function (event) {
|
||||
this.setValue(event.target.value);
|
||||
},
|
||||
render: function () {
|
||||
return <input value={this.getValue()} onChange={this.updateValue}/>
|
||||
}
|
||||
});
|
||||
var form = TestUtils.renderIntoDocument(
|
||||
<Formsy.Form onValid={onInvalid}>
|
||||
<TestInput name="foo" value="foo"/>
|
||||
</Formsy.Form>
|
||||
);
|
||||
|
||||
var input = TestUtils.findRenderedDOMComponentWithTag(form, 'INPUT');
|
||||
TestUtils.Simulate.change(input, {target: {value: ''}});
|
||||
expect(onInvalid).toHaveBeenCalled();
|
||||
|
||||
});
|
||||
|
||||
it('should use provided validate function', function () {
|
||||
|
||||
var isValid = jasmine.createSpy('valid');
|
||||
var TestInput = React.createClass({
|
||||
mixins: [Formsy.Mixin],
|
||||
updateValue: function (event) {
|
||||
this.setValue(event.target.value);
|
||||
},
|
||||
render: function () {
|
||||
if (this.isValid()) {
|
||||
isValid();
|
||||
}
|
||||
return <input value={this.getValue()} onChange={this.updateValue}/>
|
||||
},
|
||||
validate: function () {
|
||||
return this.getValue() === "checkValidity";
|
||||
}
|
||||
});
|
||||
var form = TestUtils.renderIntoDocument(
|
||||
<Formsy.Form>
|
||||
<TestInput name="foo" value="checkInvalidity"/>
|
||||
</Formsy.Form>
|
||||
);
|
||||
|
||||
var input = TestUtils.findRenderedDOMComponentWithTag(form, 'INPUT');
|
||||
TestUtils.Simulate.change(input, {target: {value: 'checkValidity'}});
|
||||
expect(isValid).toHaveBeenCalled();
|
||||
|
||||
});
|
||||
|
||||
it('should provide invalidate callback on onValiSubmit', function () {
|
||||
|
||||
var TestInput = React.createClass({
|
||||
mixins: [Formsy.Mixin],
|
||||
render: function () {
|
||||
return <input/>
|
||||
}
|
||||
});
|
||||
var TestForm = React.createClass({
|
||||
invalidate: function (model, reset, invalidate) {
|
||||
invalidate({
|
||||
foo: 'bar'
|
||||
});
|
||||
},
|
||||
render: function () {
|
||||
return (
|
||||
<Formsy.Form onValidSubmit={this.invalidate}>
|
||||
<TestInput name="foo" value="foo"/>
|
||||
</Formsy.Form>
|
||||
);
|
||||
}
|
||||
});
|
||||
var form = TestUtils.renderIntoDocument(<TestForm/>);
|
||||
|
||||
var formEl = TestUtils.findRenderedDOMComponentWithTag(form, 'form');
|
||||
var input = TestUtils.findRenderedComponentWithType(form, TestInput);
|
||||
TestUtils.Simulate.submit(formEl);
|
||||
expect(input.isValid()).toBe(false);
|
||||
|
||||
});
|
||||
|
||||
it('should provide invalidate callback on onInvalidSubmit', function () {
|
||||
|
||||
var TestInput = React.createClass({
|
||||
mixins: [Formsy.Mixin],
|
||||
render: function () {
|
||||
return <input/>
|
||||
}
|
||||
});
|
||||
var TestForm = React.createClass({
|
||||
invalidate: function (model, reset, invalidate) {
|
||||
invalidate({
|
||||
foo: 'bar'
|
||||
});
|
||||
},
|
||||
render: function () {
|
||||
return (
|
||||
<Formsy.Form onInvalidSubmit={this.invalidate}>
|
||||
<TestInput name="foo" value="foo" validations="isEmail"/>
|
||||
</Formsy.Form>
|
||||
);
|
||||
}
|
||||
});
|
||||
var form = TestUtils.renderIntoDocument(<TestForm/>);
|
||||
|
||||
var formEl = TestUtils.findRenderedDOMComponentWithTag(form, 'form');
|
||||
var input = TestUtils.findRenderedComponentWithType(form, TestInput);
|
||||
TestUtils.Simulate.submit(formEl);
|
||||
expect(input.getErrorMessage()).toBe('bar');
|
||||
|
||||
});
|
||||
|
||||
|
||||
it('should not invalidate inputs on external errors with preventExternalInvalidation prop', function () {
|
||||
|
||||
var TestInput = React.createClass({
|
||||
mixins: [Formsy.Mixin],
|
||||
render: function () {
|
||||
return <input/>
|
||||
}
|
||||
});
|
||||
var TestForm = React.createClass({
|
||||
invalidate: function (model, reset, invalidate) {
|
||||
invalidate({
|
||||
foo: 'bar'
|
||||
});
|
||||
},
|
||||
render: function () {
|
||||
return (
|
||||
<Formsy.Form onSubmit={this.invalidate} preventExternalInvalidation>
|
||||
<TestInput name="foo" value="foo"/>
|
||||
</Formsy.Form>
|
||||
);
|
||||
}
|
||||
});
|
||||
var form = TestUtils.renderIntoDocument(<TestForm/>);
|
||||
var formEl = TestUtils.findRenderedDOMComponentWithTag(form, 'form');
|
||||
var input = TestUtils.findRenderedComponentWithType(form, TestInput);
|
||||
TestUtils.Simulate.submit(formEl);
|
||||
expect(input.isValid()).toBe(true);
|
||||
|
||||
});
|
||||
|
||||
it('should invalidate inputs on external errors without preventExternalInvalidation prop', function () {
|
||||
|
||||
var TestInput = React.createClass({
|
||||
mixins: [Formsy.Mixin],
|
||||
render: function () {
|
||||
return <input/>
|
||||
}
|
||||
});
|
||||
var TestForm = React.createClass({
|
||||
invalidate: function (model, reset, invalidate) {
|
||||
invalidate({
|
||||
foo: 'bar'
|
||||
});
|
||||
},
|
||||
render: function () {
|
||||
return (
|
||||
<Formsy.Form onSubmit={this.invalidate}>
|
||||
<TestInput name="foo" value="foo"/>
|
||||
</Formsy.Form>
|
||||
);
|
||||
}
|
||||
});
|
||||
var form = TestUtils.renderIntoDocument(<TestForm/>);
|
||||
var formEl = TestUtils.findRenderedDOMComponentWithTag(form, 'form');
|
||||
var input = TestUtils.findRenderedComponentWithType(form, TestInput);
|
||||
TestUtils.Simulate.submit(formEl);
|
||||
expect(input.isValid()).toBe(false);
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
var React = global.React || require('react');
|
||||
var Mixin = require('./Mixin.js');
|
||||
module.exports = function () {
|
||||
return function (Component) {
|
||||
return React.createClass({
|
||||
mixins: [Mixin],
|
||||
render: function () {
|
||||
return React.createElement(Component, {
|
||||
setValidations: this.setValidations,
|
||||
setValue: this.setValue,
|
||||
resetValue: this.resetValue,
|
||||
getValue: this.getValue,
|
||||
hasValue: this.hasValue,
|
||||
getErrorMessage: this.getErrorMessage,
|
||||
getErrorMessages: this.getErrorMessages,
|
||||
isFormDisabled: this.isFormDisabled,
|
||||
isValid: this.isValid,
|
||||
isPristine: this.isPristine,
|
||||
isFormSubmitted: this.isFormSubmitted,
|
||||
isRequired: this.isRequired,
|
||||
showRequired: this.showRequired,
|
||||
showError: this.showError,
|
||||
isValidValue: this.isValidValue,
|
||||
...this.props
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
};
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
var React = global.React || require('react');
|
||||
var Mixin = require('./Mixin.js');
|
||||
module.exports = function (Component) {
|
||||
return React.createClass({
|
||||
mixins: [Mixin],
|
||||
render: function () {
|
||||
return React.createElement(Component, {
|
||||
setValidations: this.setValidations,
|
||||
setValue: this.setValue,
|
||||
resetValue: this.resetValue,
|
||||
getValue: this.getValue,
|
||||
hasValue: this.hasValue,
|
||||
getErrorMessage: this.getErrorMessage,
|
||||
getErrorMessages: this.getErrorMessages,
|
||||
isFormDisabled: this.isFormDisabled,
|
||||
isValid: this.isValid,
|
||||
isPristine: this.isPristine,
|
||||
isFormSubmitted: this.isFormSubmitted,
|
||||
isRequired: this.isRequired,
|
||||
showRequired: this.showRequired,
|
||||
showError: this.showError,
|
||||
isValidValue: this.isValidValue
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
40
src/Mixin.js
40
src/Mixin.js
|
|
@ -1,4 +1,5 @@
|
|||
var utils = require('./utils.js');
|
||||
var React = global.React || require('react');
|
||||
|
||||
var convertValidationsToObject = function (validations) {
|
||||
|
||||
|
|
@ -37,11 +38,14 @@ module.exports = {
|
|||
_isValid: true,
|
||||
_isPristine: true,
|
||||
_pristineValue: this.props.value,
|
||||
_validationError: '',
|
||||
_validationError: [],
|
||||
_externalError: null,
|
||||
_formSubmitted: false
|
||||
};
|
||||
},
|
||||
contextTypes: {
|
||||
formsy: React.PropTypes.object // What about required?
|
||||
},
|
||||
getDefaultProps: function () {
|
||||
return {
|
||||
validationError: '',
|
||||
|
|
@ -52,13 +56,17 @@ module.exports = {
|
|||
componentWillMount: function () {
|
||||
var configure = function () {
|
||||
this.setValidations(this.props.validations, this.props.required);
|
||||
this.props._attachToForm(this);
|
||||
|
||||
// Pass a function instead?
|
||||
this.context.formsy.attachToForm(this);
|
||||
//this.props._attachToForm(this);
|
||||
}.bind(this);
|
||||
|
||||
if (!this.props.name) {
|
||||
throw new Error('Form Input requires a name property when used');
|
||||
}
|
||||
|
||||
/*
|
||||
if (!this.props._attachToForm) {
|
||||
return setTimeout(function () {
|
||||
if (!this.isMounted()) return;
|
||||
|
|
@ -68,12 +76,14 @@ module.exports = {
|
|||
configure();
|
||||
}.bind(this), 0);
|
||||
}
|
||||
*/
|
||||
configure();
|
||||
},
|
||||
|
||||
// We have to make the validate method is kept when new props are added
|
||||
componentWillReceiveProps: function (nextProps) {
|
||||
this.setValidations(nextProps.validations, nextProps.required);
|
||||
|
||||
},
|
||||
|
||||
componentDidUpdate: function (prevProps) {
|
||||
|
|
@ -83,11 +93,17 @@ module.exports = {
|
|||
if (!utils.isSame(this.props.value, prevProps.value)) {
|
||||
this.setValue(this.props.value);
|
||||
}
|
||||
|
||||
// If validations or required is changed, run a new validation
|
||||
if (!utils.isSame(this.props.validations, prevProps.validations) || !utils.isSame(this.props.required, prevProps.required)) {
|
||||
this.context.formsy.validate(this);
|
||||
}
|
||||
},
|
||||
|
||||
// Detach it when component unmounts
|
||||
componentWillUnmount: function () {
|
||||
this.props._detachFromForm(this);
|
||||
this.context.formsy.detachFromForm(this);
|
||||
//this.props._detachFromForm(this);
|
||||
},
|
||||
|
||||
setValidations: function (validations, required) {
|
||||
|
|
@ -104,7 +120,8 @@ module.exports = {
|
|||
_value: value,
|
||||
_isPristine: false
|
||||
}, function () {
|
||||
this.props._validate(this);
|
||||
this.context.formsy.validate(this);
|
||||
//this.props._validate(this);
|
||||
}.bind(this));
|
||||
},
|
||||
resetValue: function () {
|
||||
|
|
@ -112,7 +129,8 @@ module.exports = {
|
|||
_value: this.state._pristineValue,
|
||||
_isPristine: true
|
||||
}, function () {
|
||||
this.props._validate(this);
|
||||
this.context.formsy.validate(this);
|
||||
//this.props._validate(this);
|
||||
});
|
||||
},
|
||||
getValue: function () {
|
||||
|
|
@ -122,10 +140,15 @@ module.exports = {
|
|||
return this.state._value !== '';
|
||||
},
|
||||
getErrorMessage: function () {
|
||||
return !this.isValid() || this.showRequired() ? (this.state._externalError || this.state._validationError) : null;
|
||||
var messages = this.getErrorMessages();
|
||||
return messages.length ? messages[0] : null;
|
||||
},
|
||||
getErrorMessages: function () {
|
||||
return !this.isValid() || this.showRequired() ? (this.state._externalError || this.state._validationError || []) : [];
|
||||
},
|
||||
isFormDisabled: function () {
|
||||
return this.props._isFormDisabled();
|
||||
return this.context.formsy.isFormDisabled();
|
||||
//return this.props._isFormDisabled();
|
||||
},
|
||||
isValid: function () {
|
||||
return this.state._isValid;
|
||||
|
|
@ -146,6 +169,7 @@ module.exports = {
|
|||
return !this.showRequired() && !this.isValid();
|
||||
},
|
||||
isValidValue: function (value) {
|
||||
return this.props._isValidValue.call(null, this, value);
|
||||
return this.context.formsy.isValidValue.call(null, this, value);
|
||||
//return this.props._isValidValue.call(null, this, value);
|
||||
}
|
||||
};
|
||||
|
|
|
|||
83
src/main.js
83
src/main.js
|
|
@ -1,11 +1,16 @@
|
|||
var React = global.React || require('react');
|
||||
var Formsy = {};
|
||||
var validationRules = require('./validationRules.js');
|
||||
var formDataToObject = require('form-data-to-object');
|
||||
var utils = require('./utils.js');
|
||||
var Mixin = require('./Mixin.js');
|
||||
var HOC = require('./HOC.js');
|
||||
var Decorator = require('./Decorator.js');
|
||||
var options = {};
|
||||
|
||||
Formsy.Mixin = Mixin;
|
||||
Formsy.HOC = HOC;
|
||||
Formsy.Decorator = Decorator;
|
||||
|
||||
Formsy.defaults = function (passedOptions) {
|
||||
options = passedOptions;
|
||||
|
|
@ -40,6 +45,23 @@ Formsy.Form = React.createClass({
|
|||
};
|
||||
},
|
||||
|
||||
childContextTypes: {
|
||||
formsy: React.PropTypes.object
|
||||
},
|
||||
getChildContext: function () {
|
||||
return {
|
||||
formsy: {
|
||||
attachToForm: this.attachToForm,
|
||||
detachFromForm: this.detachFromForm,
|
||||
validate: this.validate,
|
||||
isFormDisabled: this.isFormDisabled,
|
||||
isValidValue: function (component, value) {
|
||||
return this.runValidation(component, value).isValid;
|
||||
}.bind(this)
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// Add a map to store the inputs of the form, a model to store
|
||||
// the values of the form and register child inputs
|
||||
componentWillMount: function () {
|
||||
|
|
@ -98,7 +120,7 @@ Formsy.Form = React.createClass({
|
|||
if (this.props.mapping) {
|
||||
return this.props.mapping(this.model)
|
||||
} else {
|
||||
return Object.keys(this.model).reduce(function (mappedModel, key) {
|
||||
return formDataToObject(Object.keys(this.model).reduce(function (mappedModel, key) {
|
||||
|
||||
var keyArray = key.split('.');
|
||||
var base = mappedModel;
|
||||
|
|
@ -109,7 +131,7 @@ Formsy.Form = React.createClass({
|
|||
|
||||
return mappedModel;
|
||||
|
||||
}.bind(this), {});
|
||||
}.bind(this), {}));
|
||||
}
|
||||
},
|
||||
|
||||
|
|
@ -139,7 +161,7 @@ Formsy.Form = React.createClass({
|
|||
var component = this.inputs[name];
|
||||
var args = [{
|
||||
_isValid: !(name in errors),
|
||||
_validationError: errors[name]
|
||||
_validationError: typeof errors[name] === 'string' ? [errors[name]] : errors[name]
|
||||
}];
|
||||
component.setState.apply(component, args);
|
||||
}.bind(this));
|
||||
|
|
@ -171,45 +193,12 @@ Formsy.Form = React.createClass({
|
|||
}
|
||||
var args = [{
|
||||
_isValid: this.props.preventExternalInvalidation || false,
|
||||
_externalError: errors[name]
|
||||
_externalError: typeof errors[name] === 'string' ? [errors[name]] : errors[name]
|
||||
}];
|
||||
component.setState.apply(component, args);
|
||||
}.bind(this));
|
||||
},
|
||||
|
||||
// Traverse the children and children of children to find
|
||||
// all inputs by checking the name prop. Maybe do a better
|
||||
// check here
|
||||
traverseChildrenAndRegisterInputs: function (children) {
|
||||
|
||||
if (typeof children !== 'object' || children === null) {
|
||||
return children;
|
||||
}
|
||||
return React.Children.map(children, function (child) {
|
||||
|
||||
if (typeof child !== 'object' || child === null) {
|
||||
return child;
|
||||
}
|
||||
|
||||
if (child.props && child.props.name) {
|
||||
|
||||
return React.cloneElement(child, {
|
||||
_attachToForm: this.attachToForm,
|
||||
_detachFromForm: this.detachFromForm,
|
||||
_validate: this.validate,
|
||||
_isFormDisabled: this.isFormDisabled,
|
||||
_isValidValue: function (component, value) {
|
||||
return this.runValidation(component, value).isValid;
|
||||
}.bind(this)
|
||||
}, child.props && child.props.children);
|
||||
} else {
|
||||
return React.cloneElement(child, {}, this.traverseChildrenAndRegisterInputs(child.props && child.props.children));
|
||||
}
|
||||
|
||||
}, this);
|
||||
|
||||
},
|
||||
|
||||
isFormDisabled: function () {
|
||||
return this.props.disabled;
|
||||
},
|
||||
|
|
@ -288,23 +277,29 @@ Formsy.Form = React.createClass({
|
|||
error: (function () {
|
||||
|
||||
if (isValid && !isRequired) {
|
||||
return '';
|
||||
return [];
|
||||
}
|
||||
|
||||
if (validationResults.errors.length) {
|
||||
return validationResults.errors[0];
|
||||
return validationResults.errors;
|
||||
}
|
||||
|
||||
if (this.props.validationErrors && this.props.validationErrors[component.props.name]) {
|
||||
return this.props.validationErrors[component.props.name];
|
||||
return typeof this.props.validationErrors[component.props.name] === 'string' ? [this.props.validationErrors[component.props.name]] : this.props.validationErrors[component.props.name];
|
||||
}
|
||||
|
||||
if (isRequired) {
|
||||
return validationErrors[requiredResults.success[0]] || null;
|
||||
var error = validationErrors[requiredResults.success[0]];
|
||||
return error ? [error] : null;
|
||||
}
|
||||
|
||||
if (!isValid) {
|
||||
return validationErrors[validationResults.failed[0]] || validationError;
|
||||
if (validationResults.failed.length) {
|
||||
return validationResults.failed.map(function(failed) {
|
||||
return validationErrors[failed] ? validationErrors[failed] : validationError;
|
||||
}).filter(function(x, pos, arr) {
|
||||
// Remove duplicates
|
||||
return arr.indexOf(x) === pos;
|
||||
});
|
||||
}
|
||||
|
||||
}.call(this))
|
||||
|
|
@ -438,7 +433,7 @@ Formsy.Form = React.createClass({
|
|||
|
||||
return (
|
||||
<form {...this.props} onSubmit={this.submit}>
|
||||
{this.traverseChildrenAndRegisterInputs(this.props.children)}
|
||||
{this.props.children}
|
||||
</form>
|
||||
);
|
||||
|
||||
|
|
|
|||
|
|
@ -38,16 +38,25 @@ var validations = {
|
|||
if (typeof value === 'number') {
|
||||
return true;
|
||||
}
|
||||
return validations.matchRegexp(values, value, /^[-+]?(\d*[.])?\d+$/);
|
||||
return validations.matchRegexp(values, value, /^[-+]?(?:\d*[.])?\d+$/);
|
||||
},
|
||||
isAlpha: function (values, value) {
|
||||
return validations.matchRegexp(values, value, /^[a-zA-Z]+$/);
|
||||
return validations.matchRegexp(values, value, /^[A-Z]+$/i);
|
||||
},
|
||||
isAlphanumeric: function (values, value) {
|
||||
return validations.matchRegexp(values, value, /^[0-9A-Z]+$/i);
|
||||
},
|
||||
isInt: function (values, value) {
|
||||
return validations.matchRegexp(values, value, /^(?:[-+]?(?:0|[1-9]\d*))$/);
|
||||
},
|
||||
isFloat: function (values, value) {
|
||||
return validations.matchRegexp(values, value, /^(?:[-+]?(?:\d+))?(?:\.\d*)?(?:[eE][\+\-]?(?:\d+))?$/);
|
||||
},
|
||||
isWords: function (values, value) {
|
||||
return validations.matchRegexp(values, value, /^[a-zA-Z\s]+$/);
|
||||
return validations.matchRegexp(values, value, /^[A-Z\s]+$/i);
|
||||
},
|
||||
isSpecialWords: function (values, value) {
|
||||
return validations.matchRegexp(values, value, /^[a-zA-Z\s\u00C0-\u017F]+$/);
|
||||
return validations.matchRegexp(values, value, /^[A-Z\s\u00C0-\u017F]+$/i);
|
||||
},
|
||||
isLength: function (values, value, length) {
|
||||
return !isExisty(value) || isEmpty(value) || value.length === length;
|
||||
|
|
|
|||
|
|
@ -1,25 +1,22 @@
|
|||
require('babel/register');
|
||||
|
||||
var path = require('path');
|
||||
var jsdom = require('jsdom').jsdom;
|
||||
var jasmine = require('jasmine-node');
|
||||
import path from 'path';
|
||||
import testrunner from 'nodeunit/lib/reporters/default.js';
|
||||
import {jsdom} from 'jsdom';
|
||||
|
||||
global.document = jsdom();
|
||||
global.window = document.defaultView;
|
||||
global.navigator = global.window.navigator;
|
||||
|
||||
var jasmineOptions = {
|
||||
specFolders: [path.resolve(__dirname, 'specs')],
|
||||
//onComplete: onComplete,
|
||||
isVerbose: true,
|
||||
showColors: true,
|
||||
teamcity: false,
|
||||
useRequireJs: false,
|
||||
regExpSpec: /spec\.jsx$/,
|
||||
junitreport: true,
|
||||
includeStackTrace: true,
|
||||
//coffee: options.coffee,
|
||||
//growl: options.growl
|
||||
};
|
||||
|
||||
jasmine.executeSpecsInFolder(jasmineOptions);
|
||||
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"
|
||||
}, function(err) {
|
||||
if (err) {
|
||||
process.exit(1);
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -0,0 +1,519 @@
|
|||
import React from 'react';
|
||||
import TestUtils from 'react-addons-test-utils';
|
||||
|
||||
import Formsy from './..';
|
||||
import TestInput, { InputFactory } from './utils/TestInput';
|
||||
import immediate from './utils/immediate';
|
||||
|
||||
export default {
|
||||
|
||||
'should return passed and setValue() value when using getValue()': function (test) {
|
||||
|
||||
const form = TestUtils.renderIntoDocument(
|
||||
<Formsy.Form>
|
||||
<TestInput name="foo" value="foo"/>
|
||||
</Formsy.Form>
|
||||
);
|
||||
|
||||
const input = TestUtils.findRenderedDOMComponentWithTag(form, 'INPUT');
|
||||
test.equal(input.value, 'foo');
|
||||
TestUtils.Simulate.change(input, {target: {value: 'foobar'}});
|
||||
test.equal(input.value, 'foobar');
|
||||
|
||||
test.done();
|
||||
|
||||
},
|
||||
|
||||
'should set back to pristine value when running reset': function (test) {
|
||||
|
||||
let reset = null;
|
||||
const Input = InputFactory({
|
||||
componentDidMount() {
|
||||
reset = this.resetValue;
|
||||
}
|
||||
});
|
||||
const form = TestUtils.renderIntoDocument(
|
||||
<Formsy.Form>
|
||||
<Input name="foo" value="foo"/>
|
||||
</Formsy.Form>
|
||||
);
|
||||
|
||||
const input = TestUtils.findRenderedDOMComponentWithTag(form, 'INPUT');
|
||||
TestUtils.Simulate.change(input, {target: {value: 'foobar'}});
|
||||
reset();
|
||||
test.equal(input.value, 'foo');
|
||||
|
||||
test.done();
|
||||
|
||||
},
|
||||
|
||||
'should return error message passed when calling getErrorMessage()': function (test) {
|
||||
|
||||
let getErrorMessage = null;
|
||||
const Input = InputFactory({
|
||||
componentDidMount() {
|
||||
getErrorMessage = this.getErrorMessage;
|
||||
}
|
||||
});
|
||||
TestUtils.renderIntoDocument(
|
||||
<Formsy.Form>
|
||||
<Input name="foo" value="foo" validations="isEmail" validationError="Has to be email"/>
|
||||
</Formsy.Form>
|
||||
);
|
||||
|
||||
test.equal(getErrorMessage(), 'Has to be email');
|
||||
|
||||
test.done();
|
||||
|
||||
},
|
||||
|
||||
'should return true or false when calling isValid() depending on valid state': function (test) {
|
||||
|
||||
let isValid = null;
|
||||
const Input = InputFactory({
|
||||
componentDidMount() {
|
||||
isValid = this.isValid;
|
||||
}
|
||||
});
|
||||
const form = TestUtils.renderIntoDocument(
|
||||
<Formsy.Form url="/users">
|
||||
<Input name="foo" value="foo" validations="isEmail"/>
|
||||
</Formsy.Form>
|
||||
);
|
||||
|
||||
test.equal(isValid(), false);
|
||||
const input = TestUtils.findRenderedDOMComponentWithTag(form, 'INPUT');
|
||||
TestUtils.Simulate.change(input, {target: {value: 'foo@foo.com'}});
|
||||
test.equal(isValid(), true);
|
||||
|
||||
test.done();
|
||||
|
||||
},
|
||||
|
||||
'should return true or false when calling isRequired() depending on passed required attribute': function (test) {
|
||||
|
||||
const isRequireds = [];
|
||||
const Input = InputFactory({
|
||||
componentDidMount() {
|
||||
isRequireds.push(this.isRequired);
|
||||
}
|
||||
});
|
||||
TestUtils.renderIntoDocument(
|
||||
<Formsy.Form url="/users">
|
||||
<Input name="foo" value=""/>
|
||||
<Input name="foo" value="" required/>
|
||||
<Input name="foo" value="foo" required="isLength:3"/>
|
||||
</Formsy.Form>
|
||||
);
|
||||
|
||||
test.equal(isRequireds[0](), false);
|
||||
test.equal(isRequireds[1](), true);
|
||||
test.equal(isRequireds[2](), true);
|
||||
|
||||
test.done();
|
||||
|
||||
},
|
||||
|
||||
'should return true or false when calling showRequired() depending on input being empty and required is passed, or not': function (test) {
|
||||
|
||||
const showRequireds = [];
|
||||
const Input = InputFactory({
|
||||
componentDidMount() {
|
||||
showRequireds.push(this.showRequired);
|
||||
}
|
||||
});
|
||||
TestUtils.renderIntoDocument(
|
||||
<Formsy.Form url="/users">
|
||||
<Input name="A" value="foo"/>
|
||||
<Input name="B" value="" required/>
|
||||
<Input name="C" value=""/>
|
||||
</Formsy.Form>
|
||||
);
|
||||
|
||||
test.equal(showRequireds[0](), false);
|
||||
test.equal(showRequireds[1](), true);
|
||||
test.equal(showRequireds[2](), false);
|
||||
|
||||
test.done();
|
||||
|
||||
},
|
||||
|
||||
'should return true or false when calling isPristine() depending on input has been "touched" or not': function (test) {
|
||||
|
||||
let isPristine = null;
|
||||
const Input = InputFactory({
|
||||
componentDidMount() {
|
||||
isPristine = this.isPristine;
|
||||
}
|
||||
});
|
||||
const form = TestUtils.renderIntoDocument(
|
||||
<Formsy.Form url="/users">
|
||||
<Input name="A" value="foo"/>
|
||||
</Formsy.Form>
|
||||
);
|
||||
|
||||
test.equal(isPristine(), true);
|
||||
const input = TestUtils.findRenderedDOMComponentWithTag(form, 'INPUT');
|
||||
TestUtils.Simulate.change(input, {target: {value: 'foo'}});
|
||||
test.equal(isPristine(), false);
|
||||
|
||||
test.done();
|
||||
|
||||
},
|
||||
|
||||
'should allow an undefined value to be updated to a value': function (test) {
|
||||
|
||||
const TestForm = React.createClass({
|
||||
getInitialState() {
|
||||
return {value: undefined};
|
||||
},
|
||||
changeValue() {
|
||||
this.setState({
|
||||
value: 'foo'
|
||||
});
|
||||
},
|
||||
render() {
|
||||
return (
|
||||
<Formsy.Form url="/users">
|
||||
<TestInput name="A" value={this.state.value}/>
|
||||
</Formsy.Form>
|
||||
);
|
||||
}
|
||||
});
|
||||
const form = TestUtils.renderIntoDocument(<TestForm/>);
|
||||
|
||||
form.changeValue();
|
||||
const input = TestUtils.findRenderedDOMComponentWithTag(form, 'INPUT');
|
||||
immediate(() => {
|
||||
test.equal(input.value, 'foo');
|
||||
test.done();
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
'should be able to test a values validity': function (test) {
|
||||
|
||||
const TestForm = React.createClass({
|
||||
render() {
|
||||
return (
|
||||
<Formsy.Form>
|
||||
<TestInput name="A" validations="isEmail"/>
|
||||
</Formsy.Form>
|
||||
);
|
||||
}
|
||||
});
|
||||
const form = TestUtils.renderIntoDocument(<TestForm/>);
|
||||
|
||||
const input = TestUtils.findRenderedComponentWithType(form, TestInput);
|
||||
test.equal(input.isValidValue('foo@bar.com'), true);
|
||||
test.equal(input.isValidValue('foo@bar'), false);
|
||||
test.done();
|
||||
|
||||
},
|
||||
|
||||
'should be able to use an object as validations property': function (test) {
|
||||
|
||||
const TestForm = React.createClass({
|
||||
render() {
|
||||
return (
|
||||
<Formsy.Form>
|
||||
<TestInput name="A" validations={{
|
||||
isEmail: true
|
||||
}}/>
|
||||
</Formsy.Form>
|
||||
);
|
||||
}
|
||||
});
|
||||
const form = TestUtils.renderIntoDocument(<TestForm/>);
|
||||
|
||||
const input = TestUtils.findRenderedComponentWithType(form, TestInput);
|
||||
test.equal(input.isValidValue('foo@bar.com'), true);
|
||||
test.equal(input.isValidValue('foo@bar'), false);
|
||||
|
||||
test.done();
|
||||
|
||||
},
|
||||
|
||||
'should be able to pass complex values to a validation rule': function (test) {
|
||||
|
||||
const TestForm = React.createClass({
|
||||
render() {
|
||||
return (
|
||||
<Formsy.Form>
|
||||
<TestInput name="A" validations={{
|
||||
matchRegexp: /foo/
|
||||
}} value="foo"/>
|
||||
</Formsy.Form>
|
||||
);
|
||||
}
|
||||
});
|
||||
const form = TestUtils.renderIntoDocument(<TestForm/>);
|
||||
|
||||
const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput);
|
||||
test.equal(inputComponent.isValid(), true);
|
||||
const input = TestUtils.findRenderedDOMComponentWithTag(form, 'INPUT');
|
||||
TestUtils.Simulate.change(input, {target: {value: 'bar'}});
|
||||
test.equal(inputComponent.isValid(), false);
|
||||
|
||||
test.done();
|
||||
|
||||
},
|
||||
|
||||
'should be able to run a function to validate': function (test) {
|
||||
|
||||
const TestForm = React.createClass({
|
||||
customValidationA(values, value) {
|
||||
return value === 'foo';
|
||||
},
|
||||
customValidationB(values, value) {
|
||||
return value === 'foo' && values.A === 'foo';
|
||||
},
|
||||
render() {
|
||||
return (
|
||||
<Formsy.Form>
|
||||
<TestInput name="A" validations={{
|
||||
custom: this.customValidationA
|
||||
}} value="foo"/>
|
||||
<TestInput name="B" validations={{
|
||||
custom: this.customValidationB
|
||||
}} value="foo"/>
|
||||
</Formsy.Form>
|
||||
);
|
||||
}
|
||||
});
|
||||
const form = TestUtils.renderIntoDocument(<TestForm/>);
|
||||
|
||||
const inputComponent = TestUtils.scryRenderedComponentsWithType(form, TestInput);
|
||||
test.equal(inputComponent[0].isValid(), true);
|
||||
test.equal(inputComponent[1].isValid(), 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);
|
||||
|
||||
test.done();
|
||||
|
||||
},
|
||||
|
||||
'should override all error messages with error messages passed by form': function (test) {
|
||||
|
||||
const TestForm = React.createClass({
|
||||
render() {
|
||||
return (
|
||||
<Formsy.Form validationErrors={{A: 'bar'}}>
|
||||
<TestInput name="A" validations={{
|
||||
isEmail: true
|
||||
}} validationError="bar2" validationErrors={{isEmail: 'bar3'}} value="foo"/>
|
||||
</Formsy.Form>
|
||||
);
|
||||
}
|
||||
});
|
||||
const form = TestUtils.renderIntoDocument(<TestForm/>);
|
||||
|
||||
const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput);
|
||||
test.equal(inputComponent.getErrorMessage(), 'bar');
|
||||
|
||||
test.done();
|
||||
|
||||
},
|
||||
|
||||
'should override validation rules with required rules': function (test) {
|
||||
|
||||
const TestForm = React.createClass({
|
||||
render() {
|
||||
return (
|
||||
<Formsy.Form>
|
||||
<TestInput name="A"
|
||||
validations={{
|
||||
isEmail: true
|
||||
}}
|
||||
validationError="bar"
|
||||
validationErrors={{isEmail: 'bar2', isLength: 'bar3'}}
|
||||
value="f"
|
||||
required={{
|
||||
isLength: 1
|
||||
}}
|
||||
/>
|
||||
</Formsy.Form>
|
||||
);
|
||||
}
|
||||
});
|
||||
const form = TestUtils.renderIntoDocument(<TestForm/>);
|
||||
|
||||
const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput);
|
||||
test.equal(inputComponent.getErrorMessage(), 'bar3');
|
||||
|
||||
test.done();
|
||||
|
||||
},
|
||||
|
||||
'should fall back to default error message when non exist in validationErrors map': function (test) {
|
||||
|
||||
const TestForm = React.createClass({
|
||||
render() {
|
||||
return (
|
||||
<Formsy.Form>
|
||||
<TestInput name="A"
|
||||
validations={{
|
||||
isEmail: true
|
||||
}}
|
||||
validationError="bar"
|
||||
validationErrors={{foo: 'bar'}}
|
||||
value="foo"
|
||||
/>
|
||||
</Formsy.Form>
|
||||
);
|
||||
}
|
||||
});
|
||||
const form = TestUtils.renderIntoDocument(<TestForm/>);
|
||||
|
||||
const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput);
|
||||
test.equal(inputComponent.getErrorMessage(), 'bar');
|
||||
|
||||
test.done();
|
||||
|
||||
},
|
||||
|
||||
'should not be valid if it is required and required rule is true': function (test) {
|
||||
|
||||
const TestForm = React.createClass({
|
||||
render() {
|
||||
return (
|
||||
<Formsy.Form>
|
||||
<TestInput name="A"
|
||||
required
|
||||
/>
|
||||
</Formsy.Form>
|
||||
);
|
||||
}
|
||||
});
|
||||
const form = TestUtils.renderIntoDocument(<TestForm/>);
|
||||
|
||||
const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput);
|
||||
test.equal(inputComponent.isValid(), false);
|
||||
|
||||
test.done();
|
||||
|
||||
},
|
||||
|
||||
'should handle objects and arrays as values': function (test) {
|
||||
|
||||
const TestForm = React.createClass({
|
||||
getInitialState() {
|
||||
return {
|
||||
foo: {foo: 'bar'},
|
||||
bar: ['foo']
|
||||
};
|
||||
},
|
||||
render() {
|
||||
return (
|
||||
<Formsy.Form>
|
||||
<TestInput name="foo" value={this.state.foo}/>
|
||||
<TestInput name="bar" value={this.state.bar}/>
|
||||
</Formsy.Form>
|
||||
);
|
||||
}
|
||||
});
|
||||
const form = TestUtils.renderIntoDocument(<TestForm/>);
|
||||
|
||||
form.setState({
|
||||
foo: {foo: 'foo'},
|
||||
bar: ['bar']
|
||||
});
|
||||
|
||||
const inputs = TestUtils.scryRenderedComponentsWithType(form, TestInput);
|
||||
test.deepEqual(inputs[0].getValue(), {foo: 'foo'});
|
||||
test.deepEqual(inputs[1].getValue(), ['bar']);
|
||||
|
||||
test.done();
|
||||
|
||||
},
|
||||
|
||||
'should handle isFormDisabled with dynamic inputs': function (test) {
|
||||
|
||||
const TestForm = React.createClass({
|
||||
getInitialState() {
|
||||
return {
|
||||
bool: true
|
||||
};
|
||||
},
|
||||
flip() {
|
||||
this.setState({
|
||||
bool: !this.state.bool
|
||||
});
|
||||
},
|
||||
render() {
|
||||
return (
|
||||
<Formsy.Form disabled={this.state.bool}>
|
||||
{this.state.bool ?
|
||||
<TestInput name="foo" /> :
|
||||
<TestInput name="bar" />
|
||||
}
|
||||
</Formsy.Form>
|
||||
);
|
||||
}
|
||||
});
|
||||
const form = TestUtils.renderIntoDocument(<TestForm/>);
|
||||
|
||||
const input = TestUtils.findRenderedComponentWithType(form, TestInput);
|
||||
test.equal(input.isFormDisabled(), true);
|
||||
form.flip();
|
||||
test.equal(input.isFormDisabled(), false);
|
||||
|
||||
test.done();
|
||||
|
||||
},
|
||||
|
||||
'should allow for dot notation in name which maps to a deep object': function (test) {
|
||||
|
||||
const TestForm = React.createClass({
|
||||
onSubmit(model) {
|
||||
test.deepEqual(model, {foo: {bar: 'foo', test: 'test'}});
|
||||
},
|
||||
render() {
|
||||
return (
|
||||
<Formsy.Form onSubmit={this.onSubmit}>
|
||||
<TestInput name="foo.bar" value="foo"/>
|
||||
<TestInput name="foo.test" value="test"/>
|
||||
</Formsy.Form>
|
||||
);
|
||||
}
|
||||
});
|
||||
const form = TestUtils.renderIntoDocument(<TestForm/>);
|
||||
|
||||
test.expect(1);
|
||||
|
||||
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) {
|
||||
|
||||
const TestForm = React.createClass({
|
||||
onSubmit(model) {
|
||||
test.deepEqual(model, {foo: ['foo', 'bar']});
|
||||
},
|
||||
render() {
|
||||
return (
|
||||
<Formsy.Form onSubmit={this.onSubmit}>
|
||||
<TestInput name="foo[0]" value="foo"/>
|
||||
<TestInput name="foo[1]" value="bar"/>
|
||||
</Formsy.Form>
|
||||
);
|
||||
}
|
||||
});
|
||||
const form = TestUtils.renderIntoDocument(<TestForm/>);
|
||||
|
||||
test.expect(1);
|
||||
|
||||
const formEl = TestUtils.findRenderedDOMComponentWithTag(form, 'form');
|
||||
TestUtils.Simulate.submit(formEl);
|
||||
|
||||
test.done();
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
|
@ -0,0 +1,706 @@
|
|||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import TestUtils from 'react-addons-test-utils';
|
||||
|
||||
import Formsy from './..';
|
||||
import TestInput from './utils/TestInput';
|
||||
import immediate from './utils/immediate';
|
||||
import sinon from 'sinon';
|
||||
|
||||
export default {
|
||||
|
||||
'Setting up a form': {
|
||||
|
||||
'should render a form into the document': function (test) {
|
||||
|
||||
const form = TestUtils.renderIntoDocument(<Formsy.Form></Formsy.Form>);
|
||||
test.equal(ReactDOM.findDOMNode(form).tagName, 'FORM');
|
||||
|
||||
test.done();
|
||||
|
||||
},
|
||||
|
||||
'should set a class name if passed': function (test) {
|
||||
|
||||
const form = TestUtils.renderIntoDocument( <Formsy.Form className="foo"></Formsy.Form>);
|
||||
test.equal(ReactDOM.findDOMNode(form).className, 'foo');
|
||||
|
||||
test.done();
|
||||
|
||||
},
|
||||
|
||||
'should allow for null/undefined children': function (test) {
|
||||
|
||||
let model = null;
|
||||
const TestForm = React.createClass({
|
||||
render() {
|
||||
return (
|
||||
<Formsy.Form onSubmit={(formModel) => (model = formModel)}>
|
||||
<h1>Test</h1>
|
||||
{ null }
|
||||
{ undefined }
|
||||
<TestInput name="name" value={ 'foo' } />
|
||||
</Formsy.Form>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
const form = TestUtils.renderIntoDocument(<TestForm/>);
|
||||
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;
|
||||
const TestForm = React.createClass({
|
||||
componentWillMount() {
|
||||
forceUpdate = this.forceUpdate.bind(this);
|
||||
},
|
||||
render() {
|
||||
return (
|
||||
<Formsy.Form onSubmit={(formModel) => (model = formModel)}>
|
||||
{inputs}
|
||||
</Formsy.Form>);
|
||||
}
|
||||
});
|
||||
const form = TestUtils.renderIntoDocument(<TestForm/>);
|
||||
|
||||
// Wait before adding the input
|
||||
setTimeout(() => {
|
||||
inputs.push(<TestInput name="test" value="" key={inputs.length}/>);
|
||||
|
||||
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;
|
||||
const TestForm = React.createClass({
|
||||
componentWillMount() {
|
||||
forceUpdate = this.forceUpdate.bind(this);
|
||||
},
|
||||
render() {
|
||||
return (
|
||||
<Formsy.Form onSubmit={(formModel) => (model = formModel)}>
|
||||
{inputs}
|
||||
</Formsy.Form>);
|
||||
}
|
||||
});
|
||||
const form = TestUtils.renderIntoDocument(<TestForm/>);
|
||||
|
||||
// Wait before adding the input
|
||||
immediate(() => {
|
||||
inputs.push(<TestInput name="test" key={inputs.length}/>);
|
||||
|
||||
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;
|
||||
|
||||
const TestForm = React.createClass({
|
||||
componentWillMount() {
|
||||
forceUpdate = this.forceUpdate.bind(this);
|
||||
},
|
||||
render() {
|
||||
const input = <TestInput name="test" value={this.props.value} />;
|
||||
|
||||
return (
|
||||
<Formsy.Form onSubmit={(formModel) => (model = formModel)}>
|
||||
{input}
|
||||
</Formsy.Form>);
|
||||
}
|
||||
});
|
||||
let form = TestUtils.renderIntoDocument(<TestForm value="foo"/>);
|
||||
|
||||
// Wait before changing the input
|
||||
immediate(() => {
|
||||
form = TestUtils.renderIntoDocument(<TestForm value="bar"/>);
|
||||
|
||||
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();
|
||||
|
||||
Formsy.addValidationRule('runRule', runRule);
|
||||
Formsy.addValidationRule('notRunRule', notRunRule);
|
||||
|
||||
const form = TestUtils.renderIntoDocument(
|
||||
<Formsy.Form>
|
||||
<TestInput name="one" validations="runRule" value="foo"/>
|
||||
</Formsy.Form>
|
||||
);
|
||||
|
||||
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();
|
||||
Formsy.addValidationRule('ruleA', ruleA);
|
||||
Formsy.addValidationRule('ruleB', ruleB);
|
||||
|
||||
class TestForm extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {rule: 'ruleA'};
|
||||
}
|
||||
changeRule() {
|
||||
this.setState({
|
||||
rule: 'ruleB'
|
||||
});
|
||||
}
|
||||
render() {
|
||||
return (
|
||||
<Formsy.Form>
|
||||
<TestInput name="one" validations={this.state.rule} value="foo"/>
|
||||
</Formsy.Form>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const form = TestUtils.renderIntoDocument(<TestForm/>);
|
||||
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 (
|
||||
<Formsy.Form ref="formsy" onInvalid={isInValidSpy}>
|
||||
<TestInput name="one" validations="isEmail" value="foo@bar.com"/>
|
||||
{
|
||||
this.state.showSecondInput ?
|
||||
<TestInput name="two" validations="isEmail" value="foo@bar"/>
|
||||
:
|
||||
null
|
||||
}
|
||||
</Formsy.Form>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const form = TestUtils.renderIntoDocument(<TestForm/>);
|
||||
|
||||
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 (
|
||||
<Formsy.Form ref="formsy" onValid={isValidSpy}>
|
||||
<TestInput name="one" validations="isEmail" value="foo@bar.com"/>
|
||||
{
|
||||
this.state.showSecondInput ?
|
||||
<TestInput name="two" validations="isEmail" value="foo@bar"/>
|
||||
:
|
||||
null
|
||||
}
|
||||
</Formsy.Form>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const form = TestUtils.renderIntoDocument(<TestForm/>);
|
||||
|
||||
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();
|
||||
Formsy.addValidationRule('ruleA', ruleA);
|
||||
Formsy.addValidationRule('ruleB', ruleB);
|
||||
|
||||
const form = TestUtils.renderIntoDocument(
|
||||
<Formsy.Form>
|
||||
<TestInput name="one" validations="ruleA,ruleB" value="foo" />
|
||||
</Formsy.Form>
|
||||
);
|
||||
|
||||
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();
|
||||
const TestForm = React.createClass({
|
||||
render() {
|
||||
return <Formsy.Form onChange={hasChanged}></Formsy.Form>;
|
||||
}
|
||||
});
|
||||
TestUtils.renderIntoDocument(<TestForm/>);
|
||||
test.equal(hasChanged.called, false);
|
||||
test.done();
|
||||
|
||||
},
|
||||
|
||||
'should trigger onChange when form element is changed': function (test) {
|
||||
|
||||
const hasChanged = sinon.spy();
|
||||
const form = TestUtils.renderIntoDocument(
|
||||
<Formsy.Form onChange={hasChanged}>
|
||||
<TestInput name="foo"/>
|
||||
</Formsy.Form>
|
||||
);
|
||||
TestUtils.Simulate.change(TestUtils.findRenderedDOMComponentWithTag(form, 'INPUT'), {target: {value: 'bar'}});
|
||||
test.equal(hasChanged.called, true);
|
||||
test.done();
|
||||
|
||||
},
|
||||
|
||||
'should trigger onChange when new input is added to form': function (test) {
|
||||
|
||||
const hasChanged = sinon.spy();
|
||||
const TestForm = React.createClass({
|
||||
getInitialState() {
|
||||
return {
|
||||
showInput: false
|
||||
};
|
||||
},
|
||||
addInput() {
|
||||
this.setState({
|
||||
showInput: true
|
||||
})
|
||||
},
|
||||
render() {
|
||||
return (
|
||||
<Formsy.Form onChange={hasChanged}>
|
||||
{
|
||||
this.state.showInput ?
|
||||
<TestInput name="test"/>
|
||||
:
|
||||
null
|
||||
}
|
||||
</Formsy.Form>);
|
||||
}
|
||||
});
|
||||
|
||||
const form = TestUtils.renderIntoDocument(<TestForm/>);
|
||||
form.addInput();
|
||||
immediate(() => {
|
||||
test.equal(hasChanged.called, true);
|
||||
test.done();
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
'Update a form': {
|
||||
|
||||
'should allow elements to check if the form is disabled': function (test) {
|
||||
|
||||
const TestForm = React.createClass({
|
||||
getInitialState() { return { disabled: true }; },
|
||||
enableForm() { this.setState({ disabled: false }); },
|
||||
render() {
|
||||
return (
|
||||
<Formsy.Form disabled={this.state.disabled}>
|
||||
<TestInput name="foo"/>
|
||||
</Formsy.Form>);
|
||||
}
|
||||
});
|
||||
|
||||
const form = TestUtils.renderIntoDocument(<TestForm/>);
|
||||
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) {
|
||||
|
||||
const TestForm = React.createClass({
|
||||
getInitialState() { return { validationErrors: { foo: 'bar' } }; },
|
||||
onChange(values) {
|
||||
this.setState(values.foo ? { validationErrors: {} } : { validationErrors: {foo: 'bar'} });
|
||||
},
|
||||
render() {
|
||||
return (
|
||||
<Formsy.Form onChange={this.onChange} validationErrors={this.state.validationErrors}>
|
||||
<TestInput name="foo"/>
|
||||
</Formsy.Form>);
|
||||
}
|
||||
});
|
||||
const form = TestUtils.renderIntoDocument(<TestForm/>);
|
||||
|
||||
// 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();
|
||||
const TestForm = React.createClass({
|
||||
render() {
|
||||
return (
|
||||
<Formsy.Form onValidSubmit={isCalled}>
|
||||
<TestInput name="foo" validations="isEmail" value="foo@bar.com"/>
|
||||
</Formsy.Form>);
|
||||
}
|
||||
});
|
||||
const form = TestUtils.renderIntoDocument(<TestForm/>);
|
||||
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();
|
||||
const TestForm = React.createClass({
|
||||
render() {
|
||||
return (
|
||||
<Formsy.Form onInvalidSubmit={isCalled}>
|
||||
<TestInput name="foo" validations="isEmail" value="foo@bar"/>
|
||||
</Formsy.Form>);
|
||||
}
|
||||
});
|
||||
const form = TestUtils.renderIntoDocument(<TestForm/>);
|
||||
|
||||
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();
|
||||
const TestForm = React.createClass({
|
||||
render() {
|
||||
return (
|
||||
<Formsy.Form onSubmit={onSubmit}>
|
||||
<TestInput name="foo" value={false} type="checkbox" />
|
||||
<button type="submit">Save</button>
|
||||
</Formsy.Form>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
const form = TestUtils.renderIntoDocument(<TestForm/>);
|
||||
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();
|
||||
const TestForm = React.createClass({
|
||||
getInitialState() {
|
||||
return {
|
||||
value: true
|
||||
};
|
||||
},
|
||||
changeValue() {
|
||||
this.setState({
|
||||
value: false
|
||||
});
|
||||
},
|
||||
render() {
|
||||
return (
|
||||
<Formsy.Form onSubmit={onSubmit}>
|
||||
<TestInput name="foo" value={this.state.value} type="checkbox" />
|
||||
<button type="submit">Save</button>
|
||||
</Formsy.Form>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
const form = TestUtils.renderIntoDocument(<TestForm/>);
|
||||
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) {
|
||||
|
||||
const TestForm = React.createClass({
|
||||
render() {
|
||||
return (
|
||||
<Formsy.Form>
|
||||
<TestInput name="foo" value={true} type="checkbox" />
|
||||
<button type="submit">Save</button>
|
||||
</Formsy.Form>
|
||||
);
|
||||
}
|
||||
});
|
||||
const form = TestUtils.renderIntoDocument(<TestForm/>);
|
||||
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) {
|
||||
|
||||
const TestForm = React.createClass({
|
||||
getInitialState() {
|
||||
return {
|
||||
value: true
|
||||
};
|
||||
},
|
||||
changeValue() {
|
||||
this.setState({
|
||||
value: false
|
||||
});
|
||||
},
|
||||
render() {
|
||||
return (
|
||||
<Formsy.Form>
|
||||
<TestInput name="foo" value={this.state.value} type="checkbox" />
|
||||
<button type="submit">Save</button>
|
||||
</Formsy.Form>
|
||||
);
|
||||
}
|
||||
});
|
||||
const form = TestUtils.renderIntoDocument(<TestForm/>);
|
||||
const input = TestUtils.findRenderedComponentWithType(form, TestInput);
|
||||
const formsyForm = TestUtils.findRenderedComponentWithType(form, Formsy.Form);
|
||||
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) {
|
||||
|
||||
const TestForm = React.createClass({
|
||||
getInitialState() {
|
||||
return {
|
||||
value: true
|
||||
};
|
||||
},
|
||||
changeValue() {
|
||||
this.setState({
|
||||
value: false
|
||||
});
|
||||
},
|
||||
render() {
|
||||
return (
|
||||
<Formsy.Form>
|
||||
<TestInput name="foo" value={this.state.value} type="checkbox" />
|
||||
<button type="submit">Save</button>
|
||||
</Formsy.Form>
|
||||
);
|
||||
}
|
||||
});
|
||||
const form = TestUtils.renderIntoDocument(<TestForm/>);
|
||||
const input = TestUtils.findRenderedComponentWithType(form, TestInput);
|
||||
const formsyForm = TestUtils.findRenderedComponentWithType(form, Formsy.Form);
|
||||
|
||||
test.equal(input.getValue(), true);
|
||||
form.changeValue();
|
||||
test.equal(input.getValue(), false);
|
||||
formsyForm.reset({
|
||||
foo: 'bar'
|
||||
});
|
||||
test.equal(input.getValue(), 'bar');
|
||||
test.done();
|
||||
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
'.isChanged()': {
|
||||
|
||||
'initially returns false': function (test) {
|
||||
|
||||
const hasOnChanged = sinon.spy();
|
||||
const form = TestUtils.renderIntoDocument(
|
||||
<Formsy.Form onChange={hasOnChanged}>
|
||||
<TestInput name="one" value="foo" />
|
||||
</Formsy.Form>
|
||||
);
|
||||
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(
|
||||
<Formsy.Form onChange={hasOnChanged}>
|
||||
<TestInput name="one" value="foo" />
|
||||
</Formsy.Form>
|
||||
);
|
||||
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(
|
||||
<Formsy.Form onChange={hasOnChanged}>
|
||||
<TestInput name="one" value="foo" />
|
||||
</Formsy.Form>
|
||||
);
|
||||
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();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
|
@ -0,0 +1,80 @@
|
|||
import React from 'react';
|
||||
import TestUtils from 'react-addons-test-utils';
|
||||
import immediate from './utils/immediate';
|
||||
|
||||
import Formsy from './..';
|
||||
import { InputFactory } from './utils/TestInput';
|
||||
|
||||
const TestInput = InputFactory({
|
||||
render() {
|
||||
return <input value={this.getValue()} readOnly/>;
|
||||
}
|
||||
});
|
||||
|
||||
const TestForm = React.createClass({
|
||||
render() {
|
||||
return (
|
||||
<Formsy.Form>
|
||||
<TestInput name="foo" validations="equals:foo" value={this.props.inputValue}/>
|
||||
</Formsy.Form>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
export default {
|
||||
|
||||
'should pass when the value is equal': function (test) {
|
||||
|
||||
const form = TestUtils.renderIntoDocument(<TestForm inputValue="foo"/>);
|
||||
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(<TestForm inputValue="fo"/>);
|
||||
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(<TestForm inputValue={''}/>);
|
||||
const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput);
|
||||
test.equal(inputComponent.isValid(), true);
|
||||
test.done();
|
||||
|
||||
},
|
||||
|
||||
'should pass with an undefined': function (test) {
|
||||
|
||||
const form = TestUtils.renderIntoDocument(<TestForm inputValue={undefined}/>);
|
||||
const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput);
|
||||
test.equal(inputComponent.isValid(), true);
|
||||
test.done();
|
||||
|
||||
},
|
||||
|
||||
'should pass with a null': function (test) {
|
||||
|
||||
const form = TestUtils.renderIntoDocument(<TestForm inputValue={null}/>);
|
||||
const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput);
|
||||
test.equal(inputComponent.isValid(), true);
|
||||
test.done();
|
||||
|
||||
},
|
||||
|
||||
'should fail with a number': function (test) {
|
||||
|
||||
const form = TestUtils.renderIntoDocument(<TestForm inputValue={42}/>);
|
||||
const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput);
|
||||
test.equal(inputComponent.isValid(), false);
|
||||
test.done();
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
|
@ -0,0 +1,88 @@
|
|||
import React from 'react';
|
||||
import TestUtils from 'react-addons-test-utils';
|
||||
|
||||
import Formsy from './..';
|
||||
import { InputFactory } from './utils/TestInput';
|
||||
|
||||
const TestInput = InputFactory({
|
||||
render() {
|
||||
return <input value={this.getValue()} readOnly/>;
|
||||
}
|
||||
});
|
||||
|
||||
const TestForm = React.createClass({
|
||||
render() {
|
||||
return (
|
||||
<Formsy.Form>
|
||||
<TestInput name="foo" validations="isAlpha" value={this.props.inputValue}/>
|
||||
</Formsy.Form>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
export default {
|
||||
|
||||
'should pass with a default value': function (test) {
|
||||
|
||||
const form = TestUtils.renderIntoDocument(<TestForm/>);
|
||||
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(<TestForm inputValue="myValue"/>);
|
||||
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(<TestForm inputValue="myValue42"/>);
|
||||
const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput);
|
||||
test.equal(inputComponent.isValid(), false);
|
||||
test.done();
|
||||
|
||||
},
|
||||
|
||||
'should pass with an undefined': function (test) {
|
||||
|
||||
const form = TestUtils.renderIntoDocument(<TestForm inputValue={undefined}/>);
|
||||
const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput);
|
||||
test.equal(inputComponent.isValid(), true);
|
||||
test.done();
|
||||
|
||||
},
|
||||
|
||||
'should pass with a null': function (test) {
|
||||
|
||||
const form = TestUtils.renderIntoDocument(<TestForm inputValue={null}/>);
|
||||
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(<TestForm inputValue={''}/>);
|
||||
const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput);
|
||||
test.equal(inputComponent.isValid(), true);
|
||||
test.done();
|
||||
|
||||
},
|
||||
|
||||
'should fail with a number': function (test) {
|
||||
|
||||
const form = TestUtils.renderIntoDocument(<TestForm inputValue={42}/>);
|
||||
const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput);
|
||||
test.equal(inputComponent.isValid(), false);
|
||||
test.done();
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
|
@ -0,0 +1,98 @@
|
|||
import React from 'react';
|
||||
import TestUtils from 'react-addons-test-utils';
|
||||
|
||||
import Formsy from './..';
|
||||
import { InputFactory } from './utils/TestInput';
|
||||
|
||||
const TestInput = InputFactory({
|
||||
render() {
|
||||
return <input value={this.getValue()} readOnly/>;
|
||||
}
|
||||
});
|
||||
|
||||
const TestForm = React.createClass({
|
||||
render() {
|
||||
return (
|
||||
<Formsy.Form>
|
||||
<TestInput name="foo" validations="isAlphanumeric" value={this.props.inputValue}/>
|
||||
</Formsy.Form>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
export default {
|
||||
|
||||
'should pass with a default value': function (test) {
|
||||
|
||||
const form = TestUtils.renderIntoDocument(<TestForm/>);
|
||||
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(<TestForm inputValue="myValue"/>);
|
||||
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(<TestForm inputValue="myValue42"/>);
|
||||
const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput);
|
||||
test.equal(inputComponent.isValid(), true);
|
||||
test.done();
|
||||
|
||||
},
|
||||
|
||||
'should pass with an undefined': function (test) {
|
||||
|
||||
const form = TestUtils.renderIntoDocument(<TestForm inputValue={undefined}/>);
|
||||
const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput);
|
||||
test.equal(inputComponent.isValid(), true);
|
||||
test.done();
|
||||
|
||||
},
|
||||
|
||||
'should pass with a null': function (test) {
|
||||
|
||||
const form = TestUtils.renderIntoDocument(<TestForm inputValue={null}/>);
|
||||
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(<TestForm inputValue={''}/>);
|
||||
const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput);
|
||||
test.equal(inputComponent.isValid(), true);
|
||||
test.done();
|
||||
|
||||
},
|
||||
|
||||
'should pass with a number': function (test) {
|
||||
|
||||
const form = TestUtils.renderIntoDocument(<TestForm inputValue={42}/>);
|
||||
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(<TestForm inputValue={value}/>);
|
||||
const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput);
|
||||
test.equal(inputComponent.isValid(), false);
|
||||
test.done();
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
|
@ -0,0 +1,88 @@
|
|||
import React from 'react';
|
||||
import TestUtils from 'react-addons-test-utils';
|
||||
|
||||
import Formsy from './..';
|
||||
import { InputFactory } from './utils/TestInput';
|
||||
|
||||
const TestInput = InputFactory({
|
||||
render() {
|
||||
return <input value={this.getValue()} readOnly/>;
|
||||
}
|
||||
});
|
||||
|
||||
const TestForm = React.createClass({
|
||||
render() {
|
||||
return (
|
||||
<Formsy.Form>
|
||||
<TestInput name="foo" validations="isEmail" value={this.props.inputValue}/>
|
||||
</Formsy.Form>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
export default {
|
||||
|
||||
'should pass with a default value': function (test) {
|
||||
|
||||
const form = TestUtils.renderIntoDocument(<TestForm/>);
|
||||
const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput);
|
||||
test.equal(inputComponent.isValid(), true);
|
||||
test.done();
|
||||
|
||||
},
|
||||
|
||||
'should fail with "foo"': function (test) {
|
||||
|
||||
const form = TestUtils.renderIntoDocument(<TestForm inputValue="foo"/>);
|
||||
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(<TestForm inputValue="foo@foo.com"/>);
|
||||
const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput);
|
||||
test.equal(inputComponent.isValid(), true);
|
||||
test.done();
|
||||
|
||||
},
|
||||
|
||||
'should pass with an undefined': function (test) {
|
||||
|
||||
const form = TestUtils.renderIntoDocument(<TestForm inputValue={undefined}/>);
|
||||
const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput);
|
||||
test.equal(inputComponent.isValid(), true);
|
||||
test.done();
|
||||
|
||||
},
|
||||
|
||||
'should pass with a null': function (test) {
|
||||
|
||||
const form = TestUtils.renderIntoDocument(<TestForm inputValue={null}/>);
|
||||
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(<TestForm inputValue={''}/>);
|
||||
const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput);
|
||||
test.equal(inputComponent.isValid(), true);
|
||||
test.done();
|
||||
|
||||
},
|
||||
|
||||
'should fail with a number': function (test) {
|
||||
|
||||
const form = TestUtils.renderIntoDocument(<TestForm inputValue={42}/>);
|
||||
const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput);
|
||||
test.equal(inputComponent.isValid(), false);
|
||||
test.done();
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
|
@ -0,0 +1,88 @@
|
|||
import React from 'react';
|
||||
import TestUtils from 'react-addons-test-utils';
|
||||
|
||||
import Formsy from './..';
|
||||
import { InputFactory } from './utils/TestInput';
|
||||
|
||||
const TestInput = InputFactory({
|
||||
render() {
|
||||
return <input value={this.getValue()} readOnly/>;
|
||||
}
|
||||
});
|
||||
|
||||
const TestForm = React.createClass({
|
||||
render() {
|
||||
return (
|
||||
<Formsy.Form>
|
||||
<TestInput name="foo" validations="isEmptyString" value={this.props.inputValue}/>
|
||||
</Formsy.Form>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
export default {
|
||||
|
||||
'should pass with a default value': function (test) {
|
||||
|
||||
const form = TestUtils.renderIntoDocument(<TestForm/>);
|
||||
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(<TestForm inputValue="abc"/>);
|
||||
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(<TestForm inputValue=""/>);
|
||||
const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput);
|
||||
test.equal(inputComponent.isValid(), true);
|
||||
test.done();
|
||||
|
||||
},
|
||||
|
||||
'should fail with undefined': function (test) {
|
||||
|
||||
const form = TestUtils.renderIntoDocument(<TestForm inputValue={undefined}/>);
|
||||
const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput);
|
||||
test.equal(inputComponent.isValid(), false);
|
||||
test.done();
|
||||
|
||||
},
|
||||
|
||||
'should fail with null': function (test) {
|
||||
|
||||
const form = TestUtils.renderIntoDocument(<TestForm inputValue={null}/>);
|
||||
const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput);
|
||||
test.equal(inputComponent.isValid(), false);
|
||||
test.done();
|
||||
|
||||
},
|
||||
|
||||
'should fail with a number': function (test) {
|
||||
|
||||
const form = TestUtils.renderIntoDocument(<TestForm inputValue={42}/>);
|
||||
const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput);
|
||||
test.equal(inputComponent.isValid(), false);
|
||||
test.done();
|
||||
|
||||
},
|
||||
|
||||
'should fail with a zero': function (test) {
|
||||
|
||||
const form = TestUtils.renderIntoDocument(<TestForm inputValue={0}/>);
|
||||
const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput);
|
||||
test.equal(inputComponent.isValid(), false);
|
||||
test.done();
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
|
@ -0,0 +1,88 @@
|
|||
import React from 'react';
|
||||
import TestUtils from 'react-addons-test-utils';
|
||||
|
||||
import Formsy from './..';
|
||||
import { InputFactory } from './utils/TestInput';
|
||||
|
||||
const TestInput = InputFactory({
|
||||
render() {
|
||||
return <input value={this.getValue()} readOnly/>;
|
||||
}
|
||||
});
|
||||
|
||||
const TestForm = React.createClass({
|
||||
render() {
|
||||
return (
|
||||
<Formsy.Form>
|
||||
<TestInput name="foo" validations="isExisty" value={this.props.inputValue}/>
|
||||
</Formsy.Form>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
export default {
|
||||
|
||||
'should pass with a default value': function (test) {
|
||||
|
||||
const form = TestUtils.renderIntoDocument(<TestForm/>);
|
||||
const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput);
|
||||
test.equal(inputComponent.isValid(), false);
|
||||
test.done();
|
||||
|
||||
},
|
||||
|
||||
'should pass with a string': function (test) {
|
||||
|
||||
const form = TestUtils.renderIntoDocument(<TestForm inputValue="abc"/>);
|
||||
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(<TestForm inputValue=""/>);
|
||||
const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput);
|
||||
test.equal(inputComponent.isValid(), true);
|
||||
test.done();
|
||||
|
||||
},
|
||||
|
||||
'should fail with undefined': function (test) {
|
||||
|
||||
const form = TestUtils.renderIntoDocument(<TestForm inputValue={undefined}/>);
|
||||
const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput);
|
||||
test.equal(inputComponent.isValid(), false);
|
||||
test.done();
|
||||
|
||||
},
|
||||
|
||||
'should fail with null': function (test) {
|
||||
|
||||
const form = TestUtils.renderIntoDocument(<TestForm inputValue={null}/>);
|
||||
const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput);
|
||||
test.equal(inputComponent.isValid(), false);
|
||||
test.done();
|
||||
|
||||
},
|
||||
|
||||
'should pass with a number': function (test) {
|
||||
|
||||
const form = TestUtils.renderIntoDocument(<TestForm inputValue={42}/>);
|
||||
const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput);
|
||||
test.equal(inputComponent.isValid(), true);
|
||||
test.done();
|
||||
|
||||
},
|
||||
|
||||
'should pass with a zero': function (test) {
|
||||
|
||||
const form = TestUtils.renderIntoDocument(<TestForm inputValue={0}/>);
|
||||
const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput);
|
||||
test.equal(inputComponent.isValid(), true);
|
||||
test.done();
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
|
@ -0,0 +1,125 @@
|
|||
import React from 'react';
|
||||
import TestUtils from 'react-addons-test-utils';
|
||||
|
||||
import Formsy from './..';
|
||||
import { InputFactory } from './utils/TestInput';
|
||||
|
||||
const TestInput = InputFactory({
|
||||
render() {
|
||||
return <input value={this.getValue()} readOnly/>;
|
||||
}
|
||||
});
|
||||
|
||||
const TestForm = React.createClass({
|
||||
render() {
|
||||
return (
|
||||
<Formsy.Form>
|
||||
<TestInput name="foo" validations="isFloat" value={this.props.inputValue}/>
|
||||
</Formsy.Form>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
export default {
|
||||
|
||||
'should pass with a default value': function (test) {
|
||||
|
||||
const form = TestUtils.renderIntoDocument(<TestForm/>);
|
||||
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(<TestForm inputValue=""/>);
|
||||
const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput);
|
||||
test.equal(inputComponent.isValid(), true);
|
||||
test.done();
|
||||
|
||||
},
|
||||
|
||||
'should fail with a string': function (test) {
|
||||
|
||||
const form = TestUtils.renderIntoDocument(<TestForm inputValue="abc"/>);
|
||||
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(<TestForm inputValue="+42"/>);
|
||||
const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput);
|
||||
test.equal(inputComponent.isValid(), true);
|
||||
test.done();
|
||||
|
||||
},
|
||||
|
||||
'should fail string with digits': function (test) {
|
||||
|
||||
const form = TestUtils.renderIntoDocument(<TestForm inputValue="42 is an answer"/>);
|
||||
const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput);
|
||||
test.equal(inputComponent.isValid(), false);
|
||||
test.done();
|
||||
|
||||
},
|
||||
|
||||
'should pass with an int': function (test) {
|
||||
|
||||
const form = TestUtils.renderIntoDocument(<TestForm inputValue={42}/>);
|
||||
const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput);
|
||||
test.equal(inputComponent.isValid(), true);
|
||||
test.done();
|
||||
|
||||
},
|
||||
|
||||
'should pass with a float': function (test) {
|
||||
|
||||
const form = TestUtils.renderIntoDocument(<TestForm inputValue={Math.PI}/>);
|
||||
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(<TestForm inputValue="-1e3"/>);
|
||||
const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput);
|
||||
test.equal(inputComponent.isValid(), true);
|
||||
test.done();
|
||||
|
||||
},
|
||||
|
||||
'should pass with undefined': function (test) {
|
||||
|
||||
const form = TestUtils.renderIntoDocument(<TestForm inputValue={undefined}/>);
|
||||
const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput);
|
||||
test.equal(inputComponent.isValid(), true);
|
||||
test.done();
|
||||
|
||||
},
|
||||
|
||||
'should pass with null': function (test) {
|
||||
|
||||
const form = TestUtils.renderIntoDocument(<TestForm inputValue={null}/>);
|
||||
const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput);
|
||||
test.equal(inputComponent.isValid(), true);
|
||||
test.done();
|
||||
|
||||
},
|
||||
|
||||
'should pass with a zero': function (test) {
|
||||
|
||||
const form = TestUtils.renderIntoDocument(<TestForm inputValue={0}/>);
|
||||
const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput);
|
||||
test.equal(inputComponent.isValid(), true);
|
||||
test.done();
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
|
@ -0,0 +1,125 @@
|
|||
import React from 'react';
|
||||
import TestUtils from 'react-addons-test-utils';
|
||||
|
||||
import Formsy from './..';
|
||||
import { InputFactory } from './utils/TestInput';
|
||||
|
||||
const TestInput = InputFactory({
|
||||
render() {
|
||||
return <input value={this.getValue()} readOnly/>;
|
||||
}
|
||||
});
|
||||
|
||||
const TestForm = React.createClass({
|
||||
render() {
|
||||
return (
|
||||
<Formsy.Form>
|
||||
<TestInput name="foo" validations="isInt" value={this.props.inputValue}/>
|
||||
</Formsy.Form>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
export default {
|
||||
|
||||
'should pass with a default value': function (test) {
|
||||
|
||||
const form = TestUtils.renderIntoDocument(<TestForm/>);
|
||||
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(<TestForm inputValue=""/>);
|
||||
const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput);
|
||||
test.equal(inputComponent.isValid(), true);
|
||||
test.done();
|
||||
|
||||
},
|
||||
|
||||
'should fail with a string': function (test) {
|
||||
|
||||
const form = TestUtils.renderIntoDocument(<TestForm inputValue="abc"/>);
|
||||
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(<TestForm inputValue="+42"/>);
|
||||
const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput);
|
||||
test.equal(inputComponent.isValid(), true);
|
||||
test.done();
|
||||
|
||||
},
|
||||
|
||||
'should fail string with digits': function (test) {
|
||||
|
||||
const form = TestUtils.renderIntoDocument(<TestForm inputValue="42 is an answer"/>);
|
||||
const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput);
|
||||
test.equal(inputComponent.isValid(), false);
|
||||
test.done();
|
||||
|
||||
},
|
||||
|
||||
'should pass with an int': function (test) {
|
||||
|
||||
const form = TestUtils.renderIntoDocument(<TestForm inputValue={42}/>);
|
||||
const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput);
|
||||
test.equal(inputComponent.isValid(), true);
|
||||
test.done();
|
||||
|
||||
},
|
||||
|
||||
'should fail with a float': function (test) {
|
||||
|
||||
const form = TestUtils.renderIntoDocument(<TestForm inputValue={Math.PI}/>);
|
||||
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(<TestForm inputValue="-1e3"/>);
|
||||
const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput);
|
||||
test.equal(inputComponent.isValid(), false);
|
||||
test.done();
|
||||
|
||||
},
|
||||
|
||||
'should pass with undefined': function (test) {
|
||||
|
||||
const form = TestUtils.renderIntoDocument(<TestForm inputValue={undefined}/>);
|
||||
const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput);
|
||||
test.equal(inputComponent.isValid(), true);
|
||||
test.done();
|
||||
|
||||
},
|
||||
|
||||
'should pass with null': function (test) {
|
||||
|
||||
const form = TestUtils.renderIntoDocument(<TestForm inputValue={null}/>);
|
||||
const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput);
|
||||
test.equal(inputComponent.isValid(), true);
|
||||
test.done();
|
||||
|
||||
},
|
||||
|
||||
'should pass with a zero': function (test) {
|
||||
|
||||
const form = TestUtils.renderIntoDocument(<TestForm inputValue={0}/>);
|
||||
const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput);
|
||||
test.equal(inputComponent.isValid(), true);
|
||||
test.done();
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
|
@ -0,0 +1,177 @@
|
|||
import React from 'react';
|
||||
import TestUtils from 'react-addons-test-utils';
|
||||
|
||||
import Formsy from './..';
|
||||
import { InputFactory } from './utils/TestInput';
|
||||
|
||||
const TestInput = InputFactory({
|
||||
render() {
|
||||
return <input value={this.getValue()} readOnly/>;
|
||||
}
|
||||
});
|
||||
|
||||
const TestForm = React.createClass({
|
||||
render() {
|
||||
return (
|
||||
<Formsy.Form>
|
||||
<TestInput name="foo" validations={this.props.rule} value={this.props.inputValue}/>
|
||||
</Formsy.Form>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
export default {
|
||||
|
||||
'isLength:3': {
|
||||
|
||||
'should pass with a default value': function (test) {
|
||||
|
||||
const form = TestUtils.renderIntoDocument(<TestForm rule="isLength:3"/>);
|
||||
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(<TestForm rule="isLength:3" inputValue="hi"/>);
|
||||
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(<TestForm rule="isLength:3" inputValue="hi ho happ"/>);
|
||||
const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput);
|
||||
test.equal(inputComponent.isValid(), false);
|
||||
test.done();
|
||||
|
||||
},
|
||||
|
||||
'should pass with matching length': function (test) {
|
||||
|
||||
const form = TestUtils.renderIntoDocument(<TestForm rule="isLength:3" inputValue="foo"/>);
|
||||
const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput);
|
||||
test.equal(inputComponent.isValid(), true);
|
||||
test.done();
|
||||
|
||||
},
|
||||
|
||||
'should pass with undefined': function (test) {
|
||||
|
||||
const form = TestUtils.renderIntoDocument(<TestForm rule="isLength:3" inputValue={undefined}/>);
|
||||
const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput);
|
||||
test.equal(inputComponent.isValid(), true);
|
||||
test.done();
|
||||
|
||||
},
|
||||
|
||||
'should pass with null': function (test) {
|
||||
|
||||
const form = TestUtils.renderIntoDocument(<TestForm rule="isLength:3" inputValue={null}/>);
|
||||
const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput);
|
||||
test.equal(inputComponent.isValid(), true);
|
||||
test.done();
|
||||
|
||||
},
|
||||
|
||||
'should pass with empty string': function (test) {
|
||||
|
||||
const form = TestUtils.renderIntoDocument(<TestForm rule="isLength:3" inputValue=""/>);
|
||||
const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput);
|
||||
test.equal(inputComponent.isValid(), true);
|
||||
test.done();
|
||||
|
||||
},
|
||||
|
||||
'should fail with a number': function (test) {
|
||||
|
||||
const form = TestUtils.renderIntoDocument(<TestForm rule="isLength:3" inputValue={123}/>);
|
||||
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(<TestForm rule="isLength:0"/>);
|
||||
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(<TestForm rule="isLength:0" inputValue="hi"/>);
|
||||
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(<TestForm rule="isLength:0" inputValue="hi ho happ"/>);
|
||||
const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput);
|
||||
test.equal(inputComponent.isValid(), false);
|
||||
test.done();
|
||||
|
||||
},
|
||||
|
||||
'should pass with matching length': function (test) {
|
||||
|
||||
const form = TestUtils.renderIntoDocument(<TestForm rule="isLength:0" inputValue=""/>);
|
||||
const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput);
|
||||
test.equal(inputComponent.isValid(), true);
|
||||
test.done();
|
||||
|
||||
},
|
||||
|
||||
'should pass with undefined': function (test) {
|
||||
|
||||
const form = TestUtils.renderIntoDocument(<TestForm rule="isLength:0" inputValue={undefined}/>);
|
||||
const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput);
|
||||
test.equal(inputComponent.isValid(), true);
|
||||
test.done();
|
||||
|
||||
},
|
||||
|
||||
'should pass with null': function (test) {
|
||||
|
||||
const form = TestUtils.renderIntoDocument(<TestForm rule="isLength:0" inputValue={null}/>);
|
||||
const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput);
|
||||
test.equal(inputComponent.isValid(), true);
|
||||
test.done();
|
||||
|
||||
},
|
||||
|
||||
'should pass with empty string': function (test) {
|
||||
|
||||
const form = TestUtils.renderIntoDocument(<TestForm rule="isLength:0" inputValue=""/>);
|
||||
const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput);
|
||||
test.equal(inputComponent.isValid(), true);
|
||||
test.done();
|
||||
|
||||
},
|
||||
|
||||
'should fail with a number': function (test) {
|
||||
|
||||
const form = TestUtils.renderIntoDocument(<TestForm rule="isLength:0" inputValue={123}/>);
|
||||
const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput);
|
||||
test.equal(inputComponent.isValid(), false);
|
||||
test.done();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
|
@ -0,0 +1,124 @@
|
|||
import React from 'react';
|
||||
import TestUtils from 'react-addons-test-utils';
|
||||
|
||||
import Formsy from './..';
|
||||
import { InputFactory } from './utils/TestInput';
|
||||
|
||||
const TestInput = InputFactory({
|
||||
render() {
|
||||
return <input value={this.getValue()} readOnly/>;
|
||||
}
|
||||
});
|
||||
|
||||
const TestForm = React.createClass({
|
||||
render() {
|
||||
return (
|
||||
<Formsy.Form>
|
||||
<TestInput name="foo" validations="isNumeric" value={this.props.inputValue}/>
|
||||
</Formsy.Form>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
export default {
|
||||
|
||||
'should pass with a default value': function (test) {
|
||||
|
||||
const form = TestUtils.renderIntoDocument(<TestForm/>);
|
||||
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(<TestForm inputValue=""/>);
|
||||
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(<TestForm inputValue="foo"/>);
|
||||
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(<TestForm inputValue="+42"/>);
|
||||
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(<TestForm inputValue="42 is an answer"/>);
|
||||
const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput);
|
||||
test.equal(inputComponent.isValid(), false);
|
||||
test.done();
|
||||
|
||||
},
|
||||
|
||||
'should pass with an int': function (test) {
|
||||
|
||||
const form = TestUtils.renderIntoDocument(<TestForm inputValue={42}/>);
|
||||
const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput);
|
||||
test.equal(inputComponent.isValid(), true);
|
||||
test.done();
|
||||
|
||||
},
|
||||
|
||||
'should pass with a float': function (test) {
|
||||
|
||||
const form = TestUtils.renderIntoDocument(<TestForm inputValue={Math.PI}/>);
|
||||
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(<TestForm inputValue="-1e3"/>);
|
||||
const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput);
|
||||
test.equal(inputComponent.isValid(), false);
|
||||
test.done();
|
||||
|
||||
},
|
||||
|
||||
'should pass with an undefined': function (test) {
|
||||
|
||||
const form = TestUtils.renderIntoDocument(<TestForm inputValue={undefined}/>);
|
||||
const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput);
|
||||
test.equal(inputComponent.isValid(), true);
|
||||
test.done();
|
||||
|
||||
},
|
||||
|
||||
'should pass with a null': function (test) {
|
||||
|
||||
const form = TestUtils.renderIntoDocument(<TestForm inputValue={null}/>);
|
||||
const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput);
|
||||
test.equal(inputComponent.isValid(), true);
|
||||
test.done();
|
||||
|
||||
},
|
||||
|
||||
'should pass with a zero': function (test) {
|
||||
|
||||
const form = TestUtils.renderIntoDocument(<TestForm inputValue={0}/>);
|
||||
const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput);
|
||||
test.equal(inputComponent.isValid(), true);
|
||||
test.done();
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
|
@ -0,0 +1,88 @@
|
|||
import React from 'react';
|
||||
import TestUtils from 'react-addons-test-utils';
|
||||
|
||||
import Formsy from './..';
|
||||
import { InputFactory } from './utils/TestInput';
|
||||
|
||||
const TestInput = InputFactory({
|
||||
render() {
|
||||
return <input value={this.getValue()} readOnly/>;
|
||||
}
|
||||
});
|
||||
|
||||
const TestForm = React.createClass({
|
||||
render() {
|
||||
return (
|
||||
<Formsy.Form>
|
||||
<TestInput name="foo" validations="isUrl" value={this.props.inputValue}/>
|
||||
</Formsy.Form>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
export default {
|
||||
|
||||
'should pass with default value': function (test) {
|
||||
|
||||
const form = TestUtils.renderIntoDocument(<TestForm/>);
|
||||
const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput);
|
||||
test.equal(inputComponent.isValid(), true);
|
||||
test.done();
|
||||
|
||||
},
|
||||
|
||||
'should fail with "foo"': function (test) {
|
||||
|
||||
const form = TestUtils.renderIntoDocument(<TestForm inputValue="foo"/>);
|
||||
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(<TestForm inputValue="https://www.google.com/"/>);
|
||||
const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput);
|
||||
test.equal(inputComponent.isValid(), true);
|
||||
test.done();
|
||||
|
||||
},
|
||||
|
||||
'should pass with an undefined': function (test) {
|
||||
|
||||
const form = TestUtils.renderIntoDocument(<TestForm inputValue={undefined}/>);
|
||||
const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput);
|
||||
test.equal(inputComponent.isValid(), true);
|
||||
test.done();
|
||||
|
||||
},
|
||||
|
||||
'should pass with a null': function (test) {
|
||||
|
||||
const form = TestUtils.renderIntoDocument(<TestForm inputValue={null}/>);
|
||||
const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput);
|
||||
test.equal(inputComponent.isValid(), true);
|
||||
test.done();
|
||||
|
||||
},
|
||||
|
||||
'should fail with a number': function (test) {
|
||||
|
||||
const form = TestUtils.renderIntoDocument(<TestForm inputValue={42}/>);
|
||||
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(<TestForm inputValue=""/>);
|
||||
const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput);
|
||||
test.equal(inputComponent.isValid(), true);
|
||||
test.done();
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
|
@ -0,0 +1,88 @@
|
|||
import React from 'react';
|
||||
import TestUtils from 'react-addons-test-utils';
|
||||
|
||||
import Formsy from './..';
|
||||
import { InputFactory } from './utils/TestInput';
|
||||
|
||||
const TestInput = InputFactory({
|
||||
render() {
|
||||
return <input value={this.getValue()} readOnly/>;
|
||||
}
|
||||
});
|
||||
|
||||
const TestForm = React.createClass({
|
||||
render() {
|
||||
return (
|
||||
<Formsy.Form>
|
||||
<TestInput name="foo" validations="isWords" value={this.props.inputValue}/>
|
||||
</Formsy.Form>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
export default {
|
||||
|
||||
'should pass with a default value': function (test) {
|
||||
|
||||
const form = TestUtils.renderIntoDocument(<TestForm/>);
|
||||
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(<TestForm inputValue="sup"/>);
|
||||
const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput);
|
||||
test.equal(inputComponent.isValid(), true);
|
||||
test.done();
|
||||
|
||||
},
|
||||
|
||||
'should pass with 2 words': function (test) {
|
||||
|
||||
const form = TestUtils.renderIntoDocument(<TestForm inputValue="sup dude"/>);
|
||||
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(<TestForm inputValue="sup 42"/>);
|
||||
const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput);
|
||||
test.equal(inputComponent.isValid(), false);
|
||||
test.done();
|
||||
|
||||
},
|
||||
|
||||
'should pass with an undefined': function (test) {
|
||||
|
||||
const form = TestUtils.renderIntoDocument(<TestForm inputValue={undefined}/>);
|
||||
const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput);
|
||||
test.equal(inputComponent.isValid(), true);
|
||||
test.done();
|
||||
|
||||
},
|
||||
|
||||
'should pass with a null': function (test) {
|
||||
|
||||
const form = TestUtils.renderIntoDocument(<TestForm inputValue={null}/>);
|
||||
const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput);
|
||||
test.equal(inputComponent.isValid(), true);
|
||||
test.done();
|
||||
|
||||
},
|
||||
|
||||
'should fail with a number': function (test) {
|
||||
|
||||
const form = TestUtils.renderIntoDocument(<TestForm inputValue={42}/>);
|
||||
const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput);
|
||||
test.equal(inputComponent.isValid(), false);
|
||||
test.done();
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
|
@ -0,0 +1,97 @@
|
|||
import React from 'react';
|
||||
import TestUtils from 'react-addons-test-utils';
|
||||
|
||||
import Formsy from './..';
|
||||
import { InputFactory } from './utils/TestInput';
|
||||
|
||||
const TestInput = InputFactory({
|
||||
render() {
|
||||
return <input value={this.getValue()} readOnly/>;
|
||||
}
|
||||
});
|
||||
|
||||
const TestForm = React.createClass({
|
||||
render() {
|
||||
return (
|
||||
<Formsy.Form>
|
||||
<TestInput name="foo" validations="maxLength:3" value={this.props.inputValue}/>
|
||||
</Formsy.Form>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
export default {
|
||||
|
||||
'should pass with a default value': function (test) {
|
||||
|
||||
const form = TestUtils.renderIntoDocument(<TestForm/>);
|
||||
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(<TestForm inputValue="hi"/>);
|
||||
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(<TestForm inputValue="bar"/>);
|
||||
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(<TestForm inputValue="foobar"/>);
|
||||
const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput);
|
||||
test.equal(inputComponent.isValid(), false);
|
||||
test.done();
|
||||
|
||||
},
|
||||
|
||||
'should pass with empty string': function (test) {
|
||||
|
||||
const form = TestUtils.renderIntoDocument(<TestForm inputValue=""/>);
|
||||
const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput);
|
||||
test.equal(inputComponent.isValid(), true);
|
||||
test.done();
|
||||
|
||||
},
|
||||
|
||||
'should pass with an undefined': function (test) {
|
||||
|
||||
const form = TestUtils.renderIntoDocument(<TestForm inputValue={undefined}/>);
|
||||
const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput);
|
||||
test.equal(inputComponent.isValid(), true);
|
||||
test.done();
|
||||
|
||||
},
|
||||
|
||||
'should pass with a null': function (test) {
|
||||
|
||||
const form = TestUtils.renderIntoDocument(<TestForm inputValue={null}/>);
|
||||
const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput);
|
||||
test.equal(inputComponent.isValid(), true);
|
||||
test.done();
|
||||
|
||||
},
|
||||
|
||||
'should fail with a number': function (test) {
|
||||
|
||||
const form = TestUtils.renderIntoDocument(<TestForm inputValue={42}/>);
|
||||
const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput);
|
||||
test.equal(inputComponent.isValid(), false);
|
||||
test.done();
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
|
@ -0,0 +1,141 @@
|
|||
import React from 'react';
|
||||
import TestUtils from 'react-addons-test-utils';
|
||||
|
||||
import Formsy from './..';
|
||||
import { InputFactory } from './utils/TestInput';
|
||||
|
||||
const TestInput = InputFactory({
|
||||
render() {
|
||||
return <input value={this.getValue()} readOnly/>;
|
||||
}
|
||||
});
|
||||
|
||||
const TestForm = React.createClass({
|
||||
render() {
|
||||
return (
|
||||
<Formsy.Form>
|
||||
<TestInput name="foo" validations={this.props.rule} value={this.props.inputValue}/>
|
||||
</Formsy.Form>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
export default {
|
||||
|
||||
'minLength:3': {
|
||||
|
||||
'should pass with a default value': function (test) {
|
||||
|
||||
const form = TestUtils.renderIntoDocument(<TestForm rule="minLength:3"/>);
|
||||
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(<TestForm rule="minLength:3" inputValue="myValue"/>);
|
||||
const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput);
|
||||
test.equal(inputComponent.isValid(), true);
|
||||
test.done();
|
||||
|
||||
},
|
||||
|
||||
'should pass with empty string': function (test) {
|
||||
|
||||
const form = TestUtils.renderIntoDocument(<TestForm rule="minLength:3" inputValue=""/>);
|
||||
const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput);
|
||||
test.equal(inputComponent.isValid(), true);
|
||||
test.done();
|
||||
|
||||
},
|
||||
|
||||
'should pass with an undefined': function (test) {
|
||||
|
||||
const form = TestUtils.renderIntoDocument(<TestForm rule="minLength:3" inputValue={undefined}/>);
|
||||
const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput);
|
||||
test.equal(inputComponent.isValid(), true);
|
||||
test.done();
|
||||
|
||||
},
|
||||
|
||||
'should pass with a null': function (test) {
|
||||
|
||||
const form = TestUtils.renderIntoDocument(<TestForm rule="minLength:3" inputValue={null}/>);
|
||||
const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput);
|
||||
test.equal(inputComponent.isValid(), true);
|
||||
test.done();
|
||||
|
||||
},
|
||||
|
||||
'should fail with a number': function (test) {
|
||||
|
||||
const form = TestUtils.renderIntoDocument(<TestForm rule="minLength:3" inputValue={42}/>);
|
||||
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(<TestForm rule="minLength:0"/>);
|
||||
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(<TestForm rule="minLength:0" inputValue="myValue"/>);
|
||||
const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput);
|
||||
test.equal(inputComponent.isValid(), true);
|
||||
test.done();
|
||||
|
||||
},
|
||||
|
||||
'should pass with empty string': function (test) {
|
||||
|
||||
const form = TestUtils.renderIntoDocument(<TestForm rule="minLength:0" inputValue=""/>);
|
||||
const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput);
|
||||
test.equal(inputComponent.isValid(), true);
|
||||
test.done();
|
||||
|
||||
},
|
||||
|
||||
'should pass with an undefined': function (test) {
|
||||
|
||||
const form = TestUtils.renderIntoDocument(<TestForm rule="minLength:0" inputValue={undefined}/>);
|
||||
const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput);
|
||||
test.equal(inputComponent.isValid(), true);
|
||||
test.done();
|
||||
|
||||
},
|
||||
|
||||
'should pass with a null': function (test) {
|
||||
|
||||
const form = TestUtils.renderIntoDocument(<TestForm rule="minLength:0" inputValue={null}/>);
|
||||
const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput);
|
||||
test.equal(inputComponent.isValid(), true);
|
||||
test.done();
|
||||
|
||||
},
|
||||
|
||||
'should fail with a number': function (test) {
|
||||
|
||||
const form = TestUtils.renderIntoDocument(<TestForm rule="minLength:0" inputValue={42}/>);
|
||||
const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput);
|
||||
test.equal(inputComponent.isValid(), false);
|
||||
test.done();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
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(objG, objA), false);
|
||||
|
||||
test.done();
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
|
@ -0,0 +1,201 @@
|
|||
import React from 'react';
|
||||
import TestUtils from 'react-addons-test-utils';
|
||||
|
||||
import Formsy from './..';
|
||||
import TestInput, {InputFactory} from './utils/TestInput';
|
||||
import immediate from './utils/immediate';
|
||||
import sinon from 'sinon';
|
||||
|
||||
export default {
|
||||
|
||||
'should reset only changed form element when external error is passed': function (test) {
|
||||
|
||||
const form = TestUtils.renderIntoDocument(
|
||||
<Formsy.Form onSubmit={(model, reset, invalidate) => invalidate({ foo: 'bar', bar: 'foo' })}>
|
||||
<TestInput name="foo"/>
|
||||
<TestInput name="bar"/>
|
||||
</Formsy.Form>
|
||||
);
|
||||
|
||||
const input = TestUtils.scryRenderedDOMComponentsWithTag(form, 'INPUT')[0];
|
||||
const inputComponents = TestUtils.scryRenderedComponentsWithType(form, TestInput);
|
||||
|
||||
form.submit();
|
||||
test.equal(inputComponents[0].isValid(), false);
|
||||
test.equal(inputComponents[1].isValid(), false);
|
||||
|
||||
TestUtils.Simulate.change(input, {target: {value: 'bar'}});
|
||||
immediate(() => {
|
||||
test.equal(inputComponents[0].isValid(), true);
|
||||
test.equal(inputComponents[1].isValid(), false);
|
||||
test.done();
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
'should let normal validation take over when component with external error is changed': function (test) {
|
||||
|
||||
const form = TestUtils.renderIntoDocument(
|
||||
<Formsy.Form onSubmit={(model, reset, invalidate) => invalidate({ foo: 'bar' })}>
|
||||
<TestInput name="foo" validations="isEmail"/>
|
||||
</Formsy.Form>
|
||||
);
|
||||
|
||||
const input = TestUtils.findRenderedDOMComponentWithTag(form, 'INPUT');
|
||||
const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput);
|
||||
|
||||
form.submit();
|
||||
test.equal(inputComponent.isValid(), false);
|
||||
|
||||
TestUtils.Simulate.change(input, {target: {value: 'bar'}});
|
||||
immediate(() => {
|
||||
test.equal(inputComponent.getValue(), 'bar');
|
||||
test.equal(inputComponent.isValid(), false);
|
||||
test.done();
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
'should trigger an onValid handler, if passed, when form is valid': function (test) {
|
||||
|
||||
const onValid = sinon.spy();
|
||||
const onInvalid = sinon.spy();
|
||||
|
||||
TestUtils.renderIntoDocument(
|
||||
<Formsy.Form onValid={onValid} onInvalid={onInvalid}>
|
||||
<TestInput name="foo" value="bar" required/>
|
||||
</Formsy.Form>
|
||||
);
|
||||
|
||||
test.equal(onValid.called, true);
|
||||
test.equal(onInvalid.called, false);
|
||||
test.done();
|
||||
|
||||
},
|
||||
|
||||
'should trigger an onInvalid handler, if passed, when form is invalid': function (test) {
|
||||
|
||||
const onValid = sinon.spy();
|
||||
const onInvalid = sinon.spy();
|
||||
|
||||
TestUtils.renderIntoDocument(
|
||||
<Formsy.Form onValid={onValid} onInvalid={onInvalid}>
|
||||
<TestInput name="foo" required />
|
||||
</Formsy.Form>
|
||||
);
|
||||
|
||||
test.equal(onValid.called, false);
|
||||
test.equal(onInvalid.called, true);
|
||||
test.done();
|
||||
|
||||
},
|
||||
|
||||
'should be able to use provided validate function': function (test) {
|
||||
|
||||
let isValid = false;
|
||||
const CustomInput = InputFactory({
|
||||
componentDidMount() {
|
||||
isValid = this.isValid();
|
||||
}
|
||||
});
|
||||
const form = TestUtils.renderIntoDocument(
|
||||
<Formsy.Form>
|
||||
<CustomInput name="foo" value="foo" required/>
|
||||
</Formsy.Form>
|
||||
);
|
||||
|
||||
const input = TestUtils.findRenderedDOMComponentWithTag(form, 'INPUT');
|
||||
test.equal(isValid, true);
|
||||
test.done();
|
||||
|
||||
},
|
||||
|
||||
'should provide invalidate callback on onValiSubmit': function (test) {
|
||||
|
||||
const TestForm = React.createClass({
|
||||
render() {
|
||||
return (
|
||||
<Formsy.Form onValidSubmit={(model, reset, invalidate) => invalidate({ foo: 'bar' })}>
|
||||
<TestInput name="foo" value="foo"/>
|
||||
</Formsy.Form>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
const form = TestUtils.renderIntoDocument(<TestForm/>);
|
||||
|
||||
const formEl = TestUtils.findRenderedDOMComponentWithTag(form, 'form');
|
||||
const input = TestUtils.findRenderedComponentWithType(form, TestInput);
|
||||
TestUtils.Simulate.submit(formEl);
|
||||
test.equal(input.isValid(), false);
|
||||
test.done();
|
||||
|
||||
},
|
||||
|
||||
'should provide invalidate callback on onInvalidSubmit': function (test) {
|
||||
|
||||
const TestForm = React.createClass({
|
||||
render() {
|
||||
return (
|
||||
<Formsy.Form onInvalidSubmit={(model, reset, invalidate) => invalidate({ foo: 'bar' })}>
|
||||
<TestInput name="foo" value="foo" validations="isEmail"/>
|
||||
</Formsy.Form>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
const form = TestUtils.renderIntoDocument(<TestForm/>);
|
||||
const formEl = TestUtils.findRenderedDOMComponentWithTag(form, 'form');
|
||||
const input = TestUtils.findRenderedComponentWithType(form, TestInput);
|
||||
TestUtils.Simulate.submit(formEl);
|
||||
test.equal(input.getErrorMessage(), 'bar');
|
||||
|
||||
test.done();
|
||||
|
||||
},
|
||||
|
||||
'should not invalidate inputs on external errors with preventExternalInvalidation prop': function (test) {
|
||||
|
||||
const TestForm = React.createClass({
|
||||
render() {
|
||||
return (
|
||||
<Formsy.Form
|
||||
preventExternalInvalidation
|
||||
onSubmit={(model, reset, invalidate) => invalidate({ foo: 'bar' })}>
|
||||
<TestInput name="foo" value="foo"/>
|
||||
</Formsy.Form>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
const form = TestUtils.renderIntoDocument(<TestForm/>);
|
||||
const formEl = TestUtils.findRenderedDOMComponentWithTag(form, 'form');
|
||||
const input = TestUtils.findRenderedComponentWithType(form, TestInput);
|
||||
TestUtils.Simulate.submit(formEl);
|
||||
test.equal(input.isValid(), true);
|
||||
test.done();
|
||||
|
||||
},
|
||||
|
||||
'should invalidate inputs on external errors without preventExternalInvalidation prop': function (test) {
|
||||
|
||||
const TestForm = React.createClass({
|
||||
render() {
|
||||
return (
|
||||
<Formsy.Form onSubmit={(model, reset, invalidate) => invalidate({ foo: 'bar' })}>
|
||||
<TestInput name="foo" value="foo"/>
|
||||
</Formsy.Form>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
const form = TestUtils.renderIntoDocument(<TestForm/>);
|
||||
const formEl = TestUtils.findRenderedDOMComponentWithTag(form, 'form');
|
||||
const input = TestUtils.findRenderedComponentWithType(form, TestInput);
|
||||
TestUtils.Simulate.submit(formEl);
|
||||
test.equal(input.isValid(), false);
|
||||
test.done();
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
import React from 'react';
|
||||
import Formsy from './../..';
|
||||
import assign from 'react/lib/Object.assign';
|
||||
|
||||
const defaultProps = {
|
||||
mixins: [Formsy.Mixin],
|
||||
getDefaultProps() {
|
||||
return { type: 'text' };
|
||||
},
|
||||
updateValue(event) {
|
||||
this.setValue(event.target[this.props.type === 'checkbox' ? 'checked' : 'value']);
|
||||
},
|
||||
render() {
|
||||
return <input type={this.props.type} value={this.getValue()} onChange={this.updateValue}/>;
|
||||
}
|
||||
};
|
||||
|
||||
export function InputFactory(props) {
|
||||
return React.createClass(assign(defaultProps, props));
|
||||
}
|
||||
|
||||
export default React.createClass(defaultProps);
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
export default function (fn) {
|
||||
setTimeout(fn, 0);
|
||||
}
|
||||
Loading…
Reference in New Issue