Files
atom/packages/incompatible-packages/spec/incompatible-packages-component-spec.js
2018-09-25 12:00:03 -07:00

244 lines
8.6 KiB
JavaScript

/** @babel */
import etch from 'etch'
import IncompatiblePackagesComponent from '../lib/incompatible-packages-component'
describe('IncompatiblePackagesComponent', () => {
let packages, etchScheduler
beforeEach(() => {
etchScheduler = etch.getScheduler()
packages = [
{
name: 'incompatible-1',
isCompatible () {
return false
},
rebuild: function () {
return new Promise((resolve) => this.resolveRebuild = resolve)
},
getBuildFailureOutput () {
return null
},
path: '/Users/joe/.atom/packages/incompatible-1',
metadata: {
repository: 'https://github.com/atom/incompatible-1',
version: '1.0.0'
},
incompatibleModules: [
{name: 'x', version: '1.0.0', error: 'Expected version X, got Y'},
{name: 'y', version: '1.0.0', error: 'Expected version X, got Z'}
]
},
{
name: 'incompatible-2',
isCompatible () {
return false
},
rebuild () {
return new Promise((resolve) => this.resolveRebuild = resolve)
},
getBuildFailureOutput () {
return null
},
path: '/Users/joe/.atom/packages/incompatible-2',
metadata: {
repository: 'https://github.com/atom/incompatible-2',
version: '1.0.0'
},
incompatibleModules: [
{name: 'z', version: '1.0.0', error: 'Expected version X, got Y'}
]
},
{
name: 'compatible',
isCompatible () {
return true
},
rebuild () {
throw new Error('Should not rebuild a compatible package')
},
getBuildFailureOutput () {
return null
},
path: '/Users/joe/.atom/packages/b',
metadata: {
repository: 'https://github.com/atom/b',
version: '1.0.0'
},
incompatibleModules: [],
}
]
})
describe('when packages have not finished loading', () => {
it('delays rendering incompatible packages until the end of the tick', () => {
waitsForPromise(async () => {
let component =
new IncompatiblePackagesComponent({
getActivePackages: () => [],
getLoadedPackages: () => packages
})
let {element} = component
expect(element.querySelectorAll('.incompatible-package').length).toEqual(0)
await etchScheduler.getNextUpdatePromise()
expect(element.querySelectorAll('.incompatible-package').length).toBeGreaterThan(0)
})
})
})
describe('when there are no incompatible packages', () => {
it('does not render incompatible packages or the rebuild button', () => {
waitsForPromise(async () => {
expect(packages[2].isCompatible()).toBe(true)
let compatiblePackages = [packages[2]]
let component =
new IncompatiblePackagesComponent({
getActivePackages: () => compatiblePackages,
getLoadedPackages: () => compatiblePackages
})
let {element} = component
await etchScheduler.getNextUpdatePromise()
expect(element.querySelectorAll('.incompatible-package').length).toBe(0)
expect(element.querySelector('button')).toBeNull()
})
})
})
describe('when some packages previously failed to rebuild', () => {
it('renders them with failed build status and error output', () => {
waitsForPromise(async () => {
packages[1].getBuildFailureOutput = function () {
return 'The build failed'
}
let component =
new IncompatiblePackagesComponent({
getActivePackages: () => packages,
getLoadedPackages: () => packages
})
let {element} = component
await etchScheduler.getNextUpdatePromise()
let packageElement = element.querySelector('.incompatible-package:nth-child(2)')
expect(packageElement.querySelector('.badge').textContent).toBe('Rebuild Failed')
expect(packageElement.querySelector('pre').textContent).toBe('The build failed')
})
})
})
describe('when there are incompatible packages', () => {
it('renders incompatible packages and the rebuild button', () => {
waitsForPromise(async () => {
let component =
new IncompatiblePackagesComponent({
getActivePackages: () => packages,
getLoadedPackages: () => packages
})
let {element} = component
await etchScheduler.getNextUpdatePromise()
expect(element.querySelectorAll('.incompatible-package').length).toEqual(2)
expect(element.querySelector('button')).not.toBeNull()
})
})
describe('when the "Rebuild All" button is clicked', () => {
it('rebuilds every incompatible package, updating each package\'s view with status', () => {
waitsForPromise(async () => {
let component =
new IncompatiblePackagesComponent({
getActivePackages: () => packages,
getLoadedPackages: () => packages
})
let {element} = component
jasmine.attachToDOM(element)
await etchScheduler.getNextUpdatePromise()
component.refs.rebuildButton.dispatchEvent(new CustomEvent('click', {bubbles: true}))
await etchScheduler.getNextUpdatePromise() // view update
expect(component.refs.rebuildButton.disabled).toBe(true)
expect(packages[0].resolveRebuild).toBeDefined()
expect(element.querySelector('.incompatible-package:nth-child(1) .badge').textContent).toBe('Rebuilding')
expect(element.querySelector('.incompatible-package:nth-child(2) .badge')).toBeNull()
packages[0].resolveRebuild({code: 0}) // simulate rebuild success
await etchScheduler.getNextUpdatePromise() // view update
expect(packages[1].resolveRebuild).toBeDefined()
expect(element.querySelector('.incompatible-package:nth-child(1) .badge').textContent).toBe('Rebuild Succeeded')
expect(element.querySelector('.incompatible-package:nth-child(2) .badge').textContent).toBe('Rebuilding')
packages[1].resolveRebuild({code: 12, stderr: 'This is an error from the test!'}) // simulate rebuild failure
await etchScheduler.getNextUpdatePromise() // view update
expect(element.querySelector('.incompatible-package:nth-child(1) .badge').textContent).toBe('Rebuild Succeeded')
expect(element.querySelector('.incompatible-package:nth-child(2) .badge').textContent).toBe('Rebuild Failed')
expect(element.querySelector('.incompatible-package:nth-child(2) pre').textContent).toBe('This is an error from the test!')
})
})
it('displays a prompt to reload Atom when the packages finish rebuilding', () => {
waitsForPromise(async () => {
let component =
new IncompatiblePackagesComponent({
getActivePackages: () => packages,
getLoadedPackages: () => packages
})
let {element} = component
jasmine.attachToDOM(element)
await etchScheduler.getNextUpdatePromise() // view update
component.refs.rebuildButton.dispatchEvent(new CustomEvent('click', {bubbles: true}))
expect(packages[0].resolveRebuild({code: 0}))
await new Promise(global.setImmediate)
expect(packages[1].resolveRebuild({code: 0}))
await etchScheduler.getNextUpdatePromise() // view update
expect(component.refs.reloadButton).toBeDefined()
expect(element.querySelector('.alert').textContent).toMatch(/2 of 2/)
spyOn(atom, 'reload')
component.refs.reloadButton.dispatchEvent(new CustomEvent('click', {bubbles: true}))
expect(atom.reload).toHaveBeenCalled()
})
})
})
describe('when the "Package Settings" button is clicked', () => {
it('opens the settings panel for the package', () => {
waitsForPromise(async () => {
let component =
new IncompatiblePackagesComponent({
getActivePackages: () => packages,
getLoadedPackages: () => packages
})
let {element} = component
jasmine.attachToDOM(element)
await etchScheduler.getNextUpdatePromise()
spyOn(atom.workspace, 'open')
element.querySelector('.incompatible-package:nth-child(2) button').dispatchEvent(new CustomEvent('click', {bubbles: true}))
expect(atom.workspace.open).toHaveBeenCalledWith('atom://config/packages/incompatible-2')
})
})
})
})
})