react / react-0.13.3 / examples / basic-commonjs / node_modules / reactify / node_modules / react-tools / src / core / __tests__ / ReactIdentity-test.js
81155 views/**1* Copyright 2013-2014, Facebook, Inc.2* All rights reserved.3*4* This source code is licensed under the BSD-style license found in the5* LICENSE file in the root directory of this source tree. An additional grant6* of patent rights can be found in the PATENTS file in the same directory.7*8* @emails react-core9*/1011"use strict";1213var React;14var ReactTestUtils;15var reactComponentExpect;16var ReactMount;1718describe('ReactIdentity', function() {1920beforeEach(function() {21require('mock-modules').dumpCache();22React = require('React');23ReactTestUtils = require('ReactTestUtils');24reactComponentExpect = require('reactComponentExpect');25ReactMount = require('ReactMount');26});2728var idExp = /^\.[^.]+(.*)$/;29function checkId(child, expectedId) {30var actual = idExp.exec(ReactMount.getID(child));31var expected = idExp.exec(expectedId);32expect(actual).toBeTruthy();33expect(expected).toBeTruthy();34expect(actual[1]).toEqual(expected[1]);35}3637it('should allow keyed objects to express identity', function() {38var instance =39<div>40{{41first: <div />,42second: <div />43}}44</div>;4546instance = React.render(instance, document.createElement('div'));47var node = instance.getDOMNode();48reactComponentExpect(instance).toBeDOMComponentWithChildCount(2);49checkId(node.childNodes[0], '.0.$first:0');50checkId(node.childNodes[1], '.0.$second:0');51});5253it('should allow key property to express identity', function() {54var instance =55<div>56<div key="apple" />57<div key="banana" />58<div key={0} />59<div key={123} />60</div>;6162instance = React.render(instance, document.createElement('div'));63var node = instance.getDOMNode();64reactComponentExpect(instance).toBeDOMComponentWithChildCount(4);65checkId(node.childNodes[0], '.0.$apple');66checkId(node.childNodes[1], '.0.$banana');67checkId(node.childNodes[2], '.0.$0');68checkId(node.childNodes[3], '.0.$123');69});7071it('should use instance identity', function() {7273var Wrapper = React.createClass({74render: function() {75return <a key="i_get_overwritten">{this.props.children}</a>;76}77});7879var instance =80<div>81<Wrapper key="wrap1"><span key="squirrel" /></Wrapper>82<Wrapper key="wrap2"><span key="bunny" /></Wrapper>83<Wrapper><span key="chipmunk" /></Wrapper>84</div>;8586instance = React.render(instance, document.createElement('div'));87var node = instance.getDOMNode();88reactComponentExpect(instance).toBeDOMComponentWithChildCount(3);8990checkId(node.childNodes[0], '.0.$wrap1');91checkId(node.childNodes[0].firstChild, '.0.$wrap1.$squirrel');92checkId(node.childNodes[1], '.0.$wrap2');93checkId(node.childNodes[1].firstChild, '.0.$wrap2.$bunny');94checkId(node.childNodes[2], '.0.2');95checkId(node.childNodes[2].firstChild, '.0.2.$chipmunk');96});9798function renderAComponentWithKeyIntoContainer(key, container) {99100var Wrapper = React.createClass({101102render: function() {103var span1 = <span ref="span1" key={key} />;104var span2 = <span ref="span2" />;105106var map = {};107map[key] = span2;108return <div>{[span1, map]}</div>;109}110111});112113var instance = React.render(<Wrapper />, container);114var span1 = instance.refs.span1;115var span2 = instance.refs.span2;116117expect(span1.getDOMNode()).not.toBe(null);118expect(span2.getDOMNode()).not.toBe(null);119120key = key.replace(/=/g, '=0');121122checkId(span1.getDOMNode(), '.0.$' + key);123checkId(span2.getDOMNode(), '.0.1:$' + key + ':0');124}125126it('should allow any character as a key, in a detached parent', function() {127var detachedContainer = document.createElement('div');128renderAComponentWithKeyIntoContainer("<'WEIRD/&\\key'>", detachedContainer);129});130131it('should allow any character as a key, in an attached parent', function() {132// This test exists to protect against implementation details that133// incorrectly query escaped IDs using DOM tools like getElementById.134var attachedContainer = document.createElement('div');135document.body.appendChild(attachedContainer);136137renderAComponentWithKeyIntoContainer("<'WEIRD/&\\key'>", attachedContainer);138139document.body.removeChild(attachedContainer);140});141142it('should not allow scripts in keys to execute', function() {143var h4x0rKey =144'"><script>window[\'YOUVEBEENH4X0RED\']=true;</script><div id="';145146var attachedContainer = document.createElement('div');147document.body.appendChild(attachedContainer);148149renderAComponentWithKeyIntoContainer(h4x0rKey, attachedContainer);150151document.body.removeChild(attachedContainer);152153// If we get this far, make sure we haven't executed the code154expect(window.YOUVEBEENH4X0RED).toBe(undefined);155});156157it('should let restructured components retain their uniqueness', function() {158var instance0 = <span />;159var instance1 = <span />;160var instance2 = <span />;161162var TestComponent = React.createClass({163render: function() {164return (165<div>166{instance2}167{this.props.children[0]}168{this.props.children[1]}169</div>170);171}172});173174var TestContainer = React.createClass({175176render: function() {177return <TestComponent>{instance0}{instance1}</TestComponent>;178}179180});181182expect(function() {183184React.render(<TestContainer />, document.createElement('div'));185186}).not.toThrow();187});188189it('should let nested restructures retain their uniqueness', function() {190var instance0 = <span />;191var instance1 = <span />;192var instance2 = <span />;193194var TestComponent = React.createClass({195render: function() {196return (197<div>198{instance2}199{this.props.children[0]}200{this.props.children[1]}201</div>202);203}204});205206var TestContainer = React.createClass({207208render: function() {209return (210<div>211<TestComponent>{instance0}{instance1}</TestComponent>212</div>213);214}215216});217218expect(function() {219220React.render(<TestContainer />, document.createElement('div'));221222}).not.toThrow();223});224225it('should let text nodes retain their uniqueness', function() {226var TestComponent = React.createClass({227render: function() {228return <div>{this.props.children}<span /></div>;229}230});231232var TestContainer = React.createClass({233234render: function() {235return (236<TestComponent>237<div />238{'second'}239</TestComponent>240);241}242243});244245expect(function() {246247React.render(<TestContainer />, document.createElement('div'));248249}).not.toThrow();250});251252it('should retain key during updates in composite components', function() {253254var TestComponent = React.createClass({255render: function() {256return <div>{this.props.children}</div>;257}258});259260var TestContainer = React.createClass({261262getInitialState: function() {263return { swapped: false };264},265266swap: function() {267this.setState({ swapped: true });268},269270render: function() {271return (272<TestComponent>273{this.state.swapped ? this.props.second : this.props.first}274{this.state.swapped ? this.props.first : this.props.second}275</TestComponent>276);277}278279});280281var instance0 = <span key="A" />;282var instance1 = <span key="B" />;283284var wrapped = <TestContainer first={instance0} second={instance1} />;285286wrapped = React.render(wrapped, document.createElement('div'));287288var beforeID = ReactMount.getID(wrapped.getDOMNode().firstChild);289290wrapped.swap();291292var afterID = ReactMount.getID(wrapped.getDOMNode().firstChild);293294expect(beforeID).not.toEqual(afterID);295296});297298it('should not allow implicit and explicit keys to collide', function() {299var component =300<div>301<span />302<span key="0" />303</div>;304305expect(function() {306React.render(component, document.createElement('div'));307}).not.toThrow();308});309310311});312313314