react / react-0.13.3 / examples / basic-commonjs / node_modules / reactify / node_modules / react-tools / src / core / __tests__ / refs-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 = require('React');14var ReactTestUtils = require('ReactTestUtils');1516var reactComponentExpect= require('reactComponentExpect');171819/**20* Counts clicks and has a renders an item for each click. Each item rendered21* has a ref of the form "clickLogN".22*/23var ClickCounter = React.createClass({24getInitialState: function() {25return {count: this.props.initialCount};26},27triggerReset: function() {28this.setState({count: this.props.initialCount});29},30handleClick: function() {31this.setState({count: this.state.count + 1});32},33render: function() {34var children = [];35var i;36for (i=0; i < this.state.count; i++) {37children.push(38<div39className="clickLogDiv"40key={"clickLog" + i}41ref={"clickLog" + i}42/>43);44}45return (46<span className="clickIncrementer" onClick={this.handleClick}>47{children}48</span>49);50}51});5253/**54* Only purpose is to test that refs are tracked even when applied to a55* component that is injected down several layers. Ref systems are difficult to56* build in such a way that ownership is maintained in an airtight manner.57*/58var GeneralContainerComponent = React.createClass({59render: function() {60return <div>{this.props.children}</div>;61}62});6364/**65* Notice how refs ownership is maintained even when injecting a component66* into a different parent.67*/68var TestRefsComponent = React.createClass({69doReset: function() {70this.refs.myCounter.triggerReset();71},72render: function() {73return (74<div>75<div ref="resetDiv" onClick={this.doReset}>76Reset Me By Clicking This.77</div>78<GeneralContainerComponent ref="myContainer">79<ClickCounter ref="myCounter" initialCount={1}/>80</GeneralContainerComponent>81</div>82);83}84});8586/**87* Render a TestRefsComponent and ensure that the main refs are wired up.88*/89var renderTestRefsComponent = function() {90var testRefsComponent =91ReactTestUtils.renderIntoDocument(<TestRefsComponent />);9293reactComponentExpect(testRefsComponent)94.toBeCompositeComponentWithType(TestRefsComponent);9596var generalContainer = testRefsComponent.refs.myContainer;97var counter = testRefsComponent.refs.myCounter;9899reactComponentExpect(generalContainer)100.toBeCompositeComponentWithType(GeneralContainerComponent);101reactComponentExpect(counter)102.toBeCompositeComponentWithType(ClickCounter);103104return testRefsComponent;105};106107108var expectClickLogsLengthToBe = function(instance, length) {109var clickLogs =110ReactTestUtils.scryRenderedDOMComponentsWithClass(instance, 'clickLogDiv');111expect(clickLogs.length).toBe(length);112expect(Object.keys(instance.refs.myCounter.refs).length).toBe(length);113};114115describe('reactiverefs', function() {116beforeEach(function() {117require('mock-modules').dumpCache();118});119120/**121* Ensure that for every click log there is a corresponding ref (from the122* perspective of the injected ClickCounter component.123*/124it("Should increase refs with an increase in divs", function() {125var testRefsComponent = renderTestRefsComponent();126var clickIncrementer =127ReactTestUtils.findRenderedDOMComponentWithClass(128testRefsComponent,129'clickIncrementer'130);131132expectClickLogsLengthToBe(testRefsComponent, 1);133134// After clicking the reset, there should still only be one click log ref.135ReactTestUtils.Simulate.click(testRefsComponent.refs.resetDiv);136expectClickLogsLengthToBe(testRefsComponent, 1);137138// Begin incrementing clicks (and therefore refs).139ReactTestUtils.Simulate.click(clickIncrementer);140expectClickLogsLengthToBe(testRefsComponent, 2);141142ReactTestUtils.Simulate.click(clickIncrementer);143expectClickLogsLengthToBe(testRefsComponent, 3);144145// Now reset again146ReactTestUtils.Simulate.click(testRefsComponent.refs.resetDiv);147expectClickLogsLengthToBe(testRefsComponent, 1);148149});150151});152153154155/**156* Tests that when a ref hops around children, we can track that correctly.157*/158describe('ref swapping', function() {159beforeEach(function() {160require('mock-modules').dumpCache();161});162163var RefHopsAround = React.createClass({164getInitialState: function() {165return {count: 0};166},167moveRef: function() {168this.setState({ count: this.state.count + 1 });169},170render: function() {171var count = this.state.count;172/**173* What we have here, is three divs with refs (div1/2/3), but a single174* moving cursor ref `hopRef` that "hops" around the three. We'll call the175* `moveRef()` function several times and make sure that the hop ref176* points to the correct divs.177*/178return (179<div>180<div181className="first"182ref={count % 3 === 0 ? 'hopRef' : 'divOneRef'}183/>184<div185className="second"186ref={count % 3 === 1 ? 'hopRef' : 'divTwoRef'}187/>188<div189className="third"190ref={count % 3 === 2 ? 'hopRef' : 'divThreeRef'}191/>192</div>193);194}195});196197it("Allow refs to hop around children correctly", function() {198var refHopsAround = ReactTestUtils.renderIntoDocument(<RefHopsAround />);199200var firstDiv =201ReactTestUtils.findRenderedDOMComponentWithClass(refHopsAround, 'first');202var secondDiv =203ReactTestUtils.findRenderedDOMComponentWithClass(refHopsAround, 'second');204var thirdDiv =205ReactTestUtils.findRenderedDOMComponentWithClass(refHopsAround, 'third');206207expect(refHopsAround.refs.hopRef).toEqual(firstDiv);208expect(refHopsAround.refs.divTwoRef).toEqual(secondDiv);209expect(refHopsAround.refs.divThreeRef).toEqual(thirdDiv);210211refHopsAround.moveRef();212expect(refHopsAround.refs.divOneRef).toEqual(firstDiv);213expect(refHopsAround.refs.hopRef).toEqual(secondDiv);214expect(refHopsAround.refs.divThreeRef).toEqual(thirdDiv);215216refHopsAround.moveRef();217expect(refHopsAround.refs.divOneRef).toEqual(firstDiv);218expect(refHopsAround.refs.divTwoRef).toEqual(secondDiv);219expect(refHopsAround.refs.hopRef).toEqual(thirdDiv);220221/**222* Make sure that after the third, we're back to where we started and the223* refs are completely restored.224*/225refHopsAround.moveRef();226expect(refHopsAround.refs.hopRef).toEqual(firstDiv);227expect(refHopsAround.refs.divTwoRef).toEqual(secondDiv);228expect(refHopsAround.refs.divThreeRef).toEqual(thirdDiv);229});230231232it('always has a value for this.refs', function() {233var Component = React.createClass({234render: function() {235return <div />;236}237});238239var instance = ReactTestUtils.renderIntoDocument(<Component />);240expect(!!instance.refs).toBe(true);241});242});243244245246