ReactTestUtils.js 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. import {
  2. createElement
  3. } from '../src/May';
  4. import {
  5. Component
  6. } from '../src/Component';
  7. import {
  8. render
  9. } from '../src/may-dom/MayDom';
  10. import {
  11. dispatchEvent
  12. } from '../src/event';
  13. var ReactDOM = {
  14. render: render
  15. }
  16. // var React = require('react');//hyphenate
  17. // var ReactDOM = require('react-dom');
  18. // import React from '../dist/ReactANU';
  19. // var ReactDOM = React;
  20. function findAllInRenderedTree(inst, test) {
  21. var ret = [];
  22. if (!inst) {
  23. return ret;
  24. }
  25. if (inst.nodeType && inst.nodeType === 1) { //dom
  26. if (test(inst)) {
  27. ret.push(inst);
  28. }
  29. var children = [].slice.call(inst.childNodes);
  30. for (var i = 0; i < children.length; i++) {
  31. var el = children[i];
  32. ret = ret.concat(findAllInRenderedTree(el, test));
  33. }
  34. }
  35. if (inst.nodeType && inst.nodeType === 8) { //如果是文本,注释
  36. return ret;
  37. } else if (inst.mayInfo) { //如果是元素虚拟DOM
  38. var dom = inst.mayInfo.hostNode;
  39. if (dom && dom.nodeType === 1 && test(dom)) {
  40. ret.push(dom);
  41. }
  42. var children = [].slice.call(dom.childNodes);
  43. if (children) {
  44. for (var i = 0, n = children.length; i < n; i++) {
  45. var el = children[i];
  46. ret = ret.concat(findAllInRenderedTree(el, test));
  47. }
  48. }
  49. } else if (inst.mayInst) { //组件实例都带有refs对象
  50. var rendered = inst.mayInst.rendered;
  51. if (rendered) {
  52. //如果是实例
  53. ret = ret.concat(findAllInRenderedTree(rendered, test));
  54. }
  55. }
  56. return ret;
  57. }
  58. var ReactTestUtils = {
  59. renderIntoDocument: function (element) {
  60. var div = document.createElement("div");
  61. return ReactDOM.render(element, div);
  62. },
  63. isDOMComponent: function (inst) {
  64. return !!(inst && inst instanceof HTMLElement);
  65. },
  66. findAllInRenderedTree: function (inst, fn) {
  67. if (!inst) {
  68. return [];
  69. }
  70. return findAllInRenderedTree(inst, fn);
  71. },
  72. /**
  73. * 找出所有匹配指定标签的节点
  74. */
  75. scryRenderedDOMComponentsWithTag: function (root, tagName) {
  76. return ReactTestUtils.findAllInRenderedTree(root, function (inst) {
  77. return (
  78. ReactTestUtils.isDOMComponent(inst) &&
  79. inst.tagName.toUpperCase() === tagName.toUpperCase()
  80. );
  81. });
  82. },
  83. /**
  84. * 找出所有匹配指定className的节点
  85. */
  86. scryRenderedDOMComponentsWithClass: function (root, classNames) {
  87. return ReactTestUtils.findAllInRenderedTree(root, function (inst) {
  88. if (ReactTestUtils.isDOMComponent(inst)) {
  89. var className = inst.className;
  90. if (typeof className !== "string") {
  91. // SVG, probably.
  92. className = inst.getAttribute("class") || "";
  93. }
  94. var classList = className.split(/\s+/);
  95. if (!Array.isArray(classNames)) {
  96. classNames = classNames.split(/\s+/);
  97. }
  98. return classNames.every(function (name) {
  99. return classList.indexOf(name) !== -1;
  100. });
  101. }
  102. return false;
  103. });
  104. },
  105. /**
  106. *与scryRenderedDOMComponentsWithClass用法相同,但只返回一个节点,如有零个或多个匹配的节点就报错
  107. */
  108. findRenderedDOMComponentWithClass: function (root, className) {
  109. var all = ReactTestUtils.scryRenderedDOMComponentsWithClass(
  110. root,
  111. className
  112. );
  113. if (all.length !== 1) {
  114. throw new Error(
  115. "Did not find exactly one match (found: " +
  116. all.length +
  117. ") " +
  118. "for class:" +
  119. className
  120. );
  121. }
  122. return all[0];
  123. },
  124. Simulate: {},
  125. SimulateNative: {}
  126. }
  127. "click,change,keyDown,keyUp,KeyPress,mouseDown,mouseUp,mouseMove,mouseover,mouseout,mouseEnter,mouseLeave,focus".replace(/\w+/g, function (name) {
  128. ReactTestUtils.Simulate[name] = function (node, opts) {
  129. if (!node || node.nodeType !== 1) {
  130. throw "第一个参数必须为元素节点";
  131. }
  132. var fakeNativeEvent = opts || {};
  133. fakeNativeEvent.target = node;
  134. fakeNativeEvent.simulated = true;
  135. fakeNativeEvent.type = name.toLowerCase();
  136. dispatchEvent(fakeNativeEvent, name.toLowerCase());
  137. };
  138. });
  139. export default ReactTestUtils;