import { assert } from 'chai' ; import * as exec from 'child_process' ; import { ComponentDetails } from 'jfrog-client-js' ; import { before } from 'mocha' ; import * as path from 'path' ; import * as Collections from 'typescript-collections' ; import * as vscode from 'vscode' ; import { ConnectionManager } from '../../main/connect/connectionManager' ; import { NpmDependencyUpdate } from '../../main/dependencyUpdate/npmDependencyUpdate' ; import { FocusType } from '../../main/focus/abstractFocus' ; import { LogManager } from '../../main/log/logManager' ; import { ScanCacheManager } from '../../main/scanCache/scanCacheManager' ; import { ScanLogicManager } from '../../main/scanLogic/scanLogicManager' ; import { NpmTreeNode } from '../../main/treeDataProviders/dependenciesTree/dependenciesRoot/npmTree' ; import { DependenciesTreeNode } from '../../main/treeDataProviders/dependenciesTree/dependenciesTreeNode' ; import { TreesManager } from '../../main/treeDataProviders/treesManager' ; import { GeneralInfo } from '../../main/types/generalInfo' ; import { NpmUtils } from '../../main/utils/npmUtils' ; import { PackageDescriptorType , ScanUtils } from '../../main/utils/scanUtils' ; import { createScanCacheManager , getNodeByArtifactId } from './utils/utils.test' ; /**
 * Test functionality of @class NpmUtils.
 */ describe ( 'Npm Utils Tests' , ( ) => { let logManager = new LogManager ( ) . activate ( ) ; let dummyScanCacheManager = createScanCacheManager ( ) ; let treesManager = new TreesManager ( [ ] , new ConnectionManager ( logManager ) , dummyScanCacheManager , { } as ScanLogicManager , logManager ) ; let projectDirs = [ 'dependency' , 'dependencyPackageLock' , 'empty' ] ; let npmDependencyUpdate = new NpmDependencyUpdate ( ) ; let workspaceFolders ; let tmpDir = vscode . Uri . file ( path . join ( __dirname , '..' , 'resources' , 'npm' ) ) ; before ( ( ) => { workspaceFolders = [ { uri : tmpDir , name : '' , index : 0 } as vscode . WorkspaceFolder ] ; } ) ; /**
     * Test NpmUtils.locatePackageJsons.
     */ it ( 'Locate package jsons' , async ( ) => { let packageDescriptors = await ScanUtils . locatePackageDescriptors ( workspaceFolders , treesManager . logManager ) ; let packageJsons = packageDescriptors . get ( PackageDescriptorType . NPM ) ; assert . isDefined ( packageJsons ) ; assert . strictEqual ( packageJsons ?. length , projectDirs . length ) ; for ( let expectedProjectDir of projectDirs ) { let expectedPackageJson = path . join ( tmpDir . fsPath , expectedProjectDir , 'package.json' ) ; assert . isDefined ( packageJsons ?. find ( packageJsons => packageJsons . fsPath === expectedPackageJson ) , 'Should contain ' + expectedPackageJson ) ; } } ) ; /**
     * Test NpmUtils.getDependenciesPos.
     */ it ( 'Get dependencies position' , async ( ) => { let packageJson = vscode . Uri . file ( path . join ( tmpDir . fsPath , 'dependency' , 'package.json' ) ) ; let textDocument = await vscode . workspace . openTextDocument ( packageJson ) ; let dependenciesPos = NpmUtils . getDependenciesPos ( textDocument ) ; assert . deepEqual ( dependenciesPos [ 0 ] , new vscode . Position ( 7 , 2 ) ) ; packageJson = vscode . Uri . file ( path . join ( tmpDir . fsPath , 'dependencyPackageLock' , 'package.json' ) ) ; textDocument = await vscode . workspace . openTextDocument ( packageJson ) ; dependenciesPos = NpmUtils . getDependenciesPos ( textDocument ) ; assert . deepEqual ( dependenciesPos [ 0 ] , new vscode . Position ( 7 , 2 ) ) ; packageJson = vscode . Uri . file ( path . join ( tmpDir . fsPath , 'empty' , 'package.json' ) ) ; textDocument = await vscode . workspace . openTextDocument ( packageJson ) ; dependenciesPos = NpmUtils . getDependenciesPos ( textDocument ) ; assert . isEmpty ( dependenciesPos ) ; } ) ; /**
     * Test NpmUtils.getDependencyPos.
     */ it ( 'Get dependency position' , async ( ) => { let packageJson = vscode . Uri . file ( path . join ( tmpDir . fsPath , 'dependency' , 'package.json' ) ) ; let textDocument = await vscode . workspace . openTextDocument ( packageJson ) ; let dependenciesTreeNode = new DependenciesTreeNode ( new GeneralInfo ( '@types/node' , '14.14.10' , [ ] , '' , '' ) ) ; let dependencyPos = NpmUtils . getDependencyPos ( textDocument , dependenciesTreeNode , FocusType . Dependency ) ; assert . deepEqual ( dependencyPos [ 0 ] , new vscode . Position ( 13 , 4 ) ) ; assert . deepEqual ( dependencyPos [ 1 ] , new vscode . Position ( 13 , 29 ) ) ; dependenciesTreeNode = new DependenciesTreeNode ( new GeneralInfo ( '@ungap/promise-all-settled' , '1.1.2' , [ ] , '' , '' ) ) ; dependencyPos = NpmUtils . getDependencyPos ( textDocument , dependenciesTreeNode , FocusType . Dependency ) ; assert . deepEqual ( dependencyPos [ 0 ] , new vscode . Position ( 9 , 4 ) ) ; assert . deepEqual ( dependencyPos [ 1 ] , new vscode . Position ( 9 , 41 ) ) ; dependenciesTreeNode = new DependenciesTreeNode ( new GeneralInfo ( 'has-flag' , '3.0.0' , [ ] , '' , '' ) ) ; dependencyPos = NpmUtils . getDependencyPos ( textDocument , dependenciesTreeNode , FocusType . Dependency ) ; assert . deepEqual ( dependencyPos [ 0 ] , new vscode . Position ( 8 , 4 ) ) ; assert . deepEqual ( dependencyPos [ 1 ] , new vscode . Position ( 8 , 23 ) ) ; dependenciesTreeNode = new DependenciesTreeNode ( new GeneralInfo ( 'progress' , '2.0.3' , [ ] , '' , '' ) ) ; dependencyPos = NpmUtils . getDependencyPos ( textDocument , dependenciesTreeNode , FocusType . Dependency ) ; assert . deepEqual ( dependencyPos [ 0 ] , new vscode . Position ( 12 , 4 ) ) ; assert . deepEqual ( dependencyPos [ 1 ] , new vscode . Position ( 12 , 23 ) ) ; packageJson = vscode . Uri . file ( path . join ( tmpDir . fsPath , 'dependencyPackageLock' , 'package.json' ) ) ; textDocument = await vscode . workspace . openTextDocument ( packageJson ) ; dependencyPos = NpmUtils . getDependencyPos ( textDocument , dependenciesTreeNode , FocusType . Dependency ) ; assert . deepEqual ( dependencyPos [ 0 ] , new vscode . Position ( 8 , 4 ) ) ; assert . deepEqual ( dependencyPos [ 1 ] , new vscode . Position ( 8 , 23 ) ) ; packageJson = vscode . Uri . file ( path . join ( tmpDir . fsPath , 'empty' , 'package.json' ) ) ; textDocument = await vscode . workspace . openTextDocument ( packageJson ) ; dependencyPos = NpmUtils . getDependencyPos ( textDocument , dependenciesTreeNode , FocusType . Dependency ) ; assert . isEmpty ( dependencyPos ) ; } ) ; /**
     * Test NpmUtils.createNpmDependenciesTrees for not installed npm projects.
     */ it ( 'Create npm Dependencies Trees before installation' , async ( ) => { let res = await runCreateNpmDependenciesTrees ( new Collections . Set ( ) , new DependenciesTreeNode ( new GeneralInfo ( 'parent' , '1.0.0' , [ ] , '' , '' ) ) ) ; assert . deepEqual ( res [ 0 ] . label , 'package-name1' ) ; assert . deepEqual ( res [ 1 ] . label , 'package-name2 [Not installed]' ) ; assert . deepEqual ( res [ 2 ] . label , 'package-name3 [Not installed]' ) ; assert . deepEqual ( res [ 0 ] . description , '0.0.1' ) ; assert . deepEqual ( res [ 1 ] . description , '0.0.1' ) ; assert . deepEqual ( res [ 2 ] . description , '0.0.1' ) ; } ) ; it ( 'Update fixed version' , async ( ) => { installAllProjects ( ) ; let parent = new DependenciesTreeNode ( new GeneralInfo ( 'parent' , '1.0.0' , [ ] , '' , '' ) ) ; let componentsToScan = new Collections . Set ( ) ; let res = await runCreateNpmDependenciesTrees ( componentsToScan , parent ) ; let dependencyProject = res . find ( node => node instanceof NpmTreeNode && node . workspaceFolder . endsWith ( 'dependency' ) ) ; assert . isNotNull ( dependencyProject ) ; let node = getNodeByArtifactId ( dependencyProject ! , 'progress' ) ; assert . isNotNull ( node ) ; assert . equal ( node ?. generalInfo . version , '2.0.3' ) ; npmDependencyUpdate . updateDependencyVersion ( node ! , '2.0.2' ) ; res = await runCreateNpmDependenciesTrees ( componentsToScan , parent ) ; dependencyProject = res . find ( node => node instanceof NpmTreeNode && node . workspaceFolder . endsWith ( 'dependency' ) ) ; assert . isNotNull ( dependencyProject ) ; node = getNodeByArtifactId ( dependencyProject ! , 'progress' ) ; assert . isNotNull ( node ) ; assert . equal ( node ?. generalInfo . version , '2.0.2' ) ; npmDependencyUpdate . updateDependencyVersion ( node ! , '2.0.3' ) ; res = await runCreateNpmDependenciesTrees ( componentsToScan , parent ) ; dependencyProject = res . find ( node => node instanceof NpmTreeNode && node . workspaceFolder . endsWith ( 'dependency' ) ) ; assert . isNotNull ( dependencyProject ) ; node = getNodeByArtifactId ( dependencyProject ! , 'progress' ) ; assert . isNotNull ( node ) ; assert . equal ( node ?. generalInfo . version , '2.0.3' ) ; } ) ; /**
     * Test NpmUtils.createNpmDependenciesTrees.
     */ it ( 'Create npm Dependencies Trees' , async ( ) => { installAllProjects ( ) ; let parent = new DependenciesTreeNode ( new GeneralInfo ( 'parent' , '1.0.0' , [ ] , '' , '' ) ) ; let componentsToScan = new Collections . Set ( ) ; let res = await runCreateNpmDependenciesTrees ( componentsToScan , parent ) ; assert . isTrue ( componentsToScan . size ( ) === 4 ) ; let component = componentsToScan . toArray ( ) . find ( component => component . component_id === 'npm://progress:2.0.3' ) ; assert . deepEqual ( component , new ComponentDetails ( 'npm://progress:2.0.3' ) ) ; assert . deepEqual ( res [ 0 ] . label , 'package-name1' ) ; assert . deepEqual ( res [ 1 ] . label , 'package-name2' ) ; assert . deepEqual ( res [ 2 ] . label , 'package-name3' ) ; assert . deepEqual ( res [ 0 ] . parent , parent ) ; assert . deepEqual ( res [ 1 ] . parent , parent ) ; assert . deepEqual ( res [ 2 ] . parent , parent ) ; assert . lengthOf ( res [ 1 ] . children , 4 ) ; assert . lengthOf ( res [ 2 ] . children , 1 ) ; let child = res [ 1 ] . children . find ( component => component . label === 'progress' ) ; assert . deepEqual ( child ?. label , res [ 2 ] . children [ 0 ] . label ) ; assert . deepEqual ( child ?. componentId , 'progress:2.0.3' ) ; assert . deepEqual ( child ?. description , '2.0.3' ) ; assert . deepEqual ( child ?. generalInfo . scopes , [ 'prod' ] ) ; assert . deepEqual ( child ?. parent , res [ 1 ] ) ; child = res [ 1 ] . children . find ( component => component . label === 'has-flag' ) ; assert . deepEqual ( child ?. componentId , 'has-flag:3.0.0' ) ; assert . deepEqual ( child ?. description , '3.0.0' ) ; assert . deepEqual ( child ?. generalInfo . scopes , [ 'dev' ] ) ; assert . deepEqual ( child ?. parent , res [ 1 ] ) ; child = res [ 1 ] . children . find ( component => component . label === '@types/node' ) ; assert . deepEqual ( child ?. componentId , '@types/node:14.14.10' ) ; assert . deepEqual ( child ?. description , '14.14.10' ) ; assert . deepEqual ( child ?. generalInfo . scopes , [ 'prod' , 'types' ] ) ; assert . deepEqual ( child ?. parent , res [ 1 ] ) ; child = res [ 1 ] . children . find ( component => component . label === '@ungap/promise-all-settled' ) ; assert . deepEqual ( child ?. componentId , '@ungap/promise-all-settled:1.1.2' ) ; assert . deepEqual ( child ?. description , '1.1.2' ) ; assert . deepEqual ( child ?. generalInfo . scopes , [ 'dev' , 'ungap' ] ) ; assert . deepEqual ( child ?. parent , res [ 1 ] ) ; } ) ; async function runCreateNpmDependenciesTrees ( componentsToScan , parent ) { let packageDescriptors = await ScanUtils . locatePackageDescriptors ( workspaceFolders , treesManager . logManager ) ; let packageJsons = packageDescriptors . get ( PackageDescriptorType . NPM ) ; assert . isDefined ( packageJsons ) ; await NpmUtils . createDependenciesTrees ( packageJsons , componentsToScan , treesManager , parent , false ) ; return parent . children . sort ( ( lhs , rhs ) => ( < string > lhs . label ) . localeCompare ( < string > rhs . label ) ) ; } function installAllProjects ( ) { for ( let expectedProjectDir of projectDirs ) { exec . execSync ( 'npm i' , { cwd : path . join ( tmpDir . fsPath , expectedProjectDir ) } ) ; } } } ) ;