@samitouri / QOS-React-2 / commits / c885abbf21

Allow null return values for functions to-be-merged.

cpojer committed Jan 14, 2014 at 10:45 UTC c885abbf21fb04ae286f45b0fa5cc433310f8d8c
2 files changed +79 -29
src/core/ReactCompositeComponent.js
+8 -4
@@ -547,10 +547,14 @@ function mergeObjectsWithNoDuplicateKeys(one, two) {
547 */
548 function createMergedResultFunction(one, two) {
549 return function mergedResult() {
550 - return mergeObjectsWithNoDuplicateKeys(
551 - one.apply(this, arguments),
552 - two.apply(this, arguments)
553 - );
550 + var a = one.apply(this, arguments);
551 + var b = two.apply(this, arguments);
552 + if (a == null) {
553 + return b;
554 + } else if (b == null) {
555 + return a;
556 + }
557 + return mergeObjectsWithNoDuplicateKeys(a, b);
558 };
559 }
560
src/core/__tests__/ReactCompositeComponent-test.js
+71 -25
@@ -477,30 +477,6 @@ describe('ReactCompositeComponent', function() {
477 );
478 });
479
480 - it('should throw with bad getInitialState() return values', function() {
481 - var Mixin = {
482 - getInitialState: function() {
483 - return null;
484 - }
485 - };
486 - var Component = React.createClass({
487 - mixins: [Mixin],
488 - getInitialState: function() {
489 - return {x: true};
490 - },
491 - render: function() {
492 - return <span />;
493 - }
494 - });
495 - var instance = <Component />;
496 - expect(function() {
497 - ReactTestUtils.renderIntoDocument(instance);
498 - }).toThrow(
499 - 'Invariant Violation: mergeObjectsWithNoDuplicateKeys(): ' +
500 - 'Cannot merge non-objects'
501 - );
502 - });
503 -
480 it('should work with object getInitialState() return values', function() {
481 var Component = React.createClass({
482 getInitialState: function() {
@@ -546,7 +522,77 @@ describe('ReactCompositeComponent', function() {
522 return <span />;
523 }
524 });
549 - expect(() => <Component />).not.toThrow();
525 + expect(
526 + () => ReactTestUtils.renderIntoDocument(<Component />)
527 + ).not.toThrow();
528 + });
529 +
530 + it('should work with a null getInitialState return value and a mixin', () => {
531 + var Component;
532 + var instance;
533 +
534 + var Mixin = {
535 + getInitialState: function() {
536 + return {foo: 'bar'};
537 + }
538 + };
539 + Component = React.createClass({
540 + mixins: [Mixin],
541 + getInitialState: function() {
542 + return null;
543 + },
544 + render: function() {
545 + return <span />;
546 + }
547 + });
548 + expect(
549 + () => ReactTestUtils.renderIntoDocument(<Component />)
550 + ).not.toThrow();
551 +
552 + instance = <Component />;
553 + ReactTestUtils.renderIntoDocument(instance);
554 + expect(instance.state).toEqual({foo: 'bar'});
555 +
556 + // Also the other way round should work
557 + var Mixin2 = {
558 + getInitialState: function() {
559 + return null;
560 + }
561 + };
562 + Component = React.createClass({
563 + mixins: [Mixin2],
564 + getInitialState: function() {
565 + return {foo: 'bar'};
566 + },
567 + render: function() {
568 + return <span />;
569 + }
570 + });
571 + expect(
572 + () => ReactTestUtils.renderIntoDocument(<Component />)
573 + ).not.toThrow();
574 +
575 + instance = <Component />;
576 + ReactTestUtils.renderIntoDocument(instance);
577 + expect(instance.state).toEqual({foo: 'bar'});
578 +
579 + // Multiple mixins should be fine too
580 + Component = React.createClass({
581 + mixins: [Mixin, Mixin2],
582 + getInitialState: function() {
583 + return {x: true};
584 + },
585 + render: function() {
586 + return <span />;
587 + }
588 + });
589 + expect(
590 + () => ReactTestUtils.renderIntoDocument(<Component />)
591 + ).not.toThrow();
592 +
593 + instance = <Component />;
594 + ReactTestUtils.renderIntoDocument(instance);
595 + expect(instance.state).toEqual({foo: 'bar', x: true});
596 });
597
598 it('should work with object getInitialState() return values', function() {