import * as assert from 'assert' ; import { IPackageLintOptions } from '../..' ; interface IMenu { command : string ; when ? : string ; group ? : string ; } interface IPackage { name ? : string ; activationEvents ? : string [ ] ; contributes ? : { views ? : { [ viewContainerName ] : { id : string ; name : string ; when ? : string ; } [ ] ; } ; commands ? : { command : string ; } [ ] ; menus ? : { 'view/title' : IMenu [ ] ; 'explorer/context' : IMenu [ ] ; 'view/item/context' : IMenu [ ] ; commandPalette : { command : string ; when ? : string ; } [ ] ; } ; } ; } function emptyIfUndefined < T extends { } > ( value ) { return value || < T > { } ; } param packageJson export function addPackageLintSuites ( getExtensionContext , getCommands , packageJsonAsObject , options ) { const packageJson = < IPackage > packageJsonAsObject ; const commandsRegisteredButNotInPackage = options . commandsRegisteredButNotInPackage || [ ] ; let _registeredCommands ; async function getRegisteredCommands ( ) { if ( ! _registeredCommands ) { assert ( ! ! < { } | undefined > getExtensionContext ( ) , 'The extension must be activated before any tests are run, otherwise its commands won\'t have been registered yet' ) ; const registeredCommands = await getCommands ( ) ; const predefinedCommandIds = getPredefinedCommandIdsForExtension ( ) ; _registeredCommands = registeredCommands . filter ( ( cmdId ) => ! predefinedCommandIds . some ( ( c ) => c === cmdId ) ) ; } return _registeredCommands ; } const activationEvents = emptyIfUndefined ( packageJson . activationEvents ) ; const contributes = emptyIfUndefined ( packageJson . contributes ) ; const views = emptyIfUndefined ( contributes . views ) ; const commands = emptyIfUndefined ( contributes . commands ) ; const extensionPrefixWithPeriod = commands [ 0 ] . command . substr ( 0 , commands [ 0 ] . command . indexOf ( '.' ) + 1 ) ; function verifyStartsWithExtensionPrefix ( name ) { assert ( name . startsWith ( extensionPrefixWithPeriod ) , `Expected ${ name } to start with ${ extensionPrefixWithPeriod }` ) ; } function getPredefinedCommandIdsForExtension ( ) { const predefinedIds = [ ] ; for ( const viewContainerName of Object . keys ( views ) ) { const viewContainer = views [ viewContainerName ] ; for ( const view of viewContainer ) { predefinedIds . push ( `${ view . id }.focus` ) ; } } return predefinedIds ; } suite ( 'Activation events for views' , ( ) => { for ( const viewContainerName of Object . keys ( views ) ) { const viewContainer = views [ viewContainerName ] ; for ( const view of viewContainer ) { const activationEvent = `onView:${ view . id }` ; test ( view . id , ( ) => { assert ( activationEvents . some ( ( evt ) => evt === activationEvent ) , `Couldn't find activation event ${ activationEvent }` ) ; } ) ; } } } ) ; suite ( 'Activation events for commands in package.json' , ( ) => { for ( const cmd of commands ) { const cmdId = cmd . command ; const activationEvent = `onCommand:${ cmdId }` ; test ( cmdId , async ( ) => { verifyStartsWithExtensionPrefix ( cmdId ) ; const registeredCommands = await getRegisteredCommands ( ) ; assert ( registeredCommands . some ( ( c ) => c === cmdId ) , `${ cmdId } is in package.json but wasn't registered with vscode` ) ; assert ( activationEvents . some ( ( evt ) => evt === activationEvent ) , `Couldn't find activation event for command ${ cmdId }` ) ; } ) ; } for ( const event of activationEvents ) { const onCommand = 'onCommand:' ; if ( event . startsWith ( 'onCommand' ) ) { const cmdId = event . substr ( onCommand . length ) ; test ( event , async ( ) => { const registeredCommands = await getRegisteredCommands ( ) ; assert ( registeredCommands . some ( ( c ) => c === cmdId ) , `${ event } is in package.json but ${ cmdId } wasn't registered with vscode` ) ; assert ( commands . some ( cmd => cmd . command === cmdId ) , `${ event } is in package.json but ${ cmdId } wasn't a command in package.json` ) ; } ) ; } } } ) ; test ( 'Activation events for commands registered with vscode' , async ( ) => { const registeredCommands = await getRegisteredCommands ( ) ; for ( const cmd of registeredCommands ) { const cmdId = cmd ; const activationEvent = `onCommand:${ cmdId }` ; if ( cmdId . startsWith ( extensionPrefixWithPeriod ) ) { const isInPackage = commands . some ( c => c . command === cmdId ) ; if ( commandsRegisteredButNotInPackage . some ( ( c ) => c === cmdId ) ) { assert ( ! isInPackage , `${ cmdId } is in commandsRegisteredButNotInPackage but was found in package.json` ) ; assert ( ! activationEvents . some ( ( evt ) => evt === activationEvent ) , `${ cmdId } is in commandsRegisteredButNotInPackage but has an activation event` ) ; } else { assert ( isInPackage , `${ cmdId } was registered as a command during extension activation but is not in package.json` ) ; assert ( activationEvents . some ( ( evt ) => evt === activationEvent ) , `Couldn't find activation event for registered command ${ cmdId }` ) ; } } } } ) ; }