Skip to content

Commit

Permalink
Merge pull request #4209 from aruberto/iterable_node_proptype
Browse files Browse the repository at this point in the history
Allow iterables to pass node prop type check
  • Loading branch information
jimfb committed Jul 6, 2015
2 parents a8955e7 + 79fc73e commit 500d4c3
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 4 deletions.
34 changes: 30 additions & 4 deletions src/isomorphic/classic/types/ReactPropTypes.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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;
Expand Down
33 changes: 33 additions & 0 deletions src/isomorphic/classic/types/__tests__/ReactPropTypes-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down

0 comments on commit 500d4c3

Please sign in to comment.