@@ -716,4 +716,150 @@ describe('nodeProxyTracker', () => {
716716 const result = await getMainComponentAsync ( )
717717 expect ( result ) . toBeNull ( )
718718 } )
719+
720+ test ( 'assembleNodeTree should link children by id references' , ( ) => {
721+ // Create nodes with children as string IDs (how test data comes from toTestCaseFormat)
722+ const nodes = [
723+ {
724+ id : 'parent-1' ,
725+ name : 'Parent' ,
726+ type : 'FRAME' ,
727+ children : [ 'child-1' , 'child-2' ] ,
728+ } ,
729+ {
730+ id : 'child-1' ,
731+ name : 'Child1' ,
732+ type : 'FRAME' ,
733+ } ,
734+ {
735+ id : 'child-2' ,
736+ name : 'Child2' ,
737+ type : 'RECTANGLE' ,
738+ } ,
739+ ]
740+
741+ const rootNode = assembleNodeTree ( nodes )
742+
743+ expect ( rootNode . id ) . toBe ( 'parent-1' )
744+ expect ( Array . isArray ( rootNode . children ) ) . toBe ( true )
745+ expect ( rootNode . children ?. length ) . toBe ( 2 )
746+
747+ // Children should be linked as objects, not strings
748+ const child1 = rootNode . children ?. [ 0 ]
749+ expect ( typeof child1 ) . toBe ( 'object' )
750+ expect ( ( child1 as { id : string } ) ?. id ) . toBe ( 'child-1' )
751+
752+ const child2 = rootNode . children ?. [ 1 ]
753+ expect ( typeof child2 ) . toBe ( 'object' )
754+ expect ( ( child2 as { id : string } ) ?. id ) . toBe ( 'child-2' )
755+ } )
756+
757+ test ( 'assembleNodeTree should filter out undefined children' , ( ) => {
758+ // Create nodes with children referencing non-existent nodes
759+ const nodes = [
760+ {
761+ id : 'parent-1' ,
762+ name : 'Parent' ,
763+ type : 'FRAME' ,
764+ children : [ 'child-1' , 'non-existent-child' ] ,
765+ } ,
766+ {
767+ id : 'child-1' ,
768+ name : 'Child1' ,
769+ type : 'FRAME' ,
770+ } ,
771+ ]
772+
773+ const rootNode = assembleNodeTree ( nodes )
774+
775+ expect ( rootNode . id ) . toBe ( 'parent-1' )
776+ expect ( Array . isArray ( rootNode . children ) ) . toBe ( true )
777+ // Only child-1 should be in children, non-existent-child should be filtered out
778+ expect ( rootNode . children ?. length ) . toBe ( 1 )
779+ expect ( ( rootNode . children ?. [ 0 ] as { id : string } ) ?. id ) . toBe ( 'child-1' )
780+ } )
781+
782+ test ( 'assembleNodeTree TEXT node getStyledTextSegments should return stored segments' , ( ) => {
783+ // Create TEXT node with styledTextSegments data
784+ const nodes = [
785+ {
786+ id : 'text-1' ,
787+ name : 'TextNode' ,
788+ type : 'TEXT' ,
789+ characters : 'Hello World' ,
790+ styledTextSegments : [
791+ {
792+ start : 0 ,
793+ end : 5 ,
794+ characters : 'Hello' ,
795+ fontName : { family : 'Arial' , style : 'Bold' } ,
796+ fontWeight : 700 ,
797+ fontSize : 20 ,
798+ } ,
799+ {
800+ start : 6 ,
801+ end : 11 ,
802+ characters : 'World' ,
803+ fontName : { family : 'Arial' , style : 'Regular' } ,
804+ fontWeight : 400 ,
805+ fontSize : 16 ,
806+ } ,
807+ ] ,
808+ } ,
809+ ]
810+
811+ const rootNode = assembleNodeTree ( nodes )
812+
813+ expect ( rootNode . type ) . toBe ( 'TEXT' )
814+
815+ // Call getStyledTextSegments
816+ const getStyledTextSegments = (
817+ rootNode as unknown as Record < string , unknown >
818+ ) . getStyledTextSegments as ( ) => unknown [ ]
819+ expect ( typeof getStyledTextSegments ) . toBe ( 'function' )
820+
821+ const segments = getStyledTextSegments ( )
822+ expect ( Array . isArray ( segments ) ) . toBe ( true )
823+ expect ( segments . length ) . toBe ( 2 )
824+ expect ( ( segments [ 0 ] as { characters : string } ) . characters ) . toBe ( 'Hello' )
825+ expect ( ( segments [ 1 ] as { characters : string } ) . characters ) . toBe ( 'World' )
826+ } )
827+
828+ test ( 'assembleNodeTree TEXT node getStyledTextSegments should generate default segment when no styledTextSegments' , ( ) => {
829+ // Create TEXT node without styledTextSegments
830+ const nodes = [
831+ {
832+ id : 'text-1' ,
833+ name : 'TextNode' ,
834+ type : 'TEXT' ,
835+ characters : 'Test Text' ,
836+ fontName : { family : 'Inter' , style : 'Regular' } ,
837+ fontWeight : 400 ,
838+ fontSize : 14 ,
839+ lineHeight : { unit : 'AUTO' } ,
840+ letterSpacing : { unit : 'PERCENT' , value : 0 } ,
841+ fills : [ { type : 'SOLID' , color : { r : 0 , g : 0 , b : 0 } } ] ,
842+ } ,
843+ ]
844+
845+ const rootNode = assembleNodeTree ( nodes )
846+
847+ expect ( rootNode . type ) . toBe ( 'TEXT' )
848+
849+ // Call getStyledTextSegments - should generate default segment
850+ const getStyledTextSegments = (
851+ rootNode as unknown as Record < string , unknown >
852+ ) . getStyledTextSegments as ( ) => unknown [ ]
853+ const segments = getStyledTextSegments ( )
854+
855+ expect ( Array . isArray ( segments ) ) . toBe ( true )
856+ expect ( segments . length ) . toBe ( 1 )
857+
858+ const segment = segments [ 0 ] as Record < string , unknown >
859+ expect ( segment . characters ) . toBe ( 'Test Text' )
860+ expect ( segment . start ) . toBe ( 0 )
861+ expect ( segment . end ) . toBe ( 9 )
862+ expect ( segment . textDecoration ) . toBe ( 'NONE' )
863+ expect ( segment . textCase ) . toBe ( 'ORIGINAL' )
864+ } )
719865} )
0 commit comments