import { assert } from 'chai' ; import * as exec from 'child_process' ; import * as fs from 'fs-extra' ; import * as path from 'path' ; import * as tmp from 'tmp' ; import * as Collections from 'typescript-collections' ; import * as vscode from 'vscode' ; import { ConnectionManager } from '../../main/connect/connectionManager' ; import { LogManager } from '../../main/log/logManager' ; import { ScanCacheManager } from '../../main/scanCache/scanCacheManager' ; import { ScanLogicManager } from '../../main/scanLogic/scanLogicManager' ; import { PypiTreeNode } from '../../main/treeDataProviders/dependenciesTree/dependenciesRoot/pypiTree' ; import { DependenciesTreeNode } from '../../main/treeDataProviders/dependenciesTree/dependenciesTreeNode' ; import { TreesManager } from '../../main/treeDataProviders/treesManager' ; import { GeneralInfo } from '../../main/types/generalInfo' ; import { PypiUtils } from '../../main/utils/pypiUtils' ; import { createScanCacheManager } from './utils/utils.test' ; /**
 * Test functionality of @class PypiUtils.
 */ describe ( 'Pypi Utils Tests' , ( ) => { let logManager = new LogManager ( ) . activate ( ) ; let dummyScanCacheManager = createScanCacheManager ( ) ; let treesManager = new TreesManager ( [ ] , new ConnectionManager ( logManager ) , dummyScanCacheManager , { } as ScanLogicManager , logManager ) ; let projectDirs = [ 'requirements' , 'setup' , 'setupAndRequirements' ] ; let workspaceFolders = [ ] ; let tmpDir = vscode . Uri . file ( tmp . dirSync ( { } as tmp . DirOptions ) . name ) ; before ( ( ) => { fs . copySync ( path . join ( __dirname , '..' , 'resources' , 'python' ) , tmpDir . fsPath ) ; projectDirs . forEach ( projectDir => { workspaceFolders . push ( { uri : vscode . Uri . file ( path . join ( tmpDir . fsPath , projectDir ) ) , name : '' , index : 0 } as vscode . WorkspaceFolder ) ; } ) ; createVirtualEnvironment ( ) ; } ) ; /**
     * Test PypiUtils.arePythonFilesExist.
     */ it ( 'Python files exist' , async ( ) => { for ( let workspaceFolder of workspaceFolders ) { let pythonFilesExist = await PypiUtils . arePythonFilesExist ( workspaceFolder , treesManager . logManager ) ; assert . isTrue ( pythonFilesExist , workspaceFolder . uri + ' should contain Python files' ) ; } } ) ; /**
     * Test PypiUtils.getDependenciesPos.
     */ it ( 'Get dependencies position' , async ( ) => { let setupPy = vscode . Uri . file ( path . join ( tmpDir . fsPath , 'setup' , 'setup.py' ) ) ; let textDocument = await vscode . workspace . openTextDocument ( setupPy ) ; let dependenciesPos = PypiUtils . getDependenciesPos ( textDocument ) ; assert . deepEqual ( dependenciesPos [ 0 ] , new vscode . Position ( 5 , 4 ) ) ; setupPy = vscode . Uri . file ( path . join ( tmpDir . fsPath , 'setupAndRequirements' , 'setup.py' ) ) ; textDocument = await vscode . workspace . openTextDocument ( setupPy ) ; dependenciesPos = PypiUtils . getDependenciesPos ( textDocument ) ; assert . deepEqual ( dependenciesPos [ 0 ] , new vscode . Position ( 14 , 4 ) ) ; } ) ; /**
     * Test PypiUtils.getDependencyPos.
     */ it ( 'Get dependency position' , async ( ) => { let requirements = vscode . Uri . file ( path . join ( tmpDir . fsPath , 'requirements' , 'requirements.txt' ) ) ; let textDocument = await vscode . workspace . openTextDocument ( requirements ) ; let dependenciesTreeNode = new DependenciesTreeNode ( new GeneralInfo ( 'newrelic' , '2.0.0.1' , [ ] , '' , '' ) ) ; let dependencyPos = PypiUtils . getDependencyPos ( textDocument , textDocument . getText ( ) . toLowerCase ( ) , dependenciesTreeNode ) ; assert . deepEqual ( dependencyPos [ 0 ] , new vscode . Position ( 2 , 0 ) ) ; requirements = vscode . Uri . file ( path . join ( tmpDir . fsPath , 'setupAndRequirements' , 'requirements.txt' ) ) ; textDocument = await vscode . workspace . openTextDocument ( requirements ) ; dependencyPos = PypiUtils . getDependencyPos ( textDocument , textDocument . getText ( ) . toLowerCase ( ) , dependenciesTreeNode ) ; assert . deepEqual ( dependencyPos [ 0 ] , new vscode . Position ( 2 , 0 ) ) ; } ) ; /**
     * Test refreshDependencies for python projects.
     */ it ( 'Create Pypi Dependencies Trees' , async ( ) => { let localPython = getLocalPython ( ) ; let dependenciesTreeNode = new PypiTreeNode ( workspaceFolders [ 0 ] . uri . fsPath , new Collections . Set ( ) , treesManager , path . join ( workspaceFolders [ 0 ] . uri . fsPath , localPython ) , new DependenciesTreeNode ( new GeneralInfo ( 'parent' , '1.0.0' , [ ] , '' , '' ) ) ) ; dependenciesTreeNode . refreshDependencies ( true ) ; assert . deepEqual ( dependenciesTreeNode . label , 'requirements' ) ; assert . deepEqual ( dependenciesTreeNode . children . length , 5 ) ; checkFireDependency ( dependenciesTreeNode ) ; dependenciesTreeNode = new PypiTreeNode ( workspaceFolders [ 1 ] . uri . fsPath , new Collections . Set ( ) , treesManager , path . join ( workspaceFolders [ 1 ] . uri . fsPath , localPython ) , new DependenciesTreeNode ( new GeneralInfo ( 'parent' , '1.0.0' , [ ] , '' , '' ) ) ) ; dependenciesTreeNode . refreshDependencies ( true ) ; assert . deepEqual ( dependenciesTreeNode . label , 'setup' ) ; assert . deepEqual ( dependenciesTreeNode . children . length , 3 ) ; let snake = < PypiTreeNode | undefined > dependenciesTreeNode . children . filter ( child => child . label === 'snake' ) . pop ( ) ; assert . isDefined ( snake ) ; assert . deepEqual ( snake ! . children . length , 3 ) ; checkFireDependency ( snake ! ) ; dependenciesTreeNode = new PypiTreeNode ( workspaceFolders [ 2 ] . uri . fsPath , new Collections . Set ( ) , treesManager , path . join ( workspaceFolders [ 2 ] . uri . fsPath , localPython ) , new DependenciesTreeNode ( new GeneralInfo ( 'parent' , '1.0.0' , [ ] , '' , '' ) ) ) ; dependenciesTreeNode . refreshDependencies ( true ) ; assert . deepEqual ( dependenciesTreeNode . label , 'setupAndRequirements' ) ; assert . deepEqual ( dependenciesTreeNode . children . length , 3 ) ; snake = < PypiTreeNode | undefined > dependenciesTreeNode . children . filter ( child => child . label === 'snake' ) . pop ( ) ; assert . isDefined ( snake ) ; assert . deepEqual ( snake ! . children . length , 3 ) ; checkFireDependency ( snake ! ) ; } ) ; function checkFireDependency ( dependenciesTreeNode ) { let fire = dependenciesTreeNode . children . filter ( child => child . label === 'fire' ) . pop ( ) ; assert . isDefined ( fire ) ; assert . deepEqual ( fire ! . generalInfo . artifactId , 'fire' ) ; assert . deepEqual ( fire ! . generalInfo . version , '0.1.3' ) ; assert . deepEqual ( fire ! . children . length , 1 ) ; } function createVirtualEnvironment ( ) { let globalPython = getGlobalPython ( ) ; let localPython = getLocalPython ( ) ; exec . execSync ( globalPython + ' -m venv .venv' , { cwd : workspaceFolders [ 0 ] . uri . fsPath } ) ; exec . execSync ( localPython + ' -m pip install -r requirements.txt' , { cwd : workspaceFolders [ 0 ] . uri . fsPath } ) ; exec . execSync ( globalPython + ' -m venv .venv' , { cwd : workspaceFolders [ 1 ] . uri . fsPath } ) ; exec . execSync ( localPython + ' -m pip install .' , { cwd : workspaceFolders [ 1 ] . uri . fsPath } ) ; exec . execSync ( globalPython + ' -m venv .venv' , { cwd : workspaceFolders [ 2 ] . uri . fsPath } ) ; exec . execSync ( localPython + ' -m pip install .' , { cwd : workspaceFolders [ 2 ] . uri . fsPath } ) ; } function getGlobalPython ( ) { return process . platform . startsWith ( 'win' ) ? 'py -3' : 'python3' ; } function getLocalPython ( ) { if ( process . platform . startsWith ( 'win' ) ) { return path . join ( '.venv' , 'Scripts' , 'python.exe' ) ; } return path . join ( '.venv' , 'bin' , 'python' ) ; } } ) ;