jdl 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
});
|