backbone.select
Version:
Selecting Backbone models; handling selections in Backbone collections.
1,017 lines (741 loc) • 47.8 kB
JavaScript
describe( "Custom labels: Select.Me model in Select.One collection", function () {
var Model = Backbone.Model.extend( {
initialize: function () {
Backbone.Select.Me.applyTo( this );
}
} );
var Collection = Backbone.Collection.extend( {
initialize: function ( models ) {
Backbone.Select.One.applyTo( this, models );
}
} );
beforeAll( function () {
limitJasmineRecursiveScreenOutput();
} );
afterAll( function () {
restoreJasmineRecursiveScreenOutput();
} );
describe( 'Using a custom "starred" label', function () {
describe( "when selecting a model via the model's select", function () {
var model, collection, events, eventStates;
beforeEach( function () {
model = new Model();
collection = new Collection( [model] );
events = getEventSpies( [model, collection], ["selected", "starred"] );
eventStates = getEventStateStore( [model, collection], "starred" );
model.select( { label: "starred" } );
} );
afterEach( function () {
collection.close();
} );
it( 'should store the currently selected model in the "starred" property of the collection', function () {
expect( collection.starred ).toBe( model );
} );
it( 'should leave the selected property of the collection undefined', function () {
expect( collection.selected ).toBeUndefined();
} );
it( 'should create a "starred" property on the model and set it to true', function () {
expect( model.starred ).toBe( true );
} );
it( 'should leave the selected property of the model undefined', function () {
expect( model.selected ).toBeUndefined();
} );
it( 'should trigger a selected event, with label "starred" in the event options', function () {
expect( events.get( model, "selected" ) ).toHaveBeenCalledWith( model, { label: "starred" } );
} );
it( 'should trigger a selected:starred event', function () {
expect( events.get( model, "selected:starred" ) ).toHaveBeenCalledWith( model, { label: "starred" } );
} );
it( 'should not trigger more than those two selected events (including namespaced ones)', function () {
expect( events.get( model, "selected:*" ) ).toHaveCallCount( 2 );
} );
it( "should not trigger a reselected event, including any of the namespaces", function () {
expect( events.get( model, "reselected:*" ) ).not.toHaveBeenCalled();
} );
it( 'should trigger a collection select:one event, with label "starred" in the event options', function () {
expect( events.get( collection, "select:one" ) ).toHaveBeenCalledWith( model, collection, { label: "starred" } );
} );
it( 'should trigger a collection select:one:starred event', function () {
expect( events.get( collection, "select:one:starred" ) ).toHaveBeenCalledWith( model, collection, { label: "starred" } );
} );
it( 'should not trigger more than those two select:one events (including namespaced ones)', function () {
expect( events.get( collection, "select:one:*" ) ).toHaveCallCount( 2 );
} );
it( "should trigger the model's selected event after the model status has been updated", function () {
expect( eventStates.getEvent( model, "selected" ).stateOf( model ).starred ).toBe( true );
} );
it( "should trigger the model's selected:starred event after the model status has been updated", function () {
expect( eventStates.getEvent( model, "selected:starred" ).stateOf( model ).starred ).toBe( true );
} );
it( "should trigger the model's selected event after the collection status has been updated", function () {
expect( eventStates.getEvent( model, "selected" ).stateOf( collection ).starred ).toBe( model );
} );
it( "should trigger the model's selected:starred event after the collection status has been updated", function () {
expect( eventStates.getEvent( model, "selected:starred" ).stateOf( collection ).starred ).toBe( model );
} );
it( "should trigger the collection's select:one event after the model status has been updated", function () {
expect( eventStates.getEvent( collection, "select:one" ).stateOf( model ).starred ).toBe( true );
} );
it( "should trigger the collection's select:one:starred event after the model status has been updated", function () {
expect( eventStates.getEvent( collection, "select:one:starred" ).stateOf( model ).starred ).toBe( true );
} );
it( "should trigger the collection's select:one event after the collection status has been updated", function () {
expect( eventStates.getEvent( collection, "select:one" ).stateOf( collection ).starred ).toBe( model );
} );
it( "should trigger the collection's select:one:starred event after the collection status has been updated", function () {
expect( eventStates.getEvent( collection, "select:one:starred" ).stateOf( collection ).starred ).toBe( model );
} );
it( "should not trigger a reselect:one event, including any of the namespaces", function () {
expect( events.get( collection, "reselect:one:*" ) ).not.toHaveBeenCalled();
} );
} );
describe( "when selecting a model via the model's select, with options.silent enabled", function () {
var model, collection, events;
beforeEach( function () {
model = new Model();
collection = new Collection( [model] );
events = getEventSpies( [model, collection], ["selected", "starred"] );
model.select( { label: "starred", silent: true } );
} );
afterEach( function () {
collection.close();
} );
it( 'should store the currently selected model in the "starred" property of the collection', function () {
expect( collection.starred ).toBe( model );
} );
it( 'should leave the selected property of the collection undefined', function () {
expect( collection.selected ).toBeUndefined();
} );
it( 'should create a "starred" property on the model and set it to true', function () {
expect( model.starred ).toBe( true );
} );
it( 'should leave the selected property of the model undefined', function () {
expect( model.selected ).toBeUndefined();
} );
it( 'should not trigger any selection-related events on the model', function () {
expect( events.get( model, "*" ) ).not.toHaveBeenCalled();
} );
it( 'should not trigger any selection-related events on the collection', function () {
expect( events.get( collection, "*" ) ).not.toHaveBeenCalled();
} );
} );
describe( "when selecting a model via the collection's select", function () {
var model, collection, events, eventStates;
beforeEach( function () {
model = new Model();
collection = new Collection( [model] );
events = getEventSpies( [model, collection], ["selected", "starred"] );
eventStates = getEventStateStore( [model, collection], ["selected", "starred"] );
spyOn( model, "select" ).and.callThrough();
collection.select( model, { label: "starred" } );
} );
afterEach( function () {
collection.close();
} );
it( 'should store the currently selected model in the "starred" property', function () {
expect( collection.starred ).toBe( model );
} );
it( 'should tell the model to select itself, with the label option set to "starred"', function () {
expect( model.select ).toHaveBeenCalledWith( jasmine.objectContaining( { label: "starred" } ) );
} );
it( "should not trigger a reselected event, including any of the namespaces", function () {
expect( events.get( model, "reselected:*" ) ).not.toHaveBeenCalled();
} );
it( 'should trigger a select:one event, with label "starred" in the event options', function () {
expect( events.get( collection, "select:one" ) ).toHaveBeenCalledWith( model, collection, { label: "starred" } );
} );
it( 'should trigger a collection select:one:starred event', function () {
expect( events.get( collection, "select:one:starred" ) ).toHaveBeenCalledWith( model, collection, { label: "starred" } );
} );
it( 'should not trigger more than those two select:one events (including namespaced ones)', function () {
expect( events.get( collection, "select:one:*" ) ).toHaveCallCount( 2 );
} );
it( "should not trigger a reselect:one event, including any of the namespaces", function () {
expect( events.get( collection, "reselect:one:*" ) ).not.toHaveBeenCalled();
} );
it( "should trigger the model's selected event after the model status has been updated", function () {
expect( eventStates.getEvent( model, "selected" ).stateOf( model ).starred ).toBe( true );
} );
it( "should trigger the model's selected:starred event after the model status has been updated", function () {
expect( eventStates.getEvent( model, "selected:starred" ).stateOf( model ).starred ).toBe( true );
} );
it( "should trigger the model's selected event after the collection status has been updated", function () {
expect( eventStates.getEvent( model, "selected" ).stateOf( collection ).starred ).toBe( model );
} );
it( "should trigger the model's selected:starred event after the collection status has been updated", function () {
expect( eventStates.getEvent( model, "selected:starred" ).stateOf( collection ).starred ).toBe( model );
} );
it( "should trigger the collection's select:one event after the model status has been updated", function () {
expect( eventStates.getEvent( collection, "select:one" ).stateOf( model ).starred ).toBe( true );
} );
it( "should trigger the collection's select:one:starred event after the model status has been updated", function () {
expect( eventStates.getEvent( collection, "select:one:starred" ).stateOf( model ).starred ).toBe( true );
} );
it( "should trigger the collection's select:one event after the collection status has been updated", function () {
expect( eventStates.getEvent( collection, "select:one" ).stateOf( collection ).starred ).toBe( model );
} );
it( "should trigger the collection's select:one:starred event after the collection status has been updated", function () {
expect( eventStates.getEvent( collection, "select:one:starred" ).stateOf( collection ).starred ).toBe( model );
} );
} );
describe( "when selecting a model via the collection's select, with options.silent enabled", function () {
var model, collection, events;
beforeEach( function () {
model = new Model();
collection = new Collection( [model] );
events = getEventSpies( [model, collection], ["selected", "starred"] );
spyOn( model, "select" ).and.callThrough();
collection.select( model, { label: "starred", silent: true } );
} );
afterEach( function () {
collection.close();
} );
it( 'should store the currently selected model in the "starred" property', function () {
expect( collection.starred ).toBe( model );
} );
it( 'should leave the selected property undefined', function () {
expect( collection.selected ).toBeUndefined();
} );
it( 'should tell the model to select itself, with the label option set to "starred"', function () {
expect( model.select ).toHaveBeenCalledWith( jasmine.objectContaining( { label: "starred" } ) );
} );
it( 'should not trigger any selection-related events on the model', function () {
expect( events.get( model, "*" ) ).not.toHaveBeenCalled();
} );
it( 'should not trigger any selection-related events on the collection', function () {
expect( events.get( collection, "*" ) ).not.toHaveBeenCalled();
} );
} );
describe( 'when selecting a model via the model\'s select, while it is already selected with the default label ("selected")', function () {
var model, collection, events;
beforeEach( function () {
model = new Model();
collection = new Collection( [model] );
model.select();
events = getEventSpies( [model, collection], ["selected", "starred"] );
model.select( { label: "starred" } );
} );
afterEach( function () {
collection.close();
} );
it( 'should store the currently selected model in the "starred" property of the collection', function () {
expect( collection.starred ).toBe( model );
} );
it( 'should leave the selected property of the collection set to the model', function () {
expect( collection.selected ).toBe( model );
} );
it( 'should create a "starred" property on the model and set it to true', function () {
expect( model.starred ).toBe( true );
} );
it( 'should leave the selected property of the model set to true', function () {
expect( model.selected ).toBe( true );
} );
it( 'should trigger a selected event, with label "starred" in the event options', function () {
expect( events.get( model, "selected" ) ).toHaveBeenCalledWith( model, { label: "starred" } );
} );
it( 'should trigger a selected:starred event', function () {
expect( events.get( model, "selected:starred" ) ).toHaveBeenCalledWith( model, { label: "starred" } );
} );
it( 'should not trigger more than those two selected events (including namespaced ones)', function () {
expect( events.get( model, "selected:*" ) ).toHaveCallCount( 2 );
} );
it( 'should trigger a collection select:one event, with label "starred" in the event options', function () {
expect( events.get( collection, "select:one" ) ).toHaveBeenCalledWith( model, collection, { label: "starred" } );
} );
it( 'should trigger a collection select:one:starred event', function () {
expect( events.get( collection, "select:one:starred" ) ).toHaveBeenCalledWith( model, collection, { label: "starred" } );
} );
it( 'should not trigger more than those two select:one events (including namespaced ones)', function () {
expect( events.get( collection, "select:one:*" ) ).toHaveCallCount( 2 );
} );
it( "should not trigger a reselected event, including any of the namespaces", function () {
expect( events.get( model, "reselected:*" ) ).not.toHaveBeenCalled();
} );
it( "should not trigger a reselect:one event, including any of the namespaces", function () {
expect( events.get( collection, "reselect:one:*" ) ).not.toHaveBeenCalled();
} );
} );
describe( 'when selecting a model via the model\'s select, while it is already selected with another custom label ("picked")', function () {
var model, collection, events;
beforeEach( function () {
model = new Model();
collection = new Collection( [model] );
model.select( { label: "picked" } );
events = getEventSpies( [model, collection], ["selected", "picked", "starred"] );
model.select( { label: "starred" } );
} );
afterEach( function () {
collection.close();
} );
it( 'should store the currently selected model in the "starred" property of the collection', function () {
expect( collection.starred ).toBe( model );
} );
it( 'should leave the "picked" property of the collection set to the model', function () {
expect( collection.picked ).toBe( model );
} );
it( 'should create a "starred" property on the model and set it to true', function () {
expect( model.starred ).toBe( true );
} );
it( 'should leave the "picked" property of the model set to true', function () {
expect( model.picked ).toBe( true );
} );
it( 'should trigger a selected event, with label "starred" in the event options', function () {
expect( events.get( model, "selected" ) ).toHaveBeenCalledWith( model, { label: "starred" } );
} );
it( 'should trigger a selected:starred event', function () {
expect( events.get( model, "selected:starred" ) ).toHaveBeenCalledWith( model, { label: "starred" } );
} );
it( 'should not trigger more than those two selected events (including namespaced ones)', function () {
expect( events.get( model, "selected:*" ) ).toHaveCallCount( 2 );
} );
it( 'should trigger a collection select:one event, with label "starred" in the event options', function () {
expect( events.get( collection, "select:one" ) ).toHaveBeenCalledWith( model, collection, { label: "starred" } );
} );
it( 'should trigger a collection select:one:starred event', function () {
expect( events.get( collection, "select:one:starred" ) ).toHaveBeenCalledWith( model, collection, { label: "starred" } );
} );
it( 'should not trigger more than those two select:one events (including namespaced ones)', function () {
expect( events.get( collection, "select:one:*" ) ).toHaveCallCount( 2 );
} );
it( "should not trigger a reselected event, including any of the namespaces", function () {
expect( events.get( model, "reselected:*" ) ).not.toHaveBeenCalled();
} );
it( "should not trigger a reselect:one event, including any of the namespaces", function () {
expect( events.get( collection, "reselect:one:*" ) ).not.toHaveBeenCalled();
} );
} );
describe( "when selecting a model that is already selected", function () {
var model, collection, events;
beforeEach( function () {
model = new Model();
collection = new Collection( [model] );
model.select( { label: "starred" } );
events = getEventSpies( [model, collection], ["selected", "starred"] );
collection.select( model, { label: "starred" } );
} );
afterEach( function () {
collection.close();
} );
it( "should not trigger a select:one event, including any of the namespaces", function () {
expect( events.get( collection, "select:one:*" ) ).not.toHaveBeenCalled();
} );
it( 'should trigger a reselected event, with label "starred" in the event options', function () {
expect( events.get( model, "reselected" ) ).toHaveBeenCalledWith( model, { label: "starred" } );
} );
it( 'should trigger a reselected:starred event', function () {
expect( events.get( model, "reselected:starred" ) ).toHaveBeenCalledWith( model, { label: "starred" } );
} );
it( 'should not trigger more than those two reselected events (including namespaced ones)', function () {
expect( events.get( model, "reselected:*" ) ).toHaveCallCount( 2 );
} );
it( 'should trigger a reselect:one event, with label "starred" in the event options', function () {
expect( events.get( collection, "reselect:one" ) ).toHaveBeenCalledWith( model, collection, { label: "starred" } );
} );
it( "should trigger a reselect:one:starred event", function () {
expect( events.get( collection, "reselect:one:starred" ) ).toHaveBeenCalledWith( model, collection, { label: "starred" } );
} );
it( 'should not trigger more than those two reselect:one events (including namespaced ones)', function () {
expect( events.get( collection, "reselect:one:*" ) ).toHaveCallCount( 2 );
} );
} );
describe( "when selecting a model that is already selected, with options.silent enabled", function () {
var model, collection, events;
beforeEach( function () {
model = new Model();
collection = new Collection( [model] );
model.select( { label: "starred" } );
events = getEventSpies( [model, collection], ["selected", "starred"] );
collection.select( model, { silent: true, label: "starred" } );
} );
afterEach( function () {
collection.close();
} );
it( 'should not trigger any selection-related events on the model', function () {
expect( events.get( model, "*" ) ).not.toHaveBeenCalled();
} );
it( 'should not trigger any selection-related events on the collection', function () {
expect( events.get( collection, "*" ) ).not.toHaveBeenCalled();
} );
} );
describe( "when a model is already selected and selecting a different model", function () {
var m1, m2, collection, events;
beforeEach( function () {
m1 = new Model();
m2 = new Model();
collection = new Collection( [m1, m2] );
m1.select( { label: "starred" } );
events = getEventSpies( [collection], ["selected", "starred"] );
spyOn( m1, "deselect" ).and.callThrough();
m2.select( { label: "starred" } );
} );
afterEach( function () {
collection.close();
} );
it( 'should store the newly selected model in the "starred" property of the collection', function () {
expect( collection.starred ).toBe( m2 );
} );
it( 'should create a "starred" property on the newly selected model and set it to true', function () {
expect( m2.starred ).toBe( true );
} );
it( 'should deselect the "starred" property of the first model', function () {
expect( m1.starred ).toBe( false );
} );
it( 'should trigger a select:one event, with label "starred" in the event options', function () {
expect( events.get( collection, "select:one" ) ).toHaveBeenCalledWith( m2, collection, { label: "starred" } );
} );
it( 'should trigger a select:one:starred event', function () {
expect( events.get( collection, "select:one:starred" ) ).toHaveBeenCalledWith( m2, collection, { label: "starred" } );
} );
it( 'should not trigger more than those two select:one events (including namespaced ones)', function () {
expect( events.get( collection, "select:one:*" ) ).toHaveCallCount( 2 );
} );
it( "should not trigger a reselect:one event, including any of the namespaces", function () {
expect( events.get( collection, "reselect:one:*" ) ).not.toHaveBeenCalled();
} );
it( 'should trigger a deselect:one event for the first model, with label "starred" in the event options', function () {
expect( events.get( collection, "deselect:one" ) ).toHaveBeenCalledWith( m1, collection, { label: "starred" } );
} );
it( 'should trigger a deselect:one:starred event for the first model, with label "starred" in the event options', function () {
expect( events.get( collection, "deselect:one:starred" ) ).toHaveBeenCalledWith( m1, collection, { label: "starred" } );
} );
it( 'should not trigger more than those two deselect:one events (including namespaced ones)', function () {
expect( events.get( collection, "deselect:one:*" ) ).toHaveCallCount( 2 );
} );
} );
describe( "when a model is already selected and selecting a different model, with options.silent enabled", function () {
var m1, m2, collection, events;
beforeEach( function () {
m1 = new Model();
m2 = new Model();
collection = new Collection( [m1, m2] );
m1.select( { label: "starred" } );
events = getEventSpies( [m1, m2, collection], ["selected", "starred"] );
spyOn( m1, "deselect" ).and.callThrough();
m2.select( { silent: true, label: "starred" } );
} );
afterEach( function () {
collection.close();
} );
it( 'should store the newly selected model in the "starred" property of the collection', function () {
expect( collection.starred ).toBe( m2 );
} );
it( 'should create a "starred" property on the newly selected model and set it to true', function () {
expect( m2.starred ).toBe( true );
} );
it( 'should deselect the "starred" property of the first model', function () {
expect( m1.starred ).toBe( false );
} );
it( 'should not trigger any selection-related events on the first model', function () {
expect( events.get( m1, "*" ) ).not.toHaveBeenCalled();
} );
it( 'should not trigger any selection-related events on the second model', function () {
expect( events.get( m2, "*" ) ).not.toHaveBeenCalled();
} );
it( 'should not trigger any selection-related events on the collection', function () {
expect( events.get( collection, "*" ) ).not.toHaveBeenCalled();
} );
} );
describe( "when no model is selected and deselecting", function () {
var model, collection, events;
beforeEach( function () {
model = new Model();
collection = new Collection( [model] );
events = getEventSpies( [model, collection], ["selected", "starred"] );
collection.deselect( { label: "starred" } );
} );
afterEach( function () {
collection.close();
} );
it( 'should not trigger any selection-related events on the model', function () {
expect( events.get( model, "*" ) ).not.toHaveBeenCalled();
} );
it( 'should not trigger any selection-related events on the collection', function () {
expect( events.get( collection, "*" ) ).not.toHaveBeenCalled();
} );
} );
describe( "when a model is selected and deselecting the model through the model's deselect", function () {
var model, collection, events, eventStates;
beforeEach( function () {
model = new Model();
collection = new Collection( [model] );
model.select( { label: "starred" } );
events = getEventSpies( [collection], ["selected", "starred"] );
eventStates = getEventStateStore( [model, collection], ["selected", "starred"] );
model.deselect( { label: "starred" } );
} );
afterEach( function () {
collection.close();
} );
it( 'should set the "starred" property of the collection to undefined', function () {
expect( collection.starred ).toBeUndefined();
} );
it( 'should deselect the "starred" property of the deselected model', function () {
expect( model.starred ).toBe( false );
} );
it( 'should trigger a deselect:one event, with label "starred" in the event options', function () {
expect( events.get( collection, "deselect:one" ) ).toHaveBeenCalledWith( model, collection, { label: "starred" } );
} );
it( 'should trigger a deselect:one:starred event', function () {
expect( events.get( collection, "deselect:one:starred" ) ).toHaveBeenCalledWith( model, collection, { label: "starred" } );
} );
it( 'should not trigger more than those two deselect:one events (including namespaced ones)', function () {
expect( events.get( collection, "deselect:one:*" ) ).toHaveCallCount( 2 );
} );
it( "should trigger the model's deselected event after the model status has been updated", function () {
expect( eventStates.getEvent( model, "deselected" ).stateOf( model ).starred ).toBe( false );
} );
it( "should trigger the model's deselected event after the collection status has been updated", function () {
expect( eventStates.getEvent( model, "deselected" ).stateOf( collection ).starred ).toBeUndefined();
} );
it( "should trigger the model's deselected:starred event after the model status has been updated", function () {
expect( eventStates.getEvent( model, "deselected:starred" ).stateOf( model ).starred ).toBe( false );
} );
it( "should trigger the model's deselected event after the collection status has been updated", function () {
expect( eventStates.getEvent( model, "deselected:starred" ).stateOf( collection ).starred ).toBeUndefined();
} );
it( "should trigger the collection's deselect:one event after the model status has been updated", function () {
expect( eventStates.getEvent( collection, "deselect:one" ).stateOf( model ).starred ).toBe( false );
} );
it( "should trigger the collection's deselect:one event after the collection status has been updated", function () {
expect( eventStates.getEvent( collection, "deselect:one" ).stateOf( collection ).starred ).toBeUndefined();
} );
it( "should trigger the collection's deselect:one:starred event after the model status has been updated", function () {
expect( eventStates.getEvent( collection, "deselect:one:starred" ).stateOf( model ).starred ).toBe( false );
} );
it( "should trigger the collection's deselect:one:starred event after the collection status has been updated", function () {
expect( eventStates.getEvent( collection, "deselect:one:starred" ).stateOf( collection ).starred ).toBeUndefined();
} );
} );
describe( "when a model is selected and deselecting the model through the collection's deselect", function () {
var model, collection, events, eventStates;
beforeEach( function () {
model = new Model();
collection = new Collection( [model] );
model.select( { label: "starred" } );
events = getEventSpies( [collection], ["selected", "starred"] );
eventStates = getEventStateStore( [model, collection], ["selected", "starred"] );
collection.deselect( model, { label: "starred" } );
} );
afterEach( function () {
collection.close();
} );
it( 'should set the "starred" property of the collection to undefined', function () {
expect( collection.starred ).toBeUndefined();
} );
it( 'should deselect the "starred" property of the deselected model', function () {
expect( model.starred ).toBe( false );
} );
it( 'should trigger a deselect:one event, with label "starred" in the event options', function () {
expect( events.get( collection, "deselect:one" ) ).toHaveBeenCalledWith( model, collection, { label: "starred" } );
} );
it( 'should trigger a deselect:one:starred event', function () {
expect( events.get( collection, "deselect:one:starred" ) ).toHaveBeenCalledWith( model, collection, { label: "starred" } );
} );
it( 'should not trigger more than those two deselect:one events (including namespaced ones)', function () {
expect( events.get( collection, "deselect:one:*" ) ).toHaveCallCount( 2 );
} );
it( "should trigger the model's deselected event after the model status has been updated", function () {
expect( eventStates.getEvent( model, "deselected" ).stateOf( model ).starred ).toBe( false );
} );
it( "should trigger the model's deselected event after the collection status has been updated", function () {
expect( eventStates.getEvent( model, "deselected" ).stateOf( collection ).starred ).toBeUndefined();
} );
it( "should trigger the model's deselected:starred event after the model status has been updated", function () {
expect( eventStates.getEvent( model, "deselected:starred" ).stateOf( model ).starred ).toBe( false );
} );
it( "should trigger the model's deselected event after the collection status has been updated", function () {
expect( eventStates.getEvent( model, "deselected:starred" ).stateOf( collection ).starred ).toBeUndefined();
} );
it( "should trigger the collection's deselect:one event after the model status has been updated", function () {
expect( eventStates.getEvent( collection, "deselect:one" ).stateOf( model ).starred ).toBe( false );
} );
it( "should trigger the collection's deselect:one event after the collection status has been updated", function () {
expect( eventStates.getEvent( collection, "deselect:one" ).stateOf( collection ).starred ).toBeUndefined();
} );
it( "should trigger the collection's deselect:one:starred event after the model status has been updated", function () {
expect( eventStates.getEvent( collection, "deselect:one:starred" ).stateOf( model ).starred ).toBe( false );
} );
it( "should trigger the collection's deselect:one:starred event after the collection status has been updated", function () {
expect( eventStates.getEvent( collection, "deselect:one:starred" ).stateOf( collection ).starred ).toBeUndefined();
} );
} );
describe( "when a model is selected and deselecting the model, with options.silent enabled", function () {
var model, collection, events;
beforeEach( function () {
model = new Model();
collection = new Collection( [model] );
model.select( { label: "starred" } );
events = getEventSpies( [model, collection], ["selected", "starred"] );
collection.deselect( undefined, { silent: true, label: "starred" } );
} );
afterEach( function () {
collection.close();
} );
it( 'should set the "starred" property of the collection to undefined', function () {
expect( collection.starred ).toBeUndefined();
} );
it( 'should deselect the "starred" property of the deselected model', function () {
expect( model.starred ).toBe( false );
} );
it( 'should not trigger any selection-related events on the model', function () {
expect( events.get( model, "*" ) ).not.toHaveBeenCalled();
} );
it( 'should not trigger any selection-related events on the collection', function () {
expect( events.get( collection, "*" ) ).not.toHaveBeenCalled();
} );
} );
describe( 'when deselecting a model via the model\'s deselect, while it is also selected with the default label ("selected")', function () {
var model, collection, events;
beforeEach( function () {
model = new Model();
collection = new Collection( [model] );
model.select();
model.select( { label: "starred" } );
events = getEventSpies( [model, collection], ["selected", "starred"] );
model.deselect( { label: "starred" } );
} );
afterEach( function () {
collection.close();
} );
it( 'should set the "starred" property of the collection to undefined', function () {
expect( collection.starred ).toBeUndefined();
} );
it( 'should leave the selected property of the collection set to the model', function () {
expect( collection.selected ).toBe( model );
} );
it( 'should deselect the "starred" property of the deselected model', function () {
expect( model.starred ).toBe( false );
} );
it( 'should leave the selected property of the model set to true', function () {
expect( model.selected ).toBe( true );
} );
it( 'should trigger a deselected event, with label "starred" in the event options', function () {
expect( events.get( model, "deselected" ) ).toHaveBeenCalledWith( model, { label: "starred" } );
} );
it( 'should trigger a deselected:starred event', function () {
expect( events.get( model, "deselected:starred" ) ).toHaveBeenCalledWith( model, { label: "starred" } );
} );
it( 'should not trigger more than those two selected events (including namespaced ones)', function () {
expect( events.get( model, "deselected:*" ) ).toHaveCallCount( 2 );
} );
it( 'should trigger a collection deselect:one event, with label "starred" in the event options', function () {
expect( events.get( collection, "deselect:one" ) ).toHaveBeenCalledWith( model, collection, { label: "starred" } );
} );
it( 'should trigger a collection deselect:one:starred event', function () {
expect( events.get( collection, "deselect:one:starred" ) ).toHaveBeenCalledWith( model, collection, { label: "starred" } );
} );
it( 'should not trigger more than those two deselect:one events (including namespaced ones)', function () {
expect( events.get( collection, "deselect:one:*" ) ).toHaveCallCount( 2 );
} );
it( "should not trigger a reselected event, including any of the namespaces", function () {
expect( events.get( model, "reselected:*" ) ).not.toHaveBeenCalled();
} );
it( "should not trigger a reselect:one event, including any of the namespaces", function () {
expect( events.get( collection, "reselect:one:*" ) ).not.toHaveBeenCalled();
} );
} );
describe( 'when deselecting a model via the model\'s deselect, while it is also selected with another custom label ("picked")', function () {
var model, collection, events;
beforeEach( function () {
model = new Model();
collection = new Collection( [model] );
model.select( { label: "picked" } );
model.select( { label: "starred" } );
events = getEventSpies( [model, collection], ["selected", "picked", "starred"] );
model.deselect( { label: "starred" } );
} );
afterEach( function () {
collection.close();
} );
it( 'should set the "starred" property of the collection to undefined', function () {
expect( collection.starred ).toBeUndefined();
} );
it( 'should leave the "picked" property of the collection set to the model', function () {
expect( collection.picked ).toBe( model );
} );
it( 'should deselect the "starred" property of the deselected model', function () {
expect( model.starred ).toBe( false );
} );
it( 'should leave the "picked" property of the model set to true', function () {
expect( model.picked ).toBe( true );
} );
it( 'should trigger a deselected event, with label "starred" in the event options', function () {
expect( events.get( model, "deselected" ) ).toHaveBeenCalledWith( model, { label: "starred" } );
} );
it( 'should trigger a deselected:starred event', function () {
expect( events.get( model, "deselected:starred" ) ).toHaveBeenCalledWith( model, { label: "starred" } );
} );
it( 'should not trigger more than those two deselected events (including namespaced ones)', function () {
expect( events.get( model, "deselected:*" ) ).toHaveCallCount( 2 );
} );
it( 'should trigger a collection deselect:one event, with label "starred" in the event options', function () {
expect( events.get( collection, "deselect:one" ) ).toHaveBeenCalledWith( model, collection, { label: "starred" } );
} );
it( 'should trigger a collection deselect:one:starred event', function () {
expect( events.get( collection, "deselect:one:starred" ) ).toHaveBeenCalledWith( model, collection, { label: "starred" } );
} );
it( 'should not trigger more than those two deselect:one events (including namespaced ones)', function () {
expect( events.get( collection, "deselect:one:*" ) ).toHaveCallCount( 2 );
} );
it( "should not trigger a reselected event, including any of the namespaces", function () {
expect( events.get( model, "reselected:*" ) ).not.toHaveBeenCalled();
} );
it( "should not trigger a reselect:one event, including any of the namespaces", function () {
expect( events.get( collection, "reselect:one:*" ) ).not.toHaveBeenCalled();
} );
} );
} );
describe( 'automatic invocation of onSelect, onDeselect, onReselect handlers', function () {
var EventHandlingCollection, model, collection;
beforeEach( function () {
EventHandlingCollection = Collection.extend( {
onSelect: function () {},
onDeselect: function () {},
onReselect: function () {},
// Pseudo event handlers modeled on standard Backbone events `add`,
// `remove`, `reset`, `all` (as stand-ins for all others) ; should
// not be invoked automatically
onAdd: function () {},
onRemove: function () {},
onReset: function () {},
onAll: function () {}
} );
model = new Model();
collection = new EventHandlingCollection( [model] );
spyOn( collection, "onSelect" ).and.callThrough();
spyOn( collection, "onDeselect" ).and.callThrough();
spyOn( collection, "onReselect" ).and.callThrough();
spyOn( collection, "onAdd" ).and.callThrough();
spyOn( collection, "onRemove" ).and.callThrough();
spyOn( collection, "onReset" ).and.callThrough();
spyOn( collection, "onAll" ).and.callThrough();
} );
afterEach( function () {
collection.close();
} );
it( 'calls the onSelect handler when triggering a select:one event with a custom label', function () {
collection.trigger( "select:one", model, collection, { label: "starred" } );
expect( collection.onSelect ).toHaveBeenCalledWith( model, collection, { label: "starred" } );
} );
it( 'calls the onDeselect handler when triggering a deselect:one event with a custom label', function () {
collection.trigger( "deselect:one", model, collection, { label: "starred" } );
expect( collection.onDeselect ).toHaveBeenCalledWith( model, collection, { label: "starred" } );
} );
it( 'calls the onReselect handler when triggering a reselect:one event with a custom label', function () {
collection.trigger( "reselect:one", model, collection, { label: "starred" } );
expect( collection.onReselect ).toHaveBeenCalledWith( model, collection, { label: "starred" } );
} );
it( 'does not call the onSelect handler when triggering a select:one event with a namespace', function () {
collection.trigger( "select:one:starred", model, collection, { label: "starred" } );
expect( collection.onSelect ).not.toHaveBeenCalled();
} );
it( 'does not call the onDeselect handler when triggering a deselect:one event with a namespace', function () {
collection.trigger( "deselect:one:starred", model, collection, { label: "starred" } );
expect( collection.onDeselect ).not.toHaveBeenCalled();
} );
it( 'does not call the onReselect handler when triggering a reselect:one event with a namespace', function () {
collection.trigger( "reselect:one:starred", model, collection, { label: "starred" } );
expect( collection.onReselect ).not.toHaveBeenCalled();
} );
} );
} );