Merge branch 'master' into mb-tree-sitter-parsers

This commit is contained in:
Max Brunsfeld
2017-12-27 12:35:51 -08:00
12 changed files with 176 additions and 387 deletions

View File

@@ -1,19 +1,14 @@
/** @babel */
const {it, fit, ffit, fffit, beforeEach, afterEach} = require('./async-spec-helpers')
const {Emitter, Disposable, CompositeDisposable} = require('event-kit')
import {it, fit, ffit, fffit, beforeEach, afterEach} from './async-spec-helpers'
import {Emitter, Disposable, CompositeDisposable} from 'event-kit'
import {HistoryManager, HistoryProject} from '../src/history-manager'
import StateStore from '../src/state-store'
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 () => {
// Do not clobber recent project history
spyOn(atom.applicationDelegate, 'didChangeHistoryManager')
commandDisposable = jasmine.createSpyObj('Disposable', ['dispose'])
commandRegistry = jasmine.createSpyObj('CommandRegistry', ['add'])
commandRegistry.add.andReturn(commandDisposable)
@@ -185,11 +180,26 @@ describe("HistoryManager", () => {
})
})
describe("saveState" ,() => {
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'])
})

View File

@@ -63,7 +63,7 @@ else
beforeEach ->
# Do not clobber recent project history
spyOn(atom.history, 'saveState').andReturn(Promise.resolve())
spyOn(Object.getPrototypeOf(atom.history), 'saveState').andReturn(Promise.resolve())
atom.project.setPaths([specProjectPath])

View File

