flow-document-transformer.test.ts 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  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 { TransformData } from '@flowgram.ai/core';
  7. import { FlowDocument, FlowNodeTransformData } from '../src';
  8. import { baseMockAddNode } from './flow.mock';
  9. import { createDocumentContainer } from './flow-document-container.mock';
  10. interface TransformTestData {
  11. version: number;
  12. localBoundsStr: string;
  13. localID: number;
  14. worldID: number;
  15. boundsStr: string;
  16. }
  17. function getTransformData(document: FlowDocument): Record<string, TransformTestData> {
  18. const data: Record<string, TransformTestData> = {};
  19. document.traverse((node) => {
  20. const transform = node.getData<FlowNodeTransformData>(FlowNodeTransformData)!;
  21. data[node.id] = {
  22. version: transform.version,
  23. boundsStr: transform.bounds.toStyleStr(),
  24. localBoundsStr: transform.localBounds.toStyleStr(),
  25. localID: transform.transform.localID, // 用来判断是否有更新
  26. worldID: transform.transform.worldID,
  27. };
  28. });
  29. return data;
  30. }
  31. describe('flow-document-transformer', () => {
  32. let container = createDocumentContainer();
  33. beforeEach(() => {
  34. container = createDocumentContainer();
  35. container.get(FlowDocument).fromJSON(baseMockAddNode);
  36. });
  37. it('updateTransformsTree', () => {
  38. const document = container.get<FlowDocument>(FlowDocument);
  39. document.transformer.updateTransformsTree();
  40. // root 会包含三个子节点:start_0, dynamicSplit_0, end_0
  41. expect(document.root.getData<TransformData>(TransformData)!.children.length).toEqual(3);
  42. });
  43. it('transform version', () => {
  44. const document = container.get<FlowDocument>(FlowDocument);
  45. const preData = getTransformData(document);
  46. document.transformer.refresh();
  47. const postData = getTransformData(document);
  48. expect(preData.root.version).toEqual(0);
  49. expect(preData.start_0).toEqual({
  50. version: 0,
  51. boundsStr: 'left: 0px; top: 0px; width: 0px; height: 0px;',
  52. localBoundsStr: 'left: 0px; top: 0px; width: 0px; height: 0px;',
  53. localID: 0,
  54. worldID: 0,
  55. });
  56. expect(postData.start_0).toEqual({
  57. version: 2, // 更新了 size 和 position
  58. boundsStr: 'left: -140px; top: 0px; width: 280px; height: 60px;',
  59. localBoundsStr: 'left: -140px; top: 0px; width: 280px; height: 60px;',
  60. localID: 2, // 更新了 size 和 position
  61. worldID: 1,
  62. });
  63. expect(postData.root).toEqual({
  64. version: 0,
  65. boundsStr: 'left: -140px; top: 0px; width: 280px; height: 428px;',
  66. localBoundsStr: 'left: -140px; top: 0px; width: 280px; height: 428px;',
  67. localID: 0, // 只更新了 position
  68. worldID: 0,
  69. });
  70. });
  71. it('refresh', () => {
  72. const document = container.get<FlowDocument>(FlowDocument);
  73. document.transformer.refresh();
  74. const preData = getTransformData(document);
  75. document.transformer.refresh();
  76. const nextData = getTransformData(document);
  77. // 数据没有变化
  78. expect(preData).toEqual(nextData);
  79. });
  80. it('transform with tree change', () => {
  81. const document = container.get<FlowDocument>(FlowDocument);
  82. document.transformer.refresh();
  83. const preData = getTransformData(document);
  84. expect(preData.dynamicSplit_0).toEqual({
  85. version: 3,
  86. boundsStr: 'left: -140px; top: 92px; width: 280px; height: 244px;',
  87. localBoundsStr: 'left: -140px; top: 92px; width: 280px; height: 244px;',
  88. localID: 3,
  89. worldID: 1,
  90. });
  91. // expect(preData.$blockOrderIcon$block_1).toEqual({
  92. // version: 2,
  93. // boundsStr: 'left: -140px; top: 184px; width: 280px; height: 60px;',
  94. // localBoundsStr: 'left: -140px; top: 0px; width: 280px; height: 60px;',
  95. // localID: 2,
  96. // worldID: 1,
  97. // })
  98. document.addFromNode('start_0', { id: 'test', type: 'test' });
  99. document.transformer.refresh();
  100. const nextData = getTransformData(document);
  101. expect(preData.start_0).toEqual(nextData.start_0);
  102. expect(nextData.dynamicSplit_0).toEqual({
  103. version: 4,
  104. boundsStr: 'left: -140px; top: 184px; width: 280px; height: 244px;',
  105. localBoundsStr: 'left: -140px; top: 184px; width: 280px; height: 244px;',
  106. localID: 4,
  107. worldID: 2,
  108. });
  109. // 子节点页跟着更新
  110. // expect(nextData.$blockOrderIcon$block_1).toEqual({
  111. // version: 2, // 由于 local 未更新所以 version 没变
  112. // boundsStr: 'left: -140px; top: 276px; width: 280px; height: 60px;',
  113. // localBoundsStr: 'left: -140px; top: 0px; width: 280px; height: 60px;',
  114. // localID: 2, // local 相对位置未更新
  115. // worldID: 2, // world 绝对位置更新
  116. // })
  117. });
  118. });