diff --git a/src/core/__tests__/ReactComponentFlattenChildren-test.js b/src/core/__tests__/ReactComponentFlattenChildren-test.js
new file mode 100644
index 0000000000..972172c541
--- /dev/null
+++ b/src/core/__tests__/ReactComponentFlattenChildren-test.js
@@ -0,0 +1,159 @@
+/**
+ * Copyright 2013 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @jsx React.DOM
+ * @emails react-core
+ */
+
+"use strict";
+
+var React;
+
+var Fake;
+
+var singleChild = function(children) {
+ return ({children}).props.children;
+};
+
+var multiChild = function(child1, child2, child3, child4) {
+ return ({child1} {child2} {child3}{child4}).props.children;
+};
+
+
+describe('ReactComponentFlatten', function() {
+ beforeEach(function() {
+ require('mock-modules').dumpCache();
+ React = require('React');
+ var ReactComponent = require('ReactComponent');
+ var copyProperties = require('copyProperties');
+ var Constructor = function() {};
+ copyProperties(Constructor.prototype, ReactComponent.Mixin);
+ Fake = function() {
+ var instance = new Constructor();
+ instance.construct.apply(instance, arguments);
+ return instance;
+ };
+ });
+
+ it("should reuse a flat array", function() {
+ var children = [
+
,
+
+ ];
+
+ var flat = singleChild(children);
+
+ expect(flat).toBe(children);
+ expect(flat[0]._key).toEqual('0:foo');
+ expect(flat[1]._key).toEqual('0:bar');
+ });
+
+ it("should collapse a sparse array", function() {
+ var children = [
+ null,
+ ,
+
+ ];
+
+ var flat = singleChild(children);
+
+ expect(flat).not.toBe(children);
+ expect(flat.length).toEqual(2);
+ expect(flat[0]._key).toEqual('0:foo');
+ expect(flat[1]._key).toEqual('0:bar');
+ });
+
+ it("should collapse a nested array into a flat array", function() {
+ var flat = multiChild(
+ null,
+ ,
+ [, null]
+ );
+
+ expect(flat.length).toEqual(2);
+ expect(flat[0]._key).toEqual('foo');
+ expect(flat[1]._key).toEqual('2:bar');
+ });
+
+ it("should use retain key index despite static empty values", function() {
+ // TODO: Wrap in another single child (currently breaks)
+
+ var before = multiChild(
+ ,
+ ,
+ [],
+ []
+ );
+
+ var after = multiChild(
+ null,
+ ,
+ null,
+ []
+ );
+
+ expect(before.length).toEqual(4);
+ expect(after.length).toEqual(2);
+ expect(before[1]._key).toEqual(after[0]._key);
+ expect(before[3]._key).toEqual(after[1]._key);
+ });
+
+ it("should assign idempotent keys for extra flattening layers", function() {
+ var flat = multiChild(
+ null,
+ [null, ],
+ false
+ );
+
+ var preFlat = multiChild(
+ null,
+ singleChild([null, ]),
+ false
+ );
+
+ expect(flat.length).toBe(1);
+ expect(preFlat.length).toBe(1);
+ expect(preFlat[0]._key).toBe(flat[0]._key);
+ });
+
+ it("should assign idempotent strings through flattening", function() {
+ var children = [
+ 'FOO',
+ 'BAR'
+ ];
+ var flat = singleChild(children);
+ var wrappedFlat = multiChild(null, flat);
+ expect(flat).toBe(children);
+ expect(wrappedFlat.length).toBe(2);
+ expect(wrappedFlat[0]).toBe(flat[0]);
+ expect(wrappedFlat[1]).toBe(flat[1]);
+ });
+
+ it("cannot keep keys unique when children are unboxed", function() {
+ // This is a case that difficult to solve and should not actually be solved.
+ var children1 = [];
+ var children2 = [];
+ var flat1 = singleChild(children1);
+ var flat2 = singleChild(children2);
+ // There's no way to tell flat1[0] and flat2[0] apart.
+ var mergedChildren = [flat1[0], flat2[0]];
+ var newChildren = multiChild(mergedChildren);
+ expect(newChildren.length).toBe(2);
+ expect(newChildren[0]._key).toBe(newChildren[1]._key);
+ });
+
+});
+
+
diff --git a/src/core/__tests__/ReactIdentity-test.js b/src/core/__tests__/ReactIdentity-test.js
index 36dffd8391..ee3f88487f 100644
--- a/src/core/__tests__/ReactIdentity-test.js
+++ b/src/core/__tests__/ReactIdentity-test.js
@@ -67,8 +67,8 @@ describe('ReactIdentity', function() {
React.renderComponent(instance, document.createElement('div'));
var node = instance.getDOMNode();
reactComponentExpect(instance).toBeDOMComponentWithChildCount(2);
- checkId(node.childNodes[0], '.reactRoot[0].[0:apple]');
- checkId(node.childNodes[1], '.reactRoot[0].[0:banana]');
+ checkId(node.childNodes[0], '.reactRoot[0].[apple]');
+ checkId(node.childNodes[1], '.reactRoot[0].[banana]');
});
it('should use instance identity', function() {
@@ -89,15 +89,15 @@ describe('ReactIdentity', function() {
React.renderComponent(instance, document.createElement('div'));
var node = instance.getDOMNode();
reactComponentExpect(instance).toBeDOMComponentWithChildCount(3);
- checkId(node.childNodes[0], '.reactRoot[0].[0:wrap1]');
+ checkId(node.childNodes[0], '.reactRoot[0].[wrap1]');
checkId(
node.childNodes[0].firstChild,
- '.reactRoot[0].[0:wrap1].[0:squirrel]'
+ '.reactRoot[0].[wrap1].[0:squirrel]'
);
- checkId(node.childNodes[1], '.reactRoot[0].[0:wrap2]');
- checkId(node.childNodes[1].firstChild, '.reactRoot[0].[0:wrap2].[0:bunny]');
- checkId(node.childNodes[2], '.reactRoot[0].[0:2]');
- checkId(node.childNodes[2].firstChild, '.reactRoot[0].[0:2].[0:chipmunk]');
+ checkId(node.childNodes[1], '.reactRoot[0].[wrap2]');
+ checkId(node.childNodes[1].firstChild, '.reactRoot[0].[wrap2].[0:bunny]');
+ checkId(node.childNodes[2], '.reactRoot[0].[2]');
+ checkId(node.childNodes[2].firstChild, '.reactRoot[0].[2].[0:chipmunk]');
});
it('should let restructured components retain their uniqueness', function() {
diff --git a/src/utils/__tests__/mapChildren-test.js b/src/utils/__tests__/mapChildren-test.js
index 21abf64110..39f557f38e 100644
--- a/src/utils/__tests__/mapChildren-test.js
+++ b/src/utils/__tests__/mapChildren-test.js
@@ -122,12 +122,12 @@ describe('mapChildren', function() {
.instance();
expect(mapFn.calls.length).toBe(3);
- expect(mapFn).toHaveBeenCalledWith(kidOne, '0:one', 0);
- expect(mapFn).toHaveBeenCalledWith(kidTwo, '0:two', 1);
- expect(mapFn).toHaveBeenCalledWith(kidThree, '0:three', 2);
+ expect(mapFn).toHaveBeenCalledWith(kidOne, 'one', 0);
+ expect(mapFn).toHaveBeenCalledWith(kidTwo, 'two', 1);
+ expect(mapFn).toHaveBeenCalledWith(kidThree, 'three', 2);
expect(rendered.props.children).not.toEqual(instance.props.children);
expect(rendered.props.children).toHaveKeys([
- '0:0:one', '0:0:two', '0:0:three'
+ '0:one', '0:two', '0:three'
]);
});
});