pulsar/spec/history-manager-spec.js

227 lines
7.9 KiB
JavaScript

const { HistoryManager, HistoryProject } = require('../src/history-manager')
const StateStore = require('../src/state-store')
describe('HistoryManager', () => {
let historyManager, commandRegistry, project, stateStore
let commandDisposable, projectDisposable
beforeEach(async () => {
commandDisposable = jasmine.createSpyObj('Disposable', ['dispose'])
commandRegistry = jasmine.createSpyObj('CommandRegistry', ['add'])
commandRegistry.add.andReturn(commandDisposable)
stateStore = new StateStore('history-manager-test', 1)
await stateStore.save('history-manager', {
projects: [
{
paths: ['/1', 'c:\\2'],
lastOpened: new Date(2016, 9, 17, 17, 16, 23)
},
{ paths: ['/test'], lastOpened: new Date(2016, 9, 17, 11, 12, 13) }
]
})
projectDisposable = jasmine.createSpyObj('Disposable', ['dispose'])
project = jasmine.createSpyObj('Project', ['onDidChangePaths'])
project.onDidChangePaths.andCallFake(f => {
project.didChangePathsListener = f
return projectDisposable
})
historyManager = new HistoryManager({
stateStore,
project,
commands: commandRegistry
})
await historyManager.loadState()
})
afterEach(async () => {
await stateStore.clear()
})
describe('constructor', () => {
it("registers the 'clear-project-history' command function", () => {
expect(commandRegistry.add).toHaveBeenCalled()
const cmdCall = commandRegistry.add.calls[0]
expect(cmdCall.args.length).toBe(3)
expect(cmdCall.args[0]).toBe('atom-workspace')
expect(typeof cmdCall.args[1]['application:clear-project-history']).toBe(
'function'
)
})
describe('getProjects', () => {
it('returns an array of HistoryProjects', () => {
expect(historyManager.getProjects()).toEqual([
new HistoryProject(
['/1', 'c:\\2'],
new Date(2016, 9, 17, 17, 16, 23)
),
new HistoryProject(['/test'], new Date(2016, 9, 17, 11, 12, 13))
])
})
it('returns an array of HistoryProjects that is not mutable state', () => {
const firstProjects = historyManager.getProjects()
firstProjects.pop()
firstProjects[0].path = 'modified'
const secondProjects = historyManager.getProjects()
expect(secondProjects.length).toBe(2)
expect(secondProjects[0].path).not.toBe('modified')
})
})
describe('clearProjects', () => {
it('clears the list of projects', async () => {
expect(historyManager.getProjects().length).not.toBe(0)
await historyManager.clearProjects()
expect(historyManager.getProjects().length).toBe(0)
})
it('saves the state', async () => {
await historyManager.clearProjects()
const historyManager2 = new HistoryManager({
stateStore,
project,
commands: commandRegistry
})
await historyManager2.loadState()
expect(historyManager.getProjects().length).toBe(0)
})
it('fires the onDidChangeProjects event', async () => {
const didChangeSpy = jasmine.createSpy()
historyManager.onDidChangeProjects(didChangeSpy)
await historyManager.clearProjects()
expect(historyManager.getProjects().length).toBe(0)
expect(didChangeSpy).toHaveBeenCalled()
})
})
it('listens to project.onDidChangePaths adding a new project', () => {
const start = new Date()
project.didChangePathsListener(['/a/new', '/path/or/two'])
const projects = historyManager.getProjects()
expect(projects.length).toBe(3)
expect(projects[0].paths).toEqual(['/a/new', '/path/or/two'])
expect(projects[0].lastOpened).not.toBeLessThan(start)
})
it('listens to project.onDidChangePaths updating an existing project', () => {
const start = new Date()
project.didChangePathsListener(['/test'])
const projects = historyManager.getProjects()
expect(projects.length).toBe(2)
expect(projects[0].paths).toEqual(['/test'])
expect(projects[0].lastOpened).not.toBeLessThan(start)
})
})
describe('loadState', () => {
it('defaults to an empty array if no state', async () => {
await stateStore.clear()
await historyManager.loadState()
expect(historyManager.getProjects()).toEqual([])
})
it('defaults to an empty array if no projects', async () => {
await stateStore.save('history-manager', {})
await historyManager.loadState()
expect(historyManager.getProjects()).toEqual([])
})
})
describe('addProject', () => {
it('adds a new project to the end', async () => {
const date = new Date(2010, 10, 9, 8, 7, 6)
await historyManager.addProject(['/a/b'], date)
const projects = historyManager.getProjects()
expect(projects.length).toBe(3)
expect(projects[2].paths).toEqual(['/a/b'])
expect(projects[2].lastOpened).toBe(date)
})
it('adds a new project to the start', async () => {
const date = new Date()
await historyManager.addProject(['/so/new'], date)
const projects = historyManager.getProjects()
expect(projects.length).toBe(3)
expect(projects[0].paths).toEqual(['/so/new'])
expect(projects[0].lastOpened).toBe(date)
})
it('updates an existing project and moves it to the start', async () => {
const date = new Date()
await historyManager.addProject(['/test'], date)
const projects = historyManager.getProjects()
expect(projects.length).toBe(2)
expect(projects[0].paths).toEqual(['/test'])
expect(projects[0].lastOpened).toBe(date)
})
it('fires the onDidChangeProjects event when adding a project', async () => {
const didChangeSpy = jasmine.createSpy()
const beforeCount = historyManager.getProjects().length
historyManager.onDidChangeProjects(didChangeSpy)
await historyManager.addProject(['/test-new'], new Date())
expect(didChangeSpy).toHaveBeenCalled()
expect(historyManager.getProjects().length).toBe(beforeCount + 1)
})
it('fires the onDidChangeProjects event when updating a project', async () => {
const didChangeSpy = jasmine.createSpy()
const beforeCount = historyManager.getProjects().length
historyManager.onDidChangeProjects(didChangeSpy)
await historyManager.addProject(['/test'], new Date())
expect(didChangeSpy).toHaveBeenCalled()
expect(historyManager.getProjects().length).toBe(beforeCount)
})
})
describe('getProject', () => {
it('returns a project that matches the paths', () => {
const project = historyManager.getProject(['/1', 'c:\\2'])
expect(project).not.toBeNull()
expect(project.paths).toEqual(['/1', 'c:\\2'])
})
it("returns null when it can't find the project", () => {
const project = historyManager.getProject(['/1'])
expect(project).toBeNull()
})
})
describe('saveState', () => {
let savedHistory
beforeEach(() => {
// historyManager.saveState is spied on globally to prevent specs from
// modifying the shared project history. Since these tests depend on
// saveState, we unspy it but in turn spy on the state store instead
// so that no data is actually stored to it.
jasmine.unspy(historyManager, 'saveState')
spyOn(historyManager.stateStore, 'save').andCallFake((name, history) => {
savedHistory = history
return Promise.resolve()
})
})
it('saves the state', async () => {
await historyManager.addProject(['/save/state'])
await historyManager.saveState()
const historyManager2 = new HistoryManager({
stateStore,
project,
commands: commandRegistry
})
spyOn(historyManager2.stateStore, 'load').andCallFake(name =>
Promise.resolve(savedHistory)
)
await historyManager2.loadState()
expect(historyManager2.getProjects()[0].paths).toEqual(['/save/state'])
})
})
})