From 86ca7c5e3d5d7eddb6bc05805958b82f8fafd40b Mon Sep 17 00:00:00 2001 From: moklick Date: Thu, 5 Sep 2024 15:39:32 +0200 Subject: [PATCH 1/3] test(adoptUserNodes): add unit test --- .../components/utils/adopt-user-nodes.cy.ts | 119 ++++++++++++++++++ examples/react/package.json | 1 + pnpm-lock.yaml | 16 +++ 3 files changed, 136 insertions(+) create mode 100644 examples/react/cypress/components/utils/adopt-user-nodes.cy.ts diff --git a/examples/react/cypress/components/utils/adopt-user-nodes.cy.ts b/examples/react/cypress/components/utils/adopt-user-nodes.cy.ts new file mode 100644 index 00000000..acc3c8a3 --- /dev/null +++ b/examples/react/cypress/components/utils/adopt-user-nodes.cy.ts @@ -0,0 +1,119 @@ +import { adoptUserNodes } from '@xyflow/system'; + +import type { Node, NodeLookup, ParentLookup } from '@xyflow/react'; + +describe('adoptUserNodes Testing', () => { + it('builds node lookup', () => { + const nodeLookup: NodeLookup = new Map(); + const parentLookup: ParentLookup = new Map(); + + const userNode: Node = { + id: '1', + data: { label: 'node' }, + position: { x: 250, y: 5 }, + measured: { width: 100, height: 50 }, + }; + + adoptUserNodes([userNode], nodeLookup, parentLookup); + const internalNode = nodeLookup.get('1'); + + expect(nodeLookup.size).to.equal(1); + expect(internalNode).to.have.property('internals'); + }); + + it('calculates positionAbsolute with nodeOrigin', () => { + const nodeLookup: NodeLookup = new Map(); + const parentLookup: ParentLookup = new Map(); + + const userNode: Node = { + id: '1', + data: { label: 'node' }, + position: { x: 250, y: 5 }, + measured: { width: 100, height: 50 }, + }; + + adoptUserNodes([userNode], nodeLookup, parentLookup, { + nodeOrigin: [0.5, 0.5], + }); + const internalNode = nodeLookup.get('1'); + + expect(internalNode.internals.positionAbsolute.x).to.equal(userNode.position.x - userNode.measured.width / 2); + expect(internalNode.internals.positionAbsolute.y).to.equal(userNode.position.y - userNode.measured.height / 2); + }); + + it('calculates positionAbsolute for sub flow', () => { + const nodeLookup: NodeLookup = new Map(); + const parentLookup: ParentLookup = new Map(); + + const userParentNode: Node = { + id: '1', + data: { label: 'node' }, + position: { x: 100, y: 100 }, + measured: { width: 100, height: 50 }, + }; + + const userChildNode: Node = { + id: '2', + data: { label: 'child' }, + position: { x: 0, y: 0 }, + measured: { width: 100, height: 50 }, + parentId: '1', + }; + + adoptUserNodes([userParentNode, userChildNode], nodeLookup, parentLookup); + + const internalParentNode = nodeLookup.get('1'); + const internalChildNode = nodeLookup.get('2'); + + expect(nodeLookup.size).to.equal(2); + + expect(internalChildNode.internals.positionAbsolute.x).to.equal( + userChildNode.position.x + userParentNode.position.x + ); + expect(internalChildNode.internals.positionAbsolute.y).to.equal( + userChildNode.position.y + userParentNode.position.y + ); + }); + + it('calculates positionAbsolute for sub flow with nodeOrigin', () => { + const nodeLookup: NodeLookup = new Map(); + const parentLookup: ParentLookup = new Map(); + const nodeOrigin = [0.5, 0.5]; + + const userParentNode: Node = { + id: '1', + data: { label: 'node' }, + position: { x: 100, y: 100 }, + measured: { width: 100, height: 50 }, + }; + + const userChildNode: Node = { + id: '2', + data: { label: 'child' }, + position: { x: 0, y: 0 }, + measured: { width: 100, height: 50 }, + parentId: '1', + }; + + adoptUserNodes([userParentNode, userChildNode], nodeLookup, parentLookup, { + nodeOrigin, + }); + + const internalParentNode = nodeLookup.get('1'); + const internalChildNode = nodeLookup.get('2'); + + const expectedParentX = userParentNode.position.x - userParentNode.measured.width * nodeOrigin[0]; + const expectedParentY = userParentNode.position.y - userParentNode.measured.height * nodeOrigin[1]; + + expect(internalParentNode.internals.positionAbsolute.x).to.equal(expectedParentX); + expect(internalParentNode.internals.positionAbsolute.y).to.equal(expectedParentY); + + const expectedChildX = userChildNode.position.x - userChildNode.measured.width * nodeOrigin[0] + expectedParentX; + const expectedChildY = userChildNode.position.y - userChildNode.measured.height * nodeOrigin[1] + expectedParentY; + + expect(internalChildNode.internals.positionAbsolute.x).to.equal(expectedChildX); + expect(internalChildNode.internals.positionAbsolute.y).to.equal(expectedChildY); + }); +}); + +export {}; diff --git a/examples/react/package.json b/examples/react/package.json index 6b7362f5..dc73105b 100644 --- a/examples/react/package.json +++ b/examples/react/package.json @@ -16,6 +16,7 @@ "dependencies": { "@reduxjs/toolkit": "^2.2.3", "@xyflow/react": "workspace:*", + "@xyflow/system": "^0.0.41", "classcat": "^5.0.4", "dagre": "^0.8.5", "localforage": "^1.10.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ad492c30..26095bb2 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -101,6 +101,9 @@ importers: '@xyflow/react': specifier: workspace:* version: link:../../packages/react + '@xyflow/system': + specifier: ^0.0.41 + version: 0.0.41 classcat: specifier: ^5.0.4 version: 5.0.4 @@ -2211,6 +2214,9 @@ packages: peerDependencies: vite: ^4.2.0 || ^5.0.0 + '@xyflow/system@0.0.41': + resolution: {integrity: sha512-XAjs8AUA0YMfYD91cT6pLGALwbsPS64s2WBHyULqL1m0gTqXqaUSLK1P7qA/Q8HecN0RFbqlM2tPO8bmZXP0YQ==} + acorn-jsx@5.3.2: resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} peerDependencies: @@ -8424,6 +8430,16 @@ snapshots: transitivePeerDependencies: - supports-color + '@xyflow/system@0.0.41': + dependencies: + '@types/d3-drag': 3.0.7 + '@types/d3-selection': 3.0.10 + '@types/d3-transition': 3.0.8 + '@types/d3-zoom': 3.0.8 + d3-drag: 3.0.0 + d3-selection: 3.0.0 + d3-zoom: 3.0.0 + acorn-jsx@5.3.2(acorn@8.10.0): dependencies: acorn: 8.10.0 From 48a514fcbb71e01677562e88baa28500f63cd043 Mon Sep 17 00:00:00 2001 From: moklick Date: Thu, 5 Sep 2024 16:30:10 +0200 Subject: [PATCH 2/3] chore(tests): use workspace:* for @xyflow/system --- examples/react/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/react/package.json b/examples/react/package.json index dc73105b..ecbcb09f 100644 --- a/examples/react/package.json +++ b/examples/react/package.json @@ -16,7 +16,7 @@ "dependencies": { "@reduxjs/toolkit": "^2.2.3", "@xyflow/react": "workspace:*", - "@xyflow/system": "^0.0.41", + "@xyflow/system": "workspace:*", "classcat": "^5.0.4", "dagre": "^0.8.5", "localforage": "^1.10.0", From 4ffd790757ad13323a83e6ca6b3f0df1b9f714cc Mon Sep 17 00:00:00 2001 From: moklick Date: Thu, 5 Sep 2024 16:31:23 +0200 Subject: [PATCH 3/3] chore(pnpm): update lockfile --- pnpm-lock.yaml | 17 ++--------------- 1 file changed, 2 insertions(+), 15 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 26095bb2..918e9fd6 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -102,8 +102,8 @@ importers: specifier: workspace:* version: link:../../packages/react '@xyflow/system': - specifier: ^0.0.41 - version: 0.0.41 + specifier: workspace:* + version: link:../../packages/system classcat: specifier: ^5.0.4 version: 5.0.4 @@ -2214,9 +2214,6 @@ packages: peerDependencies: vite: ^4.2.0 || ^5.0.0 - '@xyflow/system@0.0.41': - resolution: {integrity: sha512-XAjs8AUA0YMfYD91cT6pLGALwbsPS64s2WBHyULqL1m0gTqXqaUSLK1P7qA/Q8HecN0RFbqlM2tPO8bmZXP0YQ==} - acorn-jsx@5.3.2: resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} peerDependencies: @@ -8430,16 +8427,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@xyflow/system@0.0.41': - dependencies: - '@types/d3-drag': 3.0.7 - '@types/d3-selection': 3.0.10 - '@types/d3-transition': 3.0.8 - '@types/d3-zoom': 3.0.8 - d3-drag: 3.0.0 - d3-selection: 3.0.0 - d3-zoom: 3.0.0 - acorn-jsx@5.3.2(acorn@8.10.0): dependencies: acorn: 8.10.0