import * as nm from '#ast/node-metadata' ; import * as cloneUtilModule from '#ast/utilities/clone-node' ; import { Node , NodeFlags , TypeFlags } from '#ast' ; import { createNode } from '#ast/utilities/node-factories' ; import { NodeMap , NodeSet } from '#ast/components' ; import { createFakeNodes , fakeNodeKind , makeJestSafe } from '../../helpers' ; const kind = fakeNodeKind ; const cloneCount = 3 ; const nonCloneCount = 2 ; const baseTypeFlags = [ TypeFlags . Object , TypeFlags . Iterable ] ; const baseFlags = [ NodeFlags . Declaration , NodeFlags . Nested ] ; const isClone = ( n ) => ! ! ( < any > n ) . cloned ; const isNotClone = ( n ) => ! ( < any > n ) . cloned ; describe ( `Node Util -> createNode()` , ( ) => { const originalMetaEntry = nm . nodeMetadata [ kind ] ; const descMap = { prop : { value : 4 , configurable : false , writable : false } } ; let props ; let node ; beforeAll ( ( ) => { const parentNode = createFakeNodes ( 1 ) [ 0 ] ; props = { nSet : new NodeSet ( [ ... createFakeNodes ( cloneCount , parentNode ) , ... createFakeNodes ( nonCloneCount ) ] ) , nMap : new NodeMap ( [ ... createFakeNodes ( cloneCount , parentNode ) , ... createFakeNodes ( nonCloneCount ) ] ) , single : createFakeNodes ( 1 , parentNode ) [ 0 ] , nonChildSet : new NodeSet ( createFakeNodes ( cloneCount , parentNode ) ) , nonChildMap : new NodeMap ( createFakeNodes ( cloneCount , parentNode ) ) , nonChildSingle : createFakeNodes ( 1 , parentNode ) [ 0 ] } ; nm . nodeMetadata [ kind ] = { baseTypeFlags , baseFlags , childContainerProperties : new Map ( [ [ 'nSet' , { key : 'nSet' , optional : false } ] , [ 'nMap' , { key : 'nMap' , optional : false } ] , [ 'single' , { key : 'single' , optional : false } ] ] ) } ; jest . spyOn ( cloneUtilModule , 'cloneNode' ) . mockImplementation ( node => { ( < any > node ) . cloned = true ; return node ; } ) ; node = createNode ( kind , < any > props , descMap ) ; } ) ; afterAll ( ( ) => { nm . nodeMetadata [ kind ] = originalMetaEntry ; jest . restoreAllMocks ( ) ; } ) ; test ( `Assigns flags` , ( ) => { expect ( node . typeFlags ) . toBe ( baseTypeFlags . reduce ( ( p , f ) => p + f ) ) ; expect ( node . flags ) . toBe ( baseFlags . reduce ( ( p , f ) => p + f ) ) ; } ) ; test ( `Assigns property descriptors` , ( ) => { expect ( Object . getOwnPropertyDescriptors ( node ) ) . toMatchObject ( descMap ) ; } ) ; test ( `Assigns properties` , ( ) => { expect ( makeJestSafe ( node ) ) . toMatchObject ( makeJestSafe ( props ) ) ; } ) ; test ( `Clones nodes in child props if node has existing parent` , ( ) => { const n = node ; expect ( n . nSet ) . not . toBe ( props . nSet ) ; expect ( n . nSet ) . toBeInstanceOf ( NodeSet ) ; expect ( n . nSet . toArray ( ) . filter ( isClone ) ) . toHaveLength ( cloneCount ) ; expect ( n . nSet . toArray ( ) . filter ( isNotClone ) ) . toHaveLength ( nonCloneCount ) ; expect ( n . nMap ) . not . toBe ( props . nMap ) ; expect ( n . nMap ) . toBeInstanceOf ( NodeMap ) ; expect ( n . nMap . toArray ( ) . filter ( isClone ) ) . toHaveLength ( cloneCount ) ; expect ( n . nMap . toArray ( ) . filter ( isNotClone ) ) . toHaveLength ( nonCloneCount ) ; expect ( isClone ( n . single ) ) . toBeTruthy ( ) ; expect ( n . nonChildSet . toArray ( ) . filter ( isNotClone ) ) . toHaveLength ( n . nonChildSet . size ) ; expect ( n . nonChildMap . toArray ( ) . filter ( isNotClone ) ) . toHaveLength ( n . nonChildMap . size ) ; expect ( isNotClone ( n . nonChildSingle ) ) . toBeTruthy ( ) ; } ) ; } ) ;