Mailspring/spec/model-view-spec.coffee
2015-10-01 21:39:44 -07:00

132 lines
4.7 KiB
CoffeeScript

_ = require 'underscore'
EventEmitter = require('events').EventEmitter
ModelView = require '../src/flux/stores/model-view'
# ModelView is an abstract base class. Basic implementation for tests
class TestModelView extends ModelView
constructor: ->
super
@_pageSize = 100
count: ->
1000
stubFillPage: (page) ->
letter = ['A','B','C','D','E','F','G','H','I','J'][page]
items = []
items.push({id: "#{letter}#{ii}"}) for ii in [0..99]
@_pages[page] =
loading: false
items: items
retrievePage: (page) ->
@_pages[page] =
items: []
loading: true
setTimeout ->
@stubFillPage(page)
, 1
describe "ModelView", ->
beforeEach ->
@view = new TestModelView()
describe "setRetainedRange", ->
it "should perform basic bounds checks to avoid fetching non-existent pages", ->
@view.setRetainedRange({start: -100, end: 15000})
expect(@view._retainedRange).toEqual({start:0, end: @view.count()})
it "should call the padding method to optionally expand the retained range", ->
spyOn(@view, 'padRetainedRange').andCallFake ({start, end}) ->
{start: start - 50, end: end + 50}
@view.setRetainedRange({start: 0, end: 100})
expect(@view._retainedRange).toEqual({start:0, end: 150})
it "should retrieve pages in the range that are not cached", ->
spyOn(@view, 'retrievePage').andCallThrough()
@view.setRetainedRange({start: 0, end: 250})
expect(@view.retrievePage.callCount).toBe(3)
expect(@view.retrievePage.calls[0].args).toEqual([0])
expect(@view.retrievePage.calls[1].args).toEqual([1])
expect(@view.retrievePage.calls[2].args).toEqual([2])
it "should not retrieve pages that are already cached", ->
@view.stubFillPage(0)
@view.stubFillPage(1)
spyOn(@view, 'retrievePage').andCallThrough()
@view.setRetainedRange({start: 0, end: 250})
expect(@view.retrievePage.callCount).toBe(1)
expect(@view.retrievePage.calls[0].args).toEqual([2])
it "should call cullPages(), allowing subclasses to remove unneeded pages from the cache", ->
spyOn(@view, 'cullPages')
@view.setRetainedRange({start: 0, end: 250})
expect(@view.cullPages).toHaveBeenCalled()
describe "accessors", ->
beforeEach ->
@view.stubFillPage(0)
@view.stubFillPage(1)
describe "loaded", ->
it "should return true if all of the retained pages are loaded", ->
@view.setRetainedRange({start: 0, end: 100})
expect(@view.loaded()).toBe(true)
it "should return false if any retained pages are still loading", ->
@view.setRetainedRange({start: 0, end: 300})
expect(@view.loaded()).toBe(false)
describe "get", ->
it "should return the item at the index provided", ->
expect(@view.get(12).id).toBe('A12')
expect(@view.get(112).id).toBe('B12')
it "should return null if the item cannot be found", ->
expect(@view.get(12154)).toBe(null)
it "should throw an exception if the user passes something other than an integer index", ->
expect(( => @view.get('oops an id'))).toThrow()
describe "getById", ->
it "should return the item with the requested id", ->
expect(@view.getById('A88')).toEqual({id: 'A88'})
expect(@view.getById('B12')).toEqual({id: 'B12'})
it "should return null if the item cannot be found", ->
expect(@view.getById('E12')).toEqual(null)
it "should return null if no id is provided", ->
expect(@view.getById(undefined)).toEqual(null)
describe "indexOfId", ->
it "should return the index of the item with the id", ->
expect(@view.indexOfId('A88')).toEqual(88)
expect(@view.indexOfId('B12')).toEqual(100 * 1 + 12)
it "should return -1 if the item cannot be found", ->
expect(@view.indexOfId('E12')).toEqual(-1)
it "should return -1 if no id is provided", ->
expect(@view.indexOfId(undefined)).toEqual(-1)
describe "pagesRetained", ->
it "should return an array of page indexes currently being maintained", ->
@view._retainedRange = {start: 0, end: 99}
expect(@view.pagesRetained()).toEqual([0])
@view._retainedRange = {start: 0, end: 340}
expect(@view.pagesRetained()).toEqual([0..3])
@view._retainedRange = {start: 900, end: 999}
expect(@view.pagesRetained()).toEqual([9])
describe "invalidateRetainedRange", ->
it "should initiate requests for all the pages in the retained range", ->
spyOn(@view, 'retrievePage')
@view._retainedRange = {start: 0, end: 340}
@view.invalidateRetainedRange()
expect(@view.retrievePage.callCount).toBe(4)
for i in [0..3]
expect(@view.retrievePage.calls[i].args).toEqual([i])