dragCreate.test.tsx 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287
  1. import React from "react";
  2. import ReactDOM from "react-dom";
  3. import ExcalidrawApp from "../excalidraw-app";
  4. import * as Renderer from "../renderer/renderScene";
  5. import { KEYS } from "../keys";
  6. import { render, fireEvent } from "./test-utils";
  7. import { ExcalidrawLinearElement } from "../element/types";
  8. import { reseed } from "../random";
  9. // Unmount ReactDOM from root
  10. ReactDOM.unmountComponentAtNode(document.getElementById("root")!);
  11. const renderScene = jest.spyOn(Renderer, "renderScene");
  12. beforeEach(() => {
  13. localStorage.clear();
  14. renderScene.mockClear();
  15. reseed(7);
  16. });
  17. const { h } = window;
  18. describe("add element to the scene when pointer dragging long enough", () => {
  19. it("rectangle", async () => {
  20. const { getByToolName, container } = await render(<ExcalidrawApp />);
  21. // select tool
  22. const tool = getByToolName("rectangle");
  23. fireEvent.click(tool);
  24. const canvas = container.querySelector("canvas")!;
  25. // start from (30, 20)
  26. fireEvent.pointerDown(canvas, { clientX: 30, clientY: 20 });
  27. // move to (60,70)
  28. fireEvent.pointerMove(canvas, { clientX: 60, clientY: 70 });
  29. // finish (position does not matter)
  30. fireEvent.pointerUp(canvas);
  31. expect(renderScene).toHaveBeenCalledTimes(7);
  32. expect(h.state.selectionElement).toBeNull();
  33. expect(h.elements.length).toEqual(1);
  34. expect(h.elements[0].type).toEqual("rectangle");
  35. expect(h.elements[0].x).toEqual(30);
  36. expect(h.elements[0].y).toEqual(20);
  37. expect(h.elements[0].width).toEqual(30); // 60 - 30
  38. expect(h.elements[0].height).toEqual(50); // 70 - 20
  39. expect(h.elements.length).toMatchSnapshot();
  40. h.elements.forEach((element) => expect(element).toMatchSnapshot());
  41. });
  42. it("ellipse", async () => {
  43. const { getByToolName, container } = await render(<ExcalidrawApp />);
  44. // select tool
  45. const tool = getByToolName("ellipse");
  46. fireEvent.click(tool);
  47. const canvas = container.querySelector("canvas")!;
  48. // start from (30, 20)
  49. fireEvent.pointerDown(canvas, { clientX: 30, clientY: 20 });
  50. // move to (60,70)
  51. fireEvent.pointerMove(canvas, { clientX: 60, clientY: 70 });
  52. // finish (position does not matter)
  53. fireEvent.pointerUp(canvas);
  54. expect(renderScene).toHaveBeenCalledTimes(7);
  55. expect(h.state.selectionElement).toBeNull();
  56. expect(h.elements.length).toEqual(1);
  57. expect(h.elements[0].type).toEqual("ellipse");
  58. expect(h.elements[0].x).toEqual(30);
  59. expect(h.elements[0].y).toEqual(20);
  60. expect(h.elements[0].width).toEqual(30); // 60 - 30
  61. expect(h.elements[0].height).toEqual(50); // 70 - 20
  62. expect(h.elements.length).toMatchSnapshot();
  63. h.elements.forEach((element) => expect(element).toMatchSnapshot());
  64. });
  65. it("diamond", async () => {
  66. const { getByToolName, container } = await render(<ExcalidrawApp />);
  67. // select tool
  68. const tool = getByToolName("diamond");
  69. fireEvent.click(tool);
  70. const canvas = container.querySelector("canvas")!;
  71. // start from (30, 20)
  72. fireEvent.pointerDown(canvas, { clientX: 30, clientY: 20 });
  73. // move to (60,70)
  74. fireEvent.pointerMove(canvas, { clientX: 60, clientY: 70 });
  75. // finish (position does not matter)
  76. fireEvent.pointerUp(canvas);
  77. expect(renderScene).toHaveBeenCalledTimes(7);
  78. expect(h.state.selectionElement).toBeNull();
  79. expect(h.elements.length).toEqual(1);
  80. expect(h.elements[0].type).toEqual("diamond");
  81. expect(h.elements[0].x).toEqual(30);
  82. expect(h.elements[0].y).toEqual(20);
  83. expect(h.elements[0].width).toEqual(30); // 60 - 30
  84. expect(h.elements[0].height).toEqual(50); // 70 - 20
  85. expect(h.elements.length).toMatchSnapshot();
  86. h.elements.forEach((element) => expect(element).toMatchSnapshot());
  87. });
  88. it("arrow", async () => {
  89. const { getByToolName, container } = await render(<ExcalidrawApp />);
  90. // select tool
  91. const tool = getByToolName("arrow");
  92. fireEvent.click(tool);
  93. const canvas = container.querySelector("canvas")!;
  94. // start from (30, 20)
  95. fireEvent.pointerDown(canvas, { clientX: 30, clientY: 20 });
  96. // move to (60,70)
  97. fireEvent.pointerMove(canvas, { clientX: 60, clientY: 70 });
  98. // finish (position does not matter)
  99. fireEvent.pointerUp(canvas);
  100. expect(renderScene).toHaveBeenCalledTimes(7);
  101. expect(h.state.selectionElement).toBeNull();
  102. expect(h.elements.length).toEqual(1);
  103. const element = h.elements[0] as ExcalidrawLinearElement;
  104. expect(element.type).toEqual("arrow");
  105. expect(element.x).toEqual(30);
  106. expect(element.y).toEqual(20);
  107. expect(element.points.length).toEqual(2);
  108. expect(element.points[0]).toEqual([0, 0]);
  109. expect(element.points[1]).toEqual([30, 50]); // (60 - 30, 70 - 20)
  110. expect(h.elements.length).toMatchSnapshot();
  111. h.elements.forEach((element) => expect(element).toMatchSnapshot());
  112. });
  113. it("line", async () => {
  114. const { getByToolName, container } = await render(<ExcalidrawApp />);
  115. // select tool
  116. const tool = getByToolName("line");
  117. fireEvent.click(tool);
  118. const canvas = container.querySelector("canvas")!;
  119. // start from (30, 20)
  120. fireEvent.pointerDown(canvas, { clientX: 30, clientY: 20 });
  121. // move to (60,70)
  122. fireEvent.pointerMove(canvas, { clientX: 60, clientY: 70 });
  123. // finish (position does not matter)
  124. fireEvent.pointerUp(canvas);
  125. expect(renderScene).toHaveBeenCalledTimes(7);
  126. expect(h.state.selectionElement).toBeNull();
  127. expect(h.elements.length).toEqual(1);
  128. const element = h.elements[0] as ExcalidrawLinearElement;
  129. expect(element.type).toEqual("line");
  130. expect(element.x).toEqual(30);
  131. expect(element.y).toEqual(20);
  132. expect(element.points.length).toEqual(2);
  133. expect(element.points[0]).toEqual([0, 0]);
  134. expect(element.points[1]).toEqual([30, 50]); // (60 - 30, 70 - 20)
  135. h.elements.forEach((element) => expect(element).toMatchSnapshot());
  136. });
  137. });
  138. describe("do not add element to the scene if size is too small", () => {
  139. it("rectangle", async () => {
  140. const { getByToolName, container } = await render(<ExcalidrawApp />);
  141. // select tool
  142. const tool = getByToolName("rectangle");
  143. fireEvent.click(tool);
  144. const canvas = container.querySelector("canvas")!;
  145. // start from (30, 20)
  146. fireEvent.pointerDown(canvas, { clientX: 30, clientY: 20 });
  147. // finish (position does not matter)
  148. fireEvent.pointerUp(canvas);
  149. expect(renderScene).toHaveBeenCalledTimes(6);
  150. expect(h.state.selectionElement).toBeNull();
  151. expect(h.elements.length).toEqual(0);
  152. });
  153. it("ellipse", async () => {
  154. const { getByToolName, container } = await render(<ExcalidrawApp />);
  155. // select tool
  156. const tool = getByToolName("ellipse");
  157. fireEvent.click(tool);
  158. const canvas = container.querySelector("canvas")!;
  159. // start from (30, 20)
  160. fireEvent.pointerDown(canvas, { clientX: 30, clientY: 20 });
  161. // finish (position does not matter)
  162. fireEvent.pointerUp(canvas);
  163. expect(renderScene).toHaveBeenCalledTimes(6);
  164. expect(h.state.selectionElement).toBeNull();
  165. expect(h.elements.length).toEqual(0);
  166. });
  167. it("diamond", async () => {
  168. const { getByToolName, container } = await render(<ExcalidrawApp />);
  169. // select tool
  170. const tool = getByToolName("diamond");
  171. fireEvent.click(tool);
  172. const canvas = container.querySelector("canvas")!;
  173. // start from (30, 20)
  174. fireEvent.pointerDown(canvas, { clientX: 30, clientY: 20 });
  175. // finish (position does not matter)
  176. fireEvent.pointerUp(canvas);
  177. expect(renderScene).toHaveBeenCalledTimes(6);
  178. expect(h.state.selectionElement).toBeNull();
  179. expect(h.elements.length).toEqual(0);
  180. });
  181. it("arrow", async () => {
  182. const { getByToolName, container } = await render(<ExcalidrawApp />);
  183. // select tool
  184. const tool = getByToolName("arrow");
  185. fireEvent.click(tool);
  186. const canvas = container.querySelector("canvas")!;
  187. // start from (30, 20)
  188. fireEvent.pointerDown(canvas, { clientX: 30, clientY: 20 });
  189. // finish (position does not matter)
  190. fireEvent.pointerUp(canvas);
  191. // we need to finalize it because arrows and lines enter multi-mode
  192. fireEvent.keyDown(document, { key: KEYS.ENTER });
  193. expect(renderScene).toHaveBeenCalledTimes(7);
  194. expect(h.state.selectionElement).toBeNull();
  195. expect(h.elements.length).toEqual(0);
  196. });
  197. it("line", async () => {
  198. const { getByToolName, container } = await render(<ExcalidrawApp />);
  199. // select tool
  200. const tool = getByToolName("line");
  201. fireEvent.click(tool);
  202. const canvas = container.querySelector("canvas")!;
  203. // start from (30, 20)
  204. fireEvent.pointerDown(canvas, { clientX: 30, clientY: 20 });
  205. // finish (position does not matter)
  206. fireEvent.pointerUp(canvas);
  207. // we need to finalize it because arrows and lines enter multi-mode
  208. fireEvent.keyDown(document, { key: KEYS.ENTER });
  209. expect(renderScene).toHaveBeenCalledTimes(7);
  210. expect(h.state.selectionElement).toBeNull();
  211. expect(h.elements.length).toEqual(0);
  212. });
  213. });