pulsar/spec/row-map-spec.coffee
2013-09-20 10:02:20 -07:00

262 lines
12 KiB
CoffeeScript

RowMap = require '../src/row-map'
describe "RowMap", ->
map = null
beforeEach ->
map = new RowMap
describe "when no mappings have been recorded", ->
it "maps buffer rows to screen rows 1:1", ->
expect(map.screenRowRangeForBufferRow(0)).toEqual [0, 1]
expect(map.screenRowRangeForBufferRow(100)).toEqual [100, 101]
describe ".mapBufferRowRange(startBufferRow, endBufferRow, screenRows)", ->
describe "when mapping to a single screen row (like a visible fold)", ->
beforeEach ->
map.mapBufferRowRange(5, 10, 1)
map.mapBufferRowRange(15, 20, 1)
map.mapBufferRowRange(25, 30, 1)
it "accounts for the mapping when translating buffer rows to screen row ranges", ->
expect(map.screenRowRangeForBufferRow(0)).toEqual [0, 1]
expect(map.screenRowRangeForBufferRow(4)).toEqual [4, 5]
expect(map.screenRowRangeForBufferRow(5)).toEqual [5, 6]
expect(map.screenRowRangeForBufferRow(9)).toEqual [5, 6]
expect(map.screenRowRangeForBufferRow(10)).toEqual [6, 7]
expect(map.screenRowRangeForBufferRow(14)).toEqual [10, 11]
expect(map.screenRowRangeForBufferRow(15)).toEqual [11, 12]
expect(map.screenRowRangeForBufferRow(19)).toEqual [11, 12]
expect(map.screenRowRangeForBufferRow(20)).toEqual [12, 13]
expect(map.screenRowRangeForBufferRow(24)).toEqual [16, 17]
expect(map.screenRowRangeForBufferRow(25)).toEqual [17, 18]
expect(map.screenRowRangeForBufferRow(29)).toEqual [17, 18]
expect(map.screenRowRangeForBufferRow(30)).toEqual [18, 19]
it "accounts for the mapping when translating screen rows to buffer row ranges", ->
expect(map.bufferRowRangeForScreenRow(0)).toEqual [0, 1]
expect(map.bufferRowRangeForScreenRow(4)).toEqual [4, 5]
expect(map.bufferRowRangeForScreenRow(5)).toEqual [5, 10]
expect(map.bufferRowRangeForScreenRow(6)).toEqual [10, 11]
expect(map.bufferRowRangeForScreenRow(10)).toEqual [14, 15]
expect(map.bufferRowRangeForScreenRow(11)).toEqual [15, 20]
expect(map.bufferRowRangeForScreenRow(12)).toEqual [20, 21]
expect(map.bufferRowRangeForScreenRow(16)).toEqual [24, 25]
expect(map.bufferRowRangeForScreenRow(17)).toEqual [25, 30]
expect(map.bufferRowRangeForScreenRow(18)).toEqual [30, 31]
describe "when mapping to zero screen rows (like an invisible fold)", ->
beforeEach ->
map.mapBufferRowRange(5, 10, 0)
map.mapBufferRowRange(15, 20, 0)
map.mapBufferRowRange(25, 30, 0)
it "accounts for the mapping when translating buffer rows to screen row ranges", ->
expect(map.screenRowRangeForBufferRow(0)).toEqual [0, 1]
expect(map.screenRowRangeForBufferRow(4)).toEqual [4, 5]
expect(map.screenRowRangeForBufferRow(5)).toEqual [5, 5]
expect(map.screenRowRangeForBufferRow(9)).toEqual [5, 5]
expect(map.screenRowRangeForBufferRow(10)).toEqual [5, 6]
expect(map.screenRowRangeForBufferRow(14)).toEqual [9, 10]
expect(map.screenRowRangeForBufferRow(15)).toEqual [10, 10]
expect(map.screenRowRangeForBufferRow(19)).toEqual [10, 10]
expect(map.screenRowRangeForBufferRow(20)).toEqual [10, 11]
expect(map.screenRowRangeForBufferRow(24)).toEqual [14, 15]
expect(map.screenRowRangeForBufferRow(25)).toEqual [15, 15]
expect(map.screenRowRangeForBufferRow(29)).toEqual [15, 15]
expect(map.screenRowRangeForBufferRow(30)).toEqual [15, 16]
it "accounts for the mapping when translating screen rows to buffer row ranges", ->
expect(map.bufferRowRangeForScreenRow(0)).toEqual [0, 1]
expect(map.bufferRowRangeForScreenRow(4)).toEqual [4, 5]
expect(map.bufferRowRangeForScreenRow(5)).toEqual [10, 11]
expect(map.bufferRowRangeForScreenRow(9)).toEqual [14, 15]
expect(map.bufferRowRangeForScreenRow(10)).toEqual [20, 21]
expect(map.bufferRowRangeForScreenRow(14)).toEqual [24, 25]
expect(map.bufferRowRangeForScreenRow(15)).toEqual [30, 31]
describe "when mapping a single buffer row to multiple screen rows (like a wrapped line)", ->
beforeEach ->
map.mapBufferRowRange(5, 6, 3)
map.mapBufferRowRange(10, 11, 2)
map.mapBufferRowRange(20, 21, 5)
it "accounts for the mapping when translating buffer rows to screen row ranges", ->
expect(map.screenRowRangeForBufferRow(0)).toEqual [0, 1]
expect(map.screenRowRangeForBufferRow(4)).toEqual [4, 5]
expect(map.screenRowRangeForBufferRow(5)).toEqual [5, 8]
expect(map.screenRowRangeForBufferRow(6)).toEqual [8, 9]
expect(map.screenRowRangeForBufferRow(9)).toEqual [11, 12]
expect(map.screenRowRangeForBufferRow(10)).toEqual [12, 14]
expect(map.screenRowRangeForBufferRow(11)).toEqual [14, 15]
expect(map.screenRowRangeForBufferRow(19)).toEqual [22, 23]
expect(map.screenRowRangeForBufferRow(20)).toEqual [23, 28]
expect(map.screenRowRangeForBufferRow(21)).toEqual [28, 29]
it "accounts for the mapping when translating screen rows to buffer row ranges", ->
expect(map.bufferRowRangeForScreenRow(0)).toEqual [0, 1]
expect(map.bufferRowRangeForScreenRow(4)).toEqual [4, 5]
expect(map.bufferRowRangeForScreenRow(5)).toEqual [5, 6]
expect(map.bufferRowRangeForScreenRow(7)).toEqual [5, 6]
expect(map.bufferRowRangeForScreenRow(8)).toEqual [6, 7]
expect(map.bufferRowRangeForScreenRow(11)).toEqual [9, 10]
expect(map.bufferRowRangeForScreenRow(12)).toEqual [10, 11]
expect(map.bufferRowRangeForScreenRow(13)).toEqual [10, 11]
expect(map.bufferRowRangeForScreenRow(14)).toEqual [11, 12]
expect(map.bufferRowRangeForScreenRow(22)).toEqual [19, 20]
expect(map.bufferRowRangeForScreenRow(23)).toEqual [20, 21]
expect(map.bufferRowRangeForScreenRow(27)).toEqual [20, 21]
expect(map.bufferRowRangeForScreenRow(28)).toEqual [21, 22]
describe "after re-mapping a row range to a new number of screen rows", ->
beforeEach ->
map.applyScreenDelta(12, 2) # simulate adding 2 more soft wraps
map.mapBufferRowRange(10, 11, 4)
it "updates translation accordingly", ->
expect(map.screenRowRangeForBufferRow(4)).toEqual [4, 5]
expect(map.screenRowRangeForBufferRow(5)).toEqual [5, 8]
expect(map.screenRowRangeForBufferRow(6)).toEqual [8, 9]
expect(map.screenRowRangeForBufferRow(9)).toEqual [11, 12]
expect(map.screenRowRangeForBufferRow(10)).toEqual [12, 16]
expect(map.screenRowRangeForBufferRow(11)).toEqual [16, 17]
expect(map.screenRowRangeForBufferRow(19)).toEqual [24, 25]
expect(map.screenRowRangeForBufferRow(20)).toEqual [25, 30]
expect(map.screenRowRangeForBufferRow(21)).toEqual [30, 31]
describe "when the row range is inside an existing 1:1 region", ->
it "preserves the starting screen row of subsequent 1:N regions", ->
map.mapBufferRowRange(5, 10, 1)
map.mapBufferRowRange(25, 30, 1)
expect(map.bufferRowRangeForScreenRow(5)).toEqual [5, 10]
expect(map.bufferRowRangeForScreenRow(21)).toEqual [25, 30]
map.mapBufferRowRange(15, 20, 1)
expect(map.bufferRowRangeForScreenRow(11)).toEqual [15, 20]
expect(map.bufferRowRangeForScreenRow(5)).toEqual [5, 10]
expect(map.bufferRowRangeForScreenRow(21)).toEqual [25, 30]
describe "when the row range surrounds existing regions", ->
it "replaces the regions inside the given buffer row range with a single region", ->
map.mapBufferRowRange(5, 10, 1) # inner fold 1
map.mapBufferRowRange(11, 13, 1) # inner fold 2
map.mapBufferRowRange(15, 20, 1) # inner fold 3
map.mapBufferRowRange(22, 27, 1) # following fold
map.mapBufferRowRange(5, 20, 1)
expect(map.bufferRowRangeForScreenRow(5)).toEqual [5, 20]
expect(map.bufferRowRangeForScreenRow(6)).toEqual [20, 21]
expect(map.bufferRowRangeForScreenRow(7)).toEqual [21, 22]
expect(map.bufferRowRangeForScreenRow(8)).toEqual [22, 27]
it "replaces regions that cover 0 buffer rows at the start or end of the buffer row range", ->
map.mapBufferRowRange(0, 0, 1)
map.mapBufferRowRange(0, 1, 1)
map.mapBufferRowRange(1, 1, 1)
map.mapBufferRowRange(0, 1, 3)
expect(map.screenRowRangeForBufferRow(0)).toEqual [0, 3]
describe "when the row range straddles existing regions", ->
it "splits the straddled regions and places the new region between them", ->
# filler region 0
map.mapBufferRowRange(4, 7, 1) # region 1
# filler region 2
map.mapBufferRowRange(13, 15, 1) # region 3
# create region straddling region 0 and region 2
map.mapBufferRowRange(2, 10, 1)
expect(map.regions[0]).toEqual(bufferRows: 2, screenRows: 2)
expect(map.regions[1]).toEqual(bufferRows: 8, screenRows: 1)
expect(map.regions[2]).toEqual(bufferRows: 3, screenRows: 8)
expect(map.regions[3]).toEqual(bufferRows: 2, screenRows: 1)
it "merges adjacent isomorphic mappings", ->
map.mapBufferRowRange(2, 4, 1)
map.mapBufferRowRange(4, 5, 2)
map.mapBufferRowRange(1, 4, 3)
expect(map.regions).toEqual [{bufferRows: 5, screenRows: 5}]
describe ".applyBufferDelta(startBufferRow, delta)", ->
describe "when applying a positive delta", ->
it "expands the region containing the given start row by the given delta", ->
map.mapBufferRowRange(4, 8, 1)
map.applyBufferDelta(5, 4)
expect(map.regions[0]).toEqual(bufferRows: 4, screenRows: 4)
expect(map.regions[1]).toEqual(bufferRows: 8, screenRows: 1)
describe "when applying a negative delta", ->
it "shrinks regions starting at the start row until the entire delta is consumed", ->
map.mapBufferRowRange(4, 8, 1)
map.mapBufferRowRange(10, 14, 1)
map.applyBufferDelta(3, -6)
expect(map.regions[0]).toEqual(bufferRows: 3, screenRows: 4)
expect(map.regions[1]).toEqual(bufferRows: 0, screenRows: 1)
expect(map.regions[2]).toEqual(bufferRows: 1, screenRows: 2)
expect(map.regions[3]).toEqual(bufferRows: 4, screenRows: 1)
describe ".applyScreenDelta(startScreenRow, delta)", ->
describe "when applying a positive delta", ->
it "can enlarge the screen side of existing regions", ->
map.mapBufferRowRange(5, 6, 3) # wrapped line
map.applyScreenDelta(5, 2) # wrap it twice more
expect(map.screenRowRangeForBufferRow(5)).toEqual [5, 10]
describe "when applying a negative delta", ->
it "can collapse the screen side of multiple regions to 0 until the entire delta has been applied", ->
map.mapBufferRowRange(5, 10, 1) # inner fold 1
map.mapBufferRowRange(11, 13, 1) # inner fold 2
map.mapBufferRowRange(15, 20, 1) # inner fold 3
map.mapBufferRowRange(22, 27, 1) # following fold
map.applyScreenDelta(6, -5)
expect(map.screenRowRangeForBufferRow(5)).toEqual [5, 6]
expect(map.screenRowRangeForBufferRow(9)).toEqual [5, 6]
expect(map.screenRowRangeForBufferRow(10)).toEqual [6, 6]
expect(map.screenRowRangeForBufferRow(19)).toEqual [6, 6]
expect(map.screenRowRangeForBufferRow(22)).toEqual [8, 9]
expect(map.screenRowRangeForBufferRow(26)).toEqual [8, 9]
it "starts collapsing the first region at the start row, not before", ->
map.mapBufferRowRange(5, 6, 4)
map.mapBufferRowRange(11, 13, 1)
map.applyScreenDelta(7, -5)
expect(map.regions[0]).toEqual(bufferRows: 5, screenRows: 5)
expect(map.regions[1]).toEqual(bufferRows: 1, screenRows: 2)
expect(map.regions[2]).toEqual(bufferRows: 5, screenRows: 2)
it "does not throw an exception when applying a delta beyond the last region", ->
map.mapBufferRowRange(5, 10, 1) # inner fold 1
map.applyScreenDelta(15, 10)