@@ -3,12 +3,13 @@ import { describe, expect, it, vi } from "vitest";
33
44import { NodeManager } from "@/nodeManager" ;
55import type { TaskNodeData } from "@/types/nodes" ;
6- import type {
7- ComponentSpec ,
8- InputSpec ,
9- OutputSpec ,
10- TaskOutputArgument ,
11- TaskSpec ,
6+ import {
7+ type ComponentSpec ,
8+ type InputSpec ,
9+ isGraphImplementation ,
10+ type OutputSpec ,
11+ type TaskOutputArgument ,
12+ type TaskSpec ,
1213} from "@/utils/componentSpec" ;
1314
1415import { duplicateNodes } from "./duplicateNodes" ;
@@ -63,7 +64,7 @@ const createMockComponentSpecWithOutputs = (
6364 acc [ output . name ] = {
6465 taskOutput : {
6566 taskId : "task1" ,
66- outputName : "result" ,
67+ outputName : output . name ,
6768 } ,
6869 } ;
6970 return acc ;
@@ -123,7 +124,7 @@ const createMockInputNode = (
123124 position,
124125 data : {
125126 label : inputName ,
126- inputSpec : { ...mockInputSpec , name : inputName } ,
127+ spec : { ...mockInputSpec , name : inputName } ,
127128 } ,
128129 selected : false ,
129130 dragging : false ,
@@ -144,7 +145,7 @@ const createMockOutputNode = (
144145 position,
145146 data : {
146147 label : outputName ,
147- outputSpec : { ...mockOutputSpec , name : outputName } ,
148+ spec : { ...mockOutputSpec , name : outputName } ,
148149 } ,
149150 selected : false ,
150151 dragging : false ,
@@ -210,7 +211,7 @@ describe("duplicateNodes", () => {
210211 if ( "graph" in result . updatedComponentSpec . implementation ! ) {
211212 expect (
212213 result . updatedComponentSpec . implementation . graph . tasks ,
213- ) . toHaveProperty ( "original-task 2 " ) ;
214+ ) . toHaveProperty ( "original-task (2) " ) ;
214215 }
215216 } ) ;
216217
@@ -236,14 +237,14 @@ describe("duplicateNodes", () => {
236237 expect ( result . newNodes ) . toHaveLength ( 1 ) ;
237238 expect ( result . newNodes [ 0 ] . type ) . toBe ( "input" ) ;
238239 expect ( result . newNodes [ 0 ] . id ) . toBe (
239- nodeManager . getNodeId ( "original-input 2 " , "input" ) ,
240+ nodeManager . getNodeId ( "original-input (2) " , "input" ) ,
240241 ) ;
241242 expect ( result . newNodes [ 0 ] . position ) . toEqual ( { x : 60 , y : 60 } ) ;
242243
243244 expect ( result . updatedComponentSpec . inputs ) . toHaveLength ( 2 ) ;
244245 expect (
245246 result . updatedComponentSpec . inputs ?. some (
246- ( input ) => input . name === "original-input 2 " ,
247+ ( input ) => input . name === "original-input (2) " ,
247248 ) ,
248249 ) . toBe ( true ) ;
249250 } ) ;
@@ -274,14 +275,14 @@ describe("duplicateNodes", () => {
274275 expect ( result . newNodes ) . toHaveLength ( 1 ) ;
275276 expect ( result . newNodes [ 0 ] . type ) . toBe ( "output" ) ;
276277 expect ( result . newNodes [ 0 ] . id ) . toBe (
277- nodeManager . getNodeId ( "original-output 2 " , "output" ) ,
278+ nodeManager . getNodeId ( "original-output (2) " , "output" ) ,
278279 ) ;
279280 expect ( result . newNodes [ 0 ] . position ) . toEqual ( { x : 310 , y : 310 } ) ;
280281
281282 expect ( result . updatedComponentSpec . outputs ) . toHaveLength ( 2 ) ;
282283 expect (
283284 result . updatedComponentSpec . outputs ?. some (
284- ( output ) => output . name === "original-output 2 " ,
285+ ( output ) => output . name === "original-output (2) " ,
285286 ) ,
286287 ) . toBe ( true ) ;
287288 } ) ;
@@ -304,13 +305,13 @@ describe("duplicateNodes", () => {
304305 const result = duplicateNodes ( componentSpec , nodes , nodeManager ) ;
305306
306307 expect ( result . newNodes ) . toHaveLength ( 2 ) ;
307- if ( "graph" in result . updatedComponentSpec . implementation ! ) {
308+ if ( isGraphImplementation ( result . updatedComponentSpec . implementation ) ) {
308309 expect (
309310 result . updatedComponentSpec . implementation . graph . tasks ,
310- ) . toHaveProperty ( "task1 2 " ) ;
311+ ) . toHaveProperty ( "task1 (2) " ) ;
311312 expect (
312313 result . updatedComponentSpec . implementation . graph . tasks ,
313- ) . toHaveProperty ( "task2 2 " ) ;
314+ ) . toHaveProperty ( "task2 (2) " ) ;
314315 }
315316 } ) ;
316317 } ) ;
@@ -418,7 +419,7 @@ describe("duplicateNodes", () => {
418419
419420 if ( "graph" in result . updatedComponentSpec . implementation ! ) {
420421 const duplicatedTask2 =
421- result . updatedComponentSpec . implementation . graph . tasks [ "task2 2 " ] ;
422+ result . updatedComponentSpec . implementation . graph . tasks [ "task2 (2) " ] ;
422423 expect ( duplicatedTask2 . arguments ) . toEqual ( { } ) ;
423424 }
424425 } ) ;
@@ -442,10 +443,10 @@ describe("duplicateNodes", () => {
442443
443444 if ( "graph" in result . updatedComponentSpec . implementation ! ) {
444445 const duplicatedTask2 =
445- result . updatedComponentSpec . implementation . graph . tasks [ "task2 2 " ] ;
446+ result . updatedComponentSpec . implementation . graph . tasks [ "task2 (2) " ] ;
446447 expect ( duplicatedTask2 . arguments ?. input1 ) . toEqual ( {
447448 taskOutput : {
448- taskId : "task1 2 " ,
449+ taskId : "task1 (2) " ,
449450 outputName : "output1" ,
450451 } ,
451452 } ) ;
@@ -495,7 +496,7 @@ describe("duplicateNodes", () => {
495496
496497 if ( "graph" in result . updatedComponentSpec . implementation ! ) {
497498 const duplicatedTask2 =
498- result . updatedComponentSpec . implementation . graph . tasks [ "task2 2 " ] ;
499+ result . updatedComponentSpec . implementation . graph . tasks [ "task2 (2) " ] ;
499500
500501 // Should remove internal connection to task1 (since task1 is being duplicated)
501502 expect ( duplicatedTask2 . arguments ?. input1 ) . toBeUndefined ( ) ;
@@ -529,10 +530,10 @@ describe("duplicateNodes", () => {
529530
530531 if ( "graph" in result . updatedComponentSpec . implementation ! ) {
531532 const duplicatedTask2 =
532- result . updatedComponentSpec . implementation . graph . tasks [ "task2 2 " ] ;
533+ result . updatedComponentSpec . implementation . graph . tasks [ "task2 (2) " ] ;
533534 expect ( duplicatedTask2 . arguments ?. input1 ) . toEqual ( {
534535 taskOutput : {
535- taskId : "task1 2 " ,
536+ taskId : "task1 (2) " ,
536537 outputName : "output1" ,
537538 } ,
538539 } ) ;
@@ -570,26 +571,45 @@ describe("duplicateNodes", () => {
570571 connection : "all" ,
571572 } ) ;
572573
573- if ( "graph" in result . updatedComponentSpec . implementation ! ) {
574+ if ( isGraphImplementation ( result . updatedComponentSpec . implementation ) ) {
574575 const duplicatedTask =
575- result . updatedComponentSpec . implementation . graph . tasks [ "task1 2 " ] ;
576+ result . updatedComponentSpec . implementation . graph . tasks [ "task1 (2) " ] ;
576577 expect ( duplicatedTask . arguments ?. input1 ) . toEqual ( {
577578 graphInput : {
578- inputName : "graph-input 2 " ,
579+ inputName : "graph-input (2) " ,
579580 } ,
580581 } ) ;
581582 }
582583 } ) ;
583584
584585 it ( "should handle graph output connections" , ( ) => {
586+ const outputSpec : OutputSpec = {
587+ ...mockOutputSpec ,
588+ name : "graph-output-node" ,
589+ } ;
590+
591+ const taskComponentSpec : ComponentSpec = {
592+ name : "task-component" ,
593+ inputs : [ ] ,
594+ outputs : [
595+ {
596+ name : "graph-output" ,
597+ type : "String" ,
598+ annotations : { } ,
599+ } ,
600+ ] ,
601+ implementation : {
602+ container : { image : "task-image" } ,
603+ } ,
604+ } ;
605+
585606 const taskSpec : TaskSpec = {
586607 ...mockTaskSpec ,
587608 arguments : { } ,
588- } ;
589-
590- const outputSpec : OutputSpec = {
591- ...mockOutputSpec ,
592- name : "graph-output" ,
609+ componentRef : {
610+ name : "task-component" ,
611+ spec : taskComponentSpec ,
612+ } ,
593613 } ;
594614
595615 const componentSpec = createMockComponentSpecWithOutputs (
@@ -601,23 +621,23 @@ describe("duplicateNodes", () => {
601621 const nodeManager = createMockNodeManager ( ) ;
602622 const nodes = [
603623 createMockTaskNode ( "task1" , taskSpec , nodeManager ) ,
604- createMockOutputNode ( "graph-output" , nodeManager ) ,
624+ createMockOutputNode ( "graph-output-node " , nodeManager ) ,
605625 ] ;
606626
607627 const result = duplicateNodes ( componentSpec , nodes , nodeManager , {
608628 connection : "all" ,
609629 } ) ;
610630
611631 // Check that outputValues are updated for duplicated outputs
612- if ( "graph" in result . updatedComponentSpec . implementation ! ) {
632+ if ( isGraphImplementation ( result . updatedComponentSpec . implementation ) ) {
613633 const outputValues =
614634 result . updatedComponentSpec . implementation . graph . outputValues ;
615635
616636 // Duplicated output should reference duplicated task
617- expect ( outputValues ?. [ "graph-output 2 " ] ) . toEqual ( {
637+ expect ( outputValues ?. [ "graph-output-node (2) " ] ) . toEqual ( {
618638 taskOutput : {
619- taskId : "task1 2 " ,
620- outputName : "result " ,
639+ taskId : "task1 (2) " ,
640+ outputName : "graph-output-node " ,
621641 } ,
622642 } ) ;
623643 }
@@ -655,7 +675,7 @@ describe("duplicateNodes", () => {
655675 it ( "should handle nodes without position annotations" , ( ) => {
656676 const taskSpecWithoutPosition = {
657677 ...mockTaskSpec ,
658- annotations : { } , // No position annotation
678+ annotations : { } ,
659679 } ;
660680
661681 const componentSpec = createMockComponentSpec ( {
0 commit comments