import { expect , use , assert } from 'chai' ; use ( require ( 'chai-string' ) ) ; import { before , after } from 'mocha' ; import * as vscode from 'vscode' ; import * as path from 'path' ; import * as os from 'os' ; import * as fs from 'fs' ; import { ValDownloader } from '../../validation/ValDownloader' ; import { PddlConfiguration , CONF_PDDL , VAL_STEP_PATH , VALIDATION_PATH , VALUE_SEQ_PATH , PDDL_PARSER , PARSER_EXECUTABLE_OR_SERVICE , EXECUTABLE_OR_SERVICE } from '../../configuration/configuration' ; import { createTestExtensionContext } from './testUtils' ; import { utils } from 'pddl-workspace' ; import { assertDefined } from '../../utils' ; class TestableValDownloader extends ValDownloader { constructor ( context , private shouldOverwriteDelegate ) { super ( context ) ; } protected async downloadDelegate ( _url , zipPath , _message ) { const thisExtension = assertDefined ( vscode . extensions . getExtension ( "jan-dolejsi.pddl" ) , `Extension 'jan-dolejsi.pddl' not found` ) ; const extensionPath = thisExtension . extensionPath ; const sourcePath = path . join ( extensionPath , "src" , "test" , "val-drop-mock.zip" ) ; console . log ( `Copying mock VAL drop from ${ sourcePath } to ${ zipPath }.` ) ; return await fs . promises . copyFile ( sourcePath , zipPath ) ; } protected getLatestStableValBuildId ( ) { return 58 ; } protected async shouldOverwrite ( toolName , yourConfiguredPath , newToolPath ) { return this . shouldOverwriteDelegate ( toolName , yourConfiguredPath , newToolPath ) ; } } suite ( 'VAL Download and Configuration' , ( ) => { let origValStepPath ; let origValConfiguration ; let origValueSeqPath ; let origParserPath ; before ( async ( ) => { const thisExtension = assertDefined ( vscode . extensions . getExtension ( "jan-dolejsi.pddl" ) , `Extension 'jan-dolejsi.pddl' not found` ) ; if ( ! thisExtension . isActive ) { await thisExtension . activate ( ) ; } const pddlConf = vscode . workspace . getConfiguration ( CONF_PDDL ) ; origValStepPath = pddlConf . inspect < string > ( VAL_STEP_PATH ) ?. globalValue ; origValConfiguration = pddlConf . inspect < string > ( VALIDATION_PATH ) ?. globalValue ; origValueSeqPath = pddlConf . inspect < string > ( VALUE_SEQ_PATH ) ?. globalValue ; origParserPath = vscode . workspace . getConfiguration ( PDDL_PARSER ) . inspect < string > ( PARSER_EXECUTABLE_OR_SERVICE ) ?. globalValue ; } ) ; test ( 'can configure ValStep' , async ( ) => { const conf = new PddlConfiguration ( await createTestExtensionContext ( ) ) ; const myValStepPath = 'MyValStep.exe' ; const pddlConf = vscode . workspace . getConfiguration ( CONF_PDDL ) ; await pddlConf . update ( VAL_STEP_PATH , myValStepPath , vscode . ConfigurationTarget . Global ) ; const actualValStepPath = await conf . getValStepPath ( ) ; expect ( actualValStepPath ) . to . equal ( myValStepPath ) ; } ) ; test ( 'does not overwrite custom ValStep configuration (legacy conf)' , async ( ) => { const extensionContext = await createTestExtensionContext ( ) ; const pddlConf = vscode . workspace . getConfiguration ( CONF_PDDL ) ; try { const valFolderPath = path . join ( extensionContext . globalStoragePath , 'val' ) ; await utils . afs . mkdirIfDoesNotExist ( valFolderPath , { mode : 0o777 , recursive : true } ) ; const valManifestPath = path . join ( valFolderPath , 'VAL.version' ) ; const previousValManifest = { "buildId" : 24 , "version" : "20190805.2" , "files" : [ "Val-20190805.2-win64/bin/ValStep.exe" , "Val-20190805.2-win64/bin/PinguPlan.exe" , "Val-20190805.2-win64/bin/DomainView.exe" , "Val-20190805.2-win64/bin/Analyse.exe" , "Val-20190805.2-win64/bin/TIM.exe" , "Val-20190805.2-win64/bin/libwinpthread-1.dll" , "Val-20190805.2-win64/bin/libVAL.dll" , "Val-20190805.2-win64/bin/PlanRec.exe" , "Val-20190805.2-win64/bin/Relax.exe" , "Val-20190805.2-win64/bin/Validate.exe" , "Val-20190805.2-win64/bin/ToFn.exe" , "Val-20190805.2-win64/bin/HowWhatWhen.exe" , "Val-20190805.2-win64/bin/PlanSeqStep.exe" , "Val-20190805.2-win64/bin/libgcc_s_seh-1.dll" , "Val-20190805.2-win64/bin/PlanToValStep.exe" , "Val-20190805.2-win64/bin/Instantiate.exe" , "Val-20190805.2-win64/bin/Parser.exe" , "Val-20190805.2-win64/bin/ValueSeq.exe" , "Val-20190805.2-win64/bin/libstdc++-6.dll" , "Val-20190805.2-win64/bin/TypeAnalysis.exe" , "Val-20190805.2-win64/README.md" ] , } ; await fs . promises . writeFile ( valManifestPath , JSON . stringify ( previousValManifest , null , 2 ) ) ; const myValStepPath = 'MyValStep.exe' ; await pddlConf . update ( VAL_STEP_PATH , myValStepPath , vscode . ConfigurationTarget . Global ) ; await pddlConf . update ( VALIDATION_PATH , path . join ( 'val' , 'Val-20190805.2-win64' , 'bin' , 'Validate.exe' ) , vscode . ConfigurationTarget . Global ) ; await pddlConf . update ( VALUE_SEQ_PATH , path . join ( 'val' , 'Val-20190805.2-win64' , 'bin' , 'ValueSeq.exe' ) , vscode . ConfigurationTarget . Global ) ; await vscode . workspace . getConfiguration ( PDDL_PARSER ) . update ( EXECUTABLE_OR_SERVICE , path . join ( 'val' , 'Val-20190805.2-win64' , 'bin' , 'Parser.exe' ) , vscode . ConfigurationTarget . Global ) ; const askedToOverwrite = [ ] ; const shouldOverwrite = function ( toolName , yourConfiguredPath , newToolPath ) : boolean { console . log ( `toolName: ${ toolName }, yourConfiguredPath: ${ yourConfiguredPath }, newToolPath: ${ newToolPath }` ) ; askedToOverwrite . push ( toolName ) ; return toolName !== 'ValStep' ; } ; const valDownloader = new TestableValDownloader ( extensionContext , shouldOverwrite ) ; await valDownloader . downloadConfigureAndCleanUp ( ) ; const conf = new PddlConfiguration ( extensionContext ) ; const actualValStepPath = await conf . getValStepPath ( ) ; expect ( actualValStepPath ) . to . equal ( myValStepPath ) ; const actualValueSeqPath = conf . getValueSeqPath ( ) ; expect ( actualValStepPath ) . to . not . be . undefined ; assert . startsWith ( actualValueSeqPath ! , path . join ( valFolderPath , 'Val-20190911.1-win64' ) , "value seq path" ) ; expect ( askedToOverwrite ) . to . deep . equal ( [ 'ValStep' ] ) ; const actualParserPath = conf . getParserPath ( ) ; if ( actualParserPath ?. includes ( ' ' ) && os . platform ( ) === 'darwin' ) { expect ( fs . existsSync ( actualParserPath ) ) . to . equal ( true , `Parser at ${ actualParserPath } should exist.` ) ; expect ( actualParserPath ) . to . include ( '\ ' , "spaces should be escaped by backslash" ) ; } } finally { const allStoredFiles = await utils . afs . getFiles ( extensionContext . globalStoragePath ) ; console . log ( `All files in the mocked global storage: \n` + allStoredFiles . join ( '\n' ) ) ; } } ) . timeout ( 10000 ) ; after ( async ( ) => { const pddlConf = vscode . workspace . getConfiguration ( CONF_PDDL ) ; await pddlConf . update ( VAL_STEP_PATH , origValStepPath , vscode . ConfigurationTarget . Global ) ; await pddlConf . update ( VALIDATION_PATH , origValConfiguration , vscode . ConfigurationTarget . Global ) ; await pddlConf . update ( VALUE_SEQ_PATH , origValueSeqPath , vscode . ConfigurationTarget . Global ) ; await vscode . workspace . getConfiguration ( PDDL_PARSER ) . update ( EXECUTABLE_OR_SERVICE , origParserPath , vscode . ConfigurationTarget . Global ) ; } ) ; } ) ;