describe("Transistor.Backbone.Collection", function () { var radio, control, collection; beforeEach(function () { radio = (function () { var stub = {}; stub.trigger = function (channel_path, event, args) { stub.callback[channel_path](event, args) } stub.callback = {}; stub.tune = function (channel_path, listener) { stub.callback[channel_path] = listener console.log('tune', stub) } return stub; }()); collection = new Transistor.Backbone.Collection({ backbone: Backbone, channel: 'news', radio: radio }) }); describe("default write access", function () { it("is not granted", function () { expect(function () { collection.add({}) }).toThrow(new Error('BackboneCollection is not mutable by user.')); expect(function () { collection.remove({}) }).toThrow(new Error('BackboneCollection is not mutable by user.')); expect(function () { collection.reset({}) }).toThrow(new Error('BackboneCollection is not mutable by user.')); expect(function () { collection.set({}) }).toThrow(new Error('BackboneCollection is not mutable by user.')); }); it('fails also on a model', function () { radio.trigger('news', 'init', [{id: 100, a:2, b:3}, {id: 101, a:12, b:23}]); var model = collection.get(100); expect(function () { model.set('a', 0); }).toThrow(new Error('BackboneCollection is not mutable by user. The model with id 100 has been changed')); assertEqual(2, collection.get(100)get('a')); }); }); describe('write access via control', function () { beforeEach(function () { control = (function () { var calls = [], record = function (call, args) { console.log('call', call, args) calls.push([call, args]) }; return { set: function () { record("set", arguments); }, insert: function () { record("insert", arguments); }, update: function () { record("update", arguments); }, remove: function () { record("remove", arguments); }, calls: calls }; }()); collection = Transistor.Backbone.Collection({ backbone: Backbone, channel: 'news', radio: radio, control: control }); }); it('delegates add to insert', function () { collection.add({a: 12, b: 13}); assertEqual(control.calls, [ ['insert', ['news', {a: 12, b: 13}]] ]); }); it('delegates remove to remove', function () { radio.trigger('news', 'init', [{id: 100, a:2, b:3}, {id: 101, a:12, b:23}]); var model = collection.get(101); collection.remove(model) assertEqual(control.calls, [ ['remove', ['news', 101]] ]); }); it('delegates reset to set', function () { collection.reset([{a: 12}, {b: 13}]) assertEqual(control.calls, [ ['set', ['news', [{a: 12}, {b: 13}]]] ]); }); it('delegates set to set', function () { collection.set([{a: 12}, {b: 13}]) assertEqual(control.calls, [ ['set', ['news', [{a: 12}, {b: 13}]]] ]); }); it('delegates model change events to update', function () { radio.trigger('news', 'init', [{id: 100, a:2, b:3}, {id: 101, a:12, b:23}]); var model = collection.get(101); model.set('a', 24); assertEqual(control.calls, [ ['update', ['news', 101, {a: 24, b:23}]] ]); }) }); describe("init event", function () { it("maps arg 'array' to a clear and set", function () { radio.trigger('news', 'init', [{a:2, b:3}, {a:12, b:23}]); assertEqual(collection.length, 2); assertEqual(collection.at(0).get('a'), 2) assertEqual(collection.at(0).get('b'), 3) assertEqual(collection.at(1).get('a'), 12) assertEqual(collection.at(1).get('b'), 23) }); }); describe("set event", function () { it("resets the collection with given collection array", function () { radio.trigger('news', 'set', { collection: [{a:2, b:3}, {a:12, b:23}] }); assertEqual(collection.length, 2); assertEqual(collection.at(0).get('a'), 2) assertEqual(collection.at(0).get('b'), 3) assertEqual(collection.at(1).get('a'), 12) assertEqual(collection.at(1).get('b'), 23) }) }); describe("insert event", function () { it("appends the entry as model", function () { radio.trigger('news', 'set', { collection: [{a:2, b:3}, {a:12, b:23}] }); radio.trigger('news', 'insert', { entry: {a:11, b:66} }); assertEqual(collection.length, 3); assertEqual(collection.at(2).get('a'), 11) assertEqual(collection.at(2).get('b'), 66) }); }); describe("update event", function () { it("changes the entry model instance", function () { radio.trigger('news', 'set', { collection: [{id: 1001,a:2, b:3}, {id: 1002, a:12, b:23}] }); var model = collection.get(1002); assertEqual(collection.length, 2); assertEqual(model.get('a'), 12) assertEqual(model.get('b'), 23) radio.trigger('news', 'update', { id: 1002, entry: {id: 1002, a:100, b:200} }); assertEqual(model.get('a'), 100) assertEqual(model.get('b'), 200) }); }); describe("update event", function () { it("changes the entry model instance", function () { radio.trigger('news', 'set', { collection: [{id: 1001,a:2, b:3}, {id: 1002, a:12, b:23}] }); assertEqual(collection.length, 2); radio.trigger('news', 'remove', { id: 1001 }); assertEqual(collection.length, 1); assertEqual(collection.at(0).id, 1002); }); }); });