use-playground-tools.test.ts 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. /**
  2. * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
  3. * SPDX-License-Identifier: MIT
  4. */
  5. import { beforeEach, describe, expect, it } from 'vitest';
  6. import { interfaces } from 'inversify';
  7. import { renderHook } from '@testing-library/react-hooks';
  8. import { delay } from '@flowgram.ai/utils';
  9. import {
  10. WorkflowDocument,
  11. WorkflowDocumentOptions,
  12. InteractiveType,
  13. EditorCursorState,
  14. LineType,
  15. } from '@flowgram.ai/free-layout-core';
  16. import { Playground, PositionData, FlowNodeBaseType } from '@flowgram.ai/editor';
  17. import { PlaygroundTools, usePlaygroundTools } from '../src';
  18. import { createDocument, createHookWrapper, nestJSON, createSubCanvasNodes } from './utils.mock';
  19. describe(
  20. 'use-playground-tools',
  21. () => {
  22. let toolsData: { current: PlaygroundTools };
  23. let playground: Playground;
  24. let container: interfaces.Container;
  25. beforeEach(async () => {
  26. container = (await createDocument()).container;
  27. playground = container.get<Playground>(Playground);
  28. // tools 工具要在 ready 之后才能生效
  29. playground.ready();
  30. const wrapper = createHookWrapper(container);
  31. const { result } = renderHook(() => usePlaygroundTools(), {
  32. wrapper,
  33. });
  34. toolsData = result;
  35. });
  36. it('zoomin', async () => {
  37. expect(toolsData.current.zoom).toEqual(1);
  38. toolsData.current.zoomin(false);
  39. expect(toolsData.current.zoom).toEqual(1.1);
  40. });
  41. it('zoomout', async () => {
  42. expect(toolsData.current.zoom).toEqual(1);
  43. toolsData.current.zoomout(false);
  44. expect(toolsData.current.zoom).toEqual(0.9);
  45. });
  46. it('fitview', async () => {
  47. playground.config.updateConfig({
  48. width: 1000,
  49. height: 800,
  50. });
  51. await toolsData.current.fitView(false);
  52. expect(playground.config.scrollData).toEqual({
  53. scrollX: -30,
  54. scrollY: -370,
  55. });
  56. });
  57. it('autoLayout', async () => {
  58. const doc = container.get(WorkflowDocument);
  59. let startPos = doc.getNode('start_0')!.getData(PositionData)!;
  60. const endPos = doc.getNode('end_0')!.getData(PositionData)!;
  61. expect(endPos.x - startPos.x).toEqual(800);
  62. const revert = await toolsData.current.autoLayout();
  63. expect(endPos.x - startPos.x).toEqual(620);
  64. revert(); // 回滚
  65. expect(endPos.x - startPos.x).toEqual(800);
  66. });
  67. it('autoLayout with nested JSON', async () => {
  68. const doc = container.get(WorkflowDocument);
  69. doc.fromJSON(nestJSON);
  70. await delay(10);
  71. let startPos = doc.getNode('start_0')!.getData(PositionData)!;
  72. const endPos = doc.getNode('end_0')!.getData(PositionData)!;
  73. expect(endPos.x - startPos.x).toEqual(800);
  74. const revert = await toolsData.current.autoLayout();
  75. expect(endPos.x - startPos.x).toEqual(810);
  76. revert(); // 回滚
  77. expect(endPos.x - startPos.x).toEqual(800);
  78. });
  79. it.skip('autoLayout with verticalLine', async () => {
  80. const document = container.get(WorkflowDocument);
  81. // TODO
  82. // const documentOptions = container.get<WorkflowDocumentOptions>(WorkflowDocumentOptions);
  83. // documentOptions.isVerticalLine = (line) => {
  84. // if (
  85. // line.from?.flowNodeType === 'loop' &&
  86. // line.to?.flowNodeType === FlowNodeBaseType.SUB_CANVAS
  87. // ) {
  88. // return true;
  89. // }
  90. // return false;
  91. // };
  92. const { loopNode, subCanvasNode } = await createSubCanvasNodes(document);
  93. const loopPos = loopNode.getData(PositionData)!;
  94. const subCanvasPos = subCanvasNode.getData(PositionData)!;
  95. await delay(10);
  96. expect({
  97. x: loopPos.x,
  98. y: loopPos.y,
  99. }).toEqual({
  100. x: -100,
  101. y: 0,
  102. });
  103. expect({
  104. x: subCanvasPos.x,
  105. y: subCanvasPos.y,
  106. }).toEqual({
  107. x: 100,
  108. y: 0,
  109. });
  110. await toolsData.current.autoLayout();
  111. await delay(10);
  112. expect({
  113. x: loopPos.x,
  114. y: loopPos.y,
  115. }).toEqual({
  116. x: 140,
  117. y: 130,
  118. });
  119. expect({
  120. x: subCanvasPos.x,
  121. y: subCanvasPos.y,
  122. }).toEqual({
  123. x: 0,
  124. y: 290,
  125. });
  126. });
  127. it('switchLineType', async () => {
  128. expect(toolsData.current.lineType).toEqual(LineType.BEZIER);
  129. toolsData.current.switchLineType();
  130. expect(toolsData.current.lineType).toEqual(LineType.LINE_CHART);
  131. toolsData.current.switchLineType();
  132. expect(toolsData.current.lineType).toEqual(LineType.BEZIER);
  133. });
  134. it('setCursorState', async () => {
  135. await toolsData.current.setCursorState(() => EditorCursorState.GRAB);
  136. expect(toolsData.current.cursorState).toEqual('GRAB');
  137. await toolsData.current.setCursorState(EditorCursorState.SELECT);
  138. expect(toolsData.current.cursorState).toEqual('SELECT');
  139. });
  140. it('setInteractiveType', async () => {
  141. await toolsData.current.setInteractiveType(InteractiveType.MOUSE);
  142. expect(toolsData.current.interactiveType).toEqual(InteractiveType.MOUSE);
  143. expect(toolsData.current.cursorState).toEqual('GRAB');
  144. await toolsData.current.setInteractiveType(InteractiveType.PAD);
  145. expect(toolsData.current.interactiveType).toEqual(InteractiveType.PAD);
  146. expect(toolsData.current.cursorState).toEqual('SELECT');
  147. });
  148. },
  149. {
  150. timeout: 30000,
  151. }
  152. );