@@ -2840,83 +2840,149 @@ describe('TextEditorComponent', () => {
describe('mouse input', () => {
describe('on the lines', () => {
it('positions the cursor on single-click or when middle/right-clicking', async () => {
for (const button of [0, 1, 2]) {
describe('when there is only one cursor and no selection', () => {
it('positions the cursor on single-click or when middle/right-clicking', async () => {
for (const button of [0, 1, 2]) {
const {component, element, editor} = buildComponent()
const {lineHeight} = component.measurements
editor.setCursorScreenPosition([Infinity, Infinity], {autoscroll: false})
component.didMouseDownOnContent({
detail: 1,
button,
clientX: clientLeftForCharacter(component, 0, 0) - 1,
clientY: clientTopForLine(component, 0) - 1
})
expect(editor.getCursorScreenPosition()).toEqual([0, 0])
const maxRow = editor.getLastScreenRow()
editor.setCursorScreenPosition([Infinity, Infinity], {autoscroll: false})
component.didMouseDownOnContent({
detail: 1,
button,
clientX: clientLeftForCharacter(component, maxRow, editor.lineLengthForScreenRow(maxRow)) + 1,
clientY: clientTopForLine(component, maxRow) + 1
})
expect(editor.getCursorScreenPosition()).toEqual([maxRow, editor.lineLengthForScreenRow(maxRow)])
component.didMouseDownOnContent({
detail: 1,
button,
clientX: clientLeftForCharacter(component, 0, editor.lineLengthForScreenRow(0)) + 1,
clientY: clientTopForLine(component, 0) + lineHeight / 2
})
expect(editor.getCursorScreenPosition()).toEqual([0, editor.lineLengthForScreenRow(0)])
component.didMouseDownOnContent({
detail: 1,
button,
clientX: (clientLeftForCharacter(component, 3, 0) + clientLeftForCharacter(component, 3, 1)) / 2,
clientY: clientTopForLine(component, 1) + lineHeight / 2
})
expect(editor.getCursorScreenPosition()).toEqual([1, 0])
component.didMouseDownOnContent({
detail: 1,
button,
clientX: (clientLeftForCharacter(component, 3, 14) + clientLeftForCharacter(component, 3, 15)) / 2,
clientY: clientTopForLine(component, 3) + lineHeight / 2
})
expect(editor.getCursorScreenPosition()).toEqual([3, 14])
component.didMouseDownOnContent({
detail: 1,
button,
clientX: (clientLeftForCharacter(component, 3, 14) + clientLeftForCharacter(component, 3, 15)) / 2 + 1,
clientY: clientTopForLine(component, 3) + lineHeight / 2
})
expect(editor.getCursorScreenPosition()).toEqual([3, 15])
editor.getBuffer().setTextInRange([[3, 14], [3, 15]], '🐣')
await component.getNextUpdatePromise()
component.didMouseDownOnContent({
detail: 1,
button,
clientX: (clientLeftForCharacter(component, 3, 14) + clientLeftForCharacter(component, 3, 16)) / 2,
clientY: clientTopForLine(component, 3) + lineHeight / 2
})
expect(editor.getCursorScreenPosition()).toEqual([3, 14])
component.didMouseDownOnContent({
detail: 1,
button,
clientX: (clientLeftForCharacter(component, 3, 14) + clientLeftForCharacter(component, 3, 16)) / 2 + 1,
clientY: clientTopForLine(component, 3) + lineHeight / 2
})
expect(editor.getCursorScreenPosition()).toEqual([3, 16])
expect(editor.testAutoscrollRequests).toEqual([])
}
})
})
describe('when there is more than one cursor', () => {
it('does not move the cursor when right-clicking', async () => {
const {component, element, editor} = buildComponent()
const {lineHeight} = component.measurements
editor.setCursorScreenPosition([Infinity, Infinity], {autoscroll: false})
editor.setCursorScreenPosition([5, 17], {autoscroll: false})
editor.addCursorAtScreenPosition([2, 4])
component.didMouseDownOnContent({
detail: 1,
button,
button: 2,
clientX: clientLeftForCharacter(component, 0, 0) - 1,
clientY: clientTopForLine(component, 0) - 1
})
expect(editor.getCursorScreenPosition()).toEqual([0, 0])
expect(editor.getCursorScreenPositions()).toEqual([Point.fromObject([5, 17]), Point.fromObject([2, 4])])
})
const maxRow = editor.getLastScreenRow()
editor.setCursorScreenPosition([Infinity, Infinity], {autoscroll: false})
it('does move the cursor when middle-clicking', async () => {
const {component, element, editor} = buildComponent()
const {lineHeight} = component.measurements
editor.setCursorScreenPosition([5, 17], {autoscroll: false})
editor.addCursorAtScreenPosition([2, 4])
component.didMouseDownOnContent({
detail: 1,
button,
clientX: clientLeftForCharacter(component, maxRow, editor.lineLengthForScreenRow(maxRow)) + 1,
clientY: clientTopForLine(component, maxRow) + 1
button: 1,
clientX: clientLeftForCharacter(component, 0, 0) - 1,
clientY: clientTopForLine(component, 0) - 1
})
expect(editor.getCursorScreenPosition()).toEqual([maxRow, editor.lineLengthForScreenRow(maxRow)])
expect(editor.getCursorScreenPositions()).toEqual([Point.fromObject([0, 0])])
})
})
describe('when there are non-empty selections', () => {
it('does not move the cursor when right-clicking', async () => {
const {component, element, editor} = buildComponent()
const {lineHeight} = component.measurements
editor.setCursorScreenPosition([5, 17], {autoscroll: false})
editor.selectRight(3)
component.didMouseDownOnContent({
detail: 1,
button,
clientX: clientLeftForCharacter(component, 0, editor.lineLengthForScreenRow(0)) + 1,
clientY: clientTopForLine(component, 0) + lineHeight / 2
button: 2,
clientX: clientLeftForCharacter(component, 0, 0) - 1,
clientY: clientTopForLine(component, 0) - 1
})
expect(editor.getCursorScreenPosition()).toEqual([0, editor.lineLengthForScreenRow(0)])
expect(editor.getSelectedScreenRange()).toEqual([[5, 17], [5, 20]])
})
it('does move the cursor when middle-clicking', async () => {
const {component, element, editor} = buildComponent()
const {lineHeight} = component.measurements
editor.setCursorScreenPosition([5, 17], {autoscroll: false})
editor.selectRight(3)
component.didMouseDownOnContent({
detail: 1,
button,
clientX: (clientLeftForCharacter(component, 3, 0) + clientLeftForCharacter(component, 3, 1)) / 2,
clientY: clientTopForLine(component, 1) + lineHeight / 2
button: 1,
clientX: clientLeftForCharacter(component, 0, 0) - 1,
clientY: clientTopForLine(component, 0) - 1
})
expect(editor.getCursorScreenPosition()).toEqual([1, 0])
component.didMouseDownOnContent({
detail: 1,
button,
clientX: (clientLeftForCharacter(component, 3, 14) + clientLeftForCharacter(component, 3, 15)) / 2,
clientY: clientTopForLine(component, 3) + lineHeight / 2
})
expect(editor.getCursorScreenPosition()).toEqual([3, 14])
component.didMouseDownOnContent({
detail: 1,
button,
clientX: (clientLeftForCharacter(component, 3, 14) + clientLeftForCharacter(component, 3, 15)) / 2 + 1,
clientY: clientTopForLine(component, 3) + lineHeight / 2
})
expect(editor.getCursorScreenPosition()).toEqual([3, 15])
editor.getBuffer().setTextInRange([[3, 14], [3, 15]], '🐣')
await component.getNextUpdatePromise()
component.didMouseDownOnContent({
detail: 1,
button,
clientX: (clientLeftForCharacter(component, 3, 14) + clientLeftForCharacter(component, 3, 16)) / 2,
clientY: clientTopForLine(component, 3) + lineHeight / 2
})
expect(editor.getCursorScreenPosition()).toEqual([3, 14])
component.didMouseDownOnContent({
detail: 1,
button,
clientX: (clientLeftForCharacter(component, 3, 14) + clientLeftForCharacter(component, 3, 16)) / 2 + 1,
clientY: clientTopForLine(component, 3) + lineHeight / 2
})
expect(editor.getCursorScreenPosition()).toEqual([3, 16])
expect(editor.testAutoscrollRequests).toEqual([])
}
expect(editor.getSelectedScreenRange()).toEqual([[0, 0], [0, 0]])
})
})
describe('when the input is for the primary mouse button', () => {