Merge pull request #4209 from aruberto/iterable_node_proptype

Allow iterables to pass node prop type check
This commit is contained in:
Jim
2015-07-05 17:19:37 -07:00
2 changed files with 63 additions and 4 deletions
+30 -4
View File
@@ -16,6 +16,7 @@ var ReactFragment = require('ReactFragment');
var ReactPropTypeLocationNames = require('ReactPropTypeLocationNames');
var emptyFunction = require('emptyFunction');
var getIteratorFn = require('getIteratorFn');
/**
* Collection of methods that allow declaration and validation of props that are
@@ -345,12 +346,37 @@ function isNode(propValue) {
if (propValue === null || ReactElement.isValidElement(propValue)) {
return true;
}
propValue = ReactFragment.extractIfFragment(propValue);
for (var k in propValue) {
if (!isNode(propValue[k])) {
return false;
var iteratorFn = getIteratorFn(propValue);
if (iteratorFn) {
var iterator = iteratorFn.call(propValue);
var step;
if (iteratorFn !== propValue.entries) {
while (!(step = iterator.next()).done) {
if (!isNode(step.value)) {
return false;
}
}
} else {
// Iterator will provide entry [k,v] tuples rather than values.
while (!(step = iterator.next()).done) {
var entry = step.value;
if (entry) {
if (!isNode(entry[1])) {
return false;
}
}
}
}
} else {
propValue = ReactFragment.extractIfFragment(propValue);
for (var k in propValue) {
if (!isNode(propValue[k])) {
return false;
}
}
}
return true;
default:
return false;
@@ -405,6 +405,39 @@ describe('ReactPropTypes', function() {
});
});
it('should not warn for iterables', function() {
var iterable = {
'@@iterator': function() {
var i = 0;
return {
next: function() {
var done = ++i > 2;
return {value: done ? undefined : <MyComponent />, done: done};
},
};
},
};
typeCheckPass(PropTypes.node, iterable);
});
it('should not warn for entry iterables', function() {
var iterable = {
'@@iterator': function() {
var i = 0;
return {
next: function() {
var done = ++i > 2;
return {value: done ? undefined : ['#' + i, <MyComponent />], done: done};
},
};
},
};
iterable.entries = iterable['@@iterator'];
typeCheckPass(PropTypes.node, iterable);
});
it('should not warn for null/undefined if not required', function() {
typeCheckPass(PropTypes.node, null);
typeCheckPass(PropTypes.node, undefined);