jdl 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +18 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +54 -0
- data/Rakefile +1 -0
- data/bin/jdl +60 -0
- data/jdl.gemspec +23 -0
- data/lib/jdl/version.rb +3 -0
- data/lib/jdl.rb +53 -0
- data/test/collection.js +1154 -0
- data/test/environment.js +35 -0
- data/test/events.js +452 -0
- data/test/index.html +29 -0
- data/test/model.coffee +43 -0
- data/test/model.js +1110 -0
- data/test/noconflict.js +12 -0
- data/test/router.js +689 -0
- data/test/sync.js +210 -0
- data/test/vendor/backbone.js +1582 -0
- data/test/vendor/jquery.js +9472 -0
- data/test/vendor/json2.js +481 -0
- data/test/vendor/qunit.css +244 -0
- data/test/vendor/qunit.js +2212 -0
- data/test/vendor/runner.js +127 -0
- data/test/vendor/underscore.js +1222 -0
- data/test/view.js +330 -0
- metadata +128 -0
data/test/collection.js
ADDED
@@ -0,0 +1,1154 @@
|
|
1
|
+
$(document).ready(function() {
|
2
|
+
|
3
|
+
var a, b, c, d, e, col, otherCol;
|
4
|
+
|
5
|
+
module("Backbone.Collection", {
|
6
|
+
|
7
|
+
setup: function() {
|
8
|
+
a = new Backbone.Model({id: 3, label: 'a'});
|
9
|
+
b = new Backbone.Model({id: 2, label: 'b'});
|
10
|
+
c = new Backbone.Model({id: 1, label: 'c'});
|
11
|
+
d = new Backbone.Model({id: 0, label: 'd'});
|
12
|
+
e = null;
|
13
|
+
col = new Backbone.Collection([a,b,c,d]);
|
14
|
+
otherCol = new Backbone.Collection();
|
15
|
+
}
|
16
|
+
|
17
|
+
});
|
18
|
+
|
19
|
+
test("new and sort", 9, function() {
|
20
|
+
var counter = 0;
|
21
|
+
col.on('sort', function(){ counter++; });
|
22
|
+
equal(col.first(), a, "a should be first");
|
23
|
+
equal(col.last(), d, "d should be last");
|
24
|
+
col.comparator = function(a, b) {
|
25
|
+
return a.id > b.id ? -1 : 1;
|
26
|
+
};
|
27
|
+
col.sort();
|
28
|
+
equal(counter, 1);
|
29
|
+
equal(col.first(), a, "a should be first");
|
30
|
+
equal(col.last(), d, "d should be last");
|
31
|
+
col.comparator = function(model) { return model.id; };
|
32
|
+
col.sort();
|
33
|
+
equal(counter, 2);
|
34
|
+
equal(col.first(), d, "d should be first");
|
35
|
+
equal(col.last(), a, "a should be last");
|
36
|
+
equal(col.length, 4);
|
37
|
+
});
|
38
|
+
|
39
|
+
test("String comparator.", 1, function() {
|
40
|
+
var collection = new Backbone.Collection([
|
41
|
+
{id: 3},
|
42
|
+
{id: 1},
|
43
|
+
{id: 2}
|
44
|
+
], {comparator: 'id'});
|
45
|
+
deepEqual(collection.pluck('id'), [1, 2, 3]);
|
46
|
+
});
|
47
|
+
|
48
|
+
test("new and parse", 3, function() {
|
49
|
+
var Collection = Backbone.Collection.extend({
|
50
|
+
parse : function(data) {
|
51
|
+
return _.filter(data, function(datum) {
|
52
|
+
return datum.a % 2 === 0;
|
53
|
+
});
|
54
|
+
}
|
55
|
+
});
|
56
|
+
var models = [{a: 1}, {a: 2}, {a: 3}, {a: 4}];
|
57
|
+
var collection = new Collection(models, {parse: true});
|
58
|
+
strictEqual(collection.length, 2);
|
59
|
+
strictEqual(collection.first().get('a'), 2);
|
60
|
+
strictEqual(collection.last().get('a'), 4);
|
61
|
+
});
|
62
|
+
|
63
|
+
test("get", 6, function() {
|
64
|
+
equal(col.get(0), d);
|
65
|
+
equal(col.get(d.clone()), d);
|
66
|
+
equal(col.get(2), b);
|
67
|
+
equal(col.get({id: 1}), c);
|
68
|
+
equal(col.get(c.clone()), c);
|
69
|
+
equal(col.get(col.first().cid), col.first());
|
70
|
+
});
|
71
|
+
|
72
|
+
test("get with non-default ids", 5, function() {
|
73
|
+
var col = new Backbone.Collection();
|
74
|
+
var MongoModel = Backbone.Model.extend({idAttribute: '_id'});
|
75
|
+
var model = new MongoModel({_id: 100});
|
76
|
+
col.add(model);
|
77
|
+
equal(col.get(100), model);
|
78
|
+
equal(col.get(model.cid), model);
|
79
|
+
equal(col.get(model), model);
|
80
|
+
equal(col.get(101), void 0);
|
81
|
+
|
82
|
+
var col2 = new Backbone.Collection();
|
83
|
+
col2.model = MongoModel;
|
84
|
+
col2.add(model.attributes);
|
85
|
+
equal(col2.get(model.clone()), col2.first());
|
86
|
+
});
|
87
|
+
|
88
|
+
test("update index when id changes", 4, function() {
|
89
|
+
var col = new Backbone.Collection();
|
90
|
+
col.add([
|
91
|
+
{id : 0, name : 'one'},
|
92
|
+
{id : 1, name : 'two'}
|
93
|
+
]);
|
94
|
+
var one = col.get(0);
|
95
|
+
equal(one.get('name'), 'one');
|
96
|
+
col.on('change:name', function (model) { ok(this.get(model)); });
|
97
|
+
one.set({name: 'dalmatians', id : 101});
|
98
|
+
equal(col.get(0), null);
|
99
|
+
equal(col.get(101).get('name'), 'dalmatians');
|
100
|
+
});
|
101
|
+
|
102
|
+
test("at", 1, function() {
|
103
|
+
equal(col.at(2), c);
|
104
|
+
});
|
105
|
+
|
106
|
+
test("pluck", 1, function() {
|
107
|
+
equal(col.pluck('label').join(' '), 'a b c d');
|
108
|
+
});
|
109
|
+
|
110
|
+
test("add", 10, function() {
|
111
|
+
var added, opts, secondAdded;
|
112
|
+
added = opts = secondAdded = null;
|
113
|
+
e = new Backbone.Model({id: 10, label : 'e'});
|
114
|
+
otherCol.add(e);
|
115
|
+
otherCol.on('add', function() {
|
116
|
+
secondAdded = true;
|
117
|
+
});
|
118
|
+
col.on('add', function(model, collection, options){
|
119
|
+
added = model.get('label');
|
120
|
+
opts = options;
|
121
|
+
});
|
122
|
+
col.add(e, {amazing: true});
|
123
|
+
equal(added, 'e');
|
124
|
+
equal(col.length, 5);
|
125
|
+
equal(col.last(), e);
|
126
|
+
equal(otherCol.length, 1);
|
127
|
+
equal(secondAdded, null);
|
128
|
+
ok(opts.amazing);
|
129
|
+
|
130
|
+
var f = new Backbone.Model({id: 20, label : 'f'});
|
131
|
+
var g = new Backbone.Model({id: 21, label : 'g'});
|
132
|
+
var h = new Backbone.Model({id: 22, label : 'h'});
|
133
|
+
var atCol = new Backbone.Collection([f, g, h]);
|
134
|
+
equal(atCol.length, 3);
|
135
|
+
atCol.add(e, {at: 1});
|
136
|
+
equal(atCol.length, 4);
|
137
|
+
equal(atCol.at(1), e);
|
138
|
+
equal(atCol.last(), h);
|
139
|
+
});
|
140
|
+
|
141
|
+
test("add multiple models", 6, function() {
|
142
|
+
var col = new Backbone.Collection([{at: 0}, {at: 1}, {at: 9}]);
|
143
|
+
col.add([{at: 2}, {at: 3}, {at: 4}, {at: 5}, {at: 6}, {at: 7}, {at: 8}], {at: 2});
|
144
|
+
for (var i = 0; i <= 5; i++) {
|
145
|
+
equal(col.at(i).get('at'), i);
|
146
|
+
}
|
147
|
+
});
|
148
|
+
|
149
|
+
test("add; at should have preference over comparator", 1, function() {
|
150
|
+
var Col = Backbone.Collection.extend({
|
151
|
+
comparator: function(a,b) {
|
152
|
+
return a.id > b.id ? -1 : 1;
|
153
|
+
}
|
154
|
+
});
|
155
|
+
|
156
|
+
var col = new Col([{id: 2}, {id: 3}]);
|
157
|
+
col.add(new Backbone.Model({id: 1}), {at: 1});
|
158
|
+
|
159
|
+
equal(col.pluck('id').join(' '), '3 1 2');
|
160
|
+
});
|
161
|
+
|
162
|
+
test("can't add model to collection twice", function() {
|
163
|
+
var col = new Backbone.Collection([{id: 1}, {id: 2}, {id: 1}, {id: 2}, {id: 3}]);
|
164
|
+
equal(col.pluck('id').join(' '), '1 2 3');
|
165
|
+
});
|
166
|
+
|
167
|
+
test("can't add different model with same id to collection twice", 1, function() {
|
168
|
+
var col = new Backbone.Collection;
|
169
|
+
col.unshift({id: 101});
|
170
|
+
col.add({id: 101});
|
171
|
+
equal(col.length, 1);
|
172
|
+
});
|
173
|
+
|
174
|
+
test("merge in duplicate models with {merge: true}", 3, function() {
|
175
|
+
var col = new Backbone.Collection;
|
176
|
+
col.add([{id: 1, name: 'Moe'}, {id: 2, name: 'Curly'}, {id: 3, name: 'Larry'}]);
|
177
|
+
col.add({id: 1, name: 'Moses'});
|
178
|
+
equal(col.first().get('name'), 'Moe');
|
179
|
+
col.add({id: 1, name: 'Moses'}, {merge: true});
|
180
|
+
equal(col.first().get('name'), 'Moses');
|
181
|
+
col.add({id: 1, name: 'Tim'}, {merge: true, silent: true});
|
182
|
+
equal(col.first().get('name'), 'Tim');
|
183
|
+
});
|
184
|
+
|
185
|
+
test("add model to multiple collections", 10, function() {
|
186
|
+
var counter = 0;
|
187
|
+
var e = new Backbone.Model({id: 10, label : 'e'});
|
188
|
+
e.on('add', function(model, collection) {
|
189
|
+
counter++;
|
190
|
+
equal(e, model);
|
191
|
+
if (counter > 1) {
|
192
|
+
equal(collection, colF);
|
193
|
+
} else {
|
194
|
+
equal(collection, colE);
|
195
|
+
}
|
196
|
+
});
|
197
|
+
var colE = new Backbone.Collection([]);
|
198
|
+
colE.on('add', function(model, collection) {
|
199
|
+
equal(e, model);
|
200
|
+
equal(colE, collection);
|
201
|
+
});
|
202
|
+
var colF = new Backbone.Collection([]);
|
203
|
+
colF.on('add', function(model, collection) {
|
204
|
+
equal(e, model);
|
205
|
+
equal(colF, collection);
|
206
|
+
});
|
207
|
+
colE.add(e);
|
208
|
+
equal(e.collection, colE);
|
209
|
+
colF.add(e);
|
210
|
+
equal(e.collection, colE);
|
211
|
+
});
|
212
|
+
|
213
|
+
test("add model with parse", 1, function() {
|
214
|
+
var Model = Backbone.Model.extend({
|
215
|
+
parse: function(obj) {
|
216
|
+
obj.value += 1;
|
217
|
+
return obj;
|
218
|
+
}
|
219
|
+
});
|
220
|
+
|
221
|
+
var Col = Backbone.Collection.extend({model: Model});
|
222
|
+
var col = new Col;
|
223
|
+
col.add({value: 1}, {parse: true});
|
224
|
+
equal(col.at(0).get('value'), 2);
|
225
|
+
});
|
226
|
+
|
227
|
+
test("add with parse and merge", function() {
|
228
|
+
var Model = Backbone.Model.extend({
|
229
|
+
parse: function (data) {
|
230
|
+
return data.model;
|
231
|
+
}
|
232
|
+
});
|
233
|
+
var collection = new Backbone.Collection();
|
234
|
+
collection.model = Model;
|
235
|
+
collection.add({id: 1});
|
236
|
+
collection.add({model: {id: 1, name: 'Alf'}}, {parse: true, merge: true});
|
237
|
+
equal(collection.first().get('name'), 'Alf');
|
238
|
+
});
|
239
|
+
|
240
|
+
test("add model to collection with sort()-style comparator", 3, function() {
|
241
|
+
var col = new Backbone.Collection;
|
242
|
+
col.comparator = function(a, b) {
|
243
|
+
return a.get('name') < b.get('name') ? -1 : 1;
|
244
|
+
};
|
245
|
+
var tom = new Backbone.Model({name: 'Tom'});
|
246
|
+
var rob = new Backbone.Model({name: 'Rob'});
|
247
|
+
var tim = new Backbone.Model({name: 'Tim'});
|
248
|
+
col.add(tom);
|
249
|
+
col.add(rob);
|
250
|
+
col.add(tim);
|
251
|
+
equal(col.indexOf(rob), 0);
|
252
|
+
equal(col.indexOf(tim), 1);
|
253
|
+
equal(col.indexOf(tom), 2);
|
254
|
+
});
|
255
|
+
|
256
|
+
test("comparator that depends on `this`", 2, function() {
|
257
|
+
var col = new Backbone.Collection;
|
258
|
+
col.negative = function(num) {
|
259
|
+
return -num;
|
260
|
+
};
|
261
|
+
col.comparator = function(a) {
|
262
|
+
return this.negative(a.id);
|
263
|
+
};
|
264
|
+
col.add([{id: 1}, {id: 2}, {id: 3}]);
|
265
|
+
deepEqual(col.pluck('id'), [3, 2, 1]);
|
266
|
+
col.comparator = function(a, b) {
|
267
|
+
return this.negative(b.id) - this.negative(a.id);
|
268
|
+
};
|
269
|
+
col.sort();
|
270
|
+
deepEqual(col.pluck('id'), [1, 2, 3]);
|
271
|
+
});
|
272
|
+
|
273
|
+
test("remove", 5, function() {
|
274
|
+
var removed = null;
|
275
|
+
var otherRemoved = null;
|
276
|
+
col.on('remove', function(model, col, options) {
|
277
|
+
removed = model.get('label');
|
278
|
+
equal(options.index, 3);
|
279
|
+
});
|
280
|
+
otherCol.on('remove', function(model, col, options) {
|
281
|
+
otherRemoved = true;
|
282
|
+
});
|
283
|
+
col.remove(d);
|
284
|
+
equal(removed, 'd');
|
285
|
+
equal(col.length, 3);
|
286
|
+
equal(col.first(), a);
|
287
|
+
equal(otherRemoved, null);
|
288
|
+
});
|
289
|
+
|
290
|
+
test("shift and pop", 2, function() {
|
291
|
+
var col = new Backbone.Collection([{a: 'a'}, {b: 'b'}, {c: 'c'}]);
|
292
|
+
equal(col.shift().get('a'), 'a');
|
293
|
+
equal(col.pop().get('c'), 'c');
|
294
|
+
});
|
295
|
+
|
296
|
+
test("slice", 2, function() {
|
297
|
+
var col = new Backbone.Collection([{a: 'a'}, {b: 'b'}, {c: 'c'}]);
|
298
|
+
var array = col.slice(1, 3);
|
299
|
+
equal(array.length, 2);
|
300
|
+
equal(array[0].get('b'), 'b');
|
301
|
+
});
|
302
|
+
|
303
|
+
test("events are unbound on remove", 3, function() {
|
304
|
+
var counter = 0;
|
305
|
+
var dj = new Backbone.Model();
|
306
|
+
var emcees = new Backbone.Collection([dj]);
|
307
|
+
emcees.on('change', function(){ counter++; });
|
308
|
+
dj.set({name : 'Kool'});
|
309
|
+
equal(counter, 1);
|
310
|
+
emcees.reset([]);
|
311
|
+
equal(dj.collection, undefined);
|
312
|
+
dj.set({name : 'Shadow'});
|
313
|
+
equal(counter, 1);
|
314
|
+
});
|
315
|
+
|
316
|
+
test("remove in multiple collections", 7, function() {
|
317
|
+
var modelData = {
|
318
|
+
id : 5,
|
319
|
+
title : 'Othello'
|
320
|
+
};
|
321
|
+
var passed = false;
|
322
|
+
var e = new Backbone.Model(modelData);
|
323
|
+
var f = new Backbone.Model(modelData);
|
324
|
+
f.on('remove', function() {
|
325
|
+
passed = true;
|
326
|
+
});
|
327
|
+
var colE = new Backbone.Collection([e]);
|
328
|
+
var colF = new Backbone.Collection([f]);
|
329
|
+
ok(e != f);
|
330
|
+
ok(colE.length === 1);
|
331
|
+
ok(colF.length === 1);
|
332
|
+
colE.remove(e);
|
333
|
+
equal(passed, false);
|
334
|
+
ok(colE.length === 0);
|
335
|
+
colF.remove(e);
|
336
|
+
ok(colF.length === 0);
|
337
|
+
equal(passed, true);
|
338
|
+
});
|
339
|
+
|
340
|
+
test("remove same model in multiple collection", 16, function() {
|
341
|
+
var counter = 0;
|
342
|
+
var e = new Backbone.Model({id: 5, title: 'Othello'});
|
343
|
+
e.on('remove', function(model, collection) {
|
344
|
+
counter++;
|
345
|
+
equal(e, model);
|
346
|
+
if (counter > 1) {
|
347
|
+
equal(collection, colE);
|
348
|
+
} else {
|
349
|
+
equal(collection, colF);
|
350
|
+
}
|
351
|
+
});
|
352
|
+
var colE = new Backbone.Collection([e]);
|
353
|
+
colE.on('remove', function(model, collection) {
|
354
|
+
equal(e, model);
|
355
|
+
equal(colE, collection);
|
356
|
+
});
|
357
|
+
var colF = new Backbone.Collection([e]);
|
358
|
+
colF.on('remove', function(model, collection) {
|
359
|
+
equal(e, model);
|
360
|
+
equal(colF, collection);
|
361
|
+
});
|
362
|
+
equal(colE, e.collection);
|
363
|
+
colF.remove(e);
|
364
|
+
ok(colF.length === 0);
|
365
|
+
ok(colE.length === 1);
|
366
|
+
equal(counter, 1);
|
367
|
+
equal(colE, e.collection);
|
368
|
+
colE.remove(e);
|
369
|
+
equal(null, e.collection);
|
370
|
+
ok(colE.length === 0);
|
371
|
+
equal(counter, 2);
|
372
|
+
});
|
373
|
+
|
374
|
+
test("model destroy removes from all collections", 3, function() {
|
375
|
+
var e = new Backbone.Model({id: 5, title: 'Othello'});
|
376
|
+
e.sync = function(method, model, options) { options.success(); };
|
377
|
+
var colE = new Backbone.Collection([e]);
|
378
|
+
var colF = new Backbone.Collection([e]);
|
379
|
+
e.destroy();
|
380
|
+
ok(colE.length === 0);
|
381
|
+
ok(colF.length === 0);
|
382
|
+
equal(undefined, e.collection);
|
383
|
+
});
|
384
|
+
|
385
|
+
test("Colllection: non-persisted model destroy removes from all collections", 3, function() {
|
386
|
+
var e = new Backbone.Model({title: 'Othello'});
|
387
|
+
e.sync = function(method, model, options) { throw "should not be called"; };
|
388
|
+
var colE = new Backbone.Collection([e]);
|
389
|
+
var colF = new Backbone.Collection([e]);
|
390
|
+
e.destroy();
|
391
|
+
ok(colE.length === 0);
|
392
|
+
ok(colF.length === 0);
|
393
|
+
equal(undefined, e.collection);
|
394
|
+
});
|
395
|
+
|
396
|
+
test("fetch", 4, function() {
|
397
|
+
var collection = new Backbone.Collection;
|
398
|
+
collection.url = '/test';
|
399
|
+
collection.fetch();
|
400
|
+
equal(this.syncArgs.method, 'read');
|
401
|
+
equal(this.syncArgs.model, collection);
|
402
|
+
equal(this.syncArgs.options.parse, true);
|
403
|
+
|
404
|
+
collection.fetch({parse: false});
|
405
|
+
equal(this.syncArgs.options.parse, false);
|
406
|
+
});
|
407
|
+
|
408
|
+
test("fetch with an error response triggers an error event", 1, function () {
|
409
|
+
var collection = new Backbone.Collection();
|
410
|
+
collection.on('error', function () {
|
411
|
+
ok(true);
|
412
|
+
});
|
413
|
+
collection.sync = function (method, model, options) { options.error(); };
|
414
|
+
collection.fetch();
|
415
|
+
});
|
416
|
+
|
417
|
+
test("ensure fetch only parses once", 1, function() {
|
418
|
+
var collection = new Backbone.Collection;
|
419
|
+
var counter = 0;
|
420
|
+
collection.parse = function(models) {
|
421
|
+
counter++;
|
422
|
+
return models;
|
423
|
+
};
|
424
|
+
collection.url = '/test';
|
425
|
+
collection.fetch();
|
426
|
+
this.syncArgs.options.success();
|
427
|
+
equal(counter, 1);
|
428
|
+
});
|
429
|
+
|
430
|
+
test("create", 4, function() {
|
431
|
+
var collection = new Backbone.Collection;
|
432
|
+
collection.url = '/test';
|
433
|
+
var model = collection.create({label: 'f'}, {wait: true});
|
434
|
+
equal(this.syncArgs.method, 'create');
|
435
|
+
equal(this.syncArgs.model, model);
|
436
|
+
equal(model.get('label'), 'f');
|
437
|
+
equal(model.collection, collection);
|
438
|
+
});
|
439
|
+
|
440
|
+
test("create with validate:true enforces validation", 2, function() {
|
441
|
+
var ValidatingModel = Backbone.Model.extend({
|
442
|
+
validate: function(attrs) {
|
443
|
+
return "fail";
|
444
|
+
}
|
445
|
+
});
|
446
|
+
var ValidatingCollection = Backbone.Collection.extend({
|
447
|
+
model: ValidatingModel
|
448
|
+
});
|
449
|
+
var col = new ValidatingCollection();
|
450
|
+
col.on('invalid', function (collection, attrs, options) {
|
451
|
+
equal(options.validationError, 'fail');
|
452
|
+
});
|
453
|
+
equal(col.create({"foo":"bar"}, {validate:true}), false);
|
454
|
+
});
|
455
|
+
|
456
|
+
test("a failing create returns model with errors", function() {
|
457
|
+
var ValidatingModel = Backbone.Model.extend({
|
458
|
+
validate: function(attrs) {
|
459
|
+
return "fail";
|
460
|
+
}
|
461
|
+
});
|
462
|
+
var ValidatingCollection = Backbone.Collection.extend({
|
463
|
+
model: ValidatingModel
|
464
|
+
});
|
465
|
+
var col = new ValidatingCollection();
|
466
|
+
var m = col.create({"foo":"bar"});
|
467
|
+
equal(m.validationError, 'fail');
|
468
|
+
equal(col.length, 1);
|
469
|
+
});
|
470
|
+
|
471
|
+
test("initialize", 1, function() {
|
472
|
+
var Collection = Backbone.Collection.extend({
|
473
|
+
initialize: function() {
|
474
|
+
this.one = 1;
|
475
|
+
}
|
476
|
+
});
|
477
|
+
var coll = new Collection;
|
478
|
+
equal(coll.one, 1);
|
479
|
+
});
|
480
|
+
|
481
|
+
test("toJSON", 1, function() {
|
482
|
+
equal(JSON.stringify(col), '[{"id":3,"label":"a"},{"id":2,"label":"b"},{"id":1,"label":"c"},{"id":0,"label":"d"}]');
|
483
|
+
});
|
484
|
+
|
485
|
+
test("where and findWhere", 8, function() {
|
486
|
+
var model = new Backbone.Model({a: 1});
|
487
|
+
var coll = new Backbone.Collection([
|
488
|
+
model,
|
489
|
+
{a: 1},
|
490
|
+
{a: 1, b: 2},
|
491
|
+
{a: 2, b: 2},
|
492
|
+
{a: 3}
|
493
|
+
]);
|
494
|
+
equal(coll.where({a: 1}).length, 3);
|
495
|
+
equal(coll.where({a: 2}).length, 1);
|
496
|
+
equal(coll.where({a: 3}).length, 1);
|
497
|
+
equal(coll.where({b: 1}).length, 0);
|
498
|
+
equal(coll.where({b: 2}).length, 2);
|
499
|
+
equal(coll.where({a: 1, b: 2}).length, 1);
|
500
|
+
equal(coll.findWhere({a: 1}), model);
|
501
|
+
equal(coll.findWhere({a: 4}), void 0);
|
502
|
+
});
|
503
|
+
|
504
|
+
test("Underscore methods", 14, function() {
|
505
|
+
equal(col.map(function(model){ return model.get('label'); }).join(' '), 'a b c d');
|
506
|
+
equal(col.any(function(model){ return model.id === 100; }), false);
|
507
|
+
equal(col.any(function(model){ return model.id === 0; }), true);
|
508
|
+
equal(col.indexOf(b), 1);
|
509
|
+
equal(col.size(), 4);
|
510
|
+
equal(col.rest().length, 3);
|
511
|
+
ok(!_.include(col.rest(), a));
|
512
|
+
ok(_.include(col.rest(), d));
|
513
|
+
ok(!col.isEmpty());
|
514
|
+
ok(!_.include(col.without(d), d));
|
515
|
+
equal(col.max(function(model){ return model.id; }).id, 3);
|
516
|
+
equal(col.min(function(model){ return model.id; }).id, 0);
|
517
|
+
deepEqual(col.chain()
|
518
|
+
.filter(function(o){ return o.id % 2 === 0; })
|
519
|
+
.map(function(o){ return o.id * 2; })
|
520
|
+
.value(),
|
521
|
+
[4, 0]);
|
522
|
+
deepEqual(col.difference([c, d]), [a, b]);
|
523
|
+
});
|
524
|
+
|
525
|
+
test("sortedIndex", function () {
|
526
|
+
var model = new Backbone.Model({key: 2});
|
527
|
+
var collection = new (Backbone.Collection.extend({
|
528
|
+
comparator: 'key'
|
529
|
+
}))([model, {key: 1}]);
|
530
|
+
equal(collection.sortedIndex(model), 1);
|
531
|
+
equal(collection.sortedIndex(model, 'key'), 1);
|
532
|
+
equal(collection.sortedIndex(model, function (model) {
|
533
|
+
return model.get('key');
|
534
|
+
}), 1);
|
535
|
+
});
|
536
|
+
|
537
|
+
test("reset", 12, function() {
|
538
|
+
var resetCount = 0;
|
539
|
+
var models = col.models;
|
540
|
+
col.on('reset', function() { resetCount += 1; });
|
541
|
+
col.reset([]);
|
542
|
+
equal(resetCount, 1);
|
543
|
+
equal(col.length, 0);
|
544
|
+
equal(col.last(), null);
|
545
|
+
col.reset(models);
|
546
|
+
equal(resetCount, 2);
|
547
|
+
equal(col.length, 4);
|
548
|
+
equal(col.last(), d);
|
549
|
+
col.reset(_.map(models, function(m){ return m.attributes; }));
|
550
|
+
equal(resetCount, 3);
|
551
|
+
equal(col.length, 4);
|
552
|
+
ok(col.last() !== d);
|
553
|
+
ok(_.isEqual(col.last().attributes, d.attributes));
|
554
|
+
col.reset();
|
555
|
+
equal(col.length, 0);
|
556
|
+
equal(resetCount, 4);
|
557
|
+
});
|
558
|
+
|
559
|
+
test ("reset with different values", function(){
|
560
|
+
var col = new Backbone.Collection({id: 1});
|
561
|
+
col.reset({id: 1, a: 1});
|
562
|
+
equal(col.get(1).get('a'), 1);
|
563
|
+
});
|
564
|
+
|
565
|
+
test("same references in reset", function() {
|
566
|
+
var model = new Backbone.Model({id: 1});
|
567
|
+
var collection = new Backbone.Collection({id: 1});
|
568
|
+
collection.reset(model);
|
569
|
+
equal(collection.get(1), model);
|
570
|
+
});
|
571
|
+
|
572
|
+
test("reset passes caller options", 3, function() {
|
573
|
+
var Model = Backbone.Model.extend({
|
574
|
+
initialize: function(attrs, options) {
|
575
|
+
this.model_parameter = options.model_parameter;
|
576
|
+
}
|
577
|
+
});
|
578
|
+
var col = new (Backbone.Collection.extend({ model: Model }))();
|
579
|
+
col.reset([{ astring: "green", anumber: 1 }, { astring: "blue", anumber: 2 }], { model_parameter: 'model parameter' });
|
580
|
+
equal(col.length, 2);
|
581
|
+
col.each(function(model) {
|
582
|
+
equal(model.model_parameter, 'model parameter');
|
583
|
+
});
|
584
|
+
});
|
585
|
+
|
586
|
+
test("trigger custom events on models", 1, function() {
|
587
|
+
var fired = null;
|
588
|
+
a.on("custom", function() { fired = true; });
|
589
|
+
a.trigger("custom");
|
590
|
+
equal(fired, true);
|
591
|
+
});
|
592
|
+
|
593
|
+
test("add does not alter arguments", 2, function(){
|
594
|
+
var attrs = {};
|
595
|
+
var models = [attrs];
|
596
|
+
new Backbone.Collection().add(models);
|
597
|
+
equal(models.length, 1);
|
598
|
+
ok(attrs === models[0]);
|
599
|
+
});
|
600
|
+
|
601
|
+
test("#714: access `model.collection` in a brand new model.", 2, function() {
|
602
|
+
var collection = new Backbone.Collection;
|
603
|
+
collection.url = '/test';
|
604
|
+
var Model = Backbone.Model.extend({
|
605
|
+
set: function(attrs) {
|
606
|
+
equal(attrs.prop, 'value');
|
607
|
+
equal(this.collection, collection);
|
608
|
+
return this;
|
609
|
+
}
|
610
|
+
});
|
611
|
+
collection.model = Model;
|
612
|
+
collection.create({prop: 'value'});
|
613
|
+
});
|
614
|
+
|
615
|
+
test("#574, remove its own reference to the .models array.", 2, function() {
|
616
|
+
var col = new Backbone.Collection([
|
617
|
+
{id: 1}, {id: 2}, {id: 3}, {id: 4}, {id: 5}, {id: 6}
|
618
|
+
]);
|
619
|
+
equal(col.length, 6);
|
620
|
+
col.remove(col.models);
|
621
|
+
equal(col.length, 0);
|
622
|
+
});
|
623
|
+
|
624
|
+
test("#861, adding models to a collection which do not pass validation, with validate:true", function() {
|
625
|
+
var Model = Backbone.Model.extend({
|
626
|
+
validate: function(attrs) {
|
627
|
+
if (attrs.id == 3) return "id can't be 3";
|
628
|
+
}
|
629
|
+
});
|
630
|
+
|
631
|
+
var Collection = Backbone.Collection.extend({
|
632
|
+
model: Model
|
633
|
+
});
|
634
|
+
|
635
|
+
var collection = new Collection;
|
636
|
+
collection.on("error", function() { ok(true); });
|
637
|
+
|
638
|
+
collection.add([{id: 1}, {id: 2}, {id: 3}, {id: 4}, {id: 5}, {id: 6}], {validate:true});
|
639
|
+
deepEqual(collection.pluck('id'), [1, 2, 4, 5, 6]);
|
640
|
+
});
|
641
|
+
|
642
|
+
test("Invalid models are discarded with validate:true.", 5, function() {
|
643
|
+
var collection = new Backbone.Collection;
|
644
|
+
collection.on('test', function() { ok(true); });
|
645
|
+
collection.model = Backbone.Model.extend({
|
646
|
+
validate: function(attrs){ if (!attrs.valid) return 'invalid'; }
|
647
|
+
});
|
648
|
+
var model = new collection.model({id: 1, valid: true});
|
649
|
+
collection.add([model, {id: 2}], {validate:true});
|
650
|
+
model.trigger('test');
|
651
|
+
ok(collection.get(model.cid));
|
652
|
+
ok(collection.get(1));
|
653
|
+
ok(!collection.get(2));
|
654
|
+
equal(collection.length, 1);
|
655
|
+
});
|
656
|
+
|
657
|
+
test("multiple copies of the same model", 3, function() {
|
658
|
+
var col = new Backbone.Collection();
|
659
|
+
var model = new Backbone.Model();
|
660
|
+
col.add([model, model]);
|
661
|
+
equal(col.length, 1);
|
662
|
+
col.add([{id: 1}, {id: 1}]);
|
663
|
+
equal(col.length, 2);
|
664
|
+
equal(col.last().id, 1);
|
665
|
+
});
|
666
|
+
|
667
|
+
test("#964 - collection.get return inconsistent", 2, function() {
|
668
|
+
var c = new Backbone.Collection();
|
669
|
+
ok(c.get(null) === undefined);
|
670
|
+
ok(c.get() === undefined);
|
671
|
+
});
|
672
|
+
|
673
|
+
test("#1112 - passing options.model sets collection.model", 2, function() {
|
674
|
+
var Model = Backbone.Model.extend({});
|
675
|
+
var c = new Backbone.Collection([{id: 1}], {model: Model});
|
676
|
+
ok(c.model === Model);
|
677
|
+
ok(c.at(0) instanceof Model);
|
678
|
+
});
|
679
|
+
|
680
|
+
test("null and undefined are invalid ids.", 2, function() {
|
681
|
+
var model = new Backbone.Model({id: 1});
|
682
|
+
var collection = new Backbone.Collection([model]);
|
683
|
+
model.set({id: null});
|
684
|
+
ok(!collection.get('null'));
|
685
|
+
model.set({id: 1});
|
686
|
+
model.set({id: undefined});
|
687
|
+
ok(!collection.get('undefined'));
|
688
|
+
});
|
689
|
+
|
690
|
+
test("falsy comparator", 4, function(){
|
691
|
+
var Col = Backbone.Collection.extend({
|
692
|
+
comparator: function(model){ return model.id; }
|
693
|
+
});
|
694
|
+
var col = new Col();
|
695
|
+
var colFalse = new Col(null, {comparator: false});
|
696
|
+
var colNull = new Col(null, {comparator: null});
|
697
|
+
var colUndefined = new Col(null, {comparator: undefined});
|
698
|
+
ok(col.comparator);
|
699
|
+
ok(!colFalse.comparator);
|
700
|
+
ok(!colNull.comparator);
|
701
|
+
ok(colUndefined.comparator);
|
702
|
+
});
|
703
|
+
|
704
|
+
test("#1355 - `options` is passed to success callbacks", 2, function(){
|
705
|
+
var m = new Backbone.Model({x:1});
|
706
|
+
var col = new Backbone.Collection();
|
707
|
+
var opts = {
|
708
|
+
success: function(collection, resp, options){
|
709
|
+
ok(options);
|
710
|
+
}
|
711
|
+
};
|
712
|
+
col.sync = m.sync = function( method, collection, options ){
|
713
|
+
options.success(collection, [], options);
|
714
|
+
};
|
715
|
+
col.fetch(opts);
|
716
|
+
col.create(m, opts);
|
717
|
+
});
|
718
|
+
|
719
|
+
test("#1412 - Trigger 'request' and 'sync' events.", 4, function() {
|
720
|
+
var collection = new Backbone.Collection;
|
721
|
+
collection.url = '/test';
|
722
|
+
Backbone.ajax = function(settings){ settings.success(); };
|
723
|
+
|
724
|
+
collection.on('request', function(obj, xhr, options) {
|
725
|
+
ok(obj === collection, "collection has correct 'request' event after fetching");
|
726
|
+
});
|
727
|
+
collection.on('sync', function(obj, response, options) {
|
728
|
+
ok(obj === collection, "collection has correct 'sync' event after fetching");
|
729
|
+
});
|
730
|
+
collection.fetch();
|
731
|
+
collection.off();
|
732
|
+
|
733
|
+
collection.on('request', function(obj, xhr, options) {
|
734
|
+
ok(obj === collection.get(1), "collection has correct 'request' event after one of its models save");
|
735
|
+
});
|
736
|
+
collection.on('sync', function(obj, response, options) {
|
737
|
+
ok(obj === collection.get(1), "collection has correct 'sync' event after one of its models save");
|
738
|
+
});
|
739
|
+
collection.create({id: 1});
|
740
|
+
collection.off();
|
741
|
+
});
|
742
|
+
|
743
|
+
test("#1447 - create with wait adds model.", 1, function() {
|
744
|
+
var collection = new Backbone.Collection;
|
745
|
+
var model = new Backbone.Model;
|
746
|
+
model.sync = function(method, model, options){ options.success(); };
|
747
|
+
collection.on('add', function(){ ok(true); });
|
748
|
+
collection.create(model, {wait: true});
|
749
|
+
});
|
750
|
+
|
751
|
+
test("#1448 - add sorts collection after merge.", 1, function() {
|
752
|
+
var collection = new Backbone.Collection([
|
753
|
+
{id: 1, x: 1},
|
754
|
+
{id: 2, x: 2}
|
755
|
+
]);
|
756
|
+
collection.comparator = function(model){ return model.get('x'); };
|
757
|
+
collection.add({id: 1, x: 3}, {merge: true});
|
758
|
+
deepEqual(collection.pluck('id'), [2, 1]);
|
759
|
+
});
|
760
|
+
|
761
|
+
test("#1655 - groupBy can be used with a string argument.", 3, function() {
|
762
|
+
var collection = new Backbone.Collection([{x: 1}, {x: 2}]);
|
763
|
+
var grouped = collection.groupBy('x');
|
764
|
+
strictEqual(_.keys(grouped).length, 2);
|
765
|
+
strictEqual(grouped[1][0].get('x'), 1);
|
766
|
+
strictEqual(grouped[2][0].get('x'), 2);
|
767
|
+
});
|
768
|
+
|
769
|
+
test("#1655 - sortBy can be used with a string argument.", 1, function() {
|
770
|
+
var collection = new Backbone.Collection([{x: 3}, {x: 1}, {x: 2}]);
|
771
|
+
var values = _.map(collection.sortBy('x'), function(model) {
|
772
|
+
return model.get('x');
|
773
|
+
});
|
774
|
+
deepEqual(values, [1, 2, 3]);
|
775
|
+
});
|
776
|
+
|
777
|
+
test("#1604 - Removal during iteration.", 0, function() {
|
778
|
+
var collection = new Backbone.Collection([{}, {}]);
|
779
|
+
collection.on('add', function() {
|
780
|
+
collection.at(0).destroy();
|
781
|
+
});
|
782
|
+
collection.add({}, {at: 0});
|
783
|
+
});
|
784
|
+
|
785
|
+
test("#1638 - `sort` during `add` triggers correctly.", function() {
|
786
|
+
var collection = new Backbone.Collection;
|
787
|
+
collection.comparator = function(model) { return model.get('x'); };
|
788
|
+
var added = [];
|
789
|
+
collection.on('add', function(model) {
|
790
|
+
model.set({x: 3});
|
791
|
+
collection.sort();
|
792
|
+
added.push(model.id);
|
793
|
+
});
|
794
|
+
collection.add([{id: 1, x: 1}, {id: 2, x: 2}]);
|
795
|
+
deepEqual(added, [1, 2]);
|
796
|
+
});
|
797
|
+
|
798
|
+
test("fetch parses models by default", 1, function() {
|
799
|
+
var model = {};
|
800
|
+
var Collection = Backbone.Collection.extend({
|
801
|
+
url: 'test',
|
802
|
+
model: Backbone.Model.extend({
|
803
|
+
parse: function(resp) {
|
804
|
+
strictEqual(resp, model);
|
805
|
+
}
|
806
|
+
})
|
807
|
+
});
|
808
|
+
new Collection().fetch();
|
809
|
+
this.ajaxSettings.success([model]);
|
810
|
+
});
|
811
|
+
|
812
|
+
test("`sort` shouldn't always fire on `add`", 1, function() {
|
813
|
+
var c = new Backbone.Collection([{id: 1}, {id: 2}, {id: 3}], {
|
814
|
+
comparator: 'id'
|
815
|
+
});
|
816
|
+
c.sort = function(){ ok(true); };
|
817
|
+
c.add([]);
|
818
|
+
c.add({id: 1});
|
819
|
+
c.add([{id: 2}, {id: 3}]);
|
820
|
+
c.add({id: 4});
|
821
|
+
});
|
822
|
+
|
823
|
+
test("#1407 parse option on constructor parses collection and models", 2, function() {
|
824
|
+
var model = {
|
825
|
+
namespace : [{id: 1}, {id:2}]
|
826
|
+
};
|
827
|
+
var Collection = Backbone.Collection.extend({
|
828
|
+
model: Backbone.Model.extend({
|
829
|
+
parse: function(model) {
|
830
|
+
model.name = 'test';
|
831
|
+
return model;
|
832
|
+
}
|
833
|
+
}),
|
834
|
+
parse: function(model) {
|
835
|
+
return model.namespace;
|
836
|
+
}
|
837
|
+
});
|
838
|
+
var c = new Collection(model, {parse:true});
|
839
|
+
|
840
|
+
equal(c.length, 2);
|
841
|
+
equal(c.at(0).get('name'), 'test');
|
842
|
+
});
|
843
|
+
|
844
|
+
test("#1407 parse option on reset parses collection and models", 2, function() {
|
845
|
+
var model = {
|
846
|
+
namespace : [{id: 1}, {id:2}]
|
847
|
+
};
|
848
|
+
var Collection = Backbone.Collection.extend({
|
849
|
+
model: Backbone.Model.extend({
|
850
|
+
parse: function(model) {
|
851
|
+
model.name = 'test';
|
852
|
+
return model;
|
853
|
+
}
|
854
|
+
}),
|
855
|
+
parse: function(model) {
|
856
|
+
return model.namespace;
|
857
|
+
}
|
858
|
+
});
|
859
|
+
var c = new Collection();
|
860
|
+
c.reset(model, {parse:true});
|
861
|
+
|
862
|
+
equal(c.length, 2);
|
863
|
+
equal(c.at(0).get('name'), 'test');
|
864
|
+
});
|
865
|
+
|
866
|
+
|
867
|
+
test("Reset includes previous models in triggered event.", 1, function() {
|
868
|
+
var model = new Backbone.Model();
|
869
|
+
var collection = new Backbone.Collection([model])
|
870
|
+
.on('reset', function(collection, options) {
|
871
|
+
deepEqual(options.previousModels, [model]);
|
872
|
+
});
|
873
|
+
collection.reset([]);
|
874
|
+
});
|
875
|
+
|
876
|
+
test("set", function() {
|
877
|
+
var m1 = new Backbone.Model();
|
878
|
+
var m2 = new Backbone.Model({id: 2});
|
879
|
+
var m3 = new Backbone.Model();
|
880
|
+
var c = new Backbone.Collection([m1, m2]);
|
881
|
+
|
882
|
+
// Test add/change/remove events
|
883
|
+
c.on('add', function(model) {
|
884
|
+
strictEqual(model, m3);
|
885
|
+
});
|
886
|
+
c.on('change', function(model) {
|
887
|
+
strictEqual(model, m2);
|
888
|
+
});
|
889
|
+
c.on('remove', function(model) {
|
890
|
+
strictEqual(model, m1);
|
891
|
+
});
|
892
|
+
|
893
|
+
// remove: false doesn't remove any models
|
894
|
+
c.set([], {remove: false});
|
895
|
+
strictEqual(c.length, 2);
|
896
|
+
|
897
|
+
// add: false doesn't add any models
|
898
|
+
c.set([m1, m2, m3], {add: false});
|
899
|
+
strictEqual(c.length, 2);
|
900
|
+
|
901
|
+
// merge: false doesn't change any models
|
902
|
+
c.set([m1, {id: 2, a: 1}], {merge: false});
|
903
|
+
strictEqual(m2.get('a'), void 0);
|
904
|
+
|
905
|
+
// add: false, remove: false only merges existing models
|
906
|
+
c.set([m1, {id: 2, a: 0}, m3, {id: 4}], {add: false, remove: false});
|
907
|
+
strictEqual(c.length, 2);
|
908
|
+
strictEqual(m2.get('a'), 0);
|
909
|
+
|
910
|
+
// default options add/remove/merge as appropriate
|
911
|
+
c.set([{id: 2, a: 1}, m3]);
|
912
|
+
strictEqual(c.length, 2);
|
913
|
+
strictEqual(m2.get('a'), 1);
|
914
|
+
|
915
|
+
// Test removing models not passing an argument
|
916
|
+
c.off('remove').on('remove', function(model) {
|
917
|
+
ok(model === m2 || model === m3);
|
918
|
+
});
|
919
|
+
c.set([]);
|
920
|
+
strictEqual(c.length, 0);
|
921
|
+
});
|
922
|
+
|
923
|
+
test("set with only cids", 3, function() {
|
924
|
+
var m1 = new Backbone.Model;
|
925
|
+
var m2 = new Backbone.Model;
|
926
|
+
var c = new Backbone.Collection;
|
927
|
+
c.set([m1, m2]);
|
928
|
+
equal(c.length, 2);
|
929
|
+
c.set([m1]);
|
930
|
+
equal(c.length, 1);
|
931
|
+
c.set([m1, m1, m1, m2, m2], {remove: false});
|
932
|
+
equal(c.length, 2);
|
933
|
+
});
|
934
|
+
|
935
|
+
test("set with only idAttribute", 3, function() {
|
936
|
+
var m1 = { _id: 1 };
|
937
|
+
var m2 = { _id: 2 };
|
938
|
+
var col = Backbone.Collection.extend({
|
939
|
+
model: Backbone.Model.extend({
|
940
|
+
idAttribute: '_id'
|
941
|
+
})
|
942
|
+
});
|
943
|
+
var c = new col;
|
944
|
+
c.set([m1, m2]);
|
945
|
+
equal(c.length, 2);
|
946
|
+
c.set([m1]);
|
947
|
+
equal(c.length, 1);
|
948
|
+
c.set([m1, m1, m1, m2, m2], {remove: false});
|
949
|
+
equal(c.length, 2);
|
950
|
+
});
|
951
|
+
|
952
|
+
test("set + merge with default values defined", function() {
|
953
|
+
var Model = Backbone.Model.extend({
|
954
|
+
defaults: {
|
955
|
+
key: 'value'
|
956
|
+
}
|
957
|
+
});
|
958
|
+
var m = new Model({id: 1});
|
959
|
+
var col = new Backbone.Collection([m], {model: Model});
|
960
|
+
equal(col.first().get('key'), 'value');
|
961
|
+
|
962
|
+
col.set({id: 1, key: 'other'});
|
963
|
+
equal(col.first().get('key'), 'other');
|
964
|
+
|
965
|
+
col.set({id: 1, other: 'value'});
|
966
|
+
equal(col.first().get('key'), 'other');
|
967
|
+
equal(col.length, 1);
|
968
|
+
});
|
969
|
+
|
970
|
+
test('merge without mutation', function () {
|
971
|
+
var Model = Backbone.Model.extend({
|
972
|
+
initialize: function (attrs, options) {
|
973
|
+
if (attrs.child) {
|
974
|
+
this.set('child', new Model(attrs.child, options), options);
|
975
|
+
}
|
976
|
+
}
|
977
|
+
});
|
978
|
+
var Collection = Backbone.Collection.extend({model: Model});
|
979
|
+
var data = [{id: 1, child: {id: 2}}];
|
980
|
+
var collection = new Collection(data);
|
981
|
+
equal(collection.first().id, 1);
|
982
|
+
collection.set(data);
|
983
|
+
equal(collection.first().id, 1);
|
984
|
+
collection.set([{id: 2, child: {id: 2}}].concat(data));
|
985
|
+
deepEqual(collection.pluck('id'), [2, 1]);
|
986
|
+
});
|
987
|
+
|
988
|
+
test("`set` and model level `parse`", function() {
|
989
|
+
var Model = Backbone.Model.extend({
|
990
|
+
parse: function (res) { return res.model; }
|
991
|
+
});
|
992
|
+
var Collection = Backbone.Collection.extend({
|
993
|
+
model: Model,
|
994
|
+
parse: function (res) { return res.models; }
|
995
|
+
});
|
996
|
+
var model = new Model({id: 1});
|
997
|
+
var collection = new Collection(model);
|
998
|
+
collection.set({models: [
|
999
|
+
{model: {id: 1}},
|
1000
|
+
{model: {id: 2}}
|
1001
|
+
]}, {parse: true});
|
1002
|
+
equal(collection.first(), model);
|
1003
|
+
});
|
1004
|
+
|
1005
|
+
test("`set` data is only parsed once", function() {
|
1006
|
+
var collection = new Backbone.Collection();
|
1007
|
+
collection.model = Backbone.Model.extend({
|
1008
|
+
parse: function (data) {
|
1009
|
+
equal(data.parsed, void 0);
|
1010
|
+
data.parsed = true;
|
1011
|
+
return data;
|
1012
|
+
}
|
1013
|
+
});
|
1014
|
+
collection.set({}, {parse: true});
|
1015
|
+
});
|
1016
|
+
|
1017
|
+
test('`set` matches input order in the absence of a comparator', function () {
|
1018
|
+
var one = new Backbone.Model({id: 1});
|
1019
|
+
var two = new Backbone.Model({id: 2});
|
1020
|
+
var three = new Backbone.Model({id: 3});
|
1021
|
+
var collection = new Backbone.Collection([one, two, three]);
|
1022
|
+
collection.set([{id: 3}, {id: 2}, {id: 1}]);
|
1023
|
+
deepEqual(collection.models, [three, two, one]);
|
1024
|
+
collection.set([{id: 1}, {id: 2}]);
|
1025
|
+
deepEqual(collection.models, [one, two]);
|
1026
|
+
collection.set([two, three, one]);
|
1027
|
+
deepEqual(collection.models, [two, three, one]);
|
1028
|
+
collection.set([{id: 1}, {id: 2}], {remove: false});
|
1029
|
+
deepEqual(collection.models, [two, three, one]);
|
1030
|
+
collection.set([{id: 1}, {id: 2}, {id: 3}], {merge: false});
|
1031
|
+
deepEqual(collection.models, [one, two, three]);
|
1032
|
+
collection.set([three, two, one, {id: 4}], {add: false});
|
1033
|
+
deepEqual(collection.models, [one, two, three]);
|
1034
|
+
});
|
1035
|
+
|
1036
|
+
test("#1894 - Push should not trigger a sort", 0, function() {
|
1037
|
+
var Collection = Backbone.Collection.extend({
|
1038
|
+
comparator: 'id',
|
1039
|
+
sort: function() {
|
1040
|
+
ok(false);
|
1041
|
+
}
|
1042
|
+
});
|
1043
|
+
new Collection().push({id: 1});
|
1044
|
+
});
|
1045
|
+
|
1046
|
+
test("`set` with non-normal id", function() {
|
1047
|
+
var Collection = Backbone.Collection.extend({
|
1048
|
+
model: Backbone.Model.extend({idAttribute: '_id'})
|
1049
|
+
});
|
1050
|
+
var collection = new Collection({_id: 1});
|
1051
|
+
collection.set([{_id: 1, a: 1}], {add: false});
|
1052
|
+
equal(collection.first().get('a'), 1);
|
1053
|
+
});
|
1054
|
+
|
1055
|
+
test("#1894 - `sort` can optionally be turned off", 0, function() {
|
1056
|
+
var Collection = Backbone.Collection.extend({
|
1057
|
+
comparator: 'id',
|
1058
|
+
sort: function() { ok(true); }
|
1059
|
+
});
|
1060
|
+
new Collection().add({id: 1}, {sort: false});
|
1061
|
+
});
|
1062
|
+
|
1063
|
+
test("#1915 - `parse` data in the right order in `set`", function() {
|
1064
|
+
var collection = new (Backbone.Collection.extend({
|
1065
|
+
parse: function (data) {
|
1066
|
+
strictEqual(data.status, 'ok');
|
1067
|
+
return data.data;
|
1068
|
+
}
|
1069
|
+
}));
|
1070
|
+
var res = {status: 'ok', data:[{id: 1}]};
|
1071
|
+
collection.set(res, {parse: true});
|
1072
|
+
});
|
1073
|
+
|
1074
|
+
asyncTest("#1939 - `parse` is passed `options`", 1, function () {
|
1075
|
+
var collection = new (Backbone.Collection.extend({
|
1076
|
+
url: '/',
|
1077
|
+
parse: function (data, options) {
|
1078
|
+
strictEqual(options.xhr.someHeader, 'headerValue');
|
1079
|
+
return data;
|
1080
|
+
}
|
1081
|
+
}));
|
1082
|
+
var ajax = Backbone.ajax;
|
1083
|
+
Backbone.ajax = function (params) {
|
1084
|
+
_.defer(params.success);
|
1085
|
+
return {someHeader: 'headerValue'};
|
1086
|
+
};
|
1087
|
+
collection.fetch({
|
1088
|
+
success: function () { start(); }
|
1089
|
+
});
|
1090
|
+
Backbone.ajax = ajax;
|
1091
|
+
});
|
1092
|
+
|
1093
|
+
test("`add` only `sort`s when necessary", 2, function () {
|
1094
|
+
var collection = new (Backbone.Collection.extend({
|
1095
|
+
comparator: 'a'
|
1096
|
+
}))([{id: 1}, {id: 2}, {id: 3}]);
|
1097
|
+
collection.on('sort', function () { ok(true); });
|
1098
|
+
collection.add({id: 4}); // do sort, new model
|
1099
|
+
collection.add({id: 1, a: 1}, {merge: true}); // do sort, comparator change
|
1100
|
+
collection.add({id: 1, b: 1}, {merge: true}); // don't sort, no comparator change
|
1101
|
+
collection.add({id: 1, a: 1}, {merge: true}); // don't sort, no comparator change
|
1102
|
+
collection.add(collection.models); // don't sort, nothing new
|
1103
|
+
collection.add(collection.models, {merge: true}); // don't sort
|
1104
|
+
});
|
1105
|
+
|
1106
|
+
test("`add` only `sort`s when necessary with comparator function", 3, function () {
|
1107
|
+
var collection = new (Backbone.Collection.extend({
|
1108
|
+
comparator: function(a, b) {
|
1109
|
+
return a.get('a') > b.get('a') ? 1 : (a.get('a') < b.get('a') ? -1 : 0);
|
1110
|
+
}
|
1111
|
+
}))([{id: 1}, {id: 2}, {id: 3}]);
|
1112
|
+
collection.on('sort', function () { ok(true); });
|
1113
|
+
collection.add({id: 4}); // do sort, new model
|
1114
|
+
collection.add({id: 1, a: 1}, {merge: true}); // do sort, model change
|
1115
|
+
collection.add({id: 1, b: 1}, {merge: true}); // do sort, model change
|
1116
|
+
collection.add({id: 1, a: 1}, {merge: true}); // don't sort, no model change
|
1117
|
+
collection.add(collection.models); // don't sort, nothing new
|
1118
|
+
collection.add(collection.models, {merge: true}); // don't sort
|
1119
|
+
});
|
1120
|
+
|
1121
|
+
test("Attach options to collection.", 2, function() {
|
1122
|
+
var model = new Backbone.Model;
|
1123
|
+
var comparator = function(){};
|
1124
|
+
|
1125
|
+
var collection = new Backbone.Collection([], {
|
1126
|
+
model: model,
|
1127
|
+
comparator: comparator
|
1128
|
+
});
|
1129
|
+
|
1130
|
+
ok(collection.model === model);
|
1131
|
+
ok(collection.comparator === comparator);
|
1132
|
+
});
|
1133
|
+
|
1134
|
+
test("`add` overrides `set` flags", function () {
|
1135
|
+
var collection = new Backbone.Collection();
|
1136
|
+
collection.once('add', function (model, collection, options) {
|
1137
|
+
collection.add({id: 2}, options);
|
1138
|
+
});
|
1139
|
+
collection.set({id: 1});
|
1140
|
+
equal(collection.length, 2);
|
1141
|
+
});
|
1142
|
+
|
1143
|
+
test("#2606 - Collection#create, success arguments", 1, function() {
|
1144
|
+
var collection = new Backbone.Collection;
|
1145
|
+
collection.url = 'test';
|
1146
|
+
collection.create({}, {
|
1147
|
+
success: function(model, resp, options) {
|
1148
|
+
strictEqual(resp, 'response');
|
1149
|
+
}
|
1150
|
+
});
|
1151
|
+
this.ajaxSettings.success('response');
|
1152
|
+
});
|
1153
|
+
|
1154
|
+
});
|