UNPKG

backbone.select

Version:

Selecting Backbone models; handling selections in Backbone collections.

1,062 lines (809 loc) 111 kB
describe( "models shared between multiple collections", function () { var Model = Backbone.Model.extend( { initialize: function () { Backbone.Select.Me.applyTo( this ); } } ); var SingleSelectCollection = Backbone.Collection.extend( { initialize: function ( models ) { Backbone.Select.One.applyTo( this, models ); } } ); var MultiSelectCollection = Backbone.Collection.extend( { initialize: function ( models ) { Backbone.Select.Many.applyTo( this, models ); } } ); beforeAll( function () { limitJasmineRecursiveScreenOutput(); } ); afterAll( function () { restoreJasmineRecursiveScreenOutput(); } ); describe( "when selecting a model in a single-select collection", function () { var model, singleCollectionA, singleCollectionB, multiCollectionA; beforeEach( function () { model = new Model(); singleCollectionA = new SingleSelectCollection( [model] ); singleCollectionB = new SingleSelectCollection( [model] ); multiCollectionA = new MultiSelectCollection( [model] ); spyOn( model, "trigger" ).and.callThrough(); spyOn( singleCollectionA, "trigger" ).and.callThrough(); spyOn( singleCollectionB, "trigger" ).and.callThrough(); spyOn( multiCollectionA, "trigger" ).and.callThrough(); singleCollectionA.select( model ); } ); afterEach( function () { singleCollectionA.close(); singleCollectionB.close(); multiCollectionA.close(); } ); it( "should be selected in the originating collection", function () { expect( singleCollectionA.selected ).toBe( model ); } ); it( "should be selected in another single-select collection", function () { expect( singleCollectionB.selected ).toBe( model ); } ); it( "should be among the selected models in another multi-select collection", function () { expect( multiCollectionA.selected[model.cid] ).not.toBeUndefined(); } ); it( "should be selected itself", function () { expect( model.selected ).toBe( true ); } ); it( 'should trigger a selected event on the model', function () { expect( model.trigger ).toHaveBeenCalledWith( "selected", model, { label: "selected" } ); } ); it( 'should trigger a select:one event on the originating collection', function () { expect( singleCollectionA.trigger ).toHaveBeenCalledWith( "select:one", model, singleCollectionA, { label: "selected" } ); } ); it( 'should trigger a select:one event on another single-select collection', function () { expect( singleCollectionB.trigger ).toHaveBeenCalledWith( "select:one", model, singleCollectionB, { label: "selected" } ); } ); it( 'should trigger a select:some or selected:all event on another multi-select collection', function () { expect( multiCollectionA.trigger ).toHaveBeenCalledWith( "select:all", { selected: [model], deselected: [] }, multiCollectionA, { label: "selected" } ); } ); it( 'should not trigger a reselected event on the model', function () { expect( model.trigger ).not.toHaveBeenCalledWithInitial( "reselected" ); } ); it( "should not trigger a reselect:one event on the originating collection", function () { expect( singleCollectionA.trigger ).not.toHaveBeenCalledWithInitial( "reselect:one" ); } ); it( "should not trigger a reselect:one event on another single-select collection", function () { expect( singleCollectionB.trigger ).not.toHaveBeenCalledWithInitial( "reselect:one" ); } ); it( "should not trigger a reselect:any event on another multi-select collection", function () { expect( multiCollectionA.trigger ).not.toHaveBeenCalledWithInitial( "reselect:any" ); } ); } ); describe( "when selecting a model in a single-select collection, with options.silent enabled", function () { var model, singleCollectionA, singleCollectionB, multiCollectionA; beforeEach( function () { model = new Model(); singleCollectionA = new SingleSelectCollection( [model] ); singleCollectionB = new SingleSelectCollection( [model] ); multiCollectionA = new MultiSelectCollection( [model] ); spyOn( model, "trigger" ).and.callThrough(); spyOn( singleCollectionA, "trigger" ).and.callThrough(); spyOn( singleCollectionB, "trigger" ).and.callThrough(); spyOn( multiCollectionA, "trigger" ).and.callThrough(); singleCollectionA.select( model, {silent: true} ); } ); afterEach( function () { singleCollectionA.close(); singleCollectionB.close(); multiCollectionA.close(); } ); it( "should be selected in another single-select collection", function () { expect( singleCollectionB.selected ).toBe( model ); } ); it( "should be among the selected models in another multi-select collection", function () { expect( multiCollectionA.selected[model.cid] ).not.toBeUndefined(); } ); it( 'should not trigger a selected event on the model', function () { expect( model.trigger ).not.toHaveBeenCalledWithInitial( "selected" ); } ); it( 'should not trigger a select:one event on the originating collection', function () { expect( singleCollectionA.trigger ).not.toHaveBeenCalledWithInitial( "select:one" ); } ); it( 'should not trigger a select:one event on another single-select collection', function () { expect( singleCollectionB.trigger ).not.toHaveBeenCalledWithInitial( "select:one" ); } ); it( 'should not trigger a select:some or selected:all event on another multi-select collection', function () { expect( multiCollectionA.trigger ).not.toHaveBeenCalledWithInitial( "select:some" ); expect( multiCollectionA.trigger ).not.toHaveBeenCalledWithInitial( "select:all" ); } ); } ); describe( "when selecting a model in a multi-select collection", function () { var model, singleCollectionA, multiCollectionA, multiCollectionB; beforeEach( function () { model = new Model(); singleCollectionA = new SingleSelectCollection( [model] ); multiCollectionA = new MultiSelectCollection( [model] ); multiCollectionB = new MultiSelectCollection( [model] ); spyOn( model, "trigger" ).and.callThrough(); spyOn( singleCollectionA, "trigger" ).and.callThrough(); spyOn( multiCollectionA, "trigger" ).and.callThrough(); spyOn( multiCollectionB, "trigger" ).and.callThrough(); multiCollectionA.select( model ); } ); afterEach( function () { singleCollectionA.close(); multiCollectionA.close(); multiCollectionB.close(); } ); it( "should be selected in the originating collection", function () { expect( multiCollectionA.selected[model.cid] ).not.toBeUndefined(); } ); it( "should be selected in another single-select collection", function () { expect( singleCollectionA.selected ).toBe( model ); } ); it( "should be among the selected models in another multi-select collection", function () { expect( multiCollectionB.selected[model.cid] ).not.toBeUndefined(); } ); it( "should be selected itself", function () { expect( model.selected ).toBe( true ); } ); it( 'should trigger a selected event on the model', function () { expect( model.trigger ).toHaveBeenCalledWith( "selected", model, { label: "selected" } ); } ); it( 'should trigger a select:some or selected:all event on the originating collection', function () { expect( multiCollectionA.trigger ).toHaveBeenCalledWith( "select:all", { selected: [model], deselected: [] }, multiCollectionA, { label: "selected" } ); } ); it( 'should trigger a select:one event on another single-select collection', function () { expect( singleCollectionA.trigger ).toHaveBeenCalledWith( "select:one", model, singleCollectionA, { label: "selected" } ); } ); it( 'should trigger a select:some or selected:all event on another multi-select collection', function () { expect( multiCollectionB.trigger ).toHaveBeenCalledWith( "select:all", { selected: [model], deselected: [] }, multiCollectionB, { label: "selected" } ); } ); it( 'should not trigger a reselected event on the model', function () { expect( model.trigger ).not.toHaveBeenCalledWithInitial( "reselected" ); } ); it( "should not trigger a reselect:any event on the originating collection", function () { expect( multiCollectionA.trigger ).not.toHaveBeenCalledWithInitial( "reselect:any" ); } ); it( "should not trigger a reselect:one event on another single-select collection", function () { expect( singleCollectionA.trigger ).not.toHaveBeenCalledWithInitial( "reselect:one" ); } ); it( "should not trigger a reselect:any event on another multi-select collection", function () { expect( multiCollectionB.trigger ).not.toHaveBeenCalledWithInitial( "reselect:any" ); } ); } ); describe( "when selecting a model in a multi-select collection, with options.silent enabled", function () { var model, singleCollectionA, multiCollectionA, multiCollectionB; beforeEach( function () { model = new Model(); singleCollectionA = new SingleSelectCollection( [model] ); multiCollectionA = new MultiSelectCollection( [model] ); multiCollectionB = new MultiSelectCollection( [model] ); spyOn( model, "trigger" ).and.callThrough(); spyOn( singleCollectionA, "trigger" ).and.callThrough(); spyOn( multiCollectionA, "trigger" ).and.callThrough(); spyOn( multiCollectionB, "trigger" ).and.callThrough(); multiCollectionA.select( model, {silent: true} ); } ); afterEach( function () { singleCollectionA.close(); multiCollectionA.close(); multiCollectionB.close(); } ); it( "should be selected in another single-select collection", function () { expect( singleCollectionA.selected ).toBe( model ); } ); it( "should be among the selected models in another multi-select collection", function () { expect( multiCollectionB.selected[model.cid] ).not.toBeUndefined(); } ); it( 'should not trigger a selected event on the model', function () { expect( model.trigger ).not.toHaveBeenCalledWithInitial( "selected" ); } ); it( 'should not trigger a select:some or selected:all event on the originating collection', function () { expect( multiCollectionA.trigger ).not.toHaveBeenCalledWithInitial( "select:some" ); expect( multiCollectionA.trigger ).not.toHaveBeenCalledWithInitial( "select:all" ); } ); it( 'should not trigger a select:one event on another single-select collection', function () { expect( singleCollectionA.trigger ).not.toHaveBeenCalledWithInitial( "select:one" ); } ); it( 'should not trigger a select:some or selected:all event on another multi-select collection', function () { expect( multiCollectionB.trigger ).not.toHaveBeenCalledWithInitial( "select:some" ); expect( multiCollectionB.trigger ).not.toHaveBeenCalledWithInitial( "select:all" ); } ); } ); describe( "when selecting a model, which is shared across collections, with its select method", function () { var model, singleCollectionA, multiCollectionA; beforeEach( function () { model = new Model(); singleCollectionA = new SingleSelectCollection( [model] ); multiCollectionA = new MultiSelectCollection( [model] ); spyOn( model, "trigger" ).and.callThrough(); spyOn( singleCollectionA, "trigger" ).and.callThrough(); spyOn( multiCollectionA, "trigger" ).and.callThrough(); model.select(); } ); afterEach( function () { singleCollectionA.close(); multiCollectionA.close(); } ); it( "should be selected in a single-select collection", function () { expect( singleCollectionA.selected ).toBe( model ); } ); it( "should be among the selected models in a multi-select collection", function () { expect( multiCollectionA.selected[model.cid] ).not.toBeUndefined(); } ); it( "should be selected itself", function () { expect( model.selected ).toBe( true ); } ); it( 'should trigger a selected event on the model', function () { expect( model.trigger ).toHaveBeenCalledWith( "selected", model, { label: "selected" } ); } ); it( 'should trigger a select:one event on the single-select collection', function () { expect( singleCollectionA.trigger ).toHaveBeenCalledWith( "select:one", model, singleCollectionA, { label: "selected" } ); } ); it( 'should trigger a select:some or selected:all event on the multi-select collection', function () { expect( multiCollectionA.trigger ).toHaveBeenCalledWith( "select:all", { selected: [model], deselected: [] }, multiCollectionA, { label: "selected" } ); } ); it( 'should not trigger a reselected event on the model', function () { expect( model.trigger ).not.toHaveBeenCalledWithInitial( "reselected" ); } ); it( "should not trigger a reselect:one event on the single-select collection", function () { expect( singleCollectionA.trigger ).not.toHaveBeenCalledWithInitial( "reselect:one" ); } ); it( "should not trigger a reselect:any event on the multi-select collection", function () { expect( multiCollectionA.trigger ).not.toHaveBeenCalledWithInitial( "reselect:any" ); } ); } ); describe( "when selecting a model, which is shared across collections, with its select method and options.silent enabled", function () { var model, singleCollectionA, multiCollectionA; beforeEach( function () { model = new Model(); singleCollectionA = new SingleSelectCollection( [model] ); multiCollectionA = new MultiSelectCollection( [model] ); spyOn( model, "trigger" ).and.callThrough(); spyOn( singleCollectionA, "trigger" ).and.callThrough(); spyOn( multiCollectionA, "trigger" ).and.callThrough(); model.select( {silent: true} ); } ); afterEach( function () { singleCollectionA.close(); multiCollectionA.close(); } ); it( "should be selected in a single-select collection", function () { expect( singleCollectionA.selected ).toBe( model ); } ); it( "should be among the selected models in a multi-select collection", function () { expect( multiCollectionA.selected[model.cid] ).not.toBeUndefined(); } ); it( 'should not trigger a selected event on the model', function () { expect( model.trigger ).not.toHaveBeenCalledWithInitial( "selected" ); } ); it( 'should not trigger a select:one event on the single-select collection', function () { expect( singleCollectionA.trigger ).not.toHaveBeenCalledWithInitial( "select:one" ); } ); it( 'should not trigger a select:some or selected:all event on the multi-select collection', function () { expect( multiCollectionA.trigger ).not.toHaveBeenCalledWithInitial( "select:some" ); expect( multiCollectionA.trigger ).not.toHaveBeenCalledWithInitial( "select:all" ); } ); } ); describe( "when re-selecting a model in a single-select collection", function () { var model1, model2, singleCollectionA, singleCollectionB, multiCollectionA; beforeEach( function () { model1 = new Model(); model2 = new Model(); singleCollectionA = new SingleSelectCollection( [model1] ); singleCollectionB = new SingleSelectCollection( [model1] ); multiCollectionA = new MultiSelectCollection( [model1, model2] ); multiCollectionA.select( model2 ); multiCollectionA.select( model1 ); spyOn( model1, "trigger" ).and.callThrough(); spyOn( singleCollectionA, "trigger" ).and.callThrough(); spyOn( singleCollectionB, "trigger" ).and.callThrough(); spyOn( multiCollectionA, "trigger" ).and.callThrough(); singleCollectionA.select( model1 ); } ); afterEach( function () { singleCollectionA.close(); singleCollectionB.close(); multiCollectionA.close(); } ); it( "should not deselect other selected models in a multi-select collection", function () { expect( multiCollectionA.selected[model2.cid] ).not.toBeUndefined(); } ); it( 'should not trigger a selected event on the model', function () { expect( model1.trigger ).not.toHaveBeenCalledWithInitial( "selected" ); } ); it( 'should not trigger a select:one event on the originating collection', function () { expect( singleCollectionA.trigger ).not.toHaveBeenCalledWithInitial( "select:one" ); } ); it( 'should not trigger a select:one event on another single-select collection', function () { expect( singleCollectionB.trigger ).not.toHaveBeenCalledWithInitial( "select:one" ); } ); it( 'should not trigger a select:some or selected:all event on another multi-select collection', function () { expect( multiCollectionA.trigger ).not.toHaveBeenCalledWithInitial( "select:some" ); expect( multiCollectionA.trigger ).not.toHaveBeenCalledWithInitial( "select:all" ); } ); it( 'should trigger a reselected event on the model', function () { expect( model1.trigger ).toHaveBeenCalledWith( "reselected", model1, { label: "selected" } ); } ); it( "should trigger a reselect:one event on the originating collection", function () { expect( singleCollectionA.trigger ).toHaveBeenCalledWith( "reselect:one", model1, singleCollectionA, { label: "selected" } ); } ); it( "should trigger a reselect:one event on another single-select collection", function () { expect( singleCollectionB.trigger ).toHaveBeenCalledWith( "reselect:one", model1, singleCollectionB, { label: "selected" } ); } ); it( "should trigger a reselect:any event on another multi-select collection, with an array containing the model as second parameter", function () { expect( multiCollectionA.trigger ).toHaveBeenCalledWith( "reselect:any", [model1], multiCollectionA, { label: "selected" } ); } ); } ); describe( "when re-selecting a model in a single-select collection, with options.silent enabled", function () { var model1, model2, singleCollectionA, singleCollectionB, multiCollectionA; beforeEach( function () { model1 = new Model(); model2 = new Model(); singleCollectionA = new SingleSelectCollection( [model1, model2] ); singleCollectionB = new SingleSelectCollection( [model1, model2] ); multiCollectionA = new MultiSelectCollection( [model1, model2] ); singleCollectionA.select( model1 ); spyOn( model1, "trigger" ).and.callThrough(); spyOn( singleCollectionA, "trigger" ).and.callThrough(); spyOn( singleCollectionB, "trigger" ).and.callThrough(); spyOn( multiCollectionA, "trigger" ).and.callThrough(); singleCollectionA.select( model1, {silent: true} ); } ); afterEach( function () { singleCollectionA.close(); singleCollectionB.close(); multiCollectionA.close(); } ); it( 'should not trigger a selected event on the model', function () { expect( model1.trigger ).not.toHaveBeenCalledWithInitial( "selected" ); } ); it( 'should not trigger a select:one event on the originating collection', function () { expect( singleCollectionA.trigger ).not.toHaveBeenCalledWithInitial( "select:one" ); } ); it( 'should not trigger a select:one event on another single-select collection', function () { expect( singleCollectionB.trigger ).not.toHaveBeenCalledWithInitial( "select:one" ); } ); it( 'should not trigger a select:some or selected:all event on another multi-select collection', function () { expect( multiCollectionA.trigger ).not.toHaveBeenCalledWithInitial( "select:some" ); expect( multiCollectionA.trigger ).not.toHaveBeenCalledWithInitial( "select:all" ); } ); it( 'should not trigger a reselected event on the model', function () { expect( model1.trigger ).not.toHaveBeenCalledWithInitial( "reselected" ); } ); it( "should not trigger a reselect:one event on the originating collection", function () { expect( singleCollectionA.trigger ).not.toHaveBeenCalledWithInitial( "reselect:one" ); } ); it( "should not trigger a reselect:one event on another single-select collection", function () { expect( singleCollectionB.trigger ).not.toHaveBeenCalledWithInitial( "reselect:one" ); } ); it( "should not trigger a reselect:any event on another multi-select collection", function () { expect( multiCollectionA.trigger ).not.toHaveBeenCalledWithInitial( "reselect:any" ); } ); } ); describe( "when re-selecting a model in a multi-select collection", function () { var model1, model2, singleCollectionA, multiCollectionA, multiCollectionB; beforeEach( function () { model1 = new Model(); model2 = new Model(); singleCollectionA = new SingleSelectCollection( [model1, model2] ); multiCollectionA = new MultiSelectCollection( [model1, model2] ); multiCollectionB = new MultiSelectCollection( [model1, model2] ); multiCollectionA.select( model1 ); spyOn( model1, "trigger" ).and.callThrough(); spyOn( singleCollectionA, "trigger" ).and.callThrough(); spyOn( multiCollectionA, "trigger" ).and.callThrough(); spyOn( multiCollectionB, "trigger" ).and.callThrough(); multiCollectionA.select( model1 ); } ); afterEach( function () { singleCollectionA.close(); multiCollectionA.close(); multiCollectionB.close(); } ); it( 'should not trigger a selected event on the model', function () { expect( model1.trigger ).not.toHaveBeenCalledWithInitial( "selected" ); } ); it( 'should not trigger a select:some or selected:all event on the originating collection', function () { expect( multiCollectionA.trigger ).not.toHaveBeenCalledWithInitial( "select:some" ); expect( multiCollectionA.trigger ).not.toHaveBeenCalledWithInitial( "select:all" ); } ); it( 'should not trigger a select:one event on another single-select collection', function () { expect( singleCollectionA.trigger ).not.toHaveBeenCalledWithInitial( "select:one" ); } ); it( 'should not trigger a select:some or selected:all event on another multi-select collection', function () { expect( multiCollectionB.trigger ).not.toHaveBeenCalledWithInitial( "select:some" ); expect( multiCollectionB.trigger ).not.toHaveBeenCalledWithInitial( "select:all" ); } ); it( 'should trigger a reselected event on the model', function () { expect( model1.trigger ).toHaveBeenCalledWith( "reselected", model1, { label: "selected" } ); } ); it( "should trigger a reselect:any event on the originating collection, with an array containing the model as second parameter", function () { expect( multiCollectionA.trigger ).toHaveBeenCalledWith( "reselect:any", [model1], multiCollectionA, { label: "selected" } ); } ); it( "should trigger a reselect:one event on another single-select collection", function () { expect( singleCollectionA.trigger ).toHaveBeenCalledWith( "reselect:one", model1, singleCollectionA, { label: "selected" } ); } ); it( "should trigger a reselect:any event on another multi-select collection, with an array containing the model as second parameter", function () { expect( multiCollectionB.trigger ).toHaveBeenCalledWith( "reselect:any", [model1], multiCollectionB, { label: "selected" } ); } ); } ); describe( "when re-selecting a model in a multi-select collection, with options.silent enabled", function () { var model1, model2, singleCollectionA, multiCollectionA, multiCollectionB; beforeEach( function () { model1 = new Model(); model2 = new Model(); singleCollectionA = new SingleSelectCollection( [model1, model2] ); multiCollectionA = new MultiSelectCollection( [model1, model2] ); multiCollectionB = new MultiSelectCollection( [model1, model2] ); multiCollectionA.select( model1 ); spyOn( model1, "trigger" ).and.callThrough(); spyOn( singleCollectionA, "trigger" ).and.callThrough(); spyOn( multiCollectionA, "trigger" ).and.callThrough(); spyOn( multiCollectionB, "trigger" ).and.callThrough(); multiCollectionA.select( model1, {silent: true} ); } ); afterEach( function () { singleCollectionA.close(); multiCollectionA.close(); multiCollectionB.close(); } ); it( 'should not trigger a selected event on the model', function () { expect( model1.trigger ).not.toHaveBeenCalledWithInitial( "selected" ); } ); it( 'should not trigger a select:some or selected:all event on the originating collection', function () { expect( multiCollectionA.trigger ).not.toHaveBeenCalledWithInitial( "select:some" ); expect( multiCollectionA.trigger ).not.toHaveBeenCalledWithInitial( "select:all" ); } ); it( 'should not trigger a select:one event on another single-select collection', function () { expect( singleCollectionA.trigger ).not.toHaveBeenCalledWithInitial( "select:one" ); } ); it( 'should not trigger a select:some or selected:all event on another multi-select collection', function () { expect( multiCollectionB.trigger ).not.toHaveBeenCalledWithInitial( "select:some" ); expect( multiCollectionB.trigger ).not.toHaveBeenCalledWithInitial( "select:all" ); } ); it( 'should not trigger a reselected event on the model', function () { expect( model1.trigger ).not.toHaveBeenCalledWithInitial( "reselected" ); } ); it( "should not trigger a reselect:any event on the originating collection", function () { expect( multiCollectionA.trigger ).not.toHaveBeenCalledWithInitial( "reselect:any" ); } ); it( "should not trigger a reselect:one event on another single-select collection", function () { expect( singleCollectionA.trigger ).not.toHaveBeenCalledWithInitial( "reselect:one" ); } ); it( "should not trigger a reselect:any event on another multi-select collection", function () { expect( multiCollectionB.trigger ).not.toHaveBeenCalledWithInitial( "reselect:any" ); } ); } ); describe( "when re-selecting a model, which is shared across collections, with its select method", function () { var model1, model2, singleCollectionA, multiCollectionA; beforeEach( function () { model1 = new Model(); model2 = new Model(); singleCollectionA = new SingleSelectCollection( [model1, model2] ); multiCollectionA = new MultiSelectCollection( [model1, model2] ); model1.select(); spyOn( model1, "trigger" ).and.callThrough(); spyOn( singleCollectionA, "trigger" ).and.callThrough(); spyOn( multiCollectionA, "trigger" ).and.callThrough(); model1.select(); } ); afterEach( function () { singleCollectionA.close(); multiCollectionA.close(); } ); it( "should remain selected in a single-select collection", function () { expect( singleCollectionA.selected ).toBe( model1 ); } ); it( "should remain among the selected models in a multi-select collection", function () { expect( multiCollectionA.selected[model1.cid] ).not.toBeUndefined(); } ); it( "should remain selected itself", function () { expect( model1.selected ).toBe( true ); } ); it( 'should not trigger a selected event on the model', function () { expect( model1.trigger ).not.toHaveBeenCalledWithInitial( "selected" ); } ); it( 'should not trigger a select:one event on the single-select collection', function () { expect( singleCollectionA.trigger ).not.toHaveBeenCalledWithInitial( "select:one" ); } ); it( 'should not trigger a select:some or selected:all event on the multi-select collection', function () { expect( multiCollectionA.trigger ).not.toHaveBeenCalledWithInitial( "select:some" ); expect( multiCollectionA.trigger ).not.toHaveBeenCalledWithInitial( "select:all" ); } ); it( 'should trigger a reselected event on the model', function () { expect( model1.trigger ).toHaveBeenCalledWith( "reselected", model1, { label: "selected" } ); } ); it( "should trigger a reselect:one event on the single-select collection", function () { expect( singleCollectionA.trigger ).toHaveBeenCalledWith( "reselect:one", model1, singleCollectionA, { label: "selected" } ); } ); it( "should trigger a reselect:any event on the multi-select collection, with an array containing the model as second parameter", function () { expect( multiCollectionA.trigger ).toHaveBeenCalledWith( "reselect:any", [model1], multiCollectionA, { label: "selected" } ); } ); } ); describe( "when re-selecting a model, which is shared across collections, with its select method and options.silent enabled", function () { var model1, model2, singleCollectionA, multiCollectionA; beforeEach( function () { model1 = new Model(); model2 = new Model(); singleCollectionA = new SingleSelectCollection( [model1, model2] ); multiCollectionA = new MultiSelectCollection( [model1, model2] ); model1.select(); spyOn( model1, "trigger" ).and.callThrough(); spyOn( singleCollectionA, "trigger" ).and.callThrough(); spyOn( multiCollectionA, "trigger" ).and.callThrough(); model1.select( {silent: true} ); } ); afterEach( function () { singleCollectionA.close(); multiCollectionA.close(); } ); it( 'should not trigger a selected event on the model', function () { expect( model1.trigger ).not.toHaveBeenCalledWithInitial( "selected" ); } ); it( 'should not trigger a select:one event on the single-select collection', function () { expect( singleCollectionA.trigger ).not.toHaveBeenCalledWithInitial( "select:one" ); } ); it( 'should not trigger a select:some or selected:all event on the multi-select collection', function () { expect( multiCollectionA.trigger ).not.toHaveBeenCalledWithInitial( "select:some" ); expect( multiCollectionA.trigger ).not.toHaveBeenCalledWithInitial( "select:all" ); } ); it( 'should not trigger a reselected event on the model', function () { expect( model1.trigger ).not.toHaveBeenCalledWithInitial( "reselected" ); } ); it( "should not trigger a reselect:one event on the single-select collection", function () { expect( singleCollectionA.trigger ).not.toHaveBeenCalledWithInitial( "reselect:one" ); } ); it( "should not trigger a reselect:any event on the multi-select collection", function () { expect( multiCollectionA.trigger ).not.toHaveBeenCalledWithInitial( "reselect:any" ); } ); } ); describe( "when a model is already selected and a different model is selected in a single-select collection", function () { var model1, model2, singleCollectionA, singleCollectionB, multiCollectionA; beforeEach( function () { model1 = new Model(); model2 = new Model(); singleCollectionA = new SingleSelectCollection( [model1, model2] ); singleCollectionB = new SingleSelectCollection( [model1, model2] ); multiCollectionA = new MultiSelectCollection( [model1, model2] ); model1.select(); spyOn( model1, "trigger" ).and.callThrough(); spyOn( model2, "trigger" ).and.callThrough(); spyOn( singleCollectionA, "trigger" ).and.callThrough(); spyOn( singleCollectionB, "trigger" ).and.callThrough(); spyOn( multiCollectionA, "trigger" ).and.callThrough(); singleCollectionA.select( model2 ); } ); afterEach( function () { singleCollectionA.close(); singleCollectionB.close(); multiCollectionA.close(); } ); it( "should be selected in the originating collection", function () { expect( singleCollectionA.selected ).toBe( model2 ); } ); it( "should be selected in another single-select collection", function () { expect( singleCollectionB.selected ).toBe( model2 ); } ); it( "should be selected in another multi-select collection", function () { expect( multiCollectionA.selected[model2.cid] ).not.toBeUndefined(); } ); it( "should be selected itself", function () { expect( model2.selected ).toBe( true ); } ); it( "should deselect the first model", function () { expect( model1.selected ).toBe( false ); } ); it( "should deselect the first model in another multi-select collection", function () { expect( multiCollectionA.selected[model1.cid] ).toBeUndefined(); } ); it( 'should trigger a selected event on the selected model', function () { expect( model2.trigger ).toHaveBeenCalledWith( "selected", model2, { label: "selected" } ); } ); it( 'should trigger a deselected event on the first model', function () { expect( model1.trigger ).toHaveBeenCalledWith( "deselected", model1, { label: "selected" } ); } ); it( 'should trigger a deselect:one event on the originating collection', function () { expect( singleCollectionA.trigger ).toHaveBeenCalledWith( "deselect:one", model1, singleCollectionA, { label: "selected" } ); } ); it( 'should trigger a select:one event on the originating collection', function () { expect( singleCollectionA.trigger ).toHaveBeenCalledWith( "select:one", model2, singleCollectionA, { label: "selected" } ); } ); it( 'should trigger a deselect:one event on another single-select collection', function () { expect( singleCollectionB.trigger ).toHaveBeenCalledWith( "deselect:one", model1, singleCollectionB, { label: "selected" } ); } ); it( 'should trigger a select:one event on another single-select collection', function () { expect( singleCollectionB.trigger ).toHaveBeenCalledWith( "select:one", model2, singleCollectionB, { label: "selected" } ); } ); it( 'should trigger a select:none and a select:some event on another multi-select collection', function () { // The process is made up of two steps. First, the previous model is // deselected, then the new one selected. Both steps are merged into a // single `select:some` event with a unified diff of `{ selected: [model2], // deselected: [model1] }`. expect( multiCollectionA.trigger ).toHaveBeenCalledWith( "select:some", { selected: [model2], deselected: [model1] }, multiCollectionA, { label: "selected" } ); } ); it( 'should not trigger a reselected event on the selected model', function () { expect( model2.trigger ).not.toHaveBeenCalledWithInitial( "reselected" ); } ); it( "should not trigger a reselect:one event on the originating collection", function () { expect( singleCollectionA.trigger ).not.toHaveBeenCalledWithInitial( "reselect:one" ); } ); it( "should not trigger a reselect:one event on another single-select collection", function () { expect( singleCollectionB.trigger ).not.toHaveBeenCalledWithInitial( "reselect:one" ); } ); it( "should not trigger a reselect:any event on another multi-select collection", function () { expect( multiCollectionA.trigger ).not.toHaveBeenCalledWithInitial( "reselect:any" ); } ); } ); describe( "when a model is already selected and a different model is selected with its select method", function () { describe( "when both models are shared among multi-select collections only", function () { var model1, model2, multiCollectionA, multiCollectionB; beforeEach( function () { model1 = new Model(); model2 = new Model(); multiCollectionA = new MultiSelectCollection( [model1, model2] ); multiCollectionB = new MultiSelectCollection( [model1, model2] ); model1.select(); spyOn( model1, "trigger" ).and.callThrough(); spyOn( model2, "trigger" ).and.callThrough(); spyOn( multiCollectionA, "trigger" ).and.callThrough(); model2.select(); } ); afterEach( function () { multiCollectionA.close(); multiCollectionB.close(); } ); it( "should be selected in all collections", function () { expect( multiCollectionA.selected[model2.cid] ).not.toBeUndefined(); expect( multiCollectionB.selected[model2.cid] ).not.toBeUndefined(); } ); it( "should leave the first model selected in all collections", function () { expect( multiCollectionA.selected[model1.cid] ).not.toBeUndefined(); expect( multiCollectionB.selected[model1.cid] ).not.toBeUndefined(); } ); it( 'should not trigger a selected event on the first model', function () { expect( model1.trigger ).not.toHaveBeenCalledWithInitial( "selected" ); } ); it( 'should not trigger a deselected event on the first model', function () { expect( model1.trigger ).not.toHaveBeenCalledWithInitial( "deselected" ); } ); it( 'should trigger a selected event on the second model', function () { expect( model2.trigger ).toHaveBeenCalledWith( "selected", model2, { label: "selected" } ); } ); it( 'should trigger a select:some or selected:all event on a multi-select collection', function () { expect( multiCollectionA.trigger ).toHaveBeenCalledWith( "select:all", { selected: [model2], deselected: [] }, multiCollectionA, { label: "selected" } ); } ); it( 'should not trigger a reselected event on the first model', function () { expect( model1.trigger ).not.toHaveBeenCalledWithInitial( "reselected", model1 ); } ); it( 'should not trigger a reselected event on the second model', function () { expect( model2.trigger ).not.toHaveBeenCalledWithInitial( "reselected", model2 ); } ); it( "should not trigger a reselect:any event on a multi-select collection", function () { expect( multiCollectionA.trigger ).not.toHaveBeenCalledWithInitial( "reselect:any" ); } ); } ); describe( "when both models are shared, with at least one single-select collection among the collections", function () { // As soon as both models are part of a single-select collection, only one of them can be flagged as selected. // That even extends to multi-select collections sharing those models. var model1, model2, singleCollectionA, multiCollectionA; beforeEach( function () { model1 = new Model(); model2 = new Model(); singleCollectionA = new SingleSelectCollection( [model1, model2] ); multiCollectionA = new MultiSelectCollection( [model1, model2] ); model1.select(); spyOn( model1, "trigger" ).and.callThrough(); spyOn( model2, "trigger" ).and.callThrough(); spyOn( singleCollectionA, "trigger" ).and.callThrough(); spyOn( multiCollectionA, "trigger" ).and.callThrough(); model2.select(); } ); afterEach( function () { singleCollectionA.close(); multiCollectionA.close(); } ); it( "should be selected in the single-select collection", function () { expect( singleCollectionA.selected ).toBe( model2 ); } ); it( "should be selected in the multi-select collection", function () { expect( multiCollectionA.selected[model2.cid] ).not.toBeUndefined(); } ); it( "should deselect the first model", function () { expect( model1.selected ).toBe( false ); } ); it( "should deselect the first model in the multi-select collection", function () { expect( multiCollectionA.selected[model1.cid] ).toBeUndefined(); } ); it( 'should not trigger a selected event on the first model', function () { expect( model1.trigger ).not.toHaveBeenCalledWithInitial( "selected" ); } ); it( 'should trigger a deselected event on the first model', function () { expect( model1.trigger ).toHaveBeenCalledWith( "deselected", model1, { label: "selected" } ); } ); it( 'should trigger a selected event on the second model', function () { expect( model2.trigger ).toHaveBeenCalledWith( "selected", model2, { label: "selected" } ); } ); it( 'should trigger a deselect:one event on the single-select collection', function () { expect( singleCollectionA.trigger ).toHaveBeenCalledWith( "deselect:one", model1, singleCollectionA, { label: "selected" } ); } ); it( 'should trigger a select:one event on the single-select collection', function () { expect( singleCollectionA.trigger ).toHaveBeenCalledWith( "select:one", model2, singleCollectionA, { label: "selected" } ); } ); it( 'should trigger a select:none and a select:some event on the multi-select collection', function () { // The process is made up of two steps. First, the previous model is // deselected, then the new one selected. Both steps are merged into a // single `select:some` event with a unified diff of `{ selected: [model2], // deselected: [model1] }`. expect( multiCollectionA.trigger ).toHaveBeenCalledWith( "select:some", { selected: [model2], deselected: [model1] }, multiCollectionA, { label: "selected" } ); } ); it( 'should not trigger a reselected event on the first model', function () { expect( model1.trigger ).not.toHaveBeenCalledWithInitial( "reselected", model1 ); } ); it( 'should not trigger a reselected event on the second model', function () { expect( model2.trigger ).not.toHaveBeenCalledWithInitial( "reselected", model2 ); } ); it( "should not trigger a reselect:one event on the single-select collection", function () { expect( singleCollectionA.trigger ).not.toHaveBeenCalledWithInitial( "reselect:one" ); } ); it( "should not trigger a reselect:any event on the multi-select collection", function () { expect( multiCollectionA.trigger ).not.toHaveBeenCalledWithInitial( "reselect:any" ); } ); } ); describe( "when the first model is shared with at least one single-select collection, but not the second", function () { var model1, model2, singleCollectionA, multiCollectionA; beforeEach( function () { model1 = new Model(); model2 = new Model(); singleCollectionA = new SingleSelectCollection( [model1] ); multiCollectionA = new MultiSelectCollection( [model1, model2] ); model1.select(); spyOn( model1, "trigger" ).and.callThrough(); spyOn( model2, "trigger" ).and.callThrough(); spyOn( singleCollectionA, "trigger" ).and.callThrough(); spyOn( multiCollectionA, "trigger" ).and.callThrough(); model2.select(); } ); afterEach( function () { singleCollectionA.close(); multiCollectionA.close(); } ); it( "should be selected itself", function () { expect( model2.selected ).toBe( true ); } ); it( "should be selected in the multi-select collection", function () { expect( multiCollectionA.selected[model2.cid] ).not.toBeUndefined(); } ); it( "should leave the first model selected", function () { expect( model1.selected ).toBe( true ); } ); it( "should leave the first model selected in the single-select collection", function () { expect( singleCollectionA.selected ).toBe( model1 ); } ); it( "should leave the first model selected in the multi-select collection", function () { expect( multiCollectionA.selected[model1.cid] ).not.toBeUndefined(); } ); it( 'should not trigger a selected event on the first model', function () { expect( model1.trigger ).not.toHaveBeenCalledWithInitial( "selected" ); } ); it( 'should not trigger a deselected event on the first model', function () { expect( model1.trigger ).not.toHaveBeenCalledWithInitial( "deselected" ); } ); it( 'should trigger a selected event on the second model', function () { expect( model2.trigger ).toHaveBeenCalledWith( "selected", model2, { label: "selected" } ); } ); it( 'should not trigger a deselect:one event on the single-select collection', function () { expect( singleCollectionA.trigger ).not.toHaveBeenCalledWithInitial( "deselect:one" ); } ); it( 'should not trigger a select:one event on the single-select collection', function () { expect( singleCollectionA.trigger ).not.toHaveBeenCalledWithInitial( "select:one" ); } ); it( 'should trigger a select:some or select:all event on the multi-select collection', function () { expect( multiCollectionA.trigger ).toHaveBeenCalledWith( "select:all", { selected: [model2], deselected: [] }, multiCollectionA, { label: "selected" } ); } ); it( 'should not trigger a reselected event on the first model', function () { expect( model1.trigger ).not.toHaveBeenCalledWithInitial( "reselected" ); } ); it( 'should not trigger a reselected event on the second model', function () { expect( model2.trigger ).not.toHaveBeenCalledWithInitial( "reselected" ); } ); it( "should not trigger a reselect:one event on the single-select collection", function () { expect( singleCollectionA.trigger ).not.toHaveBeenCalledWithInitial( "reselect:one" ); }