ReactTestUtils-test.jsx 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402
  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/renderers/dom/test/__tests__/ReactTestUtils-test.js
  21. describe("ReactTestUtils", function() {
  22. // this.timeout(200000);
  23. // before(async () => {
  24. // await beforeHook();
  25. // });
  26. // after(async () => {
  27. // await afterHook(false);
  28. // });
  29. var body = document.body,
  30. div;
  31. beforeEach(function() {
  32. div = document.createElement("div");
  33. body.appendChild(div);
  34. });
  35. afterEach(function() {
  36. body.removeChild(div);
  37. });
  38. it("can scryRenderedDOMComponentsWithClass with TextComponent", () => {
  39. class Wrapper extends React.Component {
  40. render() {
  41. return (
  42. <div>
  43. Hello <span>Jim</span>
  44. </div>
  45. );
  46. }
  47. }
  48. const renderedComponent = ReactTestUtils.renderIntoDocument(<Wrapper />);
  49. const scryResults = ReactTestUtils.scryRenderedDOMComponentsWithClass(
  50. renderedComponent,
  51. "NonExistentClass"
  52. );
  53. expect(scryResults.length).toBe(0);
  54. });
  55. it("can scryRenderedDOMComponentsWithClass with className contains \\n", () => {
  56. class Wrapper extends React.Component {
  57. render() {
  58. return (
  59. <div>
  60. Hello <span className={"x\ny"}>Jim</span>
  61. </div>
  62. );
  63. }
  64. }
  65. const renderedComponent = ReactTestUtils.renderIntoDocument(<Wrapper />);
  66. const scryResults = ReactTestUtils.scryRenderedDOMComponentsWithClass(
  67. renderedComponent,
  68. "x"
  69. );
  70. expect(scryResults.length).toBe(1);
  71. });
  72. it("can scryRenderedDOMComponentsWithClass with multiple classes", () => {
  73. class Wrapper extends React.Component {
  74. render() {
  75. return (
  76. <div>
  77. Hello <span className={"x y z"}>Jim</span>
  78. </div>
  79. );
  80. }
  81. }
  82. const renderedComponent = ReactTestUtils.renderIntoDocument(<Wrapper />);
  83. const scryResults1 = ReactTestUtils.scryRenderedDOMComponentsWithClass(
  84. renderedComponent,
  85. "x y"
  86. );
  87. expect(scryResults1.length).toBe(1);
  88. const scryResults2 = ReactTestUtils.scryRenderedDOMComponentsWithClass(
  89. renderedComponent,
  90. "x z"
  91. );
  92. expect(scryResults2.length).toBe(1);
  93. const scryResults3 = ReactTestUtils.scryRenderedDOMComponentsWithClass(
  94. renderedComponent,
  95. ["x", "y"]
  96. );
  97. expect(scryResults3.length).toBe(1);
  98. expect(scryResults1[0]).toBe(scryResults2[0]);
  99. expect(scryResults1[0]).toBe(scryResults3[0]);
  100. const scryResults4 = ReactTestUtils.scryRenderedDOMComponentsWithClass(
  101. renderedComponent,
  102. ["x", "a"]
  103. );
  104. expect(scryResults4.length).toBe(0);
  105. const scryResults5 = ReactTestUtils.scryRenderedDOMComponentsWithClass(
  106. renderedComponent,
  107. ["x a"]
  108. );
  109. expect(scryResults5.length).toBe(0);
  110. });
  111. /*it("traverses children in the correct order", () => {
  112. class Wrapper extends React.Component {
  113. render() {
  114. return <div>{this.props.children}</div>;
  115. }
  116. }
  117. const container = document.createElement("div");
  118. ReactDOM.render(
  119. <Wrapper>
  120. {null}
  121. <div>purple</div>
  122. </Wrapper>,
  123. container
  124. );
  125. const tree = ReactDOM.render(
  126. <Wrapper>
  127. <div>orange</div>
  128. <div>purple</div>
  129. </Wrapper>,
  130. container
  131. );
  132. const log = [];
  133. ReactTestUtils.findAllInRenderedTree(tree, function(child) {
  134. if (ReactTestUtils.isDOMComponent(child)) {
  135. log.push(ReactDOM.findDOMNode(child).textContent);
  136. }
  137. });
  138. // Should be document order, not mount order (which would be purple, orange)
  139. expect(log).toEqual(["orangepurple", "orange", "purple"]);
  140. });
  141. it("should support injected wrapper components as DOM components", () => {
  142. const injectedDOMComponents = [
  143. "button",
  144. "form",
  145. "iframe",
  146. "img",
  147. "input",
  148. "option",
  149. "select",
  150. "textarea"
  151. ];
  152. injectedDOMComponents.forEach(function(type) {
  153. const testComponent = ReactTestUtils.renderIntoDocument(
  154. React.createElement(type)
  155. );
  156. expect(testComponent.tagName).toBe(type.toUpperCase());
  157. expect(ReactTestUtils.isDOMComponent(testComponent)).toBe(true);
  158. });
  159. // Full-page components (html, head, body) can't be rendered into a div
  160. // directly...
  161. class Root extends React.Component {
  162. render() {
  163. return (
  164. <html ref="html">
  165. <head ref="head">
  166. <title>hello</title>
  167. </head>
  168. <body ref="body">hello, world</body>
  169. </html>
  170. );
  171. }
  172. }
  173. // const markup = ReactDOMServer.renderToString(<Root />);
  174. // const testDocument = getTestDocument(markup);
  175. // const component = ReactDOM.render(<Root />, testDocument.body);
  176. // expect(component.refs.html.tagName).toBe("HTML");
  177. // expect(component.refs.head.tagName).toBe("HEAD");
  178. // expect(component.refs.body.tagName).toBe("BODY");
  179. // expect(ReactTestUtils.isDOMComponent(component.refs.html)).toBe(true);
  180. // expect(ReactTestUtils.isDOMComponent(component.refs.head)).toBe(true);
  181. // expect(ReactTestUtils.isDOMComponent(component.refs.body)).toBe(true);
  182. });
  183. it("can scry with stateless components involved", () => {
  184. const Stateless = () => (
  185. <div>
  186. <hr />
  187. </div>
  188. );
  189. class SomeComponent extends React.Component {
  190. render() {
  191. return (
  192. <div>
  193. <Stateless />
  194. <hr />
  195. </div>
  196. );
  197. }
  198. }
  199. const inst = ReactTestUtils.renderIntoDocument(<SomeComponent />);
  200. const hrs = ReactTestUtils.scryRenderedDOMComponentsWithTag(inst, "hr");
  201. expect(hrs.length).toBe(2);
  202. });
  203. it("should change the value of an input field", () => {
  204. const obj = {
  205. handler: function(e) {
  206. e.persist();
  207. }
  208. };
  209. spyOn(obj, "handler").and.callThrough();
  210. const container = document.createElement("div");
  211. const instance = ReactDOM.render(
  212. <input type="text" onChange={obj.handler} />,
  213. container
  214. );
  215. const node = ReactDOM.findDOMNode(instance);
  216. node.value = "giraffe";
  217. ReactTestUtils.Simulate.change(node);
  218. expect(obj.handler).toHaveBeenCalledWith({ target: node });
  219. });
  220. it("should change the value of an input field in a component", () => {
  221. class SomeComponent extends React.Component {
  222. render() {
  223. return (
  224. <div>
  225. <input type="text" ref="input" onChange={this.props.handleChange} />
  226. </div>
  227. );
  228. }
  229. }
  230. const obj = {
  231. handler: function(e) {
  232. e.persist();
  233. }
  234. };
  235. spyOn(obj, "handler").and.callThrough();
  236. const container = document.createElement("div");
  237. const instance = ReactDOM.render(
  238. <SomeComponent handleChange={obj.handler} />,
  239. container
  240. );
  241. const node = ReactDOM.findDOMNode(instance.refs.input);
  242. node.value = "zebra";
  243. ReactTestUtils.Simulate.change(node);
  244. expect(obj.handler).toHaveBeenCalledWith({ target: node });
  245. });
  246. it("should throw when attempting to use a React element", () => {
  247. class SomeComponent extends React.Component {
  248. render() {
  249. return <div onClick={this.props.handleClick}>hello, world.</div>;
  250. }
  251. }
  252. const handler = spyOn.createSpy();
  253. const shallowRenderer = ReactShallowRenderer();
  254. const result = shallowRenderer.render(
  255. <SomeComponent handleClick={handler} />
  256. );
  257. expect(() => ReactTestUtils.Simulate.click(result)).toThrowError(
  258. "TestUtils.Simulate expected a DOM node as the first argument but received " +
  259. "a React element. Pass the DOM node you wish to simulate the event on instead. " +
  260. "Note that TestUtils.Simulate will not work if you are using shallow rendering."
  261. );
  262. expect(handler).toNotHaveBeenCalled();
  263. });
  264. it("should throw when attempting to use a component instance", () => {
  265. class SomeComponent extends React.Component {
  266. render() {
  267. return <div onClick={this.props.handleClick}>hello, world.</div>;
  268. }
  269. }
  270. let handler = spyOn.createSpy("spy");
  271. let container = document.createElement("div");
  272. let instance = ReactDOM.render(
  273. <SomeComponent handleClick={handler} />,
  274. container
  275. );
  276. expect(() => ReactTestUtils.Simulate.click(instance)).toThrowError(
  277. "TestUtils.Simulate expected a DOM node as the first argument but received " +
  278. "a component instance. Pass the DOM node you wish to simulate the event on instead."
  279. );
  280. expect(handler).toNotHaveBeenCalled();
  281. });
  282. it("should not warn when used with extra properties", () => {
  283. spyOn(console, "error");
  284. const CLIENT_X = 100;
  285. class Component extends React.Component {
  286. handleClick(e) {
  287. expect(e.clientX).toBe(CLIENT_X);
  288. }
  289. render() {
  290. return <div onClick={this.handleClick} />;
  291. }
  292. }
  293. const element = document.createElement("div");
  294. const instance = ReactDOM.render(<Component />, element);
  295. ReactTestUtils.Simulate.click(ReactDOM.findDOMNode(instance), {
  296. clientX: CLIENT_X
  297. });
  298. console.log(!!console.error.spyArgs);
  299. expect(console.error.spyArgs).toBe(undefined);
  300. });
  301. it("should set the type of the event", () => {
  302. let event;
  303. const stub = function(e) {
  304. e.persist();
  305. event = e;
  306. };
  307. const container = document.createElement("div");
  308. const instance = ReactDOM.render(<div onKeyDown={stub} />, container);
  309. const node = ReactDOM.findDOMNode(instance);
  310. ReactTestUtils.Simulate.keyDown(node);
  311. expect(event.type).toBe("keydown");
  312. expect(event.nativeEvent.type).toBe("keydown");
  313. });
  314. it("should work with renderIntoDocument", () => {
  315. var target;
  316. var i = 0;
  317. const onChange = spyOn.createSpy();
  318. class MyComponent extends React.Component {
  319. render() {
  320. return (
  321. <div>
  322. <input type="text" onChange={onChange} />
  323. </div>
  324. );
  325. }
  326. }
  327. const instance = ReactTestUtils.renderIntoDocument(<MyComponent />);
  328. const input = ReactTestUtils.findRenderedDOMComponentWithTag(
  329. instance,
  330. "input"
  331. );
  332. input.value = "giraffe";
  333. ReactTestUtils.Simulate.change(input);
  334. expect(onChange).toHaveBeenCalledWith({ target: input });
  335. });
  336. it("should call setState callback with no arguments", () => {
  337. let mockArgs;
  338. class Component extends React.Component {
  339. componentDidMount() {
  340. this.setState({}, (...args) => (mockArgs = args));
  341. }
  342. render() {
  343. return false;
  344. }
  345. }
  346. ReactTestUtils.renderIntoDocument(<Component />);
  347. expect(mockArgs.length).toEqual(0);
  348. });*/
  349. });