mirror of
https://github.com/Foundry376/Mailspring.git
synced 2024-12-29 20:04:59 +08:00
213 lines
7.8 KiB
CoffeeScript
213 lines
7.8 KiB
CoffeeScript
_ = require 'underscore'
|
|
|
|
{Thread} = require 'mailspring-exports'
|
|
{ListTabular} = require 'mailspring-component-kit'
|
|
|
|
ListDataSource = ListTabular.DataSource
|
|
ListSelection = ListTabular.Selection
|
|
|
|
describe "ListSelection", ->
|
|
beforeEach ->
|
|
@trigger = jasmine.createSpy('trigger')
|
|
|
|
@items = []
|
|
@items.push(new Thread(id: "#{ii}")) for ii in [0..99]
|
|
|
|
@view = new ListDataSource()
|
|
@view.indexOfId = jasmine.createSpy('indexOfId').andCallFake (id) =>
|
|
_.findIndex(@items, _.matcher({id}))
|
|
@view.get = jasmine.createSpy('get').andCallFake (idx) =>
|
|
@items[idx]
|
|
|
|
@selection = new ListSelection(@view, @trigger)
|
|
|
|
it "should initialize with an empty set", ->
|
|
expect(@selection.items()).toEqual([])
|
|
expect(@selection.ids()).toEqual([])
|
|
|
|
it "should throw an exception if a view is not provided", ->
|
|
expect( => new ListSelection(null, @trigger)).toThrow()
|
|
|
|
describe "set", ->
|
|
it "should replace the current selection with the provided models", ->
|
|
@selection.set([@items[2], @items[4], @items[7]])
|
|
expect(@selection.ids()).toEqual(['2', '4', '7'])
|
|
@selection.set([@items[2], @items[5], @items[6]])
|
|
expect(@selection.ids()).toEqual(['2', '5', '6'])
|
|
|
|
it "should throw an exception if the items passed are not models", ->
|
|
expect( => @selection.set(['hi'])).toThrow()
|
|
|
|
it "should trigger", ->
|
|
@selection.set([@items[2], @items[4], @items[7]])
|
|
expect(@trigger).toHaveBeenCalled()
|
|
|
|
describe "clear", ->
|
|
beforeEach ->
|
|
@selection.set([@items[2]])
|
|
|
|
it "should empty the selection set", ->
|
|
@selection.clear()
|
|
expect(@selection.ids()).toEqual([])
|
|
|
|
it "should trigger", ->
|
|
@selection.clear()
|
|
expect(@trigger).toHaveBeenCalled()
|
|
|
|
describe "remove", ->
|
|
beforeEach ->
|
|
@selection.set([@items[2], @items[4], @items[7]])
|
|
|
|
it "should do nothing if called without a valid item", ->
|
|
@selection.remove(null)
|
|
@selection.remove(undefined)
|
|
@selection.remove(false)
|
|
expect(@selection.ids()).toEqual(['2', '4', '7'])
|
|
|
|
it "should remove the item from the set", ->
|
|
@selection.remove(@items[2])
|
|
expect(@selection.ids()).toEqual(['4', '7'])
|
|
|
|
it "should throw an exception if any item passed is not a model", ->
|
|
expect( => @selection.remove('hi')).toThrow()
|
|
|
|
it "should accept an array of models as well as a single item", ->
|
|
@selection.remove([@items[2], @items[4]])
|
|
expect(@selection.ids()).toEqual(['7'])
|
|
|
|
it "should trigger", ->
|
|
@selection.remove()
|
|
expect(@trigger).toHaveBeenCalled()
|
|
|
|
describe "_applyChangeRecord", ->
|
|
it "should replace items in the selection with the matching provided items, if present", ->
|
|
@selection.set([@items[2], @items[4], @items[7]])
|
|
expect(@selection.items()[0]).toBe(@items[2])
|
|
expect(@selection.items()[0].subject).toBe(undefined)
|
|
newItem2 = new Thread(id: '2', subject:'Hello world!')
|
|
@selection._applyChangeRecord({objectClass: 'Thread', objects: [newItem2], type: 'persist'})
|
|
expect(@selection.items()[0].subject).toBe('Hello world!')
|
|
|
|
it "should rremove items in the selection if type is unpersist", ->
|
|
@selection.set([@items[2], @items[4], @items[7]])
|
|
newItem2 = new Thread(id: '2', subject:'Hello world!')
|
|
@selection._applyChangeRecord({objectClass: 'Thread', objects: [newItem2], type: 'unpersist'})
|
|
expect(@selection.ids()).toEqual(['4', '7'])
|
|
|
|
describe "toggle", ->
|
|
beforeEach ->
|
|
@selection.set([@items[2]])
|
|
|
|
it "should do nothing if called without a valid item", ->
|
|
@selection.toggle(null)
|
|
@selection.toggle(undefined)
|
|
@selection.toggle(false)
|
|
expect(@selection.ids()).toEqual(['2'])
|
|
|
|
it "should throw an exception if the item passed is not a model", ->
|
|
expect( => @selection.toggle('hi')).toThrow()
|
|
|
|
it "should select the item if it is not selected", ->
|
|
@selection.toggle(@items[3])
|
|
expect(@selection.ids()).toEqual(['2', '3'])
|
|
|
|
it "should de-select the item if it is selected", ->
|
|
@selection.toggle(@items[2])
|
|
expect(@selection.ids()).toEqual([])
|
|
|
|
it "should trigger", ->
|
|
@selection.toggle(@items[2])
|
|
expect(@trigger).toHaveBeenCalled()
|
|
|
|
describe "expandTo", ->
|
|
it "should select the item, if no other items are selected", ->
|
|
@selection.clear()
|
|
@selection.expandTo(@items[2])
|
|
expect(@selection.ids()).toEqual(['2'])
|
|
|
|
it "should do nothing if called without a valid item", ->
|
|
@selection.expandTo(null)
|
|
@selection.expandTo(undefined)
|
|
@selection.expandTo(false)
|
|
expect(@selection.ids()).toEqual([])
|
|
|
|
it "should throw an exception if the item passed is not a model", ->
|
|
expect( => @selection.expandTo('hi')).toThrow()
|
|
|
|
it "should select all items from the last selected item to the provided item when the provided item is below the current selection", ->
|
|
@selection.set([@items[2], @items[5]])
|
|
@selection.expandTo(@items[8])
|
|
expect(@selection.ids()).toEqual(['2','5','6','7','8'])
|
|
|
|
it "should select all items from the last selected item to the provided item when the provided item is above the current selection", ->
|
|
@selection.set([@items[7], @items[5]])
|
|
@selection.expandTo(@items[2])
|
|
expect(@selection.ids()).toEqual(['7', '5', '4', '3', '2'])
|
|
|
|
it "should not do anything if the provided item is not in the view set", ->
|
|
@selection.set([@items[2]])
|
|
@selection.expandTo(new Thread(id:'not-in-view!'))
|
|
expect(@selection.ids()).toEqual(['2'])
|
|
|
|
it "should re-order items so that the order still reflects the order selection actions were taken", ->
|
|
@selection.set([@items[10], @items[4], @items[1]])
|
|
@selection.expandTo(@items[8])
|
|
expect(@selection.ids()).toEqual(['10','1','2','3','4','5','6','7','8'])
|
|
|
|
it "should trigger", ->
|
|
@selection.set([@items[5], @items[4], @items[1]])
|
|
@selection.expandTo(@items[8])
|
|
expect(@trigger).toHaveBeenCalled()
|
|
|
|
describe "walk", ->
|
|
beforeEach ->
|
|
@selection.set([@items[2]])
|
|
|
|
it "should trigger", ->
|
|
current = @items[4]
|
|
next = @items[5]
|
|
@selection.walk({current, next})
|
|
expect(@trigger).toHaveBeenCalled()
|
|
|
|
it "should select both items if neither the start row or the end row are selected", ->
|
|
current = @items[4]
|
|
next = @items[5]
|
|
@selection.walk({current, next})
|
|
expect(@selection.ids()).toEqual(['2', '4', '5'])
|
|
|
|
it "should select only one item if either current or next is null or undefined", ->
|
|
current = null
|
|
next = @items[5]
|
|
@selection.walk({current, next})
|
|
expect(@selection.ids()).toEqual(['2', '5'])
|
|
|
|
next = null
|
|
current = @items[7]
|
|
@selection.walk({current, next})
|
|
expect(@selection.ids()).toEqual(['2', '5', '7'])
|
|
|
|
describe "when the `next` item is a step backwards in the selection history", ->
|
|
it "should deselect the current item", ->
|
|
@selection.set([@items[2], @items[3], @items[4], @items[5]])
|
|
current = @items[5]
|
|
next = @items[4]
|
|
@selection.walk({current, next})
|
|
expect(@selection.ids()).toEqual(['2', '3', '4'])
|
|
|
|
describe "otherwise", ->
|
|
it "should select the next item", ->
|
|
@selection.set([@items[2], @items[3], @items[4], @items[5]])
|
|
current = @items[5]
|
|
next = @items[6]
|
|
@selection.walk({current, next})
|
|
expect(@selection.ids()).toEqual(['2', '3', '4', '5', '6'])
|
|
|
|
describe "if the item was already selected", ->
|
|
it "should re-order the selection array so the selection still represents selection history", ->
|
|
@selection.set([@items[5], @items[8], @items[7], @items[6]])
|
|
expect(@selection.ids()).toEqual(['5', '8', '7', '6'])
|
|
|
|
current = @items[6]
|
|
next = @items[5]
|
|
@selection.walk({current, next})
|
|
expect(@selection.ids()).toEqual(['8', '7', '6', '5'])
|