-
Notifications
You must be signed in to change notification settings - Fork 291
/
nested_record.js
664 lines (556 loc) · 29.1 KB
/
nested_record.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
/**
* Nested Records (SC.Record) Unit Test
*
* @author Evin Grano
*/
// ..........................................................
// Basic Set up needs to move to the setup and teardown
//
var NestedRecord, store, testParent, testParent2, testParent3, childData1;
var initModels = function() {
NestedRecord.ParentRecordTest = SC.Record.extend({
/** Child Record Namespace */
nestedRecordNamespace: NestedRecord,
name: SC.Record.attr(String),
info: SC.Record.toOne('NestedRecord.ChildRecordTest', { nested: true })
});
NestedRecord.ChildRecordTest = SC.Record.extend({
name: SC.Record.attr(String),
value: SC.Record.attr(String)
});
};
// ..........................................................
// Basic SC.Record Stuff
//
module("Basic SC.Record Functions w/ Parent > Child", {
setup: function() {
NestedRecord = SC.Object.create({
store: SC.Store.create()
});
window.NestedRecord = NestedRecord;
store = NestedRecord.store;
initModels();
SC.RunLoop.begin();
// Test Parent 1
testParent = store.createRecord(NestedRecord.ParentRecordTest, {
guid: 'p1',
name: 'Parent Name',
info: {
type: 'ChildRecordTest',
name: 'Child Name',
value: 'Blue Goo',
guid: '5001'
}
});
// Test parent 2
testParent2 = NestedRecord.store.createRecord(NestedRecord.ParentRecordTest, {
guid: 'p2',
name: 'Parent Name 2',
info: {
type: 'ChildRecordTest',
name: 'Child Name 2',
value: 'Purple Goo',
guid: '5002'
}
});
// Test parent 3
testParent3 = NestedRecord.store.createRecord(NestedRecord.ParentRecordTest, {
guid: 'p3',
name: 'Parent Name 3',
info: {
type: 'ChildRecordTest',
name: 'Child Name 3',
value: 'Pink Goo'
}
});
SC.RunLoop.end();
// ..........................................................
// Child Data
//
childData1 = {
type: 'ChildRecordTest',
name: 'Child Name',
value: 'Green Goo',
guid: '5002'
};
},
teardown: function() {
delete NestedRecord.ParentRecordTest;
delete NestedRecord.ChildRecordTest;
testParent = null;
testParent2 = null;
store = null;
childData1 = null;
NestedRecord = null;
//delete(window.NestedRecord);
}
});
test("Function: readAttribute()", function() {
equals(testParent.readAttribute('name'), 'Parent Name', "readAttribute should be correct for name attribute");
equals(testParent.readAttribute('nothing'), null, "readAttribute should be correct for invalid key");
same(testParent.readAttribute('info'),
{
type: 'ChildRecordTest',
name: 'Child Name',
value: 'Blue Goo',
guid: '5001'
},
"readAttribute should be correct for info child attribute");
});
test("Support Multiple Parent Records With Different Child Records", function() {
same(testParent3.readAttribute('info'),
{
type: 'ChildRecordTest',
name: 'Child Name 3',
value: 'Pink Goo'
},
"readAttribute should be correct for info child attribute on new record");
equals(testParent3.get('info').get('value'), 'Pink Goo', "get should retrieve the proper value on new record");
same(testParent2.readAttribute('info'),
{
type: 'ChildRecordTest',
name: 'Child Name 2',
value: 'Purple Goo',
guid: '5002'
},
"readAttribute should be correct for info child attribute on new record");
equals(testParent2.get('info').get('value'), 'Purple Goo', "get should retrieve the proper value on new record");
same(testParent.readAttribute('info'),
{
type: 'ChildRecordTest',
name: 'Child Name',
value: 'Blue Goo',
guid: '5001'
},
"readAttribute should be correct for info child attribute on first record");
equals(testParent.get('info').get('value'), 'Blue Goo', "get should retrieve the proper value on first record");
});
test("Function: writeAttribute()", function() {
testParent.writeAttribute('name', 'New Parent Name');
equals(testParent.get('name'), 'New Parent Name', "writeAttribute should be the new name attribute");
testParent.writeAttribute('nothing', 'nothing');
equals(testParent.get('nothing'), 'nothing', "writeAttribute should be correct for new key");
testParent.writeAttribute('info', {
type: 'ChildRecordTest',
name: 'New Child Name',
value: 'Red Goo'
});
same(testParent.readAttribute('info'),
{
type: 'ChildRecordTest',
name: 'New Child Name',
value: 'Red Goo'
},
"writeAttribute with readAttribute should be correct for info child attribute");
testParent3.writeAttribute('info', {
type: 'ChildRecordTest',
name: 'New Child Name',
value: 'Red Goo'
});
same(testParent3.readAttribute('info'),
{
type: 'ChildRecordTest',
name: 'New Child Name',
value: 'Red Goo'
},
"writeAttribute with readAttribute should be correct for info child attribute");
});
test("Basic Read", function() {
var id;
// Test general gets
equals(testParent.get('name'), 'Parent Name', "get should be correct for name attribute");
equals(testParent.get('nothing'), null, "get should be correct for invalid key");
// Test Child Record creation
var cr = testParent.get('info');
// Check Model Class information
ok(SC.kindOf(cr, SC.Record), "get() creates an actual instance that is a kind of a SC.Record Object");
ok(SC.instanceOf(cr, NestedRecord.ChildRecordTest), "get() creates an actual instance of a ChildRecordTest Object");
// Check reference information
var pm = cr.get('primaryKey');
var key = cr.get(pm);
var storeRef = store.find(NestedRecord.ChildRecordTest, key);
ok(storeRef, 'checking that the store has the instance of the child record with proper primary key');
equals(cr, storeRef, "checking the parent reference is the same as the direct store reference");
// Check to see if the attributes of a Child Record match the reference of the parent
same(storeRef.get('attributes'), testParent.readAttribute('info'), "check that the ChildRecord's attributes are the same as the ParentRecord's readAttribute for the reference");
// Duplication check
var sameCR = testParent.get('info');
ok(sameCR, "check to see if we have an instance of a child record again");
var oldKey = cr.get(pm), newKey = sameCR.get(pm);
equals(oldKey, newKey, "check to see if the Primary Key are the same");
same(sameCR, cr, "check to see that it is the same child record as before");
});
test("Basic Read when Child Record has no primary key", function() {
var id;
// Test general gets
equals(testParent3.get('name'), 'Parent Name 3', "get should be correct for name attribute");
equals(testParent3.get('nothing'), null, "get should be correct for invalid key");
// Test Child Record creation
var cr = testParent3.get('info');
// Check Model Class information
ok(SC.kindOf(cr, SC.Record), "get() creates an actual instance that is a kind of a SC.Record Object");
ok(SC.instanceOf(cr, NestedRecord.ChildRecordTest), "get() creates an actual instance of a ChildRecordTest Object");
// Check reference information
var key = cr.get('id');
var storeRef = store.find(NestedRecord.ChildRecordTest, key);
ok(storeRef, 'checking that the store has the instance of the child record with proper primary key');
equals(cr, storeRef, "checking the parent reference is the same as the direct store reference");
// Check to see if the attributes of a Child Record match the reference of the parent
same(storeRef.get('attributes'), testParent3.readAttribute('info'), "check that the ChildRecord's attributes are the same as the ParentRecord's readAttribute for the reference");
// Duplication check
var sameCR = testParent3.get('info');
ok(sameCR, "check to see if we have an instance of a child record again");
var oldKey = cr.get('id'), newKey = sameCR.get('id');
equals(oldKey, newKey, "check to see if the Primary Key are the same");
same(sameCR, cr, "check to see that it is the same child record as before");
});
test("Basic Write As a Hash", function() {
// Test general gets
testParent.set('name', 'New Parent Name');
equals(testParent.get('name'), 'New Parent Name', "set() should change name attribute");
testParent.set('nothing', 'nothing');
equals(testParent.get('nothing'), 'nothing', "set should change non-existent property to a new property");
// Test Child Record creation
var oldCR = testParent.get('info');
testParent.set('info', {
type: 'ChildRecordTest',
name: 'New Child Name',
value: 'Red Goo',
guid: '6001'
});
var cr = testParent.get('info');
// Check Model Class information
ok(SC.kindOf(cr, SC.Record), "set() with an object creates an actual instance that is a kind of a SC.Record Object");
ok(SC.instanceOf(cr, NestedRecord.ChildRecordTest), "set() with an object creates an actual instance of a ChildRecordTest Object");
// Check reference information
var pm = cr.get('primaryKey');
var key = cr.get(pm);
var storeRef = store.find(NestedRecord.ChildRecordTest, key);
ok(storeRef, 'after a set() with an object, checking that the store has the instance of the child record with proper primary key');
equals(cr, storeRef, "after a set with an object, checking the parent reference is the same as the direct store reference");
var oldKey = oldCR.get(pm);
ok(!(oldKey === key), 'check to see that the old child record has a different key from the new child record');
// Check for changes on the child bubble to the parent.
cr.set('name', 'Child Name Change');
equals(cr.get('name'), 'Child Name Change', "after a set('name', <new>) on child, checking that the value is updated");
ok(cr.get('status') & SC.Record.DIRTY, 'check that the child record is dirty');
ok(testParent.get('status') & SC.Record.DIRTY, 'check that the parent record is dirty');
var newCR = testParent.get('info');
same(newCR, cr, "after a set('name', <new>) on child, checking to see that the parent has received the changes from the child record");
same(testParent.readAttribute('info'), cr.get('attributes'), "after a set('name', <new>) on child, readAttribute on the parent should be correct for info child attributes");
});
test("Basic Write As a Hash when Child Record has no primary key", function() {
// Test general gets
testParent3.set('name', 'New Parent Name');
equals(testParent3.get('name'), 'New Parent Name', "set() should change name attribute");
testParent3.set('nothing', 'nothing');
equals(testParent3.get('nothing'), 'nothing', "set should change non-existent property to a new property");
// Test Child Record creation
var oldCR = testParent3.get('info');
var oldKey = oldCR.get('id');
testParent3.set('info', {
type: 'ChildRecordTest',
name: 'New Child Name',
value: 'Red Goo'
});
var cr = testParent3.get('info');
// Check Model Class information
ok(SC.kindOf(cr, SC.Record), "set() with an object creates an actual instance that is a kind of a SC.Record Object");
ok(SC.instanceOf(cr, NestedRecord.ChildRecordTest), "set() with an object creates an actual instance of a ChildRecordTest Object");
// Check reference information
var key = cr.get('id');
var storeRef = store.find(NestedRecord.ChildRecordTest, key);
ok(storeRef, 'after a set() with an object, checking that the store has the instance of the child record with proper primary key');
equals(cr, storeRef, "after a set with an object, checking the parent reference is the same as the direct store reference");
equals(oldKey, key, 'check to see that the old child record has the same key as the new child record');
// Check for changes on the child bubble to the parent.
cr.set('name', 'Child Name Change');
equals(cr.get('name'), 'Child Name Change', "after a set('name', <new>) on child, checking that the value is updated");
ok(cr.get('status') & SC.Record.DIRTY, 'check that the child record is dirty');
ok(testParent3.get('status') & SC.Record.DIRTY, 'check that the parent record is dirty');
var newCR = testParent3.get('info');
same(newCR, cr, "after a set('name', <new>) on child, checking to see that the parent has received the changes from the child record");
same(testParent3.readAttribute('info'), cr.get('attributes'), "after a set('name', <new>) on child, readAttribute on the parent should be correct for info child attributes");
});
test("Basic Write As a Child Record", function() {
// Test general gets
testParent.set('name', 'New Parent Name');
equals(testParent.get('name'), 'New Parent Name', "set() should change name attribute");
testParent.set('nothing', 'nothing');
equals(testParent.get('nothing'), 'nothing', "set should change non-existent property to a new property");
// Test Child Record creation
var store = testParent.get('store');
var cr = store.createRecord(NestedRecord.ChildRecordTest, {type: 'ChildRecordTest', name: 'New Child Name', value: 'Red Goo', guid: '6001'});
// Check Model Class information
ok(SC.kindOf(cr, SC.Record), "before the set(), check for actual instance that is a kind of a SC.Record Object");
ok(SC.instanceOf(cr, NestedRecord.ChildRecordTest), "before the set(), check for actual instance of a ChildRecordTest Object");
testParent.set('info', cr);
cr = testParent.get('info');
// Check Model Class information
ok(SC.kindOf(cr, SC.Record), "set() with an object creates an actual instance that is a kind of a SC.Record Object");
ok(SC.instanceOf(cr, NestedRecord.ChildRecordTest), "set() with an object creates an actual instance of a ChildRecordTest Object");
// Check reference information
var pm = cr.get('primaryKey');
var key = cr.get(pm);
var storeRef = store.find(NestedRecord.ChildRecordTest, key);
ok(storeRef, 'after a set() with an object, checking that the store has the instance of the child record with proper primary key');
equals(cr, storeRef, "after a set with an object, checking the parent reference is the same as the direct store reference");
// Check for changes on the child bubble to the parent.
cr.set('name', 'Child Name Change');
equals(cr.get('name'), 'Child Name Change', "after a set('name', <new>) on child, checking that the value is updated");
ok(cr.get('status') & SC.Record.DIRTY, 'check that the child record is dirty');
ok(testParent.get('status') & SC.Record.DIRTY, 'check that the parent record is dirty');
var newCR = testParent.get('info');
same(newCR, cr, "after a set('name', <new>) on child, checking to see that the parent has received the changes from the child record");
same(testParent.readAttribute('info'), cr.get('attributes'), "after a set('name', <new>) on child, readAttribute on the parent should be correct for info child attributes");
// Make sure you can set the child to null.
testParent.set('info', null);
equals(testParent.get('info'), null, 'should be able to set child record to null');
});
test("Basic Write As a Child Record when Child Record has no primary key", function() {
// Test general gets
testParent3.set('name', 'New Parent Name');
equals(testParent3.get('name'), 'New Parent Name', "set() should change name attribute");
testParent3.set('nothing', 'nothing');
equals(testParent3.get('nothing'), 'nothing', "set should change non-existent property to a new property");
// Test Child Record creation
var store = testParent3.get('store');
var cr = store.createRecord(NestedRecord.ChildRecordTest, {type: 'ChildRecordTest', name: 'New Child Name', value: 'Red Goo', guid: '6001'});
// Check Model Class information
ok(SC.kindOf(cr, SC.Record), "before the set(), check for actual instance that is a kind of a SC.Record Object");
ok(SC.instanceOf(cr, NestedRecord.ChildRecordTest), "before the set(), check for actual instance of a ChildRecordTest Object");
testParent3.set('info', cr);
cr = testParent3.get('info');
// Check Model Class information
ok(SC.kindOf(cr, SC.Record), "set() with an object creates an actual instance that is a kind of a SC.Record Object");
ok(SC.instanceOf(cr, NestedRecord.ChildRecordTest), "set() with an object creates an actual instance of a ChildRecordTest Object");
// Check reference information
var key = cr.get('id');
var storeRef = store.find(NestedRecord.ChildRecordTest, key);
ok(storeRef, 'after a set() with an object, checking that the store has the instance of the child record with proper primary key');
equals(cr, storeRef, "after a set with an object, checking the parent reference is the same as the direct store reference");
// Check for changes on the child bubble to the parent.
cr.set('name', 'Child Name Change');
equals(cr.get('name'), 'Child Name Change', "after a set('name', <new>) on child, checking that the value is updated");
ok(cr.get('status') & SC.Record.DIRTY, 'check that the child record is dirty');
ok(testParent3.get('status') & SC.Record.DIRTY, 'check that the parent record is dirty');
var newCR = testParent3.get('info');
same(newCR, cr, "after a set('name', <new>) on child, checking to see that the parent has received the changes from the child record");
same(testParent3.readAttribute('info'), cr.get('attributes'), "after a set('name', <new>) on child, readAttribute on the parent should be correct for info child attributes");
// Make sure you can set the child to null.
testParent3.set('info', null);
equals(testParent3.get('info'), null, 'should be able to set child record to null');
});
test("Writing over a child record should remove caches in the store.", function() {
// Test Child Record creation
var cr, key, store = testParent.get('store'), cacheLength, idx, storeKeys = [], ids = [], sks;
// Get the child record once before setting it in order to test that this child
// doesn't become abandoned in the store.
cr = testParent.get('info');
storeKeys.push(cr.get('storeKey'));
ids.push(cr.get('id'));
ids = ids.uniq();
// Once we get the child record, certain caches are created in the store.
// Verify the cache lengths to prove that there are no leaked objects.
cacheLength = 0;
for (key in store.parentRecords) { cacheLength += 1; }
equals(cacheLength, 1, 'there should only be one parent record registered in the store');
cacheLength = 0;
for (key in store.childRecords) { cacheLength += 1; }
equals(cacheLength, 1, 'there should only be one child record registered in the store');
cacheLength = 0;
for (key in store.records) { cacheLength += 1; }
equals(cacheLength, 4, 'there should be four records cached in the store');
cacheLength = 0;
for (key in store.dataHashes) { if (store.dataHashes[key] !== null) cacheLength += 1; }
equals(cacheLength, 4, 'there should be four non-null datahashes in the store');
// Overwrite the child record with a new child record with the same guid.
testParent.set('info', {type: 'ChildRecordTest', name: 'New Child Name', value: 'Red Goo', guid: '5001'});
cr = testParent.get('info');
storeKeys.push(cr.get('storeKey'));
ids.push(cr.get('id'));
ids = ids.uniq();
// Verify the cache lengths to prove that there are no leaked objects.
cacheLength = 0;
for (key in store.parentRecords) { cacheLength += 1; }
equals(cacheLength, 1, 'there should only be one parent record registered in the store after replacing child record once');
cacheLength = 0;
for (key in store.childRecords) { cacheLength += 1; }
equals(cacheLength, 1, 'there should only be one child record registered in the store after replacing child record once');
cacheLength = 0;
for (key in store.records) { cacheLength += 1; }
equals(cacheLength, 4, 'there should be four records cached in the store after replacing child record once');
cacheLength = 0;
for (key in store.dataHashes) { if (store.dataHashes[key] !== null) cacheLength += 1; }
equals(cacheLength, 4, 'there should be four non-null datahashes in the store after replacing child record once');
// Overwrite the child record with a new child record with the same guid.
testParent.set('info', store.createRecord(NestedRecord.ChildRecordTest, {type: 'ChildRecordTest', name: 'New Child Name', value: 'Orange Goo', guid: '6001'}));
cr = testParent.get('info');
storeKeys.push(cr.get('storeKey'));
ids.push(cr.get('id'));
ids = ids.uniq();
// Verify the cache lengths to prove that there are no leaked objects.
cacheLength = 0;
for (key in store.parentRecords) { cacheLength += 1; }
equals(cacheLength, 1, 'there should only be one parent record registered in the store after replacing child record twice');
cacheLength = 0;
for (key in store.childRecords) { cacheLength += 1; }
equals(cacheLength, 1, 'there should only be one child record registered in the store after replacing child record twice');
cacheLength = 0;
for (key in store.records) { cacheLength += 1; }
equals(cacheLength, 4, 'there should be four records cached in the store after replacing child record twice');
cacheLength = 0;
for (key in store.dataHashes) { if (store.dataHashes[key] !== null) cacheLength += 1; }
equals(cacheLength, 4, 'there should be four non-null datahashes in the store after replacing child record twice');
// Make sure you can set the child to null.
testParent.set('info', null);
cr = testParent.get('info');
// Verify the cache lengths to prove that there are no leaked objects.
cacheLength = 0;
for (key in store.parentRecords) { cacheLength += 1; }
equals(cacheLength, 1, 'there should only be one parent record registered in the store after removing child record');
cacheLength = 0;
for (key in store.childRecords) { cacheLength += 1; }
equals(cacheLength, 0, 'there should be no child record registered in the store after removing child record');
cacheLength = 0;
for (key in store.records) { cacheLength += 1; }
equals(cacheLength, 3, 'there should be three records cached in the store after removing child record');
cacheLength = 0;
for (key in store.dataHashes) { if (store.dataHashes[key] !== null) cacheLength += 1; }
equals(cacheLength, 3, 'there should be three non-null datahashes in the store after removing child record');
});
test("Child Status Changed", function() {
var cr;
cr = testParent.get('info');
equals(cr.get('status'), testParent.get('status'), 'after initializing the parent to READY_NEW, check that the child record matches');
SC.RunLoop.begin();
store.writeStatus(testParent.storeKey, SC.Record.READY_DIRTY);
store.dataHashDidChange(testParent.storeKey);
equals(cr.get('status'), testParent.get('status'), 'after setting the parent to READY_DIRTY, check that the child record matches');
SC.RunLoop.end();
SC.RunLoop.begin();
store.writeStatus(testParent.storeKey, SC.Record.BUSY_REFRESH);
store.dataHashDidChange(testParent.storeKey);
equals(cr.get('status'), testParent.get('status'), 'after setting the parent to BUSY_REFRESH, check that the child record matches');
SC.RunLoop.end();
});
test("Child Status Matches Store Status", function() {
var cr;
var storeStatus;
cr = testParent.get('info');
storeStatus = store.readStatus(cr.storeKey);
equals(storeStatus, cr.get('status'), 'after initializing the parent to READY_NEW, check that the store status matches for the child');
equals(cr.get('status'), testParent.get('status'), 'after initializing the parent to READY_NEW, check that the child record matches');
SC.RunLoop.begin();
store.writeStatus(testParent.storeKey, SC.Record.READY_CLEAN);
store.dataHashDidChange(testParent.storeKey);
SC.RunLoop.end();
storeStatus = store.readStatus(cr.storeKey);
equals(testParent.get('status'), SC.Record.READY_CLEAN, 'parent status should be READY_CLEAN');
equals(storeStatus, cr.get('status'), 'after setting the parent to READY_CLEAN, the child\'s status and store status should be READY_CLEAN before calling get(\'status\') on the child');
equals(cr.get('status'), testParent.get('status'), 'after setting the parent to READY_CLEAN, check that the child record matches');
SC.RunLoop.begin();
store.writeStatus(testParent.storeKey, SC.Record.READY_DIRTY);
store.dataHashDidChange(testParent.storeKey);
SC.RunLoop.end();
storeStatus = store.readStatus(cr.storeKey);
equals(testParent.get('status'), SC.Record.READY_DIRTY, 'parent status should be READY_DIRTY');
equals(storeStatus, cr.get('status'), 'after setting the parent to READY_DIRTY, the child\'s status and store status should be READY_DIRTY before calling get(\'status\') on the child');
equals(cr.get('status'), testParent.get('status'), 'after setting the parent to READY_DIRTY, check that the child record matches');
SC.RunLoop.begin();
store.writeStatus(testParent.storeKey, SC.Record.BUSY_REFRESH);
store.dataHashDidChange(testParent.storeKey);
storeStatus = store.readStatus(cr.storeKey);
SC.RunLoop.end();
equals(testParent.get('status'), SC.Record.BUSY_REFRESH, 'parent status should be BUSY_REFRESH');
equals(storeStatus, cr.get('status'), 'after setting the parent to BUSY_REFRESH, the child\'s status and store status should be BUSY_REFRESH before calling get(\'status\') on the child');
equals(cr.get('status'), testParent.get('status'), 'after setting the parent to BUSY_REFRESH, check that the child record matches');
});
/**
This test illustrates that unloading the parent record also unloads the child
record.
*/
test("Unloading the parent record also unloads the child record.", function() {
var parentId, child, childId, parentStoreKey, childStoreKey;
parentId = testParent3.get('id');
parentStoreKey = testParent3.get('storeKey');
child = testParent3.get('info');
childId = child.get('id');
childStoreKey = child.get('storeKey');
store.unloadRecord(NestedRecord.ParentRecordTest, parentId);
equals(testParent3.get('status'), SC.Record.EMPTY, 'parent status should be EMPTY');
equals(child.get('status'), SC.Record.EMPTY, 'child status should be EMPTY');
});
/**
This test illustrates that reloading the parent record doesn't create
duplicates of the child record.
*/
test("Reloading the parent record uses same child record.", function() {
var parentId, child, childId, parentStoreKey, childStoreKey, newChildStoreKey;
var key, cacheLength;
parentId = testParent3.get('id');
parentStoreKey = testParent3.get('storeKey');
child = testParent3.get('info');
childId = child.get('id');
childStoreKey = child.get('storeKey');
// Once we get the child record, certain caches are created in the store.
// Verify the cache lengths to prove that there are no leaked objects.
cacheLength = 0;
for (key in store.parentRecords) { cacheLength += 1; }
equals(cacheLength, 1, 'there should only be one parent record registered in the store');
cacheLength = 0;
for (key in store.childRecords) { cacheLength += 1; }
equals(cacheLength, 1, 'there should only be one child record registered in the store');
cacheLength = 0;
for (key in store.records) { cacheLength += 1; }
equals(cacheLength, 4, 'there should be four records cached in the store');
cacheLength = 0;
for (key in store.dataHashes) { if (store.dataHashes[key] !== null) cacheLength += 1; }
equals(cacheLength, 4, 'there should be four non-null datahashes in the store');
// Unload the record
store.unloadRecord(NestedRecord.ParentRecordTest, parentId);
equals(testParent3.get('status'), SC.Record.EMPTY, 'parent status should be EMPTY');
equals(child.get('status'), SC.Record.EMPTY, 'child status should be EMPTY');
// Verify the cache lengths to prove that there are no leaked objects.
cacheLength = 0;
for (key in store.parentRecords) { cacheLength += 1; }
equals(cacheLength, 1, 'there should only be one parent record registered in the store');
cacheLength = 0;
for (key in store.childRecords) { cacheLength += 1; }
equals(cacheLength, 0, 'there should be zero child records registered in the store');
cacheLength = 0;
for (key in store.records) { cacheLength += 1; }
equals(cacheLength, 2, 'there should be two records cached in the store');
cacheLength = 0;
for (key in store.dataHashes) { if (store.dataHashes[key] !== null) cacheLength += 1; }
equals(cacheLength, 2, 'there should be two non-null datahashes in the store');
// Reload the record
SC.RunLoop.begin();
parentStoreKey = store.loadRecord(NestedRecord.ParentRecordTest, {
name: 'Parent Name 3',
info: {
type: 'ChildRecordTest',
name: 'Child Name 3',
value: 'Pink Goo'
}
},
parentId);
SC.RunLoop.end();
testParent3 = store.materializeRecord(parentStoreKey);
child = testParent3.get('info');
equals(testParent3.get('status'), SC.Record.READY_CLEAN, 'parent status should be READY_CLEAN');
equals(child.get('status'), SC.Record.READY_CLEAN, 'child status should be READY_CLEAN');
// Verify the cache lengths to prove that there are no leaked objects.
cacheLength = 0;
for (key in store.parentRecords) { cacheLength += 1; }
equals(cacheLength, 1, 'there should only be one parent record registered in the store');
cacheLength = 0;
for (key in store.childRecords) { cacheLength += 1; }
equals(cacheLength, 1, 'there should only be one child record registered in the store');
cacheLength = 0;
for (key in store.records) { cacheLength += 1; }
equals(cacheLength, 4, 'there should be four records cached in the store');
cacheLength = 0;
for (key in store.dataHashes) { if (store.dataHashes[key] !== null) cacheLength += 1; }
equals(cacheLength, 4, 'there should be four non-null datahashes in the store');
});