2017-09-29 02:18:56 +03:00
const path = require ( 'path' )
2017-10-03 23:20:48 +03:00
const url = require ( 'url' )
2017-09-29 02:18:56 +03:00
const Package = require ( '../src/package' )
const PackageManager = require ( '../src/package-manager' )
const temp = require ( 'temp' ) . track ( )
const fs = require ( 'fs-plus' )
const { Disposable } = require ( 'atom' )
const { buildKeydownEvent } = require ( '../src/keymap-extensions' )
const { mockLocalStorage } = require ( './spec-helper' )
const ModuleCache = require ( '../src/module-cache' )
2017-09-29 03:04:46 +03:00
const { it , fit , ffit , beforeEach , afterEach } = require ( './async-spec-helpers' )
2017-09-29 02:18:56 +03:00
describe ( 'PackageManager' , ( ) => {
function createTestElement ( className ) {
const element = document . createElement ( 'div' )
element . className = className
return element
}
beforeEach ( ( ) => {
spyOn ( ModuleCache , 'add' )
} )
describe ( 'initialize' , ( ) => {
it ( 'adds regular package path' , ( ) => {
const packageManger = new PackageManager ( { } )
const configDirPath = path . join ( '~' , 'someConfig' )
packageManger . initialize ( { configDirPath } )
expect ( packageManger . packageDirPaths . length ) . toBe ( 1 )
expect ( packageManger . packageDirPaths [ 0 ] ) . toBe ( path . join ( configDirPath , 'packages' ) )
} )
it ( 'adds regular package path and dev package path in dev mode' , ( ) => {
const packageManger = new PackageManager ( { } )
const configDirPath = path . join ( '~' , 'someConfig' )
packageManger . initialize ( { configDirPath , devMode : true } )
expect ( packageManger . packageDirPaths . length ) . toBe ( 2 )
expect ( packageManger . packageDirPaths ) . toContain ( path . join ( configDirPath , 'packages' ) )
expect ( packageManger . packageDirPaths ) . toContain ( path . join ( configDirPath , 'dev' , 'packages' ) )
} )
} )
describe ( '::getApmPath()' , ( ) => {
it ( 'returns the path to the apm command' , ( ) => {
let apmPath = path . join ( process . resourcesPath , 'app' , 'apm' , 'bin' , 'apm' )
if ( process . platform === 'win32' ) {
apmPath += '.cmd'
}
expect ( atom . packages . getApmPath ( ) ) . toBe ( apmPath )
} )
describe ( 'when the core.apmPath setting is set' , ( ) => {
beforeEach ( ( ) => atom . config . set ( 'core.apmPath' , '/path/to/apm' ) )
2017-09-29 03:09:55 +03:00
it ( 'returns the value of the core.apmPath config setting' , ( ) => {
expect ( atom . packages . getApmPath ( ) ) . toBe ( '/path/to/apm' )
} )
2017-09-29 02:18:56 +03:00
} )
} )
describe ( '::loadPackages()' , ( ) => {
beforeEach ( ( ) => spyOn ( atom . packages , 'loadAvailablePackage' ) )
2017-09-29 03:04:46 +03:00
afterEach ( async ( ) => {
await atom . packages . deactivatePackages ( )
atom . packages . unloadPackages ( )
2017-09-29 02:18:56 +03:00
} )
it ( 'sets hasLoadedInitialPackages' , ( ) => {
expect ( atom . packages . hasLoadedInitialPackages ( ) ) . toBe ( false )
atom . packages . loadPackages ( )
expect ( atom . packages . hasLoadedInitialPackages ( ) ) . toBe ( true )
} )
} )
describe ( '::loadPackage(name)' , ( ) => {
beforeEach ( ( ) => atom . config . set ( 'core.disabledPackages' , [ ] ) )
it ( 'returns the package' , ( ) => {
const pack = atom . packages . loadPackage ( 'package-with-index' )
expect ( pack instanceof Package ) . toBe ( true )
expect ( pack . metadata . name ) . toBe ( 'package-with-index' )
} )
it ( 'returns the package if it has an invalid keymap' , ( ) => {
spyOn ( atom , 'inSpecMode' ) . andReturn ( false )
const pack = atom . packages . loadPackage ( 'package-with-broken-keymap' )
expect ( pack instanceof Package ) . toBe ( true )
expect ( pack . metadata . name ) . toBe ( 'package-with-broken-keymap' )
} )
it ( 'returns the package if it has an invalid stylesheet' , ( ) => {
spyOn ( atom , 'inSpecMode' ) . andReturn ( false )
const pack = atom . packages . loadPackage ( 'package-with-invalid-styles' )
expect ( pack instanceof Package ) . toBe ( true )
expect ( pack . metadata . name ) . toBe ( 'package-with-invalid-styles' )
expect ( pack . stylesheets . length ) . toBe ( 0 )
const addErrorHandler = jasmine . createSpy ( )
atom . notifications . onDidAddNotification ( addErrorHandler )
expect ( ( ) => pack . reloadStylesheets ( ) ) . not . toThrow ( )
expect ( addErrorHandler . callCount ) . toBe ( 2 )
expect ( addErrorHandler . argsForCall [ 1 ] [ 0 ] . message ) . toContain ( 'Failed to reload the package-with-invalid-styles package stylesheets' )
expect ( addErrorHandler . argsForCall [ 1 ] [ 0 ] . options . packageName ) . toEqual ( 'package-with-invalid-styles' )
} )
it ( 'returns null if the package has an invalid package.json' , ( ) => {
spyOn ( atom , 'inSpecMode' ) . andReturn ( false )
const addErrorHandler = jasmine . createSpy ( )
atom . notifications . onDidAddNotification ( addErrorHandler )
expect ( atom . packages . loadPackage ( 'package-with-broken-package-json' ) ) . toBeNull ( )
expect ( addErrorHandler . callCount ) . toBe ( 1 )
expect ( addErrorHandler . argsForCall [ 0 ] [ 0 ] . message ) . toContain ( 'Failed to load the package-with-broken-package-json package' )
expect ( addErrorHandler . argsForCall [ 0 ] [ 0 ] . options . packageName ) . toEqual ( 'package-with-broken-package-json' )
} )
2017-09-29 03:09:55 +03:00
it ( 'returns null if the package name or path starts with a dot' , ( ) => {
expect ( atom . packages . loadPackage ( '/Users/user/.atom/packages/.git' ) ) . toBeNull ( )
} )
2017-09-29 02:18:56 +03:00
it ( 'normalizes short repository urls in package.json' , ( ) => {
let { metadata } = atom . packages . loadPackage ( 'package-with-short-url-package-json' )
expect ( metadata . repository . type ) . toBe ( 'git' )
expect ( metadata . repository . url ) . toBe ( 'https://github.com/example/repo' ) ;
( { metadata } = atom . packages . loadPackage ( 'package-with-invalid-url-package-json' ) )
expect ( metadata . repository . type ) . toBe ( 'git' )
expect ( metadata . repository . url ) . toBe ( 'foo' )
} )
it ( 'trims git+ from the beginning and .git from the end of repository URLs, even if npm already normalized them ' , ( ) => {
const { metadata } = atom . packages . loadPackage ( 'package-with-prefixed-and-suffixed-repo-url' )
expect ( metadata . repository . type ) . toBe ( 'git' )
expect ( metadata . repository . url ) . toBe ( 'https://github.com/example/repo' )
} )
it ( 'returns null if the package is not found in any package directory' , ( ) => {
spyOn ( console , 'warn' )
expect ( atom . packages . loadPackage ( 'this-package-cannot-be-found' ) ) . toBeNull ( )
expect ( console . warn . callCount ) . toBe ( 1 )
expect ( console . warn . argsForCall [ 0 ] [ 0 ] ) . toContain ( 'Could not resolve' )
} )
describe ( 'when the package is deprecated' , ( ) => {
it ( 'returns null' , ( ) => {
spyOn ( console , 'warn' )
expect ( atom . packages . loadPackage ( path . join ( _ _dirname , 'fixtures' , 'packages' , 'wordcount' ) ) ) . toBeNull ( )
expect ( atom . packages . isDeprecatedPackage ( 'wordcount' , '2.1.9' ) ) . toBe ( true )
expect ( atom . packages . isDeprecatedPackage ( 'wordcount' , '2.2.0' ) ) . toBe ( true )
expect ( atom . packages . isDeprecatedPackage ( 'wordcount' , '2.2.1' ) ) . toBe ( false )
expect ( atom . packages . getDeprecatedPackageMetadata ( 'wordcount' ) . version ) . toBe ( '<=2.2.0' )
} )
} )
it ( 'invokes ::onDidLoadPackage listeners with the loaded package' , ( ) => {
let loadedPackage = null
atom . packages . onDidLoadPackage ( pack => {
loadedPackage = pack
} )
atom . packages . loadPackage ( 'package-with-main' )
expect ( loadedPackage . name ) . toBe ( 'package-with-main' )
} )
it ( "registers any deserializers specified in the package's package.json" , ( ) => {
atom . packages . loadPackage ( 'package-with-deserializers' )
const state1 = { deserializer : 'Deserializer1' , a : 'b' }
expect ( atom . deserializers . deserialize ( state1 ) ) . toEqual ( {
wasDeserializedBy : 'deserializeMethod1' ,
state : state1
} )
const state2 = { deserializer : 'Deserializer2' , c : 'd' }
expect ( atom . deserializers . deserialize ( state2 ) ) . toEqual ( {
wasDeserializedBy : 'deserializeMethod2' ,
state : state2
} )
} )
it ( 'early-activates any atom.directory-provider or atom.repository-provider services that the package provide' , ( ) => {
jasmine . useRealClock ( )
const providers = [ ]
atom . packages . serviceHub . consume ( 'atom.directory-provider' , '^0.1.0' , provider => providers . push ( provider ) )
atom . packages . loadPackage ( 'package-with-directory-provider' )
expect ( providers . map ( p => p . name ) ) . toEqual ( [ 'directory provider from package-with-directory-provider' ] )
} )
describe ( "when there are view providers specified in the package's package.json" , ( ) => {
const model1 = { worksWithViewProvider1 : true }
const model2 = { worksWithViewProvider2 : true }
2017-09-29 03:04:46 +03:00
afterEach ( async ( ) => {
await atom . packages . deactivatePackage ( 'package-with-view-providers' )
atom . packages . unloadPackage ( 'package-with-view-providers' )
2017-09-29 02:18:56 +03:00
} )
it ( 'does not load the view providers immediately' , ( ) => {
const pack = atom . packages . loadPackage ( 'package-with-view-providers' )
expect ( pack . mainModule ) . toBeNull ( )
expect ( ( ) => atom . views . getView ( model1 ) ) . toThrow ( )
expect ( ( ) => atom . views . getView ( model2 ) ) . toThrow ( )
} )
2017-09-29 03:04:46 +03:00
it ( 'registers the view providers when the package is activated' , async ( ) => {
2017-09-29 02:18:56 +03:00
atom . packages . loadPackage ( 'package-with-view-providers' )
2017-09-29 03:04:46 +03:00
await atom . packages . activatePackage ( 'package-with-view-providers' )
2017-09-29 02:18:56 +03:00
2017-09-29 03:04:46 +03:00
const element1 = atom . views . getView ( model1 )
expect ( element1 instanceof HTMLDivElement ) . toBe ( true )
expect ( element1 . dataset . createdBy ) . toBe ( 'view-provider-1' )
const element2 = atom . views . getView ( model2 )
expect ( element2 instanceof HTMLDivElement ) . toBe ( true )
expect ( element2 . dataset . createdBy ) . toBe ( 'view-provider-2' )
2017-09-29 02:18:56 +03:00
} )
it ( "registers the view providers when any of the package's deserializers are used" , ( ) => {
atom . packages . loadPackage ( 'package-with-view-providers' )
spyOn ( atom . views , 'addViewProvider' ) . andCallThrough ( )
atom . deserializers . deserialize ( {
deserializer : 'DeserializerFromPackageWithViewProviders' ,
a : 'b'
} )
expect ( atom . views . addViewProvider . callCount ) . toBe ( 2 )
atom . deserializers . deserialize ( {
deserializer : 'DeserializerFromPackageWithViewProviders' ,
a : 'b'
} )
expect ( atom . views . addViewProvider . callCount ) . toBe ( 2 )
const element1 = atom . views . getView ( model1 )
expect ( element1 instanceof HTMLDivElement ) . toBe ( true )
expect ( element1 . dataset . createdBy ) . toBe ( 'view-provider-1' )
const element2 = atom . views . getView ( model2 )
expect ( element2 instanceof HTMLDivElement ) . toBe ( true )
expect ( element2 . dataset . createdBy ) . toBe ( 'view-provider-2' )
} )
} )
it ( "registers the config schema in the package's metadata, if present" , ( ) => {
let pack = atom . packages . loadPackage ( 'package-with-json-config-schema' )
expect ( atom . config . getSchema ( 'package-with-json-config-schema' ) ) . toEqual ( {
type : 'object' ,
properties : {
a : { type : 'number' , default : 5 } ,
b : { type : 'string' , default : 'five' }
}
} )
expect ( pack . mainModule ) . toBeNull ( )
atom . packages . unloadPackage ( 'package-with-json-config-schema' )
atom . config . clear ( )
pack = atom . packages . loadPackage ( 'package-with-json-config-schema' )
expect ( atom . config . getSchema ( 'package-with-json-config-schema' ) ) . toEqual ( {
type : 'object' ,
properties : {
a : { type : 'number' , default : 5 } ,
b : { type : 'string' , default : 'five' }
}
} )
} )
describe ( 'when a package does not have deserializers, view providers or a config schema in its package.json' , ( ) => {
beforeEach ( ( ) => mockLocalStorage ( ) )
it ( "defers loading the package's main module if the package previously used no Atom APIs when its main module was required" , ( ) => {
const pack1 = atom . packages . loadPackage ( 'package-with-main' )
expect ( pack1 . mainModule ) . toBeDefined ( )
atom . packages . unloadPackage ( 'package-with-main' )
const pack2 = atom . packages . loadPackage ( 'package-with-main' )
expect ( pack2 . mainModule ) . toBeNull ( )
} )
it ( "does not defer loading the package's main module if the package previously used Atom APIs when its main module was required" , ( ) => {
const pack1 = atom . packages . loadPackage ( 'package-with-eval-time-api-calls' )
expect ( pack1 . mainModule ) . toBeDefined ( )
atom . packages . unloadPackage ( 'package-with-eval-time-api-calls' )
const pack2 = atom . packages . loadPackage ( 'package-with-eval-time-api-calls' )
expect ( pack2 . mainModule ) . not . toBeNull ( )
} )
} )
} )
describe ( '::loadAvailablePackage(availablePackage)' , ( ) => {
describe ( 'if the package was preloaded' , ( ) => {
it ( 'adds the package path to the module cache' , ( ) => {
const availablePackage = atom . packages . getAvailablePackages ( ) . find ( p => p . name === 'spell-check' )
availablePackage . isBundled = true
expect ( atom . packages . preloadedPackages [ availablePackage . name ] ) . toBeUndefined ( )
expect ( atom . packages . isPackageLoaded ( availablePackage . name ) ) . toBe ( false )
const metadata = atom . packages . loadPackageMetadata ( availablePackage )
atom . packages . preloadPackage (
availablePackage . name ,
{
rootDirPath : path . relative ( atom . packages . resourcePath , availablePackage . path ) ,
metadata
}
)
atom . packages . loadAvailablePackage ( availablePackage )
expect ( atom . packages . isPackageLoaded ( availablePackage . name ) ) . toBe ( true )
expect ( ModuleCache . add ) . toHaveBeenCalledWith ( availablePackage . path , metadata )
} )
it ( 'deactivates it if it had been disabled' , ( ) => {
const availablePackage = atom . packages . getAvailablePackages ( ) . find ( p => p . name === 'spell-check' )
availablePackage . isBundled = true
expect ( atom . packages . preloadedPackages [ availablePackage . name ] ) . toBeUndefined ( )
expect ( atom . packages . isPackageLoaded ( availablePackage . name ) ) . toBe ( false )
const metadata = atom . packages . loadPackageMetadata ( availablePackage )
const preloadedPackage = atom . packages . preloadPackage (
availablePackage . name ,
{
rootDirPath : path . relative ( atom . packages . resourcePath , availablePackage . path ) ,
metadata
}
)
expect ( preloadedPackage . keymapActivated ) . toBe ( true )
expect ( preloadedPackage . settingsActivated ) . toBe ( true )
expect ( preloadedPackage . menusActivated ) . toBe ( true )
atom . packages . loadAvailablePackage ( availablePackage , new Set ( [ availablePackage . name ] ) )
expect ( atom . packages . isPackageLoaded ( availablePackage . name ) ) . toBe ( false )
expect ( preloadedPackage . keymapActivated ) . toBe ( false )
expect ( preloadedPackage . settingsActivated ) . toBe ( false )
expect ( preloadedPackage . menusActivated ) . toBe ( false )
} )
it ( 'deactivates it and reloads the new one if trying to load the same package outside of the bundle' , ( ) => {
const availablePackage = atom . packages . getAvailablePackages ( ) . find ( p => p . name === 'spell-check' )
availablePackage . isBundled = true
expect ( atom . packages . preloadedPackages [ availablePackage . name ] ) . toBeUndefined ( )
expect ( atom . packages . isPackageLoaded ( availablePackage . name ) ) . toBe ( false )
const metadata = atom . packages . loadPackageMetadata ( availablePackage )
const preloadedPackage = atom . packages . preloadPackage (
availablePackage . name ,
{
rootDirPath : path . relative ( atom . packages . resourcePath , availablePackage . path ) ,
metadata
}
)
expect ( preloadedPackage . keymapActivated ) . toBe ( true )
expect ( preloadedPackage . settingsActivated ) . toBe ( true )
expect ( preloadedPackage . menusActivated ) . toBe ( true )
availablePackage . isBundled = false
atom . packages . loadAvailablePackage ( availablePackage )
expect ( atom . packages . isPackageLoaded ( availablePackage . name ) ) . toBe ( true )
expect ( preloadedPackage . keymapActivated ) . toBe ( false )
expect ( preloadedPackage . settingsActivated ) . toBe ( false )
expect ( preloadedPackage . menusActivated ) . toBe ( false )
} )
} )
describe ( 'if the package was not preloaded' , ( ) => {
it ( 'adds the package path to the module cache' , ( ) => {
const availablePackage = atom . packages . getAvailablePackages ( ) . find ( p => p . name === 'spell-check' )
availablePackage . isBundled = true
const metadata = atom . packages . loadPackageMetadata ( availablePackage )
atom . packages . loadAvailablePackage ( availablePackage )
expect ( ModuleCache . add ) . toHaveBeenCalledWith ( availablePackage . path , metadata )
} )
} )
} )
describe ( 'preloading' , ( ) => {
it ( 'requires the main module, loads the config schema and activates keymaps, menus and settings without reactivating them during package activation' , ( ) => {
const availablePackage = atom . packages . getAvailablePackages ( ) . find ( p => p . name === 'spell-check' )
availablePackage . isBundled = true
const metadata = atom . packages . loadPackageMetadata ( availablePackage )
expect ( atom . packages . preloadedPackages [ availablePackage . name ] ) . toBeUndefined ( )
expect ( atom . packages . isPackageLoaded ( availablePackage . name ) ) . toBe ( false )
atom . packages . packagesCache = { }
atom . packages . packagesCache [ availablePackage . name ] = {
main : path . join ( availablePackage . path , metadata . main ) ,
grammarPaths : [ ]
}
const preloadedPackage = atom . packages . preloadPackage (
availablePackage . name ,
{
rootDirPath : path . relative ( atom . packages . resourcePath , availablePackage . path ) ,
metadata
}
)
expect ( preloadedPackage . keymapActivated ) . toBe ( true )
expect ( preloadedPackage . settingsActivated ) . toBe ( true )
expect ( preloadedPackage . menusActivated ) . toBe ( true )
expect ( preloadedPackage . mainModule ) . toBeTruthy ( )
expect ( preloadedPackage . configSchemaRegisteredOnLoad ) . toBeTruthy ( )
spyOn ( atom . keymaps , 'add' )
spyOn ( atom . menu , 'add' )
spyOn ( atom . contextMenu , 'add' )
spyOn ( atom . config , 'setSchema' )
atom . packages . loadAvailablePackage ( availablePackage )
expect ( preloadedPackage . getMainModulePath ( ) ) . toBe ( path . join ( availablePackage . path , metadata . main ) )
atom . packages . activatePackage ( availablePackage . name )
expect ( atom . keymaps . add ) . not . toHaveBeenCalled ( )
expect ( atom . menu . add ) . not . toHaveBeenCalled ( )
expect ( atom . contextMenu . add ) . not . toHaveBeenCalled ( )
expect ( atom . config . setSchema ) . not . toHaveBeenCalled ( )
expect ( preloadedPackage . keymapActivated ) . toBe ( true )
expect ( preloadedPackage . settingsActivated ) . toBe ( true )
expect ( preloadedPackage . menusActivated ) . toBe ( true )
expect ( preloadedPackage . mainModule ) . toBeTruthy ( )
expect ( preloadedPackage . configSchemaRegisteredOnLoad ) . toBeTruthy ( )
} )
it ( 'deactivates disabled keymaps during package activation' , ( ) => {
const availablePackage = atom . packages . getAvailablePackages ( ) . find ( p => p . name === 'spell-check' )
availablePackage . isBundled = true
const metadata = atom . packages . loadPackageMetadata ( availablePackage )
expect ( atom . packages . preloadedPackages [ availablePackage . name ] ) . toBeUndefined ( )
expect ( atom . packages . isPackageLoaded ( availablePackage . name ) ) . toBe ( false )
atom . packages . packagesCache = { }
atom . packages . packagesCache [ availablePackage . name ] = {
main : path . join ( availablePackage . path , metadata . main ) ,
grammarPaths : [ ]
}
const preloadedPackage = atom . packages . preloadPackage (
availablePackage . name ,
{
rootDirPath : path . relative ( atom . packages . resourcePath , availablePackage . path ) ,
metadata
}
)
expect ( preloadedPackage . keymapActivated ) . toBe ( true )
expect ( preloadedPackage . settingsActivated ) . toBe ( true )
expect ( preloadedPackage . menusActivated ) . toBe ( true )
atom . packages . loadAvailablePackage ( availablePackage )
atom . config . set ( 'core.packagesWithKeymapsDisabled' , [ availablePackage . name ] )
atom . packages . activatePackage ( availablePackage . name )
expect ( preloadedPackage . keymapActivated ) . toBe ( false )
expect ( preloadedPackage . settingsActivated ) . toBe ( true )
expect ( preloadedPackage . menusActivated ) . toBe ( true )
} )
} )
describe ( '::unloadPackage(name)' , ( ) => {
describe ( 'when the package is active' , ( ) => {
2017-09-29 03:04:46 +03:00
it ( 'throws an error' , async ( ) => {
const pack = await atom . packages . activatePackage ( 'package-with-main' )
expect ( atom . packages . isPackageLoaded ( pack . name ) ) . toBeTruthy ( )
expect ( atom . packages . isPackageActive ( pack . name ) ) . toBeTruthy ( )
expect ( ( ) => atom . packages . unloadPackage ( pack . name ) ) . toThrow ( )
expect ( atom . packages . isPackageLoaded ( pack . name ) ) . toBeTruthy ( )
expect ( atom . packages . isPackageActive ( pack . name ) ) . toBeTruthy ( )
2017-09-29 02:18:56 +03:00
} )
} )
describe ( 'when the package is not loaded' , ( ) => {
it ( 'throws an error' , ( ) => {
expect ( atom . packages . isPackageLoaded ( 'unloaded' ) ) . toBeFalsy ( )
expect ( ( ) => atom . packages . unloadPackage ( 'unloaded' ) ) . toThrow ( )
expect ( atom . packages . isPackageLoaded ( 'unloaded' ) ) . toBeFalsy ( )
} )
} )
describe ( 'when the package is loaded' , ( ) => {
it ( 'no longers reports it as being loaded' , ( ) => {
const pack = atom . packages . loadPackage ( 'package-with-main' )
expect ( atom . packages . isPackageLoaded ( pack . name ) ) . toBeTruthy ( )
atom . packages . unloadPackage ( pack . name )
expect ( atom . packages . isPackageLoaded ( pack . name ) ) . toBeFalsy ( )
} )
} )
it ( 'invokes ::onDidUnloadPackage listeners with the unloaded package' , ( ) => {
atom . packages . loadPackage ( 'package-with-main' )
let unloadedPackage
atom . packages . onDidUnloadPackage ( pack => {
unloadedPackage = pack
} )
atom . packages . unloadPackage ( 'package-with-main' )
expect ( unloadedPackage . name ) . toBe ( 'package-with-main' )
} )
} )
describe ( '::activatePackage(id)' , ( ) => {
describe ( 'when called multiple times' , ( ) => {
2017-09-29 03:04:46 +03:00
it ( 'it only calls activate on the package once' , async ( ) => {
2017-09-29 02:18:56 +03:00
spyOn ( Package . prototype , 'activateNow' ) . andCallThrough ( )
2017-09-29 03:04:46 +03:00
await atom . packages . activatePackage ( 'package-with-index' )
await atom . packages . activatePackage ( 'package-with-index' )
await atom . packages . activatePackage ( 'package-with-index' )
2017-09-29 02:18:56 +03:00
2017-09-29 03:04:46 +03:00
expect ( Package . prototype . activateNow . callCount ) . toBe ( 1 )
2017-09-29 02:18:56 +03:00
} )
} )
describe ( 'when the package has a main module' , ( ) => {
describe ( 'when the metadata specifies a main module path˜ ' , ( ) => {
2017-09-29 03:04:46 +03:00
it ( 'requires the module at the specified path' , async ( ) => {
2017-09-29 02:18:56 +03:00
const mainModule = require ( './fixtures/packages/package-with-main/main-module' )
spyOn ( mainModule , 'activate' )
2017-09-29 03:04:46 +03:00
const pack = await atom . packages . activatePackage ( 'package-with-main' )
expect ( mainModule . activate ) . toHaveBeenCalled ( )
expect ( pack . mainModule ) . toBe ( mainModule )
2017-09-29 02:18:56 +03:00
} )
} )
describe ( 'when the metadata does not specify a main module' , ( ) => {
2017-09-29 03:04:46 +03:00
it ( 'requires index.coffee' , async ( ) => {
2017-09-29 02:18:56 +03:00
const indexModule = require ( './fixtures/packages/package-with-index/index' )
spyOn ( indexModule , 'activate' )
2017-09-29 03:04:46 +03:00
const pack = await atom . packages . activatePackage ( 'package-with-index' )
expect ( indexModule . activate ) . toHaveBeenCalled ( )
expect ( pack . mainModule ) . toBe ( indexModule )
2017-09-29 02:18:56 +03:00
} )
} )
2017-09-29 03:04:46 +03:00
it ( 'assigns config schema, including defaults when package contains a schema' , async ( ) => {
2017-09-29 02:18:56 +03:00
expect ( atom . config . get ( 'package-with-config-schema.numbers.one' ) ) . toBeUndefined ( )
2017-09-29 03:04:46 +03:00
await atom . packages . activatePackage ( 'package-with-config-schema' )
expect ( atom . config . get ( 'package-with-config-schema.numbers.one' ) ) . toBe ( 1 )
expect ( atom . config . get ( 'package-with-config-schema.numbers.two' ) ) . toBe ( 2 )
expect ( atom . config . set ( 'package-with-config-schema.numbers.one' , 'nope' ) ) . toBe ( false )
expect ( atom . config . set ( 'package-with-config-schema.numbers.one' , '10' ) ) . toBe ( true )
expect ( atom . config . get ( 'package-with-config-schema.numbers.one' ) ) . toBe ( 10 )
2017-09-29 02:18:56 +03:00
} )
describe ( 'when the package metadata includes `activationCommands`' , ( ) => {
let mainModule , promise , workspaceCommandListener , registration
beforeEach ( ( ) => {
jasmine . attachToDOM ( atom . workspace . getElement ( ) )
mainModule = require ( './fixtures/packages/package-with-activation-commands/index' )
mainModule . activationCommandCallCount = 0
spyOn ( mainModule , 'activate' ) . andCallThrough ( )
spyOn ( Package . prototype , 'requireMainModule' ) . andCallThrough ( )
workspaceCommandListener = jasmine . createSpy ( 'workspaceCommandListener' )
registration = atom . commands . add ( '.workspace' , 'activation-command' , workspaceCommandListener )
promise = atom . packages . activatePackage ( 'package-with-activation-commands' )
} )
afterEach ( ( ) => {
if ( registration ) {
registration . dispose ( )
}
mainModule = null
} )
2017-09-29 03:04:46 +03:00
it ( 'defers requiring/activating the main module until an activation event bubbles to the root view' , async ( ) => {
2017-09-29 02:18:56 +03:00
expect ( Package . prototype . requireMainModule . callCount ) . toBe ( 0 )
atom . workspace . getElement ( ) . dispatchEvent ( new CustomEvent ( 'activation-command' , { bubbles : true } ) )
2017-09-29 03:04:46 +03:00
await promise
expect ( Package . prototype . requireMainModule . callCount ) . toBe ( 1 )
2017-09-29 02:18:56 +03:00
} )
2017-09-29 03:04:46 +03:00
it ( 'triggers the activation event on all handlers registered during activation' , async ( ) => {
await atom . workspace . open ( )
const editorElement = atom . workspace . getActiveTextEditor ( ) . getElement ( )
const editorCommandListener = jasmine . createSpy ( 'editorCommandListener' )
atom . commands . add ( 'atom-text-editor' , 'activation-command' , editorCommandListener )
atom . commands . dispatch ( editorElement , 'activation-command' )
expect ( mainModule . activate . callCount ) . toBe ( 1 )
expect ( mainModule . activationCommandCallCount ) . toBe ( 1 )
expect ( editorCommandListener . callCount ) . toBe ( 1 )
expect ( workspaceCommandListener . callCount ) . toBe ( 1 )
atom . commands . dispatch ( editorElement , 'activation-command' )
expect ( mainModule . activationCommandCallCount ) . toBe ( 2 )
expect ( editorCommandListener . callCount ) . toBe ( 2 )
expect ( workspaceCommandListener . callCount ) . toBe ( 2 )
expect ( mainModule . activate . callCount ) . toBe ( 1 )
2017-09-29 02:18:56 +03:00
} )
2017-09-29 03:04:46 +03:00
it ( 'activates the package immediately when the events are empty' , async ( ) => {
2017-09-29 02:18:56 +03:00
mainModule = require ( './fixtures/packages/package-with-empty-activation-commands/index' )
spyOn ( mainModule , 'activate' ) . andCallThrough ( )
2017-09-29 03:04:46 +03:00
atom . packages . activatePackage ( 'package-with-empty-activation-commands' )
2017-09-29 02:18:56 +03:00
2017-09-29 03:04:46 +03:00
expect ( mainModule . activate . callCount ) . toBe ( 1 )
2017-09-29 02:18:56 +03:00
} )
it ( 'adds a notification when the activation commands are invalid' , ( ) => {
spyOn ( atom , 'inSpecMode' ) . andReturn ( false )
const addErrorHandler = jasmine . createSpy ( )
atom . notifications . onDidAddNotification ( addErrorHandler )
expect ( ( ) => atom . packages . activatePackage ( 'package-with-invalid-activation-commands' ) ) . not . toThrow ( )
expect ( addErrorHandler . callCount ) . toBe ( 1 )
expect ( addErrorHandler . argsForCall [ 0 ] [ 0 ] . message ) . toContain ( 'Failed to activate the package-with-invalid-activation-commands package' )
expect ( addErrorHandler . argsForCall [ 0 ] [ 0 ] . options . packageName ) . toEqual ( 'package-with-invalid-activation-commands' )
} )
it ( 'adds a notification when the context menu is invalid' , ( ) => {
spyOn ( atom , 'inSpecMode' ) . andReturn ( false )
const addErrorHandler = jasmine . createSpy ( )
atom . notifications . onDidAddNotification ( addErrorHandler )
expect ( ( ) => atom . packages . activatePackage ( 'package-with-invalid-context-menu' ) ) . not . toThrow ( )
expect ( addErrorHandler . callCount ) . toBe ( 1 )
expect ( addErrorHandler . argsForCall [ 0 ] [ 0 ] . message ) . toContain ( 'Failed to activate the package-with-invalid-context-menu package' )
expect ( addErrorHandler . argsForCall [ 0 ] [ 0 ] . options . packageName ) . toEqual ( 'package-with-invalid-context-menu' )
} )
2017-09-29 03:04:46 +03:00
it ( 'adds a notification when the grammar is invalid' , async ( ) => {
let notificationEvent
2017-09-29 02:18:56 +03:00
2017-09-29 03:04:46 +03:00
await new Promise ( resolve => {
const subscription = atom . notifications . onDidAddNotification ( event => {
notificationEvent = event
subscription . dispose ( )
resolve ( )
} )
2017-09-29 02:18:56 +03:00
2017-09-29 03:04:46 +03:00
atom . packages . activatePackage ( 'package-with-invalid-grammar' )
2017-09-29 02:18:56 +03:00
} )
2017-09-29 03:04:46 +03:00
expect ( notificationEvent . message ) . toContain ( 'Failed to load a package-with-invalid-grammar package grammar' )
expect ( notificationEvent . options . packageName ) . toEqual ( 'package-with-invalid-grammar' )
} )
2017-09-29 02:18:56 +03:00
2017-09-29 03:04:46 +03:00
it ( 'adds a notification when the settings are invalid' , async ( ) => {
let notificationEvent
2017-09-29 02:18:56 +03:00
2017-09-29 03:04:46 +03:00
await new Promise ( resolve => {
const subscription = atom . notifications . onDidAddNotification ( event => {
notificationEvent = event
subscription . dispose ( )
resolve ( )
} )
2017-09-29 02:18:56 +03:00
2017-09-29 03:04:46 +03:00
atom . packages . activatePackage ( 'package-with-invalid-settings' )
2017-09-29 02:18:56 +03:00
} )
2017-09-29 03:04:46 +03:00
expect ( notificationEvent . message ) . toContain ( 'Failed to load the package-with-invalid-settings package settings' )
expect ( notificationEvent . options . packageName ) . toEqual ( 'package-with-invalid-settings' )
2017-09-29 02:18:56 +03:00
} )
} )
} )
describe ( 'when the package metadata includes `activationHooks`' , ( ) => {
let mainModule , promise
beforeEach ( ( ) => {
mainModule = require ( './fixtures/packages/package-with-activation-hooks/index' )
spyOn ( mainModule , 'activate' ) . andCallThrough ( )
spyOn ( Package . prototype , 'requireMainModule' ) . andCallThrough ( )
} )
2017-09-29 03:04:46 +03:00
it ( 'defers requiring/activating the main module until an triggering of an activation hook occurs' , async ( ) => {
2017-09-29 02:18:56 +03:00
promise = atom . packages . activatePackage ( 'package-with-activation-hooks' )
expect ( Package . prototype . requireMainModule . callCount ) . toBe ( 0 )
atom . packages . triggerActivationHook ( 'language-fictitious:grammar-used' )
atom . packages . triggerDeferredActivationHooks ( )
2017-09-29 03:04:46 +03:00
await promise
expect ( Package . prototype . requireMainModule . callCount ) . toBe ( 1 )
2017-09-29 02:18:56 +03:00
} )
2017-09-29 03:04:46 +03:00
it ( 'does not double register activation hooks when deactivating and reactivating' , async ( ) => {
2017-09-29 02:18:56 +03:00
promise = atom . packages . activatePackage ( 'package-with-activation-hooks' )
expect ( mainModule . activate . callCount ) . toBe ( 0 )
atom . packages . triggerActivationHook ( 'language-fictitious:grammar-used' )
atom . packages . triggerDeferredActivationHooks ( )
2017-09-29 03:04:46 +03:00
await promise
expect ( mainModule . activate . callCount ) . toBe ( 1 )
2017-09-29 02:18:56 +03:00
2017-09-29 03:04:46 +03:00
await atom . packages . deactivatePackage ( 'package-with-activation-hooks' )
2017-09-29 02:18:56 +03:00
2017-09-29 03:04:46 +03:00
promise = atom . packages . activatePackage ( 'package-with-activation-hooks' )
atom . packages . triggerActivationHook ( 'language-fictitious:grammar-used' )
atom . packages . triggerDeferredActivationHooks ( )
2017-09-29 02:18:56 +03:00
2017-09-29 03:04:46 +03:00
await promise
expect ( mainModule . activate . callCount ) . toBe ( 2 )
2017-09-29 02:18:56 +03:00
} )
2017-09-29 03:04:46 +03:00
it ( 'activates the package immediately when activationHooks is empty' , async ( ) => {
2017-09-29 02:18:56 +03:00
mainModule = require ( './fixtures/packages/package-with-empty-activation-hooks/index' )
spyOn ( mainModule , 'activate' ) . andCallThrough ( )
2017-09-29 03:04:46 +03:00
expect ( Package . prototype . requireMainModule . callCount ) . toBe ( 0 )
2017-09-29 02:18:56 +03:00
2017-09-29 03:04:46 +03:00
await atom . packages . activatePackage ( 'package-with-empty-activation-hooks' )
expect ( mainModule . activate . callCount ) . toBe ( 1 )
expect ( Package . prototype . requireMainModule . callCount ) . toBe ( 1 )
2017-09-29 02:18:56 +03:00
} )
2017-09-29 03:04:46 +03:00
it ( 'activates the package immediately if the activation hook had already been triggered' , async ( ) => {
2017-09-29 02:18:56 +03:00
atom . packages . triggerActivationHook ( 'language-fictitious:grammar-used' )
atom . packages . triggerDeferredActivationHooks ( )
expect ( Package . prototype . requireMainModule . callCount ) . toBe ( 0 )
2017-09-29 03:04:46 +03:00
await atom . packages . activatePackage ( 'package-with-activation-hooks' )
expect ( Package . prototype . requireMainModule . callCount ) . toBe ( 1 )
2017-09-29 02:18:56 +03:00
} )
} )
describe ( 'when the package has no main module' , ( ) => {
it ( 'does not throw an exception' , ( ) => {
spyOn ( console , 'error' )
spyOn ( console , 'warn' ) . andCallThrough ( )
expect ( ( ) => atom . packages . activatePackage ( 'package-without-module' ) ) . not . toThrow ( )
expect ( console . error ) . not . toHaveBeenCalled ( )
expect ( console . warn ) . not . toHaveBeenCalled ( )
} )
} )
describe ( 'when the package does not export an activate function' , ( ) => {
2017-09-29 03:04:46 +03:00
it ( 'activates the package and does not throw an exception or log a warning' , async ( ) => {
2017-09-29 02:18:56 +03:00
spyOn ( console , 'warn' )
2017-09-29 03:04:46 +03:00
await atom . packages . activatePackage ( 'package-with-no-activate' )
expect ( console . warn ) . not . toHaveBeenCalled ( )
2017-09-29 02:18:56 +03:00
} )
} )
2017-09-29 03:04:46 +03:00
it ( "passes the activate method the package's previously serialized state if it exists" , async ( ) => {
const pack = await atom . packages . activatePackage ( 'package-with-serialization' )
expect ( pack . mainModule . someNumber ) . not . toBe ( 77 )
pack . mainModule . someNumber = 77
atom . packages . serializePackage ( 'package-with-serialization' )
await atom . packages . deactivatePackage ( 'package-with-serialization' )
spyOn ( pack . mainModule , 'activate' ) . andCallThrough ( )
await atom . packages . activatePackage ( 'package-with-serialization' )
expect ( pack . mainModule . activate ) . toHaveBeenCalledWith ( { someNumber : 77 } )
2017-09-29 02:18:56 +03:00
} )
2017-09-29 03:04:46 +03:00
it ( 'invokes ::onDidActivatePackage listeners with the activated package' , async ( ) => {
2017-09-29 02:18:56 +03:00
let activatedPackage
atom . packages . onDidActivatePackage ( pack => {
activatedPackage = pack
} )
2017-09-29 03:04:46 +03:00
await atom . packages . activatePackage ( 'package-with-main' )
expect ( activatedPackage . name ) . toBe ( 'package-with-main' )
2017-09-29 02:18:56 +03:00
} )
describe ( "when the package's main module throws an error on load" , ( ) => {
it ( 'adds a notification instead of throwing an exception' , ( ) => {
spyOn ( atom , 'inSpecMode' ) . andReturn ( false )
atom . config . set ( 'core.disabledPackages' , [ ] )
const addErrorHandler = jasmine . createSpy ( )
atom . notifications . onDidAddNotification ( addErrorHandler )
expect ( ( ) => atom . packages . activatePackage ( 'package-that-throws-an-exception' ) ) . not . toThrow ( )
expect ( addErrorHandler . callCount ) . toBe ( 1 )
expect ( addErrorHandler . argsForCall [ 0 ] [ 0 ] . message ) . toContain ( 'Failed to load the package-that-throws-an-exception package' )
expect ( addErrorHandler . argsForCall [ 0 ] [ 0 ] . options . packageName ) . toEqual ( 'package-that-throws-an-exception' )
} )
it ( 're-throws the exception in test mode' , ( ) => {
atom . config . set ( 'core.disabledPackages' , [ ] )
expect ( ( ) => atom . packages . activatePackage ( 'package-that-throws-an-exception' ) ) . toThrow ( 'This package throws an exception' )
} )
} )
describe ( 'when the package is not found' , ( ) => {
2017-09-29 03:04:46 +03:00
it ( 'rejects the promise' , async ( ) => {
2017-09-29 02:18:56 +03:00
spyOn ( console , 'warn' )
2017-09-29 03:04:46 +03:00
atom . config . set ( 'core.disabledPackages' , [ ] )
2017-09-29 02:18:56 +03:00
2017-09-29 03:04:46 +03:00
try {
await atom . packages . activatePackage ( 'this-doesnt-exist' )
expect ( 'Error to be thrown' ) . toBe ( '' )
} catch ( error ) {
2017-09-29 02:18:56 +03:00
expect ( console . warn . callCount ) . toBe ( 1 )
2017-09-29 03:04:46 +03:00
expect ( error . message ) . toContain ( "Failed to load package 'this-doesnt-exist'" )
}
2017-09-29 02:18:56 +03:00
} )
} )
describe ( 'keymap loading' , ( ) => {
describe ( "when the metadata does not contain a 'keymaps' manifest" , ( ) => {
2017-09-29 03:04:46 +03:00
it ( 'loads all the .cson/.json files in the keymaps directory' , async ( ) => {
2017-09-29 02:18:56 +03:00
const element1 = createTestElement ( 'test-1' )
const element2 = createTestElement ( 'test-2' )
const element3 = createTestElement ( 'test-3' )
expect ( atom . keymaps . findKeyBindings ( { keystrokes : 'ctrl-z' , target : element1 } ) ) . toHaveLength ( 0 )
expect ( atom . keymaps . findKeyBindings ( { keystrokes : 'ctrl-z' , target : element2 } ) ) . toHaveLength ( 0 )
expect ( atom . keymaps . findKeyBindings ( { keystrokes : 'ctrl-z' , target : element3 } ) ) . toHaveLength ( 0 )
2017-09-29 03:04:46 +03:00
await atom . packages . activatePackage ( 'package-with-keymaps' )
expect ( atom . keymaps . findKeyBindings ( { keystrokes : 'ctrl-z' , target : element1 } ) [ 0 ] . command ) . toBe ( 'test-1' )
expect ( atom . keymaps . findKeyBindings ( { keystrokes : 'ctrl-z' , target : element2 } ) [ 0 ] . command ) . toBe ( 'test-2' )
expect ( atom . keymaps . findKeyBindings ( { keystrokes : 'ctrl-z' , target : element3 } ) ) . toHaveLength ( 0 )
2017-09-29 02:18:56 +03:00
} )
} )
describe ( "when the metadata contains a 'keymaps' manifest" , ( ) => {
2017-09-29 03:04:46 +03:00
it ( 'loads only the keymaps specified by the manifest, in the specified order' , async ( ) => {
2017-09-29 02:18:56 +03:00
const element1 = createTestElement ( 'test-1' )
const element3 = createTestElement ( 'test-3' )
expect ( atom . keymaps . findKeyBindings ( { keystrokes : 'ctrl-z' , target : element1 } ) ) . toHaveLength ( 0 )
2017-09-29 03:04:46 +03:00
await atom . packages . activatePackage ( 'package-with-keymaps-manifest' )
expect ( atom . keymaps . findKeyBindings ( { keystrokes : 'ctrl-z' , target : element1 } ) [ 0 ] . command ) . toBe ( 'keymap-1' )
expect ( atom . keymaps . findKeyBindings ( { keystrokes : 'ctrl-n' , target : element1 } ) [ 0 ] . command ) . toBe ( 'keymap-2' )
expect ( atom . keymaps . findKeyBindings ( { keystrokes : 'ctrl-y' , target : element3 } ) ) . toHaveLength ( 0 )
2017-09-29 02:18:56 +03:00
} )
} )
describe ( 'when the keymap file is empty' , ( ) => {
2017-09-29 03:04:46 +03:00
it ( 'does not throw an error on activation' , async ( ) => {
await atom . packages . activatePackage ( 'package-with-empty-keymap' )
expect ( atom . packages . isPackageActive ( 'package-with-empty-keymap' ) ) . toBe ( true )
2017-09-29 02:18:56 +03:00
} )
} )
describe ( "when the package's keymaps have been disabled" , ( ) => {
2017-09-29 03:04:46 +03:00
it ( 'does not add the keymaps' , async ( ) => {
2017-09-29 02:18:56 +03:00
const element1 = createTestElement ( 'test-1' )
expect ( atom . keymaps . findKeyBindings ( { keystrokes : 'ctrl-z' , target : element1 } ) ) . toHaveLength ( 0 )
atom . config . set ( 'core.packagesWithKeymapsDisabled' , [ 'package-with-keymaps-manifest' ] )
2017-09-29 03:04:46 +03:00
await atom . packages . activatePackage ( 'package-with-keymaps-manifest' )
expect ( atom . keymaps . findKeyBindings ( { keystrokes : 'ctrl-z' , target : element1 } ) ) . toHaveLength ( 0 )
2017-09-29 02:18:56 +03:00
} )
} )
describe ( 'when setting core.packagesWithKeymapsDisabled' , ( ) => {
it ( "ignores package names in the array that aren't loaded" , ( ) => {
atom . packages . observePackagesWithKeymapsDisabled ( )
expect ( ( ) => atom . config . set ( 'core.packagesWithKeymapsDisabled' , [ 'package-does-not-exist' ] ) ) . not . toThrow ( )
expect ( ( ) => atom . config . set ( 'core.packagesWithKeymapsDisabled' , [ ] ) ) . not . toThrow ( )
} )
} )
describe ( "when the package's keymaps are disabled and re-enabled after it is activated" , ( ) => {
2017-09-29 03:04:46 +03:00
it ( 'removes and re-adds the keymaps' , async ( ) => {
2017-09-29 02:18:56 +03:00
const element1 = createTestElement ( 'test-1' )
atom . packages . observePackagesWithKeymapsDisabled ( )
2017-09-29 03:04:46 +03:00
await atom . packages . activatePackage ( 'package-with-keymaps-manifest' )
2017-09-29 02:18:56 +03:00
2017-09-29 03:04:46 +03:00
atom . config . set ( 'core.packagesWithKeymapsDisabled' , [ 'package-with-keymaps-manifest' ] )
expect ( atom . keymaps . findKeyBindings ( { keystrokes : 'ctrl-z' , target : element1 } ) ) . toHaveLength ( 0 )
2017-09-29 02:18:56 +03:00
2017-09-29 03:04:46 +03:00
atom . config . set ( 'core.packagesWithKeymapsDisabled' , [ ] )
expect ( atom . keymaps . findKeyBindings ( { keystrokes : 'ctrl-z' , target : element1 } ) [ 0 ] . command ) . toBe ( 'keymap-1' )
2017-09-29 02:18:56 +03:00
} )
} )
describe ( 'when the package is de-activated and re-activated' , ( ) => {
let element , events , userKeymapPath
beforeEach ( ( ) => {
userKeymapPath = path . join ( temp . mkdirSync ( ) , 'user-keymaps.cson' )
spyOn ( atom . keymaps , 'getUserKeymapPath' ) . andReturn ( userKeymapPath )
element = createTestElement ( 'test-1' )
jasmine . attachToDOM ( element )
events = [ ]
element . addEventListener ( 'user-command' , e => events . push ( e ) )
element . addEventListener ( 'test-1' , e => events . push ( e ) )
} )
afterEach ( ( ) => {
element . remove ( )
// Avoid leaking user keymap subscription
atom . keymaps . watchSubscriptions [ userKeymapPath ] . dispose ( )
delete atom . keymaps . watchSubscriptions [ userKeymapPath ]
temp . cleanupSync ( )
} )
2017-09-29 03:04:46 +03:00
it ( "doesn't override user-defined keymaps" , async ( ) => {
2017-09-29 02:18:56 +03:00
fs . writeFileSync ( userKeymapPath , ` ".test-1": {"ctrl-z": "user-command"} ` )
atom . keymaps . loadUserKeymap ( )
2017-09-29 03:04:46 +03:00
await atom . packages . activatePackage ( 'package-with-keymaps' )
atom . keymaps . handleKeyboardEvent ( buildKeydownEvent ( 'z' , { ctrl : true , target : element } ) )
expect ( events . length ) . toBe ( 1 )
expect ( events [ 0 ] . type ) . toBe ( 'user-command' )
2017-09-29 02:18:56 +03:00
2017-09-29 03:04:46 +03:00
await atom . packages . deactivatePackage ( 'package-with-keymaps' )
await atom . packages . activatePackage ( 'package-with-keymaps' )
atom . keymaps . handleKeyboardEvent ( buildKeydownEvent ( 'z' , { ctrl : true , target : element } ) )
expect ( events . length ) . toBe ( 2 )
expect ( events [ 1 ] . type ) . toBe ( 'user-command' )
2017-09-29 02:18:56 +03:00
} )
} )
} )
describe ( 'menu loading' , ( ) => {
beforeEach ( ( ) => {
atom . contextMenu . definitions = [ ]
atom . menu . template = [ ]
} )
describe ( "when the metadata does not contain a 'menus' manifest" , ( ) => {
2017-09-29 03:04:46 +03:00
it ( 'loads all the .cson/.json files in the menus directory' , async ( ) => {
2017-09-29 02:18:56 +03:00
const element = createTestElement ( 'test-1' )
expect ( atom . contextMenu . templateForElement ( element ) ) . toEqual ( [ ] )
2017-09-29 03:04:46 +03:00
await atom . packages . activatePackage ( 'package-with-menus' )
expect ( atom . menu . template . length ) . toBe ( 2 )
expect ( atom . menu . template [ 0 ] . label ) . toBe ( 'Second to Last' )
expect ( atom . menu . template [ 1 ] . label ) . toBe ( 'Last' )
expect ( atom . contextMenu . templateForElement ( element ) [ 0 ] . label ) . toBe ( 'Menu item 1' )
expect ( atom . contextMenu . templateForElement ( element ) [ 1 ] . label ) . toBe ( 'Menu item 2' )
expect ( atom . contextMenu . templateForElement ( element ) [ 2 ] . label ) . toBe ( 'Menu item 3' )
2017-09-29 02:18:56 +03:00
} )
} )
describe ( "when the metadata contains a 'menus' manifest" , ( ) => {
2017-09-29 03:04:46 +03:00
it ( 'loads only the menus specified by the manifest, in the specified order' , async ( ) => {
2017-09-29 02:18:56 +03:00
const element = createTestElement ( 'test-1' )
expect ( atom . contextMenu . templateForElement ( element ) ) . toEqual ( [ ] )
2017-09-29 03:04:46 +03:00
await atom . packages . activatePackage ( 'package-with-menus-manifest' )
expect ( atom . menu . template [ 0 ] . label ) . toBe ( 'Second to Last' )
expect ( atom . menu . template [ 1 ] . label ) . toBe ( 'Last' )
expect ( atom . contextMenu . templateForElement ( element ) [ 0 ] . label ) . toBe ( 'Menu item 2' )
expect ( atom . contextMenu . templateForElement ( element ) [ 1 ] . label ) . toBe ( 'Menu item 1' )
expect ( atom . contextMenu . templateForElement ( element ) [ 2 ] ) . toBeUndefined ( )
2017-09-29 02:18:56 +03:00
} )
} )
describe ( 'when the menu file is empty' , ( ) => {
2017-09-29 03:04:46 +03:00
it ( 'does not throw an error on activation' , async ( ) => {
await atom . packages . activatePackage ( 'package-with-empty-menu' )
expect ( atom . packages . isPackageActive ( 'package-with-empty-menu' ) ) . toBe ( true )
2017-09-29 02:18:56 +03:00
} )
} )
} )
describe ( 'stylesheet loading' , ( ) => {
describe ( "when the metadata contains a 'styleSheets' manifest" , ( ) => {
2017-09-29 03:04:46 +03:00
it ( 'loads style sheets from the styles directory as specified by the manifest' , async ( ) => {
2017-09-29 02:18:56 +03:00
const one = require . resolve ( './fixtures/packages/package-with-style-sheets-manifest/styles/1.css' )
const two = require . resolve ( './fixtures/packages/package-with-style-sheets-manifest/styles/2.less' )
const three = require . resolve ( './fixtures/packages/package-with-style-sheets-manifest/styles/3.css' )
expect ( atom . themes . stylesheetElementForId ( one ) ) . toBeNull ( )
expect ( atom . themes . stylesheetElementForId ( two ) ) . toBeNull ( )
expect ( atom . themes . stylesheetElementForId ( three ) ) . toBeNull ( )
2017-09-29 03:04:46 +03:00
await atom . packages . activatePackage ( 'package-with-style-sheets-manifest' )
expect ( atom . themes . stylesheetElementForId ( one ) ) . not . toBeNull ( )
expect ( atom . themes . stylesheetElementForId ( two ) ) . not . toBeNull ( )
expect ( atom . themes . stylesheetElementForId ( three ) ) . toBeNull ( )
expect ( getComputedStyle ( document . querySelector ( '#jasmine-content' ) ) . fontSize ) . toBe ( '1px' )
2017-09-29 02:18:56 +03:00
} )
} )
describe ( "when the metadata does not contain a 'styleSheets' manifest" , ( ) => {
2017-09-29 03:04:46 +03:00
it ( 'loads all style sheets from the styles directory' , async ( ) => {
2017-09-29 02:18:56 +03:00
const one = require . resolve ( './fixtures/packages/package-with-styles/styles/1.css' )
const two = require . resolve ( './fixtures/packages/package-with-styles/styles/2.less' )
const three = require . resolve ( './fixtures/packages/package-with-styles/styles/3.test-context.css' )
const four = require . resolve ( './fixtures/packages/package-with-styles/styles/4.css' )
expect ( atom . themes . stylesheetElementForId ( one ) ) . toBeNull ( )
expect ( atom . themes . stylesheetElementForId ( two ) ) . toBeNull ( )
expect ( atom . themes . stylesheetElementForId ( three ) ) . toBeNull ( )
expect ( atom . themes . stylesheetElementForId ( four ) ) . toBeNull ( )
2017-09-29 03:04:46 +03:00
await atom . packages . activatePackage ( 'package-with-styles' )
expect ( atom . themes . stylesheetElementForId ( one ) ) . not . toBeNull ( )
expect ( atom . themes . stylesheetElementForId ( two ) ) . not . toBeNull ( )
expect ( atom . themes . stylesheetElementForId ( three ) ) . not . toBeNull ( )
expect ( atom . themes . stylesheetElementForId ( four ) ) . not . toBeNull ( )
expect ( getComputedStyle ( document . querySelector ( '#jasmine-content' ) ) . fontSize ) . toBe ( '3px' )
2017-09-29 02:18:56 +03:00
} )
} )
2017-09-29 03:04:46 +03:00
it ( "assigns the stylesheet's context based on the filename" , async ( ) => {
await atom . packages . activatePackage ( 'package-with-styles' )
2017-09-29 02:18:56 +03:00
2017-09-29 03:04:46 +03:00
let count = 0
for ( let styleElement of atom . styles . getStyleElements ( ) ) {
if ( styleElement . sourcePath . match ( /1.css/ ) ) {
expect ( styleElement . context ) . toBe ( undefined )
count ++
}
2017-09-29 02:18:56 +03:00
2017-09-29 03:04:46 +03:00
if ( styleElement . sourcePath . match ( /2.less/ ) ) {
expect ( styleElement . context ) . toBe ( undefined )
count ++
}
2017-09-29 02:18:56 +03:00
2017-09-29 03:04:46 +03:00
if ( styleElement . sourcePath . match ( /3.test-context.css/ ) ) {
expect ( styleElement . context ) . toBe ( 'test-context' )
count ++
}
2017-09-29 02:18:56 +03:00
2017-09-29 03:04:46 +03:00
if ( styleElement . sourcePath . match ( /4.css/ ) ) {
expect ( styleElement . context ) . toBe ( undefined )
count ++
2017-09-29 02:18:56 +03:00
}
2017-09-29 03:04:46 +03:00
}
2017-09-29 02:18:56 +03:00
2017-09-29 03:04:46 +03:00
expect ( count ) . toBe ( 4 )
2017-09-29 02:18:56 +03:00
} )
} )
describe ( 'grammar loading' , ( ) => {
2017-09-29 03:04:46 +03:00
it ( "loads the package's grammars" , async ( ) => {
await atom . packages . activatePackage ( 'package-with-grammars' )
expect ( atom . grammars . selectGrammar ( 'a.alot' ) . name ) . toBe ( 'Alot' )
expect ( atom . grammars . selectGrammar ( 'a.alittle' ) . name ) . toBe ( 'Alittle' )
2017-09-29 02:18:56 +03:00
} )
2017-11-30 04:22:35 +03:00
it ( 'loads any tree-sitter grammars defined in the package' , async ( ) => {
await atom . packages . activatePackage ( 'package-with-tree-sitter-grammar' )
const grammar = atom . grammars . selectGrammar ( 'test.somelang' )
expect ( grammar . name ) . toBe ( 'Some Language' )
expect ( grammar . languageModule . isFakeTreeSitterParser ) . toBe ( true )
} )
2017-09-29 02:18:56 +03:00
} )
describe ( 'scoped-property loading' , ( ) => {
2017-09-29 03:04:46 +03:00
it ( 'loads the scoped properties' , async ( ) => {
await atom . packages . activatePackage ( 'package-with-settings' )
expect ( atom . config . get ( 'editor.increaseIndentPattern' , { scope : [ '.source.omg' ] } ) ) . toBe ( '^a' )
2017-09-29 02:18:56 +03:00
} )
} )
2017-10-03 23:20:48 +03:00
2017-10-18 01:23:10 +03:00
describe ( "URI handler registration" , ( ) => {
it ( "registers the package's specified URI handler" , async ( ) => {
const uri = 'atom://package-with-uri-handler/some/url?with=args'
const mod = require ( './fixtures/packages/package-with-uri-handler' )
spyOn ( mod , 'handleURI' )
2017-10-03 23:20:48 +03:00
spyOn ( atom . packages , 'hasLoadedInitialPackages' ) . andReturn ( true )
2017-10-18 01:23:10 +03:00
const activationPromise = atom . packages . activatePackage ( 'package-with-uri-handler' )
atom . dispatchURIMessage ( uri )
2017-10-03 23:20:48 +03:00
await activationPromise
2017-10-18 01:23:10 +03:00
expect ( mod . handleURI ) . toHaveBeenCalledWith ( url . parse ( uri , true ) , uri )
2017-10-03 23:20:48 +03:00
} )
} )
2017-09-29 02:18:56 +03:00
describe ( 'service registration' , ( ) => {
2017-09-29 03:04:46 +03:00
it ( "registers the package's provided and consumed services" , async ( ) => {
2017-09-29 02:18:56 +03:00
const consumerModule = require ( './fixtures/packages/package-with-consumed-services' )
2017-09-29 03:04:46 +03:00
2017-09-29 02:18:56 +03:00
let firstServiceV3Disposed = false
let firstServiceV4Disposed = false
let secondServiceDisposed = false
spyOn ( consumerModule , 'consumeFirstServiceV3' ) . andReturn ( new Disposable ( ( ) => { firstServiceV3Disposed = true } ) )
spyOn ( consumerModule , 'consumeFirstServiceV4' ) . andReturn ( new Disposable ( ( ) => { firstServiceV4Disposed = true } ) )
spyOn ( consumerModule , 'consumeSecondService' ) . andReturn ( new Disposable ( ( ) => { secondServiceDisposed = true } ) )
2017-09-29 03:04:46 +03:00
await atom . packages . activatePackage ( 'package-with-consumed-services' )
await atom . packages . activatePackage ( 'package-with-provided-services' )
expect ( consumerModule . consumeFirstServiceV3 . callCount ) . toBe ( 1 )
expect ( consumerModule . consumeFirstServiceV3 ) . toHaveBeenCalledWith ( 'first-service-v3' )
expect ( consumerModule . consumeFirstServiceV4 ) . toHaveBeenCalledWith ( 'first-service-v4' )
expect ( consumerModule . consumeSecondService ) . toHaveBeenCalledWith ( 'second-service' )
2017-09-29 02:18:56 +03:00
2017-09-29 03:04:46 +03:00
consumerModule . consumeFirstServiceV3 . reset ( )
consumerModule . consumeFirstServiceV4 . reset ( )
consumerModule . consumeSecondService . reset ( )
2017-09-29 02:18:56 +03:00
2017-09-29 03:04:46 +03:00
await atom . packages . deactivatePackage ( 'package-with-provided-services' )
expect ( firstServiceV3Disposed ) . toBe ( true )
expect ( firstServiceV4Disposed ) . toBe ( true )
expect ( secondServiceDisposed ) . toBe ( true )
2017-09-29 02:18:56 +03:00
2017-09-29 03:04:46 +03:00
await atom . packages . deactivatePackage ( 'package-with-consumed-services' )
await atom . packages . activatePackage ( 'package-with-provided-services' )
expect ( consumerModule . consumeFirstServiceV3 ) . not . toHaveBeenCalled ( )
expect ( consumerModule . consumeFirstServiceV4 ) . not . toHaveBeenCalled ( )
expect ( consumerModule . consumeSecondService ) . not . toHaveBeenCalled ( )
2017-09-29 02:18:56 +03:00
} )
2017-09-29 03:04:46 +03:00
it ( 'ignores provided and consumed services that do not exist' , async ( ) => {
2017-09-29 02:18:56 +03:00
const addErrorHandler = jasmine . createSpy ( )
atom . notifications . onDidAddNotification ( addErrorHandler )
2017-09-29 03:04:46 +03:00
await atom . packages . activatePackage ( 'package-with-missing-consumed-services' )
await atom . packages . activatePackage ( 'package-with-missing-provided-services' )
expect ( atom . packages . isPackageActive ( 'package-with-missing-consumed-services' ) ) . toBe ( true )
expect ( atom . packages . isPackageActive ( 'package-with-missing-provided-services' ) ) . toBe ( true )
expect ( addErrorHandler . callCount ) . toBe ( 0 )
2017-09-29 02:18:56 +03:00
} )
} )
} )
describe ( '::serialize' , ( ) => {
2017-09-29 03:04:46 +03:00
it ( 'does not serialize packages that threw an error during activation' , async ( ) => {
2017-09-29 02:18:56 +03:00
spyOn ( atom , 'inSpecMode' ) . andReturn ( false )
spyOn ( console , 'warn' )
2017-09-29 03:04:46 +03:00
const badPack = await atom . packages . activatePackage ( 'package-that-throws-on-activate' )
spyOn ( badPack . mainModule , 'serialize' ) . andCallThrough ( )
2017-09-29 02:18:56 +03:00
2017-09-29 03:04:46 +03:00
atom . packages . serialize ( )
expect ( badPack . mainModule . serialize ) . not . toHaveBeenCalled ( )
2017-09-29 02:18:56 +03:00
} )
2017-09-29 03:04:46 +03:00
it ( "absorbs exceptions that are thrown by the package module's serialize method" , async ( ) => {
2017-09-29 02:18:56 +03:00
spyOn ( console , 'error' )
2017-09-29 03:04:46 +03:00
await atom . packages . activatePackage ( 'package-with-serialize-error' )
await atom . packages . activatePackage ( 'package-with-serialization' )
atom . packages . serialize ( )
expect ( atom . packages . packageStates [ 'package-with-serialize-error' ] ) . toBeUndefined ( )
expect ( atom . packages . packageStates [ 'package-with-serialization' ] ) . toEqual ( { someNumber : 1 } )
expect ( console . error ) . toHaveBeenCalled ( )
2017-09-29 02:18:56 +03:00
} )
} )
describe ( '::deactivatePackages()' , ( ) => {
2017-09-29 03:04:46 +03:00
it ( 'deactivates all packages but does not serialize them' , async ( ) => {
const pack1 = await atom . packages . activatePackage ( 'package-with-deactivate' )
const pack2 = await atom . packages . activatePackage ( 'package-with-serialization' )
spyOn ( pack1 . mainModule , 'deactivate' )
spyOn ( pack2 . mainModule , 'serialize' )
await atom . packages . deactivatePackages ( )
expect ( pack1 . mainModule . deactivate ) . toHaveBeenCalled ( )
expect ( pack2 . mainModule . serialize ) . not . toHaveBeenCalled ( )
2017-09-29 02:18:56 +03:00
} )
} )
describe ( '::deactivatePackage(id)' , ( ) => {
afterEach ( ( ) => atom . packages . unloadPackages ( ) )
2017-09-29 03:04:46 +03:00
it ( "calls `deactivate` on the package's main module if activate was successful" , async ( ) => {
2017-09-29 02:18:56 +03:00
spyOn ( atom , 'inSpecMode' ) . andReturn ( false )
2017-09-29 03:04:46 +03:00
const pack = await atom . packages . activatePackage ( 'package-with-deactivate' )
expect ( atom . packages . isPackageActive ( 'package-with-deactivate' ) ) . toBeTruthy ( )
spyOn ( pack . mainModule , 'deactivate' ) . andCallThrough ( )
2017-09-29 02:18:56 +03:00
2017-09-29 03:04:46 +03:00
await atom . packages . deactivatePackage ( 'package-with-deactivate' )
expect ( pack . mainModule . deactivate ) . toHaveBeenCalled ( )
expect ( atom . packages . isPackageActive ( 'package-with-module' ) ) . toBeFalsy ( )
2017-09-29 02:18:56 +03:00
2017-09-29 03:04:46 +03:00
spyOn ( console , 'warn' )
const badPack = await atom . packages . activatePackage ( 'package-that-throws-on-activate' )
expect ( atom . packages . isPackageActive ( 'package-that-throws-on-activate' ) ) . toBeTruthy ( )
spyOn ( badPack . mainModule , 'deactivate' ) . andCallThrough ( )
2017-09-29 02:18:56 +03:00
2017-09-29 03:04:46 +03:00
await atom . packages . deactivatePackage ( 'package-that-throws-on-activate' )
expect ( badPack . mainModule . deactivate ) . not . toHaveBeenCalled ( )
expect ( atom . packages . isPackageActive ( 'package-that-throws-on-activate' ) ) . toBeFalsy ( )
2017-09-29 02:18:56 +03:00
} )
2017-09-29 03:04:46 +03:00
it ( "absorbs exceptions that are thrown by the package module's deactivate method" , async ( ) => {
2017-09-29 02:18:56 +03:00
spyOn ( console , 'error' )
2017-09-29 03:04:46 +03:00
await atom . packages . activatePackage ( 'package-that-throws-on-deactivate' )
await atom . packages . deactivatePackage ( 'package-that-throws-on-deactivate' )
expect ( console . error ) . toHaveBeenCalled ( )
2017-09-29 02:18:56 +03:00
} )
2017-09-29 03:04:46 +03:00
it ( "removes the package's grammars" , async ( ) => {
await atom . packages . activatePackage ( 'package-with-grammars' )
await atom . packages . deactivatePackage ( 'package-with-grammars' )
expect ( atom . grammars . selectGrammar ( 'a.alot' ) . name ) . toBe ( 'Null Grammar' )
expect ( atom . grammars . selectGrammar ( 'a.alittle' ) . name ) . toBe ( 'Null Grammar' )
2017-09-29 02:18:56 +03:00
} )
2017-09-29 03:04:46 +03:00
it ( "removes the package's keymaps" , async ( ) => {
await atom . packages . activatePackage ( 'package-with-keymaps' )
await atom . packages . deactivatePackage ( 'package-with-keymaps' )
expect ( atom . keymaps . findKeyBindings ( { keystrokes : 'ctrl-z' , target : createTestElement ( 'test-1' ) } ) ) . toHaveLength ( 0 )
expect ( atom . keymaps . findKeyBindings ( { keystrokes : 'ctrl-z' , target : createTestElement ( 'test-2' ) } ) ) . toHaveLength ( 0 )
2017-09-29 02:18:56 +03:00
} )
2017-09-29 03:04:46 +03:00
it ( "removes the package's stylesheets" , async ( ) => {
await atom . packages . activatePackage ( 'package-with-styles' )
await atom . packages . deactivatePackage ( 'package-with-styles' )
2017-09-29 02:18:56 +03:00
2017-09-29 03:04:46 +03:00
const one = require . resolve ( './fixtures/packages/package-with-style-sheets-manifest/styles/1.css' )
const two = require . resolve ( './fixtures/packages/package-with-style-sheets-manifest/styles/2.less' )
const three = require . resolve ( './fixtures/packages/package-with-style-sheets-manifest/styles/3.css' )
expect ( atom . themes . stylesheetElementForId ( one ) ) . not . toExist ( )
expect ( atom . themes . stylesheetElementForId ( two ) ) . not . toExist ( )
expect ( atom . themes . stylesheetElementForId ( three ) ) . not . toExist ( )
2017-09-29 02:18:56 +03:00
} )
2017-09-29 03:04:46 +03:00
it ( "removes the package's scoped-properties" , async ( ) => {
await atom . packages . activatePackage ( 'package-with-settings' )
expect ( atom . config . get ( 'editor.increaseIndentPattern' , { scope : [ '.source.omg' ] } ) ) . toBe ( '^a' )
2017-09-29 02:18:56 +03:00
2017-09-29 03:04:46 +03:00
await atom . packages . deactivatePackage ( 'package-with-settings' )
expect ( atom . config . get ( 'editor.increaseIndentPattern' , { scope : [ '.source.omg' ] } ) ) . toBeUndefined ( )
2017-09-29 02:18:56 +03:00
} )
2017-09-29 03:04:46 +03:00
it ( 'invokes ::onDidDeactivatePackage listeners with the deactivated package' , async ( ) => {
await atom . packages . activatePackage ( 'package-with-main' )
2017-09-29 02:18:56 +03:00
let deactivatedPackage
2017-09-29 03:04:46 +03:00
atom . packages . onDidDeactivatePackage ( pack => {
deactivatedPackage = pack
2017-09-29 02:18:56 +03:00
} )
2017-09-29 03:04:46 +03:00
await atom . packages . deactivatePackage ( 'package-with-main' )
expect ( deactivatedPackage . name ) . toBe ( 'package-with-main' )
2017-09-29 02:18:56 +03:00
} )
} )
describe ( '::activate()' , ( ) => {
beforeEach ( ( ) => {
spyOn ( atom , 'inSpecMode' ) . andReturn ( false )
jasmine . snapshotDeprecations ( )
spyOn ( console , 'warn' )
atom . packages . loadPackages ( )
const loadedPackages = atom . packages . getLoadedPackages ( )
expect ( loadedPackages . length ) . toBeGreaterThan ( 0 )
} )
2017-09-29 03:04:46 +03:00
afterEach ( async ( ) => {
await atom . packages . deactivatePackages ( )
atom . packages . unloadPackages ( )
jasmine . restoreDeprecationsSnapshot ( )
2017-09-29 02:18:56 +03:00
} )
2017-09-29 03:04:46 +03:00
it ( 'sets hasActivatedInitialPackages' , async ( ) => {
2017-09-29 02:18:56 +03:00
spyOn ( atom . styles , 'getUserStyleSheetPath' ) . andReturn ( null )
spyOn ( atom . packages , 'activatePackages' )
expect ( atom . packages . hasActivatedInitialPackages ( ) ) . toBe ( false )
2017-09-29 03:04:46 +03:00
await atom . packages . activate ( )
expect ( atom . packages . hasActivatedInitialPackages ( ) ) . toBe ( true )
2017-09-29 02:18:56 +03:00
} )
it ( 'activates all the packages, and none of the themes' , ( ) => {
const packageActivator = spyOn ( atom . packages , 'activatePackages' )
const themeActivator = spyOn ( atom . themes , 'activatePackages' )
atom . packages . activate ( )
expect ( packageActivator ) . toHaveBeenCalled ( )
expect ( themeActivator ) . toHaveBeenCalled ( )
const packages = packageActivator . mostRecentCall . args [ 0 ]
for ( let pack of packages ) { expect ( [ 'atom' , 'textmate' ] ) . toContain ( pack . getType ( ) ) }
const themes = themeActivator . mostRecentCall . args [ 0 ]
themes . map ( ( theme ) => expect ( [ 'theme' ] ) . toContain ( theme . getType ( ) ) )
} )
2017-09-29 03:04:46 +03:00
it ( 'calls callbacks registered with ::onDidActivateInitialPackages' , async ( ) => {
2017-09-29 02:18:56 +03:00
const package1 = atom . packages . loadPackage ( 'package-with-main' )
const package2 = atom . packages . loadPackage ( 'package-with-index' )
const package3 = atom . packages . loadPackage ( 'package-with-activation-commands' )
spyOn ( atom . packages , 'getLoadedPackages' ) . andReturn ( [ package1 , package2 , package3 ] )
spyOn ( atom . themes , 'activatePackages' )
atom . packages . activate ( )
2017-09-29 03:04:46 +03:00
await new Promise ( resolve => atom . packages . onDidActivateInitialPackages ( resolve ) )
jasmine . unspy ( atom . packages , 'getLoadedPackages' )
expect ( atom . packages . getActivePackages ( ) . includes ( package1 ) ) . toBe ( true )
expect ( atom . packages . getActivePackages ( ) . includes ( package2 ) ) . toBe ( true )
expect ( atom . packages . getActivePackages ( ) . includes ( package3 ) ) . toBe ( false )
2017-09-29 02:18:56 +03:00
} )
} )
describe ( '::enablePackage(id) and ::disablePackage(id)' , ( ) => {
describe ( 'with packages' , ( ) => {
2017-09-29 03:04:46 +03:00
it ( 'enables a disabled package' , async ( ) => {
2017-09-29 02:18:56 +03:00
const packageName = 'package-with-main'
atom . config . pushAtKeyPath ( 'core.disabledPackages' , packageName )
atom . packages . observeDisabledPackages ( )
expect ( atom . config . get ( 'core.disabledPackages' ) ) . toContain ( packageName )
const pack = atom . packages . enablePackage ( packageName )
2017-09-29 03:04:46 +03:00
await new Promise ( resolve => atom . packages . onDidActivatePackage ( resolve ) )
2017-09-29 02:18:56 +03:00
2017-09-29 03:04:46 +03:00
expect ( atom . packages . getLoadedPackages ( ) ) . toContain ( pack )
expect ( atom . packages . getActivePackages ( ) ) . toContain ( pack )
expect ( atom . config . get ( 'core.disabledPackages' ) ) . not . toContain ( packageName )
2017-09-29 02:18:56 +03:00
} )
2017-09-29 03:04:46 +03:00
it ( 'disables an enabled package' , async ( ) => {
2017-09-29 02:18:56 +03:00
const packageName = 'package-with-main'
2017-09-29 03:04:46 +03:00
const pack = await atom . packages . activatePackage ( packageName )
2017-09-29 02:18:56 +03:00
2017-09-29 03:04:46 +03:00
atom . packages . observeDisabledPackages ( )
expect ( atom . config . get ( 'core.disabledPackages' ) ) . not . toContain ( packageName )
await new Promise ( resolve => {
atom . packages . onDidDeactivatePackage ( resolve )
atom . packages . disablePackage ( packageName )
2017-09-29 02:18:56 +03:00
} )
2017-09-29 03:04:46 +03:00
expect ( atom . packages . getActivePackages ( ) ) . not . toContain ( pack )
expect ( atom . config . get ( 'core.disabledPackages' ) ) . toContain ( packageName )
2017-09-29 02:18:56 +03:00
} )
it ( 'returns null if the package cannot be loaded' , ( ) => {
spyOn ( console , 'warn' )
expect ( atom . packages . enablePackage ( 'this-doesnt-exist' ) ) . toBeNull ( )
expect ( console . warn . callCount ) . toBe ( 1 )
} )
it ( 'does not disable an already disabled package' , ( ) => {
const packageName = 'package-with-main'
atom . config . pushAtKeyPath ( 'core.disabledPackages' , packageName )
atom . packages . observeDisabledPackages ( )
expect ( atom . config . get ( 'core.disabledPackages' ) ) . toContain ( packageName )
atom . packages . disablePackage ( packageName )
const packagesDisabled = atom . config . get ( 'core.disabledPackages' ) . filter ( pack => pack === packageName )
expect ( packagesDisabled . length ) . toEqual ( 1 )
} )
} )
describe ( 'with themes' , ( ) => {
2017-09-29 03:04:46 +03:00
beforeEach ( ( ) => atom . themes . activateThemes ( ) )
afterEach ( ( ) => atom . themes . deactivateThemes ( ) )
2017-09-29 02:18:56 +03:00
2017-09-29 03:04:46 +03:00
it ( 'enables and disables a theme' , async ( ) => {
2017-09-29 02:18:56 +03:00
const packageName = 'theme-with-package-file'
expect ( atom . config . get ( 'core.themes' ) ) . not . toContain ( packageName )
expect ( atom . config . get ( 'core.disabledPackages' ) ) . not . toContain ( packageName )
// enabling of theme
2017-09-29 03:04:46 +03:00
const pack = atom . packages . enablePackage ( packageName )
await new Promise ( resolve => atom . packages . onDidActivatePackage ( resolve ) )
expect ( atom . packages . isPackageActive ( packageName ) ) . toBe ( true )
expect ( atom . config . get ( 'core.themes' ) ) . toContain ( packageName )
expect ( atom . config . get ( 'core.disabledPackages' ) ) . not . toContain ( packageName )
2017-09-29 02:18:56 +03:00
2017-09-29 03:04:46 +03:00
await new Promise ( resolve => {
atom . themes . onDidChangeActiveThemes ( resolve )
atom . packages . disablePackage ( packageName )
2017-09-29 02:18:56 +03:00
} )
2017-09-29 03:04:46 +03:00
expect ( atom . packages . getActivePackages ( ) ) . not . toContain ( pack )
expect ( atom . config . get ( 'core.themes' ) ) . not . toContain ( packageName )
expect ( atom . config . get ( 'core.themes' ) ) . not . toContain ( packageName )
expect ( atom . config . get ( 'core.disabledPackages' ) ) . not . toContain ( packageName )
2017-09-29 02:18:56 +03:00
} )
} )
} )
} )