computing.test.ts 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. /**
  2. * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
  3. * SPDX-License-Identifier: MIT
  4. */
  5. import { it, expect, beforeEach, describe } from 'vitest';
  6. import { interfaces } from 'inversify';
  7. import { EntityManager } from '@flowgram.ai/core';
  8. import {
  9. WorkflowDocument,
  10. WorkflowHoverService,
  11. WorkflowLineEntity,
  12. WorkflowLinesManager,
  13. WorkflowSelectService,
  14. } from '@flowgram.ai/free-layout-core';
  15. import { StackingComputing } from '../src/stacking-computing';
  16. import { StackingContextManager } from '../src/manager';
  17. import { createWorkflowContainer, workflowJSON } from './utils.mock';
  18. import { IStackingComputing, IStackingContextManager } from './type.mock';
  19. let container: interfaces.Container;
  20. let document: WorkflowDocument;
  21. let stackingContextManager: IStackingContextManager;
  22. let stackingComputing: IStackingComputing;
  23. beforeEach(async () => {
  24. container = createWorkflowContainer();
  25. container.bind(StackingContextManager).to(StackingContextManager);
  26. document = container.get<WorkflowDocument>(WorkflowDocument);
  27. stackingContextManager = container.get<StackingContextManager>(
  28. StackingContextManager,
  29. ) as unknown as IStackingContextManager;
  30. await document.fromJSON(workflowJSON);
  31. stackingContextManager.init();
  32. stackingComputing = new StackingComputing() as unknown as IStackingComputing;
  33. });
  34. describe('StackingComputing compute', () => {
  35. it('should create instance', () => {
  36. const computing = new StackingComputing();
  37. expect(computing).not.toBeUndefined();
  38. });
  39. it('should execute compute', () => {
  40. const { nodeLevel, lineLevel, topLevel, maxLevel } = stackingComputing.compute({
  41. root: document.root,
  42. nodes: stackingContextManager.nodes,
  43. context: stackingContextManager.context,
  44. });
  45. expect(topLevel).toBe(8);
  46. expect(maxLevel).toBe(16);
  47. expect(Object.fromEntries(nodeLevel)).toEqual({
  48. start_0: 1,
  49. condition_0: 2,
  50. end_0: 3,
  51. loop_0: 4,
  52. break_0: 6,
  53. variable_0: 7,
  54. });
  55. expect(Object.fromEntries(lineLevel)).toEqual({
  56. 'start_0_-condition_0_': 0,
  57. 'start_0_-loop_0_': 0,
  58. 'condition_0_if-end_0_': 0,
  59. 'condition_0_else-end_0_': 0,
  60. 'loop_0_-end_0_': 0,
  61. 'break_0_-variable_0_': 5,
  62. });
  63. });
  64. it('should put hovered line on max level', () => {
  65. const hoverService = container.get<WorkflowHoverService>(WorkflowHoverService);
  66. const hoveredLineId = 'start_0_-loop_0_';
  67. hoverService.updateHoveredKey(hoveredLineId);
  68. const { lineLevel, maxLevel } = stackingComputing.compute({
  69. root: document.root,
  70. nodes: stackingContextManager.nodes,
  71. context: stackingContextManager.context,
  72. });
  73. const hoveredLineLevel = lineLevel.get(hoveredLineId);
  74. expect(hoveredLineLevel).toBe(maxLevel);
  75. });
  76. it('should put selected line on max level', () => {
  77. const entityManager = container.get<EntityManager>(EntityManager);
  78. const selectService = container.get<WorkflowSelectService>(WorkflowSelectService);
  79. const selectedLineId = 'start_0_-loop_0_';
  80. const selectedLine = entityManager.getEntityById<WorkflowLineEntity>(selectedLineId)!;
  81. selectService.selection = [selectedLine];
  82. const { lineLevel, maxLevel } = stackingComputing.compute({
  83. root: document.root,
  84. nodes: stackingContextManager.nodes,
  85. context: stackingContextManager.context,
  86. });
  87. const selectedLineLevel = lineLevel.get(selectedLineId);
  88. expect(selectedLineLevel).toBe(maxLevel);
  89. });
  90. it('should put drawing line on max level', () => {
  91. const linesManager = container.get<WorkflowLinesManager>(WorkflowLinesManager);
  92. const drawingLine = linesManager.createLine({
  93. from: 'start_0',
  94. drawingTo: { x: 100, y: 100 },
  95. })!;
  96. const { lineLevel, maxLevel } = stackingComputing.compute({
  97. root: document.root,
  98. nodes: stackingContextManager.nodes,
  99. context: stackingContextManager.context,
  100. });
  101. const drawingLineLevel = lineLevel.get(drawingLine.id);
  102. expect(drawingLineLevel).toBe(maxLevel);
  103. });
  104. it('should put selected nodes on top level', () => {
  105. const selectService = container.get<WorkflowSelectService>(WorkflowSelectService);
  106. const selectedNodeId = 'start_0';
  107. const selectedNode = document.getNode(selectedNodeId)!;
  108. selectService.selectNode(selectedNode);
  109. const { nodeLevel, topLevel } = stackingComputing.compute({
  110. root: document.root,
  111. nodes: stackingContextManager.nodes,
  112. context: stackingContextManager.context,
  113. });
  114. const selectedNodeLevel = nodeLevel.get(selectedNodeId);
  115. expect(selectedNodeLevel).toBe(topLevel);
  116. });
  117. });
  118. describe('StackingComputing builtin methods', () => {
  119. it('computeNodeIndexesMap', () => {
  120. const nodeIndexes = stackingComputing.computeNodeIndexesMap(stackingContextManager.nodes);
  121. expect(Object.fromEntries(nodeIndexes)).toEqual({
  122. root: 0,
  123. start_0: 1,
  124. condition_0: 2,
  125. end_0: 3,
  126. loop_0: 4,
  127. break_0: 5,
  128. variable_0: 6,
  129. });
  130. });
  131. it('computeTopLevel', () => {
  132. const topLevel = stackingComputing.computeTopLevel(stackingContextManager.nodes);
  133. expect(topLevel).toEqual(8);
  134. });
  135. });