mirror of
https://github.com/pulsar-edit/pulsar.git
synced 2024-11-13 08:44:12 +03:00
Reorganize specs on TextEditorPresenter to mirror structure of state
This commit is contained in:
parent
59b109654e
commit
de0b5c4c62
@ -18,347 +18,341 @@ describe "TextEditorPresenter", ->
|
||||
for key, value of expected
|
||||
expect(actual[key]).toBe value
|
||||
|
||||
describe "::state.content", ->
|
||||
describe "on initialization", ->
|
||||
it "assigns .scrollWidth based on the clientWidth and the width of the longest line", ->
|
||||
maxLineLength = editor.getMaxScreenLineLength()
|
||||
# These `describe` and `it` blocks mirror the structure of the ::state object.
|
||||
# Please maintain this structure when adding specs for new state fields.
|
||||
describe "::state", ->
|
||||
describe ".content", ->
|
||||
describe ".scrollWidth", ->
|
||||
it "is initialized as the max of the clientWidth and the width of the longest line", ->
|
||||
maxLineLength = editor.getMaxScreenLineLength()
|
||||
|
||||
presenter = new TextEditorPresenter(model: editor, clientWidth: 50, baseCharacterWidth: 10)
|
||||
expect(presenter.state.content.scrollWidth).toBe 10 * maxLineLength + 1
|
||||
presenter = new TextEditorPresenter(model: editor, clientWidth: 50, baseCharacterWidth: 10)
|
||||
expect(presenter.state.content.scrollWidth).toBe 10 * maxLineLength + 1
|
||||
|
||||
presenter = new TextEditorPresenter(model: editor, clientWidth: 10 * maxLineLength + 20, baseCharacterWidth: 10)
|
||||
expect(presenter.state.content.scrollWidth).toBe 10 * maxLineLength + 20
|
||||
presenter = new TextEditorPresenter(model: editor, clientWidth: 10 * maxLineLength + 20, baseCharacterWidth: 10)
|
||||
expect(presenter.state.content.scrollWidth).toBe 10 * maxLineLength + 20
|
||||
|
||||
it "assigns .indentGuidesVisible based on the editor.showIndentGuide config setting", ->
|
||||
presenter = new TextEditorPresenter(model: editor)
|
||||
expect(presenter.state.content.indentGuidesVisible).toBe false
|
||||
it "updates when the ::clientWidth changes", ->
|
||||
maxLineLength = editor.getMaxScreenLineLength()
|
||||
presenter = new TextEditorPresenter(model: editor, clientWidth: 50, baseCharacterWidth: 10)
|
||||
|
||||
atom.config.set('editor.showIndentGuide', true)
|
||||
presenter = new TextEditorPresenter(model: editor)
|
||||
expect(presenter.state.content.indentGuidesVisible).toBe true
|
||||
expect(presenter.state.content.scrollWidth).toBe 10 * maxLineLength + 1
|
||||
presenter.setClientWidth(10 * maxLineLength + 20)
|
||||
expect(presenter.state.content.scrollWidth).toBe 10 * maxLineLength + 20
|
||||
|
||||
describe "when the ::clientWidth changes", ->
|
||||
it "updates .scrollWidth", ->
|
||||
maxLineLength = editor.getMaxScreenLineLength()
|
||||
presenter = new TextEditorPresenter(model: editor, clientWidth: 50, baseCharacterWidth: 10)
|
||||
it "updates when the ::baseCharacterWidth changes", ->
|
||||
maxLineLength = editor.getMaxScreenLineLength()
|
||||
presenter = new TextEditorPresenter(model: editor, clientWidth: 50, baseCharacterWidth: 10)
|
||||
|
||||
expect(presenter.state.content.scrollWidth).toBe 10 * maxLineLength + 1
|
||||
presenter.setClientWidth(10 * maxLineLength + 20)
|
||||
expect(presenter.state.content.scrollWidth).toBe 10 * maxLineLength + 20
|
||||
expect(presenter.state.content.scrollWidth).toBe 10 * maxLineLength + 1
|
||||
presenter.setBaseCharacterWidth(15)
|
||||
expect(presenter.state.content.scrollWidth).toBe 15 * maxLineLength + 1
|
||||
|
||||
describe "when the ::baseCharacterWidth changes", ->
|
||||
it "updates the width of the lines if it changes the ::scrollWidth", ->
|
||||
maxLineLength = editor.getMaxScreenLineLength()
|
||||
presenter = new TextEditorPresenter(model: editor, clientWidth: 50, baseCharacterWidth: 10)
|
||||
it "updates when the scoped character widths change", ->
|
||||
waitsForPromise -> atom.packages.activatePackage('language-javascript')
|
||||
|
||||
expect(presenter.state.content.scrollWidth).toBe 10 * maxLineLength + 1
|
||||
presenter.setBaseCharacterWidth(15)
|
||||
expect(presenter.state.content.scrollWidth).toBe 15 * maxLineLength + 1
|
||||
runs ->
|
||||
maxLineLength = editor.getMaxScreenLineLength()
|
||||
presenter = new TextEditorPresenter(model: editor, clientWidth: 50, baseCharacterWidth: 10)
|
||||
|
||||
describe "when the scoped character widths change", ->
|
||||
beforeEach ->
|
||||
waitsForPromise -> atom.packages.activatePackage('language-javascript')
|
||||
expect(presenter.state.content.scrollWidth).toBe 10 * maxLineLength + 1
|
||||
presenter.setScopedCharWidth(['source.js', 'support.function.js'], 'p', 20)
|
||||
expect(presenter.state.content.scrollWidth).toBe (10 * (maxLineLength - 2)) + (20 * 2) + 1 # 2 of the characters are 20px wide now instead of 10px wide
|
||||
|
||||
it "updates the width of the lines if the ::scrollWidth changes", ->
|
||||
maxLineLength = editor.getMaxScreenLineLength()
|
||||
presenter = new TextEditorPresenter(model: editor, clientWidth: 50, baseCharacterWidth: 10)
|
||||
it "updates when ::softWrapped changes on the editor", ->
|
||||
presenter = new TextEditorPresenter(model: editor, clientWidth: 50, baseCharacterWidth: 10)
|
||||
expect(presenter.state.content.scrollWidth).toBe 10 * editor.getMaxScreenLineLength() + 1
|
||||
editor.setSoftWrapped(true)
|
||||
expect(presenter.state.content.scrollWidth).toBe 10 * editor.getMaxScreenLineLength()
|
||||
editor.setSoftWrapped(false)
|
||||
expect(presenter.state.content.scrollWidth).toBe 10 * editor.getMaxScreenLineLength() + 1
|
||||
|
||||
expect(presenter.state.content.scrollWidth).toBe 10 * maxLineLength + 1
|
||||
presenter.setScopedCharWidth(['source.js', 'support.function.js'], 'p', 20)
|
||||
expect(presenter.state.content.scrollWidth).toBe (10 * (maxLineLength - 2)) + (20 * 2) + 1 # 2 of the characters are 20px wide now instead of 10px wide
|
||||
|
||||
describe "when ::softWrapped changes on the editor", ->
|
||||
it "only accounts for the cursor in .scrollWidth if ::softWrapped is false", ->
|
||||
presenter = new TextEditorPresenter(model: editor, clientWidth: 50, baseCharacterWidth: 10)
|
||||
expect(presenter.state.content.scrollWidth).toBe 10 * editor.getMaxScreenLineLength() + 1
|
||||
editor.setSoftWrapped(true)
|
||||
expect(presenter.state.content.scrollWidth).toBe 10 * editor.getMaxScreenLineLength()
|
||||
editor.setSoftWrapped(false)
|
||||
expect(presenter.state.content.scrollWidth).toBe 10 * editor.getMaxScreenLineLength() + 1
|
||||
|
||||
describe "when the editor.showIndentGuide config setting changes", ->
|
||||
it "updates .indentGuidesVisible", ->
|
||||
presenter = new TextEditorPresenter(model: editor)
|
||||
expect(presenter.state.content.indentGuidesVisible).toBe false
|
||||
|
||||
atom.config.set('editor.showIndentGuide', true)
|
||||
expect(presenter.state.content.indentGuidesVisible).toBe true
|
||||
|
||||
atom.config.set('editor.showIndentGuide', false)
|
||||
expect(presenter.state.content.indentGuidesVisible).toBe false
|
||||
|
||||
describe "when the editor's grammar changes", ->
|
||||
it "updates .indentGuidesVisible based on the grammar's root scope", ->
|
||||
atom.config.set('editor.showIndentGuide', true, scopeSelector: ".source.js")
|
||||
|
||||
presenter = new TextEditorPresenter(model: editor)
|
||||
expect(presenter.state.content.indentGuidesVisible).toBe false
|
||||
|
||||
waitsForPromise -> atom.packages.activatePackage('language-javascript')
|
||||
|
||||
runs ->
|
||||
editor.setGrammar(atom.grammars.selectGrammar('.js'))
|
||||
expect(presenter.state.content.indentGuidesVisible).toBe true
|
||||
|
||||
editor.setGrammar(atom.grammars.selectGrammar('.txt'))
|
||||
describe ".indentGuidesVisible", ->
|
||||
it "is initialized based on the editor.showIndentGuide config setting", ->
|
||||
presenter = new TextEditorPresenter(model: editor)
|
||||
expect(presenter.state.content.indentGuidesVisible).toBe false
|
||||
|
||||
describe "::state.content.lines", ->
|
||||
lineStateForScreenRow = (presenter, screenRow) ->
|
||||
presenter.state.content.lines[presenter.model.tokenizedLineForScreenRow(screenRow).id]
|
||||
atom.config.set('editor.showIndentGuide', true)
|
||||
presenter = new TextEditorPresenter(model: editor)
|
||||
expect(presenter.state.content.indentGuidesVisible).toBe true
|
||||
|
||||
describe "on initialization", ->
|
||||
it "contains the lines that are visible on screen, plus and minus the overdraw margin", ->
|
||||
presenter = new TextEditorPresenter(model: editor, clientHeight: 15, scrollTop: 50, lineHeight: 10, lineOverdrawMargin: 1)
|
||||
it "updates when the editor.showIndentGuide config setting changes", ->
|
||||
presenter = new TextEditorPresenter(model: editor)
|
||||
expect(presenter.state.content.indentGuidesVisible).toBe false
|
||||
|
||||
expect(lineStateForScreenRow(presenter, 3)).toBeUndefined()
|
||||
atom.config.set('editor.showIndentGuide', true)
|
||||
expect(presenter.state.content.indentGuidesVisible).toBe true
|
||||
|
||||
line4 = editor.tokenizedLineForScreenRow(4)
|
||||
expectValues lineStateForScreenRow(presenter, 4), {
|
||||
screenRow: 4
|
||||
text: line4.text
|
||||
tokens: line4.tokens
|
||||
top: 10 * 4
|
||||
}
|
||||
atom.config.set('editor.showIndentGuide', false)
|
||||
expect(presenter.state.content.indentGuidesVisible).toBe false
|
||||
|
||||
line5 = editor.tokenizedLineForScreenRow(5)
|
||||
expectValues lineStateForScreenRow(presenter, 5), {
|
||||
screenRow: 5
|
||||
text: line5.text
|
||||
tokens: line5.tokens
|
||||
top: 10 * 5
|
||||
}
|
||||
it "updates when the editor's grammar changes", ->
|
||||
atom.config.set('editor.showIndentGuide', true, scopeSelector: ".source.js")
|
||||
|
||||
line6 = editor.tokenizedLineForScreenRow(6)
|
||||
expectValues lineStateForScreenRow(presenter, 6), {
|
||||
screenRow: 6
|
||||
text: line6.text
|
||||
tokens: line6.tokens
|
||||
top: 10 * 6
|
||||
}
|
||||
presenter = new TextEditorPresenter(model: editor)
|
||||
expect(presenter.state.content.indentGuidesVisible).toBe false
|
||||
|
||||
line7 = editor.tokenizedLineForScreenRow(7)
|
||||
expectValues lineStateForScreenRow(presenter, 7), {
|
||||
screenRow: 7
|
||||
text: line7.text
|
||||
tokens: line7.tokens
|
||||
top: 10 * 7
|
||||
}
|
||||
waitsForPromise -> atom.packages.activatePackage('language-javascript')
|
||||
|
||||
line8 = editor.tokenizedLineForScreenRow(8)
|
||||
expectValues lineStateForScreenRow(presenter, 8), {
|
||||
screenRow: 8
|
||||
text: line8.text
|
||||
tokens: line8.tokens
|
||||
top: 10 * 8
|
||||
}
|
||||
runs ->
|
||||
editor.setGrammar(atom.grammars.selectGrammar('.js'))
|
||||
expect(presenter.state.content.indentGuidesVisible).toBe true
|
||||
|
||||
expect(lineStateForScreenRow(presenter, 9)).toBeUndefined()
|
||||
editor.setGrammar(atom.grammars.selectGrammar('.txt'))
|
||||
expect(presenter.state.content.indentGuidesVisible).toBe false
|
||||
|
||||
it "does not overdraw beyond the first row", ->
|
||||
presenter = new TextEditorPresenter(model: editor, clientHeight: 15, scrollTop: 10, lineHeight: 10, lineOverdrawMargin: 2)
|
||||
expect(lineStateForScreenRow(presenter, 0)).toBeDefined()
|
||||
expect(lineStateForScreenRow(presenter, 1)).toBeDefined()
|
||||
expect(lineStateForScreenRow(presenter, 2)).toBeDefined()
|
||||
expect(lineStateForScreenRow(presenter, 3)).toBeDefined()
|
||||
expect(lineStateForScreenRow(presenter, 4)).toBeDefined()
|
||||
expect(lineStateForScreenRow(presenter, 5)).toBeDefined()
|
||||
expect(lineStateForScreenRow(presenter, 6)).toBeUndefined()
|
||||
describe ".lines", ->
|
||||
lineStateForScreenRow = (presenter, screenRow) ->
|
||||
presenter.state.content.lines[presenter.model.tokenizedLineForScreenRow(screenRow).id]
|
||||
|
||||
it "does not overdraw beyond the last row", ->
|
||||
presenter = new TextEditorPresenter(model: editor, clientHeight: 25, scrollTop: 105, lineHeight: 10, lineOverdrawMargin: 2)
|
||||
expect(lineStateForScreenRow(presenter, 7)).toBeUndefined()
|
||||
expect(lineStateForScreenRow(presenter, 8)).toBeDefined()
|
||||
expect(lineStateForScreenRow(presenter, 9)).toBeDefined()
|
||||
expect(lineStateForScreenRow(presenter, 10)).toBeDefined()
|
||||
expect(lineStateForScreenRow(presenter, 11)).toBeDefined()
|
||||
expect(lineStateForScreenRow(presenter, 12)).toBeDefined()
|
||||
it "contains states for lines that are visible on screen, plus and minus the overdraw margin", ->
|
||||
presenter = new TextEditorPresenter(model: editor, clientHeight: 15, scrollTop: 50, lineHeight: 10, lineOverdrawMargin: 1)
|
||||
|
||||
it "reports all lines as visible if no external ::clientHeight is assigned", ->
|
||||
presenter = new TextEditorPresenter(model: editor, scrollTop: 0, lineHeight: 10, lineOverdrawMargin: 1)
|
||||
expect(lineStateForScreenRow(presenter, 0)).toBeDefined()
|
||||
expect(lineStateForScreenRow(presenter, 12)).toBeDefined()
|
||||
expect(lineStateForScreenRow(presenter, 3)).toBeUndefined()
|
||||
|
||||
it "includes the .endOfLineInvisibles in the line state if the editor.showInvisibles config option is true", ->
|
||||
editor.setText("hello\nworld\r\n")
|
||||
presenter = new TextEditorPresenter(model: editor, clientHeight: 25, scrollTop: 0, lineHeight: 10, lineOverdrawMargin: 0)
|
||||
expect(lineStateForScreenRow(presenter, 0).endOfLineInvisibles).toBeNull()
|
||||
expect(lineStateForScreenRow(presenter, 1).endOfLineInvisibles).toBeNull()
|
||||
line4 = editor.tokenizedLineForScreenRow(4)
|
||||
expectValues lineStateForScreenRow(presenter, 4), {
|
||||
screenRow: 4
|
||||
text: line4.text
|
||||
tokens: line4.tokens
|
||||
top: 10 * 4
|
||||
}
|
||||
|
||||
atom.config.set('editor.showInvisibles', true)
|
||||
presenter = new TextEditorPresenter(model: editor, clientHeight: 25, scrollTop: 0, lineHeight: 10, lineOverdrawMargin: 0)
|
||||
expect(lineStateForScreenRow(presenter, 0).endOfLineInvisibles).toEqual [atom.config.get('editor.invisibles.eol')]
|
||||
expect(lineStateForScreenRow(presenter, 1).endOfLineInvisibles).toEqual [atom.config.get('editor.invisibles.cr'), atom.config.get('editor.invisibles.eol')]
|
||||
line5 = editor.tokenizedLineForScreenRow(5)
|
||||
expectValues lineStateForScreenRow(presenter, 5), {
|
||||
screenRow: 5
|
||||
text: line5.text
|
||||
tokens: line5.tokens
|
||||
top: 10 * 5
|
||||
}
|
||||
|
||||
describe "when ::scrollTop changes", ->
|
||||
it "updates the lines that are visible on screen", ->
|
||||
presenter = new TextEditorPresenter(model: editor, clientHeight: 25, scrollTop: 0, lineHeight: 10, lineOverdrawMargin: 1)
|
||||
line6 = editor.tokenizedLineForScreenRow(6)
|
||||
expectValues lineStateForScreenRow(presenter, 6), {
|
||||
screenRow: 6
|
||||
text: line6.text
|
||||
tokens: line6.tokens
|
||||
top: 10 * 6
|
||||
}
|
||||
|
||||
expect(lineStateForScreenRow(presenter, 0)).toBeDefined()
|
||||
expect(lineStateForScreenRow(presenter, 4)).toBeDefined()
|
||||
expect(lineStateForScreenRow(presenter, 5)).toBeUndefined()
|
||||
line7 = editor.tokenizedLineForScreenRow(7)
|
||||
expectValues lineStateForScreenRow(presenter, 7), {
|
||||
screenRow: 7
|
||||
text: line7.text
|
||||
tokens: line7.tokens
|
||||
top: 10 * 7
|
||||
}
|
||||
|
||||
presenter.setScrollTop(25)
|
||||
line8 = editor.tokenizedLineForScreenRow(8)
|
||||
expectValues lineStateForScreenRow(presenter, 8), {
|
||||
screenRow: 8
|
||||
text: line8.text
|
||||
tokens: line8.tokens
|
||||
top: 10 * 8
|
||||
}
|
||||
|
||||
expect(lineStateForScreenRow(presenter, 0)).toBeUndefined()
|
||||
expect(lineStateForScreenRow(presenter, 1)).toBeDefined()
|
||||
expect(lineStateForScreenRow(presenter, 6)).toBeDefined()
|
||||
expect(lineStateForScreenRow(presenter, 7)).toBeUndefined()
|
||||
expect(lineStateForScreenRow(presenter, 9)).toBeUndefined()
|
||||
|
||||
describe "when ::clientHeight changes", ->
|
||||
it "updates the lines that are visible on screen", ->
|
||||
presenter = new TextEditorPresenter(model: editor, clientHeight: 15, scrollTop: 15, lineHeight: 10, lineOverdrawMargin: 1)
|
||||
it "does not overdraw above the first row", ->
|
||||
presenter = new TextEditorPresenter(model: editor, clientHeight: 15, scrollTop: 10, lineHeight: 10, lineOverdrawMargin: 2)
|
||||
expect(lineStateForScreenRow(presenter, 0)).toBeDefined()
|
||||
expect(lineStateForScreenRow(presenter, 1)).toBeDefined()
|
||||
expect(lineStateForScreenRow(presenter, 2)).toBeDefined()
|
||||
expect(lineStateForScreenRow(presenter, 3)).toBeDefined()
|
||||
expect(lineStateForScreenRow(presenter, 4)).toBeDefined()
|
||||
expect(lineStateForScreenRow(presenter, 5)).toBeDefined()
|
||||
expect(lineStateForScreenRow(presenter, 6)).toBeUndefined()
|
||||
|
||||
line5 = editor.tokenizedLineForScreenRow(5)
|
||||
it "does not overdraw below the last row", ->
|
||||
presenter = new TextEditorPresenter(model: editor, clientHeight: 25, scrollTop: 105, lineHeight: 10, lineOverdrawMargin: 2)
|
||||
expect(lineStateForScreenRow(presenter, 7)).toBeUndefined()
|
||||
expect(lineStateForScreenRow(presenter, 8)).toBeDefined()
|
||||
expect(lineStateForScreenRow(presenter, 9)).toBeDefined()
|
||||
expect(lineStateForScreenRow(presenter, 10)).toBeDefined()
|
||||
expect(lineStateForScreenRow(presenter, 11)).toBeDefined()
|
||||
expect(lineStateForScreenRow(presenter, 12)).toBeDefined()
|
||||
|
||||
expect(lineStateForScreenRow(presenter, 4)).toBeDefined()
|
||||
expect(lineStateForScreenRow(presenter, 5)).toBeUndefined()
|
||||
it "includes state for all lines if no external ::clientHeight is assigned", ->
|
||||
presenter = new TextEditorPresenter(model: editor, scrollTop: 0, lineHeight: 10, lineOverdrawMargin: 1)
|
||||
expect(lineStateForScreenRow(presenter, 0)).toBeDefined()
|
||||
expect(lineStateForScreenRow(presenter, 12)).toBeDefined()
|
||||
|
||||
presenter.setClientHeight(35)
|
||||
it "updates when ::scrollTop changes", ->
|
||||
presenter = new TextEditorPresenter(model: editor, clientHeight: 25, scrollTop: 0, lineHeight: 10, lineOverdrawMargin: 1)
|
||||
|
||||
expect(lineStateForScreenRow(presenter, 5)).toBeDefined()
|
||||
expect(lineStateForScreenRow(presenter, 6)).toBeDefined()
|
||||
expect(lineStateForScreenRow(presenter, 7)).toBeUndefined()
|
||||
expect(lineStateForScreenRow(presenter, 0)).toBeDefined()
|
||||
expect(lineStateForScreenRow(presenter, 4)).toBeDefined()
|
||||
expect(lineStateForScreenRow(presenter, 5)).toBeUndefined()
|
||||
|
||||
describe "when ::lineHeight changes", ->
|
||||
it "updates the lines that are visible on screen", ->
|
||||
presenter = new TextEditorPresenter(model: editor, clientHeight: 15, scrollTop: 10, lineHeight: 10, lineOverdrawMargin: 0)
|
||||
presenter.setScrollTop(25)
|
||||
|
||||
expect(lineStateForScreenRow(presenter, 0)).toBeUndefined()
|
||||
expect(lineStateForScreenRow(presenter, 1)).toBeDefined()
|
||||
expect(lineStateForScreenRow(presenter, 2)).toBeDefined()
|
||||
expect(lineStateForScreenRow(presenter, 4)).toBeUndefined()
|
||||
expect(lineStateForScreenRow(presenter, 0)).toBeUndefined()
|
||||
expect(lineStateForScreenRow(presenter, 1)).toBeDefined()
|
||||
expect(lineStateForScreenRow(presenter, 6)).toBeDefined()
|
||||
expect(lineStateForScreenRow(presenter, 7)).toBeUndefined()
|
||||
|
||||
presenter.setLineHeight(5)
|
||||
it "updates when ::clientHeight changes", ->
|
||||
presenter = new TextEditorPresenter(model: editor, clientHeight: 15, scrollTop: 15, lineHeight: 10, lineOverdrawMargin: 1)
|
||||
|
||||
expect(lineStateForScreenRow(presenter, 0)).toBeUndefined()
|
||||
expect(lineStateForScreenRow(presenter, 1)).toBeUndefined()
|
||||
expect(lineStateForScreenRow(presenter, 2)).toBeDefined()
|
||||
expect(lineStateForScreenRow(presenter, 5)).toBeDefined()
|
||||
expect(lineStateForScreenRow(presenter, 6)).toBeUndefined()
|
||||
line5 = editor.tokenizedLineForScreenRow(5)
|
||||
|
||||
describe "when the editor's content changes", ->
|
||||
it "updates the lines state accordingly", ->
|
||||
presenter = new TextEditorPresenter(model: editor, clientHeight: 25, scrollTop: 10, lineHeight: 10, lineOverdrawMargin: 0)
|
||||
expect(lineStateForScreenRow(presenter, 4)).toBeDefined()
|
||||
expect(lineStateForScreenRow(presenter, 5)).toBeUndefined()
|
||||
|
||||
buffer.insert([2, 0], "hello\nworld\n")
|
||||
presenter.setClientHeight(35)
|
||||
|
||||
line1 = editor.tokenizedLineForScreenRow(1)
|
||||
expectValues lineStateForScreenRow(presenter, 1), {
|
||||
text: line1.text
|
||||
tokens: line1.tokens
|
||||
}
|
||||
expect(lineStateForScreenRow(presenter, 5)).toBeDefined()
|
||||
expect(lineStateForScreenRow(presenter, 6)).toBeDefined()
|
||||
expect(lineStateForScreenRow(presenter, 7)).toBeUndefined()
|
||||
|
||||
line2 = editor.tokenizedLineForScreenRow(2)
|
||||
expectValues lineStateForScreenRow(presenter, 2), {
|
||||
text: line2.text
|
||||
tokens: line2.tokens
|
||||
}
|
||||
it "updates when ::lineHeight changes", ->
|
||||
presenter = new TextEditorPresenter(model: editor, clientHeight: 15, scrollTop: 10, lineHeight: 10, lineOverdrawMargin: 0)
|
||||
|
||||
line3 = editor.tokenizedLineForScreenRow(3)
|
||||
expectValues lineStateForScreenRow(presenter, 3), {
|
||||
text: line3.text
|
||||
tokens: line3.tokens
|
||||
}
|
||||
expect(lineStateForScreenRow(presenter, 0)).toBeUndefined()
|
||||
expect(lineStateForScreenRow(presenter, 1)).toBeDefined()
|
||||
expect(lineStateForScreenRow(presenter, 2)).toBeDefined()
|
||||
expect(lineStateForScreenRow(presenter, 4)).toBeUndefined()
|
||||
|
||||
describe ".decorationClasses in line state", ->
|
||||
it "adds decoration classes to the relevant line state objects, both initially and when decorations change", ->
|
||||
marker1 = editor.markBufferRange([[4, 0], [6, 2]], invalidate: 'touch')
|
||||
decoration1 = editor.decorateMarker(marker1, type: 'line', class: 'a')
|
||||
presenter = new TextEditorPresenter(model: editor, clientHeight: 130, scrollTop: 0, lineHeight: 10, lineOverdrawMargin: 0)
|
||||
marker2 = editor.markBufferRange([[4, 0], [6, 2]], invalidate: 'touch')
|
||||
decoration2 = editor.decorateMarker(marker2, type: 'line', class: 'b')
|
||||
presenter.setLineHeight(5)
|
||||
|
||||
expect(lineStateForScreenRow(presenter, 3).decorationClasses).toBeNull()
|
||||
expect(lineStateForScreenRow(presenter, 4).decorationClasses).toEqual ['a', 'b']
|
||||
expect(lineStateForScreenRow(presenter, 5).decorationClasses).toEqual ['a', 'b']
|
||||
expect(lineStateForScreenRow(presenter, 6).decorationClasses).toEqual ['a', 'b']
|
||||
expect(lineStateForScreenRow(presenter, 7).decorationClasses).toBeNull()
|
||||
expect(lineStateForScreenRow(presenter, 0)).toBeUndefined()
|
||||
expect(lineStateForScreenRow(presenter, 1)).toBeUndefined()
|
||||
expect(lineStateForScreenRow(presenter, 2)).toBeDefined()
|
||||
expect(lineStateForScreenRow(presenter, 5)).toBeDefined()
|
||||
expect(lineStateForScreenRow(presenter, 6)).toBeUndefined()
|
||||
|
||||
editor.getBuffer().insert([5, 0], 'x')
|
||||
expect(marker1.isValid()).toBe false
|
||||
expect(lineStateForScreenRow(presenter, 4).decorationClasses).toBeNull()
|
||||
expect(lineStateForScreenRow(presenter, 5).decorationClasses).toBeNull()
|
||||
expect(lineStateForScreenRow(presenter, 6).decorationClasses).toBeNull()
|
||||
it "updates when the editor's content changes", ->
|
||||
presenter = new TextEditorPresenter(model: editor, clientHeight: 25, scrollTop: 10, lineHeight: 10, lineOverdrawMargin: 0)
|
||||
|
||||
editor.undo()
|
||||
expect(lineStateForScreenRow(presenter, 3).decorationClasses).toBeNull()
|
||||
expect(lineStateForScreenRow(presenter, 4).decorationClasses).toEqual ['a', 'b']
|
||||
expect(lineStateForScreenRow(presenter, 5).decorationClasses).toEqual ['a', 'b']
|
||||
expect(lineStateForScreenRow(presenter, 6).decorationClasses).toEqual ['a', 'b']
|
||||
expect(lineStateForScreenRow(presenter, 7).decorationClasses).toBeNull()
|
||||
buffer.insert([2, 0], "hello\nworld\n")
|
||||
|
||||
marker1.setBufferRange([[2, 0], [4, 2]])
|
||||
expect(lineStateForScreenRow(presenter, 1).decorationClasses).toBeNull()
|
||||
expect(lineStateForScreenRow(presenter, 2).decorationClasses).toEqual ['a']
|
||||
expect(lineStateForScreenRow(presenter, 3).decorationClasses).toEqual ['a']
|
||||
expect(lineStateForScreenRow(presenter, 4).decorationClasses).toEqual ['a', 'b']
|
||||
expect(lineStateForScreenRow(presenter, 5).decorationClasses).toEqual ['b']
|
||||
expect(lineStateForScreenRow(presenter, 6).decorationClasses).toEqual ['b']
|
||||
expect(lineStateForScreenRow(presenter, 7).decorationClasses).toBeNull()
|
||||
line1 = editor.tokenizedLineForScreenRow(1)
|
||||
expectValues lineStateForScreenRow(presenter, 1), {
|
||||
text: line1.text
|
||||
tokens: line1.tokens
|
||||
}
|
||||
|
||||
decoration1.destroy()
|
||||
expect(lineStateForScreenRow(presenter, 2).decorationClasses).toBeNull()
|
||||
expect(lineStateForScreenRow(presenter, 3).decorationClasses).toBeNull()
|
||||
expect(lineStateForScreenRow(presenter, 4).decorationClasses).toEqual ['b']
|
||||
expect(lineStateForScreenRow(presenter, 5).decorationClasses).toEqual ['b']
|
||||
expect(lineStateForScreenRow(presenter, 6).decorationClasses).toEqual ['b']
|
||||
expect(lineStateForScreenRow(presenter, 7).decorationClasses).toBeNull()
|
||||
line2 = editor.tokenizedLineForScreenRow(2)
|
||||
expectValues lineStateForScreenRow(presenter, 2), {
|
||||
text: line2.text
|
||||
tokens: line2.tokens
|
||||
}
|
||||
|
||||
marker2.destroy()
|
||||
expect(lineStateForScreenRow(presenter, 2).decorationClasses).toBeNull()
|
||||
expect(lineStateForScreenRow(presenter, 3).decorationClasses).toBeNull()
|
||||
expect(lineStateForScreenRow(presenter, 4).decorationClasses).toBeNull()
|
||||
expect(lineStateForScreenRow(presenter, 5).decorationClasses).toBeNull()
|
||||
expect(lineStateForScreenRow(presenter, 6).decorationClasses).toBeNull()
|
||||
expect(lineStateForScreenRow(presenter, 7).decorationClasses).toBeNull()
|
||||
line3 = editor.tokenizedLineForScreenRow(3)
|
||||
expectValues lineStateForScreenRow(presenter, 3), {
|
||||
text: line3.text
|
||||
tokens: line3.tokens
|
||||
}
|
||||
|
||||
it "honors the 'onlyEmpty' option on line decorations", ->
|
||||
presenter = new TextEditorPresenter(model: editor, clientHeight: 130, scrollTop: 0, lineHeight: 10, lineOverdrawMargin: 0)
|
||||
marker = editor.markBufferRange([[4, 0], [6, 1]])
|
||||
decoration = editor.decorateMarker(marker, type: 'line', class: 'a', onlyEmpty: true)
|
||||
describe "[lineId]", -> # line state objects
|
||||
it "includes the .endOfLineInvisibles if the editor.showInvisibles config option is true", ->
|
||||
editor.setText("hello\nworld\r\n")
|
||||
presenter = new TextEditorPresenter(model: editor, clientHeight: 25, scrollTop: 0, lineHeight: 10, lineOverdrawMargin: 0)
|
||||
expect(lineStateForScreenRow(presenter, 0).endOfLineInvisibles).toBeNull()
|
||||
expect(lineStateForScreenRow(presenter, 1).endOfLineInvisibles).toBeNull()
|
||||
|
||||
expect(lineStateForScreenRow(presenter, 4).decorationClasses).toBeNull()
|
||||
expect(lineStateForScreenRow(presenter, 5).decorationClasses).toBeNull()
|
||||
expect(lineStateForScreenRow(presenter, 6).decorationClasses).toBeNull()
|
||||
atom.config.set('editor.showInvisibles', true)
|
||||
presenter = new TextEditorPresenter(model: editor, clientHeight: 25, scrollTop: 0, lineHeight: 10, lineOverdrawMargin: 0)
|
||||
expect(lineStateForScreenRow(presenter, 0).endOfLineInvisibles).toEqual [atom.config.get('editor.invisibles.eol')]
|
||||
expect(lineStateForScreenRow(presenter, 1).endOfLineInvisibles).toEqual [atom.config.get('editor.invisibles.cr'), atom.config.get('editor.invisibles.eol')]
|
||||
|
||||
marker.clearTail()
|
||||
describe ".decorationClasses", ->
|
||||
it "adds decoration classes to the relevant line state objects, both initially and when decorations change", ->
|
||||
marker1 = editor.markBufferRange([[4, 0], [6, 2]], invalidate: 'touch')
|
||||
decoration1 = editor.decorateMarker(marker1, type: 'line', class: 'a')
|
||||
presenter = new TextEditorPresenter(model: editor, clientHeight: 130, scrollTop: 0, lineHeight: 10, lineOverdrawMargin: 0)
|
||||
marker2 = editor.markBufferRange([[4, 0], [6, 2]], invalidate: 'touch')
|
||||
decoration2 = editor.decorateMarker(marker2, type: 'line', class: 'b')
|
||||
|
||||
expect(lineStateForScreenRow(presenter, 4).decorationClasses).toBeNull()
|
||||
expect(lineStateForScreenRow(presenter, 5).decorationClasses).toBeNull()
|
||||
expect(lineStateForScreenRow(presenter, 6).decorationClasses).toEqual ['a']
|
||||
expect(lineStateForScreenRow(presenter, 3).decorationClasses).toBeNull()
|
||||
expect(lineStateForScreenRow(presenter, 4).decorationClasses).toEqual ['a', 'b']
|
||||
expect(lineStateForScreenRow(presenter, 5).decorationClasses).toEqual ['a', 'b']
|
||||
expect(lineStateForScreenRow(presenter, 6).decorationClasses).toEqual ['a', 'b']
|
||||
expect(lineStateForScreenRow(presenter, 7).decorationClasses).toBeNull()
|
||||
|
||||
it "honors the 'onlyNonEmpty' option on line decorations", ->
|
||||
presenter = new TextEditorPresenter(model: editor, clientHeight: 130, scrollTop: 0, lineHeight: 10, lineOverdrawMargin: 0)
|
||||
marker = editor.markBufferRange([[4, 0], [6, 2]])
|
||||
decoration = editor.decorateMarker(marker, type: 'line', class: 'a', onlyNonEmpty: true)
|
||||
editor.getBuffer().insert([5, 0], 'x')
|
||||
expect(marker1.isValid()).toBe false
|
||||
expect(lineStateForScreenRow(presenter, 4).decorationClasses).toBeNull()
|
||||
expect(lineStateForScreenRow(presenter, 5).decorationClasses).toBeNull()
|
||||
expect(lineStateForScreenRow(presenter, 6).decorationClasses).toBeNull()
|
||||
|
||||
expect(lineStateForScreenRow(presenter, 4).decorationClasses).toEqual ['a']
|
||||
expect(lineStateForScreenRow(presenter, 5).decorationClasses).toEqual ['a']
|
||||
expect(lineStateForScreenRow(presenter, 6).decorationClasses).toEqual ['a']
|
||||
editor.undo()
|
||||
expect(lineStateForScreenRow(presenter, 3).decorationClasses).toBeNull()
|
||||
expect(lineStateForScreenRow(presenter, 4).decorationClasses).toEqual ['a', 'b']
|
||||
expect(lineStateForScreenRow(presenter, 5).decorationClasses).toEqual ['a', 'b']
|
||||
expect(lineStateForScreenRow(presenter, 6).decorationClasses).toEqual ['a', 'b']
|
||||
expect(lineStateForScreenRow(presenter, 7).decorationClasses).toBeNull()
|
||||
|
||||
marker.clearTail()
|
||||
marker1.setBufferRange([[2, 0], [4, 2]])
|
||||
expect(lineStateForScreenRow(presenter, 1).decorationClasses).toBeNull()
|
||||
expect(lineStateForScreenRow(presenter, 2).decorationClasses).toEqual ['a']
|
||||
expect(lineStateForScreenRow(presenter, 3).decorationClasses).toEqual ['a']
|
||||
expect(lineStateForScreenRow(presenter, 4).decorationClasses).toEqual ['a', 'b']
|
||||
expect(lineStateForScreenRow(presenter, 5).decorationClasses).toEqual ['b']
|
||||
expect(lineStateForScreenRow(presenter, 6).decorationClasses).toEqual ['b']
|
||||
expect(lineStateForScreenRow(presenter, 7).decorationClasses).toBeNull()
|
||||
|
||||
expect(lineStateForScreenRow(presenter, 6).decorationClasses).toBeNull()
|
||||
decoration1.destroy()
|
||||
expect(lineStateForScreenRow(presenter, 2).decorationClasses).toBeNull()
|
||||
expect(lineStateForScreenRow(presenter, 3).decorationClasses).toBeNull()
|
||||
expect(lineStateForScreenRow(presenter, 4).decorationClasses).toEqual ['b']
|
||||
expect(lineStateForScreenRow(presenter, 5).decorationClasses).toEqual ['b']
|
||||
expect(lineStateForScreenRow(presenter, 6).decorationClasses).toEqual ['b']
|
||||
expect(lineStateForScreenRow(presenter, 7).decorationClasses).toBeNull()
|
||||
|
||||
it "does not decorate the last line of a non-empty line decoration range if it ends at column 0", ->
|
||||
presenter = new TextEditorPresenter(model: editor, clientHeight: 130, scrollTop: 0, lineHeight: 10, lineOverdrawMargin: 0)
|
||||
marker = editor.markBufferRange([[4, 0], [6, 0]])
|
||||
decoration = editor.decorateMarker(marker, type: 'line', class: 'a')
|
||||
marker2.destroy()
|
||||
expect(lineStateForScreenRow(presenter, 2).decorationClasses).toBeNull()
|
||||
expect(lineStateForScreenRow(presenter, 3).decorationClasses).toBeNull()
|
||||
expect(lineStateForScreenRow(presenter, 4).decorationClasses).toBeNull()
|
||||
expect(lineStateForScreenRow(presenter, 5).decorationClasses).toBeNull()
|
||||
expect(lineStateForScreenRow(presenter, 6).decorationClasses).toBeNull()
|
||||
expect(lineStateForScreenRow(presenter, 7).decorationClasses).toBeNull()
|
||||
|
||||
expect(lineStateForScreenRow(presenter, 4).decorationClasses).toEqual ['a']
|
||||
expect(lineStateForScreenRow(presenter, 5).decorationClasses).toEqual ['a']
|
||||
expect(lineStateForScreenRow(presenter, 6).decorationClasses).toBeNull()
|
||||
it "honors the 'onlyEmpty' option on line decorations", ->
|
||||
presenter = new TextEditorPresenter(model: editor, clientHeight: 130, scrollTop: 0, lineHeight: 10, lineOverdrawMargin: 0)
|
||||
marker = editor.markBufferRange([[4, 0], [6, 1]])
|
||||
decoration = editor.decorateMarker(marker, type: 'line', class: 'a', onlyEmpty: true)
|
||||
|
||||
it "does not apply line decorations to mini editors", ->
|
||||
editor.setMini(true)
|
||||
presenter = new TextEditorPresenter(model: editor, clientHeight: 10, scrollTop: 0, lineHeight: 10, lineOverdrawMargin: 0)
|
||||
marker = editor.markBufferRange([[0, 0], [0, 0]])
|
||||
decoration = editor.decorateMarker(marker, type: 'line', class: 'a')
|
||||
expect(lineStateForScreenRow(presenter, 0).decorationClasses).toBeNull()
|
||||
expect(lineStateForScreenRow(presenter, 4).decorationClasses).toBeNull()
|
||||
expect(lineStateForScreenRow(presenter, 5).decorationClasses).toBeNull()
|
||||
expect(lineStateForScreenRow(presenter, 6).decorationClasses).toBeNull()
|
||||
|
||||
editor.setMini(false)
|
||||
expect(lineStateForScreenRow(presenter, 0).decorationClasses).toEqual ['cursor-line', 'a']
|
||||
marker.clearTail()
|
||||
|
||||
editor.setMini(true)
|
||||
expect(lineStateForScreenRow(presenter, 0).decorationClasses).toBeNull()
|
||||
expect(lineStateForScreenRow(presenter, 4).decorationClasses).toBeNull()
|
||||
expect(lineStateForScreenRow(presenter, 5).decorationClasses).toBeNull()
|
||||
expect(lineStateForScreenRow(presenter, 6).decorationClasses).toEqual ['a']
|
||||
|
||||
it "honors the 'onlyNonEmpty' option on line decorations", ->
|
||||
presenter = new TextEditorPresenter(model: editor, clientHeight: 130, scrollTop: 0, lineHeight: 10, lineOverdrawMargin: 0)
|
||||
marker = editor.markBufferRange([[4, 0], [6, 2]])
|
||||
decoration = editor.decorateMarker(marker, type: 'line', class: 'a', onlyNonEmpty: true)
|
||||
|
||||
expect(lineStateForScreenRow(presenter, 4).decorationClasses).toEqual ['a']
|
||||
expect(lineStateForScreenRow(presenter, 5).decorationClasses).toEqual ['a']
|
||||
expect(lineStateForScreenRow(presenter, 6).decorationClasses).toEqual ['a']
|
||||
|
||||
marker.clearTail()
|
||||
|
||||
expect(lineStateForScreenRow(presenter, 6).decorationClasses).toBeNull()
|
||||
|
||||
it "does not decorate the last line of a non-empty line decoration range if it ends at column 0", ->
|
||||
presenter = new TextEditorPresenter(model: editor, clientHeight: 130, scrollTop: 0, lineHeight: 10, lineOverdrawMargin: 0)
|
||||
marker = editor.markBufferRange([[4, 0], [6, 0]])
|
||||
decoration = editor.decorateMarker(marker, type: 'line', class: 'a')
|
||||
|
||||
expect(lineStateForScreenRow(presenter, 4).decorationClasses).toEqual ['a']
|
||||
expect(lineStateForScreenRow(presenter, 5).decorationClasses).toEqual ['a']
|
||||
expect(lineStateForScreenRow(presenter, 6).decorationClasses).toBeNull()
|
||||
|
||||
it "does not apply line decorations to mini editors", ->
|
||||
editor.setMini(true)
|
||||
presenter = new TextEditorPresenter(model: editor, clientHeight: 10, scrollTop: 0, lineHeight: 10, lineOverdrawMargin: 0)
|
||||
marker = editor.markBufferRange([[0, 0], [0, 0]])
|
||||
decoration = editor.decorateMarker(marker, type: 'line', class: 'a')
|
||||
expect(lineStateForScreenRow(presenter, 0).decorationClasses).toBeNull()
|
||||
|
||||
editor.setMini(false)
|
||||
expect(lineStateForScreenRow(presenter, 0).decorationClasses).toEqual ['cursor-line', 'a']
|
||||
|
||||
editor.setMini(true)
|
||||
expect(lineStateForScreenRow(presenter, 0).decorationClasses).toBeNull()
|
||||
|
Loading…
Reference in New Issue
Block a user