import { attachScopes } from '..' ; describe ( 'attachScopes' , function ( ) { it ( 'attaches a scope to the top level' , function ( ) { const ast = { type : 'Program' , start : 0 , end : 8 , body : [ { type : 'VariableDeclaration' , start : 0 , end : 8 , declarations : [ { type : 'VariableDeclarator' , start : 4 , end : 7 , id : { type : 'Identifier' , start : 4 , end : 7 , name : 'foo' } , init : null } ] , kind : 'var' } ] , sourceType : 'module' } ; const scope = attachScopes ( ast , 'scope' ) ; expect ( scope . contains ( 'foo' ) ) . toBeTruthy ( ) ; expect ( scope . contains ( 'bar' ) ) . toBeFalsy ( ) ; } ) ; it ( 'adds multiple declarators from a single var declaration' , function ( ) { const ast = { type : 'Program' , start : 0 , end : 13 , body : [ { type : 'VariableDeclaration' , start : 0 , end : 13 , declarations : [ { type : 'VariableDeclarator' , start : 4 , end : 7 , id : { type : 'Identifier' , start : 4 , end : 7 , name : 'foo' } , init : null } , { type : 'VariableDeclarator' , start : 9 , end : 12 , id : { type : 'Identifier' , start : 9 , end : 12 , name : 'bar' } , init : null } ] , kind : 'var' } ] , sourceType : 'module' } ; const scope = attachScopes ( ast , 'scope' ) ; expect ( scope . contains ( 'foo' ) ) . toBeTruthy ( ) ; expect ( scope . contains ( 'bar' ) ) . toBeTruthy ( ) ; } ) ; it ( 'adds named declarators from a deconstructed declaration' , function ( ) { const ast = { type : 'Program' , start : 0 , end : 13 , body : [ { type : 'VariableDeclaration' , start : 0 , end : 42 , declarations : [ { type : 'VariableDeclarator' , start : 4 , end : 41 , id : { type : 'ObjectPattern' , start : 4 , end : 15 , properties : [ { type : 'Property' , start : 6 , end : 10 , method : false , shorthand : false , computed : false , key : { type : 'Literal' , start : 6 , end : 7 , value : 1 , raw : '1' } , value : { type : 'Identifier' , start : 9 , end : 10 , name : 'a' } , kind : 'init' } , { type : 'Property' , start : 12 , end : 13 , method : false , shorthand : true , computed : false , key : { type : 'Identifier' , start : 12 , end : 13 , name : 'b' } , kind : 'init' , value : { type : 'Identifier' , start : 12 , end : 13 , name : 'b' } } ] } , init : { type : 'ObjectExpression' , start : 18 , end : 41 , properties : [ { type : 'Property' , start : 22 , end : 28 , method : false , shorthand : false , computed : false , key : { type : 'Literal' , start : 22 , end : 23 , value : 1 , raw : '1' } , value : { type : 'Literal' , start : 25 , end : 28 , value : 'a' , raw : "'a'" } , kind : 'init' } , { type : 'Property' , start : 32 , end : 38 , method : false , shorthand : false , computed : false , key : { type : 'Identifier' , start : 32 , end : 33 , name : 'b' } , value : { type : 'Literal' , start : 35 , end : 38 , value : 'b' , raw : "'b'" } , kind : 'init' } ] } } ] , kind : 'var' } ] , sourceType : 'module' } ; const scope = attachScopes ( ast , 'scope' ) ; expect ( scope . contains ( 'a' ) ) . toBeTruthy ( ) ; expect ( scope . contains ( 'b' ) ) . toBeTruthy ( ) ; } ) ; it ( 'adds rest elements from a deconstructed object declaration' , function ( ) { const ast = { type : 'Program' , start : 0 , end : 66 , body : [ { type : 'VariableDeclaration' , start : 0 , end : 66 , declarations : [ { type : 'VariableDeclarator' , start : 6 , end : 66 , id : { type : 'ObjectPattern' , start : 6 , end : 26 , properties : [ { type : 'Property' , start : 8 , end : 9 , method : false , shorthand : true , computed : false , key : { type : 'Identifier' , start : 8 , end : 9 , name : 'x' } , kind : 'init' , value : { type : 'Identifier' , start : 8 , end : 9 , name : 'x' } } , { type : 'Property' , start : 11 , end : 15 , method : false , shorthand : false , computed : false , key : { type : 'Identifier' , start : 11 , end : 12 , name : 'y' } , value : { type : 'Identifier' , start : 14 , end : 15 , name : 'z' } , kind : 'init' } , { type : 'RestElement' , start : 17 , end : 24 , argument : { type : 'Identifier' , start : 20 , end : 24 , name : 'rest' } } ] } , init : { type : 'ObjectExpression' , start : 29 , end : 66 , properties : [ { type : 'Property' , start : 31 , end : 36 , method : false , shorthand : false , computed : false , key : { type : 'Identifier' , start : 31 , end : 32 , name : 'x' } , value : { type : 'Literal' , start : 34 , end : 36 , value : 10 , raw : '10' } , kind : 'init' } , { type : 'Property' , start : 38 , end : 43 , method : false , shorthand : false , computed : false , key : { type : 'Identifier' , start : 38 , end : 39 , name : 'y' } , value : { type : 'Literal' , start : 41 , end : 43 , value : 20 , raw : '20' } , kind : 'init' } , { type : 'Property' , start : 45 , end : 50 , method : false , shorthand : false , computed : false , key : { type : 'Identifier' , start : 45 , end : 46 , name : 'z' } , value : { type : 'Literal' , start : 48 , end : 50 , value : 30 , raw : '30' } , kind : 'init' } , { type : 'Property' , start : 52 , end : 57 , method : false , shorthand : false , computed : false , key : { type : 'Identifier' , start : 52 , end : 53 , name : 'w' } , value : { type : 'Literal' , start : 55 , end : 57 , value : 40 , raw : '40' } , kind : 'init' } , { type : 'Property' , start : 59 , end : 64 , method : false , shorthand : false , computed : false , key : { type : 'Identifier' , start : 59 , end : 60 , name : 'k' } , value : { type : 'Literal' , start : 62 , end : 64 , value : 50 , raw : '50' } , kind : 'init' } ] } } ] , kind : 'const' } ] , sourceType : 'module' } ; const scope = attachScopes ( ast , 'scope' ) ; expect ( scope . contains ( 'x' ) ) . toBeTruthy ( ) ; expect ( scope . contains ( 'y' ) ) . toBeFalsy ( ) ; expect ( scope . contains ( 'z' ) ) . toBeTruthy ( ) ; expect ( scope . contains ( 'rest' ) ) . toBeTruthy ( ) ; } ) ; it ( 'adds nested declarators from a deconstructed declaration' , function ( ) { const ast = { type : 'Program' , start : 0 , end : 40 , body : [ { type : 'VariableDeclaration' , start : 0 , end : 40 , declarations : [ { type : 'VariableDeclarator' , start : 4 , end : 39 , id : { type : 'ObjectPattern' , start : 4 , end : 19 , properties : [ { type : 'Property' , start : 6 , end : 17 , method : false , shorthand : false , computed : false , key : { type : 'Identifier' , start : 6 , end : 7 , name : 'a' } , value : { type : 'ObjectPattern' , start : 9 , end : 17 , properties : [ { type : 'Property' , start : 11 , end : 15 , method : false , shorthand : false , computed : false , key : { type : 'Identifier' , start : 11 , end : 12 , name : 'b' } , value : { type : 'Identifier' , start : 14 , end : 15 , name : 'c' } , kind : 'init' } ] } , kind : 'init' } ] } , init : { type : 'ObjectExpression' , start : 22 , end : 39 , properties : [ { type : 'Property' , start : 24 , end : 37 , method : false , shorthand : false , computed : false , key : { type : 'Identifier' , start : 24 , end : 25 , name : 'a' } , value : { type : 'ObjectExpression' , start : 27 , end : 37 , properties : [ { type : 'Property' , start : 29 , end : 35 , method : false , shorthand : false , computed : false , key : { type : 'Identifier' , start : 29 , end : 30 , name : 'b' } , value : { type : 'Literal' , start : 32 , end : 35 , value : 'b' , raw : "'b'" } , kind : 'init' } ] } , kind : 'init' } ] } } ] , kind : 'let' } ] , sourceType : 'module' } ; const scope = attachScopes ( ast , 'scope' ) ; expect ( scope . contains ( 'a' ) ) . toBeFalsy ( ) ; expect ( scope . contains ( 'b' ) ) . toBeFalsy ( ) ; expect ( scope . contains ( 'c' ) ) . toBeTruthy ( ) ; } ) ; it ( 'supports FunctionDeclarations without id' , function ( ) { const ast = { type : 'Program' , start : 0 , end : 33 , body : [ { type : 'ExportDefaultDeclaration' , start : 0 , end : 32 , declaration : { type : 'FunctionDeclaration' , start : 15 , end : 32 , id : null , generator : false , expression : false , async : false , params : [ ] , body : { type : 'BlockStatement' , start : 26 , end : 32 , body : [ ] } } } ] , sourceType : 'module' } ; expect ( ( ) => { attachScopes ( ast , 'scope' ) ; } ) . not . toThrow ( ) ; } ) ; it ( 'supports catch without a parameter' , function ( ) { const ast = { "type" : "Program" , "start" : 0 , "end" : 23 , "body" : [ { "type" : "TryStatement" , "start" : 0 , "end" : 23 , "block" : { "type" : "BlockStatement" , "start" : 4 , "end" : 10 , "body" : [ ] } , "handler" : { "type" : "CatchClause" , "start" : 11 , "end" : 23 , "param" : null , "body" : { "type" : "BlockStatement" , "start" : 17 , "end" : 23 , "body" : [ ] } } , "finalizer" : null } ] , "sourceType" : "script" } ; expect ( ( ) => { attachScopes ( ast , 'scope' ) ; } ) . not . toThrow ( ) ; } ) ; } ) ;