Skip to content

Commit

Permalink
[added] CustomPropType.all to allow multiple validations
Browse files Browse the repository at this point in the history
This will allow us to have multiple validations applied on a single
prop.
  • Loading branch information
mtscout6 committed May 27, 2015
1 parent d238d23 commit dfec023
Show file tree
Hide file tree
Showing 5 changed files with 101 additions and 6 deletions.
3 changes: 2 additions & 1 deletion karma.conf.js
Expand Up @@ -13,7 +13,8 @@ module.exports = function (config) {
frameworks: [
'mocha',
'chai',
'sinon'
'sinon',
'sinon-chai'
],

files: [
Expand Down
4 changes: 3 additions & 1 deletion package.json
Expand Up @@ -64,6 +64,7 @@
"karma-mocha-reporter": "^1.0.2",
"karma-phantomjs-launcher": "^0.1.4",
"karma-sinon": "^1.0.3",
"karma-sinon-chai": "^0.3.0",
"karma-sourcemap-loader": "^0.3.4",
"karma-webpack": "^1.5.0",
"less": "^2.4.0",
Expand All @@ -79,6 +80,7 @@
"rimraf": "^2.3.2",
"semver": "^4.3.4",
"sinon": "^1.10.3",
"sinon-chai": "^2.7.0",
"style-loader": "^0.12.0",
"transform-loader": "^0.2.1",
"webpack": "^1.7.2",
Expand All @@ -88,4 +90,4 @@
"dependencies": {
"classnames": "^2.0.0"
}
}
}
31 changes: 29 additions & 2 deletions src/utils/CustomPropTypes.js
@@ -1,6 +1,6 @@
const ANONYMOUS = '<<anonymous>>';

let CustomPropTypes = {
const CustomPropTypes = {
/**
* Checks whether a prop provides a DOM element
*
Expand All @@ -14,6 +14,7 @@ let CustomPropTypes = {
* @returns {Error|undefined}
*/
mountable: createMountableChecker(),

/**
* Checks whether a prop matches a key of an associated object
*
Expand All @@ -32,7 +33,9 @@ let CustomPropTypes = {
* @param componentName
* @returns {Error|undefined}
*/
singlePropFrom: createSinglePropFromChecker
singlePropFrom: createSinglePropFromChecker,

all
};

/**
Expand Down Expand Up @@ -108,4 +111,28 @@ function createSinglePropFromChecker(arrOfProps) {
return validate;
}

function all(propTypes) {
if (propTypes === undefined) {
throw new Error('No validations provided');
}

if (!(propTypes instanceof Array)) {
throw new Error('Invalid argument must be an array');
}

if (propTypes.length === 0) {
throw new Error('No validations provided');
}

return function(props, propName, componentName) {
for(let i = 0; i < propTypes.length; i++) {
let result = propTypes[i](props, propName, componentName);

if (result !== undefined && result !== null) {
return result;
}
}
};
}

export default CustomPropTypes;
1 change: 1 addition & 0 deletions test/.eslintrc
Expand Up @@ -4,6 +4,7 @@
},
"globals": {
"assert": true,
"expect": true,
"sinon": true
},
"plugins": [
Expand Down
68 changes: 66 additions & 2 deletions test/CustomPropTypesSpec.js → test/utils/CustomPropTypesSpec.js
@@ -1,8 +1,8 @@
import React from 'react';
import ReactTestUtils from 'react/lib/ReactTestUtils';
import CustomPropTypes from '../src/utils/CustomPropTypes';
import CustomPropTypes from '../../src/utils/CustomPropTypes';

describe('CustomPropTypes', function () {
describe('CustomPropTypes', function() {

describe('mountable', function () {
function validate(prop) {
Expand Down Expand Up @@ -67,4 +67,68 @@ describe('CustomPropTypes', function () {
validate(testProps).should.be.instanceOf(Error);
});
});

describe('all', function() {
let validators;
const props = {
key: 'value'
};
const propName = 'key';
const componentName = 'TestComponent';

beforeEach(function() {
validators = [
sinon.stub(),
sinon.stub(),
sinon.stub()
];
});

it('with no arguments provided', function() {
expect(() => {
CustomPropTypes.all();
}).to.throw(Error, /No validations provided/);
});

it('with no validations provided', function() {
expect(() => {
CustomPropTypes.all([]);
}).to.throw(Error, /No validations provided/);
});

it('with invalid arguments provided', function() {
expect(() => {
CustomPropTypes.all(1);
}).to.throw(Error, /Invalid argument must be an array/);
});

it('validates each validation', function() {
const all = CustomPropTypes.all(validators);

let result = all(props, propName, componentName);
expect(result).to.equal(undefined);

validators.forEach(x => {
x.should.have.been.calledOnce
.and.calledWith(props, propName, componentName);
});
});

it('returns first validation failure', function() {
let err = new Error('Failure');
validators[1].returns(err);
const all = CustomPropTypes.all(validators);

let result = all(props, propName, componentName);
expect(result).to.equal(err);

validators[0].should.have.been.calledOnce
.and.calledWith(props, propName, componentName);

validators[1].should.have.been.calledOnce
.and.calledWith(props, propName, componentName);

validators[2].should.not.have.been.called;
});
});
});

0 comments on commit dfec023

Please sign in to comment.