ReactIdentity-test.jsx 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. import PropTypes from '../../lib/ReactPropTypes';
  2. import ReactTestUtils from "../../lib/ReactTestUtils";
  3. import React from '../../src/May';
  4. import { render, unmountComponentAtNode, findDOMNode } from '../../src/may-dom/MayDom';
  5. import { shallowCompare } from '../../src/PureComponent';
  6. var ReactDOM = {
  7. render: render,
  8. unmountComponentAtNode: unmountComponentAtNode,
  9. findDOMNode: findDOMNode
  10. }
  11. React.render = render;
  12. // import React from "../../dist/ReactANU";
  13. // var ReactDOM = React;
  14. // var ReactTestUtils = {
  15. // renderIntoDocument: function (element) {
  16. // var div = document.createElement("div");
  17. // return React.render(element, div);
  18. // }
  19. // };
  20. //https://github.com/facebook/react/blob/master/src/isomorphic/children/__tests__/ReactChildren-test.js
  21. describe("ReactIdentity", function () {
  22. // this.timeout(200000);
  23. it("should allow key property to express identity", () => {
  24. var node;
  25. var Component = props => (
  26. <div ref={c => (node = c)}>
  27. <div key={props.swap ? "banana" : "apple"} id={props.swap ? "banana" : "apple"} />
  28. <div key={props.swap ? "apple" : "banana"} id={props.swap ? "apple" : "banana"} />
  29. </div>
  30. );
  31. var container = document.createElement("div");
  32. ReactDOM.render(<Component />, container);
  33. var origChildren = Array.from(node.childNodes);
  34. ReactDOM.render(<Component swap={true} />, container);
  35. var newChildren = Array.from(node.childNodes);
  36. expect(origChildren[0] === newChildren[1]).toBe(true);
  37. expect(origChildren[1] === newChildren[0]).toBe(true);
  38. });
  39. it("should use composite identity", () => {
  40. class Wrapper extends React.Component {
  41. render() {
  42. return <a>{this.props.children}</a>;
  43. }
  44. }
  45. var container = document.createElement("div");
  46. var node1;
  47. var node2;
  48. ReactDOM.render(
  49. <Wrapper key="wrap1"><span ref={c => (node1 = c)} /></Wrapper>,
  50. container
  51. );
  52. ReactDOM.render(
  53. <Wrapper key="wrap2"><span ref={c => (node2 = c)} /></Wrapper>,
  54. container
  55. );
  56. expect(node1).not.toBe(node2);
  57. });
  58. function renderAComponentWithKeyIntoContainer(key, container) {
  59. class Wrapper extends React.Component {
  60. render() {
  61. return <div><span ref="span" key={key} /></div>;
  62. }
  63. }
  64. var instance = ReactDOM.render(<Wrapper />, container);
  65. var span = instance.refs.span;
  66. expect(ReactDOM.findDOMNode(span)).not.toBe(null);
  67. }
  68. it("should allow any character as a key, in a detached parent", () => {
  69. var detachedContainer = document.createElement("div");
  70. renderAComponentWithKeyIntoContainer("<'WEIRD/&\\key'>", detachedContainer);
  71. });
  72. it("should allow any character as a key, in an attached parent", () => {
  73. // This test exists to protect against implementation details that
  74. // incorrectly query escaped IDs using DOM tools like getElementById.
  75. var attachedContainer = document.createElement("div");
  76. document.body.appendChild(attachedContainer);
  77. renderAComponentWithKeyIntoContainer("<'WEIRD/&\\key'>", attachedContainer);
  78. document.body.removeChild(attachedContainer);
  79. });
  80. it("should not allow scripts in keys to execute", () => {
  81. var h4x0rKey =
  82. "\"><script>window['YOUVEBEENH4X0RED']=true;</script><div id=\"";
  83. var attachedContainer = document.createElement("div");
  84. document.body.appendChild(attachedContainer);
  85. renderAComponentWithKeyIntoContainer(h4x0rKey, attachedContainer);
  86. document.body.removeChild(attachedContainer);
  87. // If we get this far, make sure we haven't executed the code
  88. expect(window.YOUVEBEENH4X0RED).toBe(undefined);
  89. });
  90. it("should let restructured components retain their uniqueness", () => {
  91. var instance0 = <span />;
  92. var instance1 = <span />;
  93. var instance2 = <span />;
  94. class TestComponent extends React.Component {
  95. render() {
  96. return (
  97. <div>
  98. {instance2}
  99. {this.props.children[0]}
  100. {this.props.children[1]}
  101. </div>
  102. );
  103. }
  104. }
  105. class TestContainer extends React.Component {
  106. render() {
  107. return <TestComponent>{instance0}{instance1}</TestComponent>;
  108. }
  109. }
  110. expect(function() {
  111. ReactTestUtils.renderIntoDocument(<TestContainer />);
  112. }).not.toThrow();
  113. });
  114. it("should let nested restructures retain their uniqueness", () => {
  115. var instance0 = <span />;
  116. var instance1 = <span />;
  117. var instance2 = <span />;
  118. class TestComponent extends React.Component {
  119. render() {
  120. return (
  121. <div>
  122. {instance2}
  123. {this.props.children[0]}
  124. {this.props.children[1]}
  125. </div>
  126. );
  127. }
  128. }
  129. class TestContainer extends React.Component {
  130. render() {
  131. return (
  132. <div>
  133. <TestComponent>{instance0}{instance1}</TestComponent>
  134. </div>
  135. );
  136. }
  137. }
  138. expect(function() {
  139. ReactTestUtils.renderIntoDocument(<TestContainer />);
  140. }).not.toThrow();
  141. });
  142. it("should let text nodes retain their uniqueness", () => {
  143. class TestComponent extends React.Component {
  144. render() {
  145. return <div>{this.props.children}<span /></div>;
  146. }
  147. }
  148. class TestContainer extends React.Component {
  149. render() {
  150. return (
  151. <TestComponent>
  152. <div />
  153. {"second"}
  154. </TestComponent>
  155. );
  156. }
  157. }
  158. expect(function() {
  159. ReactTestUtils.renderIntoDocument(<TestContainer />);
  160. }).not.toThrow();
  161. });
  162. it('should retain key during updates in composite components', () => {
  163. class TestComponent extends React.Component {
  164. render() {
  165. return <div>{this.props.children}</div>;
  166. }
  167. }
  168. class TestContainer extends React.Component {
  169. state = {swapped: false};
  170. swap = () => {
  171. this.setState({swapped: true});
  172. };
  173. render() {
  174. return (
  175. <TestComponent>
  176. {this.state.swapped ? this.props.second : this.props.first}
  177. {this.state.swapped ? this.props.first : this.props.second}
  178. </TestComponent>
  179. );
  180. }
  181. }
  182. var instance0 = <span key="A" />;
  183. var instance1 = <span key="B" />;
  184. var wrapped = <TestContainer first={instance0} second={instance1} />;
  185. wrapped = ReactDOM.render(wrapped, document.createElement('div'));
  186. var div = ReactDOM.findDOMNode(wrapped);
  187. var beforeA = div.childNodes[0];
  188. var beforeB = div.childNodes[1];
  189. wrapped.swap();
  190. var afterA = div.childNodes[1];
  191. var afterB = div.childNodes[0];
  192. expect(beforeA).toBe(afterA);
  193. expect(beforeB).toBe(afterB);
  194. });
  195. it('should not allow implicit and explicit keys to collide', () => {
  196. var component = (
  197. <div>
  198. <span />
  199. <span key="0" />
  200. </div>
  201. );
  202. expect(function() {
  203. ReactTestUtils.renderIntoDocument(component);
  204. }).not.toThrow();
  205. });
  206. });