source: Dev/trunk/src/client/dojo/tests/data/ItemFileWriteStore.js

Last change on this file was 483, checked in by hendrikvanantwerpen, 11 years ago

Added Dojo 1.9.3 release.

File size: 56.5 KB
Line 
1// FIXME: this test assumes the existence of the global object "tests"
2define([
3  "dojo/main",
4  "doh/main",
5  "require",
6  "./readOnlyItemFileTestTemplates",
7  "dojo/data/ItemFileWriteStore",
8  "dojo/data/api/Read",
9  "dojo/data/api/Identity",
10  "dojo/data/api/Write",
11  "dojo/data/api/Notification"], function(dojo, doh, require){
12
13dojo.getObject("data.ItemFileWriteStore", true, tests);
14
15// First, make sure ItemFileWriteStore can still pass all the same unit tests
16// that we use for its superclass, ItemFileReadStore:
17tests.data.readOnlyItemFileTestTemplates.registerTestsForDatastore("dojo.data.ItemFileWriteStore");
18
19tests.data.ItemFileWriteStore.getTestData = function(name){
20        var data = {};
21        if(name === "reference_integrity"){
22                if(dojo.isBrowser){
23                        data = {url: require.toUrl("./reference_integrity.json")};
24                }else{
25                        data =
26                                { data: {
27                                        "identifier": "id",
28                                        "label": "name",
29                                        "items": [
30                                                {"id": 1, "name": "Item 1"},
31                                                {"id": 2, "name": "Item 2"},
32                                                {"id": 3, "name": "Item 3"},
33                                                {"id": 4, "name": "Item 4"},
34                                                {"id": 5, "name": "Item 5"},
35                                                {"id": 6, "name": "Item 6"},
36                                                {"id": 7, "name": "Item 7"},
37                                                {"id": 8, "name": "Item 8"},
38                                                {"id": 9, "name": "Item 9"},
39                                                {"id": 10, "name": "Item 10", "friends": [{"_reference": 1},{"_reference": 3},{"_reference": 5}]},
40                                                {"id": 11, "name": "Item 11", "friends": [{"_reference": 10}], "siblings": [{"_reference": 10}]},
41                                                {"id": 12, "name": "Item 12", "friends": [{"_reference": 3},{"_reference": 7}], "enemies": [{"_reference": 10}]},
42                                                {"id": 13, "name": "Item 13", "friends": [{"_reference": 10}]},
43                                                {"id": 14, "name": "Item 14", "friends": [{"_reference": 11}]},
44                                                {"id": 15, "name": "item 15", "friends": [{"id": 16, "name": "Item 16"}]}
45                                        ]
46                                }
47                        };
48                }
49        }
50        return data;
51};
52
53
54// Now run some tests that are specific to the write-access features:
55doh.register("tests.data.ItemFileWriteStore",
56        [
57                function test_getFeatures(){
58                        // summary:
59                        //              Simple test of the getFeatures function of the store
60                        // description:
61                        //              Simple test of the getFeatures function of the store
62                        var store = new dojo.data.ItemFileWriteStore(tests.data.readOnlyItemFileTestTemplates.getTestData("countries"));
63
64                        var features = store.getFeatures();
65
66                        // make sure we have the expected features:
67                        doh.assertTrue(features["dojo.data.api.Read"] !== null);
68                        doh.assertTrue(features["dojo.data.api.Identity"] !== null);
69                        doh.assertTrue(features["dojo.data.api.Write"] !== null);
70                        doh.assertTrue(features["dojo.data.api.Notification"] !== null);
71                        doh.assertFalse(features["iggy"]);
72
73                        // and only the expected features:
74                        var count = 0;
75                        for(var i in features){
76                                doh.assertTrue((i === "dojo.data.api.Read" ||
77                                        i === "dojo.data.api.Identity" ||
78                                        i === "dojo.data.api.Write" ||
79                                        i === "dojo.data.api.Notification"));
80                                count++;
81                        }
82                        doh.assertEqual(count, 4);
83                },
84                function testWriteAPI_setValue(){
85                        // summary:
86                        //              Simple test of the setValue API
87                        // description:
88                        //              Simple test of the setValue API
89                        var store = new dojo.data.ItemFileWriteStore(tests.data.readOnlyItemFileTestTemplates.getTestData("countries"));
90
91                        var deferred = new doh.Deferred();
92                        var onComplete = function(items, request){
93                                doh.assertEqual(1, items.length);
94                                var item = items[0];
95                                doh.assertTrue(store.containsValue(item, "capital", "Cairo"));
96
97                                // FIXME:
98                                //        Okay, so this seems very odd.  Maybe I'm just being dense.
99                                //        These tests works:
100                                doh.assertEqual(store.isDirty(item), false);
101                                doh.assertTrue(store.isDirty(item) === false);
102                                //        But these seemingly equivalent tests will not work:
103                                // doh.assertFalse(store.isDirty(item));
104                                // doh.assertTrue(!(store.isDirty(item)));
105                                //
106                                //        All of which seems especially weird, given that this *does* work:
107                                doh.assertFalse(store.isDirty());
108
109                                doh.assertTrue(store.isDirty(item) === false);
110                                doh.assertTrue(!store.isDirty());
111                                store.setValue(item, "capital", "New Cairo");
112                                doh.assertTrue(store.isDirty(item));
113                                doh.assertTrue(store.isDirty());
114                                doh.assertEqual(store.getValue(item, "capital").toString(), "New Cairo");
115                                deferred.callback(true);
116                        };
117                        var onError = function(error, request){
118                                deferred.errback(error);
119                        };
120                        store.fetch({query:{name:"Egypt"}, onComplete: onComplete, onError: onError});
121                        return deferred; //Object
122                },
123                function testWriteAPI_setValues(){
124                        // summary:
125                        //              Simple test of the setValues API
126                        // description:
127                        //              Simple test of the setValues API
128                        var store = new dojo.data.ItemFileWriteStore(tests.data.readOnlyItemFileTestTemplates.getTestData("countries"));
129
130                        var deferred = new doh.Deferred();
131                        function onComplete(items, request){
132                                doh.assertEqual(1, items.length);
133                                var item = items[0];
134                                doh.assertTrue(store.containsValue(item, "name", "Egypt"));
135                                doh.assertTrue(store.isDirty(item) === false);
136                                doh.assertTrue(!store.isDirty());
137                                store.setValues(item, "name", ["Egypt 1", "Egypt 2"]);
138                                doh.assertTrue(store.isDirty(item));
139                                doh.assertTrue(store.isDirty());
140                                var values = store.getValues(item, "name");
141                                doh.assertTrue(values[0] == "Egypt 1");
142                                doh.assertTrue(values[1] == "Egypt 2");
143                                deferred.callback(true);
144                        }
145                        function onError(error, request){
146                                deferred.errback(error);
147                        }
148                        store.fetch({query:{name:"Egypt"}, onComplete: onComplete, onError: onError});
149                        return deferred; //Object
150                },
151                function testWriteAPI_unsetAttribute(){
152                        // summary:
153                        //              Simple test of the unsetAttribute API
154                        // description:
155                        //              Simple test of the unsetAttribute API
156                        var store = new dojo.data.ItemFileWriteStore(tests.data.readOnlyItemFileTestTemplates.getTestData("countries"));
157
158                        var deferred = new doh.Deferred();
159                        function onComplete(items, request){
160                                doh.assertEqual(1, items.length);
161                                var item = items[0];
162                                doh.assertTrue(store.containsValue(item, "name", "Egypt"));
163                                doh.assertTrue(store.isDirty(item) === false);
164                                doh.assertTrue(!store.isDirty());
165                                store.unsetAttribute(item, "name");
166                                doh.assertTrue(store.isDirty(item));
167                                doh.assertTrue(store.isDirty());
168                                doh.assertTrue(!store.hasAttribute(item, "name"));
169                                deferred.callback(true);
170                        }
171                        function onError(error, request){
172                                deferred.errback(error);
173                        }
174                        store.fetch({query:{name:"Egypt"}, onComplete: onComplete, onError: onError});
175                        return deferred; //Object
176                },
177                function testWriteAPI_newItem(){
178                        // summary:
179                        //              Simple test of the newItem API
180                        // description:
181                        //              Simple test of the newItem API
182                        var store = new dojo.data.ItemFileWriteStore(tests.data.readOnlyItemFileTestTemplates.getTestData("countries"));
183
184                        var deferred = new doh.Deferred();
185                        doh.assertTrue(!store.isDirty());
186
187                        var onNewInvoked = false;
188                        store.onNew = function(newItem, parentInfo){
189
190                                doh.assertTrue(newItem !== null);
191                                doh.assertTrue(parentInfo === null);
192                                doh.assertTrue(store.isItem(newItem));
193                                onNewInvoked = true;
194                        };
195                        var canada = store.newItem({name: "Canada", abbr:"ca", capital:"Ottawa"});
196                        doh.assertTrue(onNewInvoked);
197
198                        doh.assertTrue(store.isDirty(canada));
199                        doh.assertTrue(store.isDirty());
200                        doh.assertTrue(store.getValues(canada, "name") == "Canada");
201                        function onComplete(items, request){
202                                doh.assertEqual(1, items.length);
203                                var item = items[0];
204                                doh.assertTrue(store.containsValue(item, "name", "Canada"));
205                                deferred.callback(true);
206                        }
207                        function onError(error, request){
208                                deferred.errback(error);
209                        }
210                        store.fetch({query:{name:"Canada"}, onComplete: onComplete, onError: onError});
211                        return deferred; //Object
212                },
213                function testWriteAPI_newItem_withParent(){
214                        // summary:
215                        //              Simple test of the newItem API with a parent assignment
216                        // description:
217                        //              Simple test of the newItem API with a parent assignment
218                        var store = new dojo.data.ItemFileWriteStore(tests.data.readOnlyItemFileTestTemplates.getTestData("countries"));
219
220                        var deferred = new doh.Deferred();
221                        doh.assertTrue(!store.isDirty());
222
223                        var onError = function(error, request){
224                                deferred.errback(error);
225                        };
226
227                        var onComplete = function(items, request){
228                                doh.assertEqual(1, items.length);
229                                var item = items[0];
230                                doh.assertTrue(store.containsValue(item, "name", "Egypt"));
231
232                                //Attach an onNew to validate we get expected values.
233                                var onNewInvoked = false;
234                                store.onNew = function(newItem, parentInfo){
235                                        doh.assertEqual(item, parentInfo.item);
236                                        doh.assertEqual("cities", parentInfo.attribute);
237                                        doh.assertTrue(parentInfo.oldValue === undefined);
238                                        doh.assertTrue(parentInfo.newValue === newItem);
239                                        onNewInvoked = true;
240                                };
241
242                                //Attach an onSet and verify onSet is NOT called in this case.
243                                store.onSet = function(item, attribute, oldValue, newValue){
244                                        doh.assertTrue(false);
245                                };
246
247
248
249                                //See if we can add in a new item representing the city of Cairo.
250                                //This should also call the onNew set above....
251                                var newItem = store.newItem({name: "Cairo", abbr: "Cairo"}, {parent: item, attribute: "cities"});
252                                doh.assertTrue(onNewInvoked);
253
254                                function onCompleteNewItemShallow(items, request){
255                                        doh.assertEqual(0, items.length);
256                                        function onCompleteNewItemDeep(items, request){
257                                                doh.assertEqual(1, items.length);
258                                                var item = items[0];
259                                                doh.assertEqual("Cairo", store.getValue(item, "name"));
260                                                deferred.callback(true);
261                                        }
262                                        //Do a deep search now, should find the new item of the city with name attribute Cairo.
263                                        store.fetch({query:{name:"Cairo"}, onComplete: onCompleteNewItemDeep, onError: onError, queryOptions: {deep:true}});
264                                }
265                                //Do a shallow search first, should find nothing.
266                                store.fetch({query:{name:"Cairo"}, onComplete: onCompleteNewItemShallow, onError: onError});
267                        };
268                        store.fetch({query:{name:"Egypt"}, onComplete: onComplete, onError: onError});
269                        return deferred; //Object
270                },
271
272                function testWriteAPI_newItem_multiple_withParent(){
273                        // summary:
274                        //              Simple test of the newItem API with a parent assignment multiple times.
275                        // description:
276                        //              Simple test of the newItem API with a parent assignment multiple times.
277                        var store = new dojo.data.ItemFileWriteStore(tests.data.readOnlyItemFileTestTemplates.getTestData("countries"));
278
279                        var deferred = new doh.Deferred();
280
281                        doh.assertTrue(!store.isDirty());
282
283                        function onComplete(items, request){
284                                doh.assertEqual(1, items.length);
285                                var item = items[0];
286                                doh.assertTrue(store.containsValue(item, "name", "Egypt"));
287
288                                //Attach an onNew to validate we get expected values.
289                                store.onNew = function(newItem, parentInfo){
290                                        doh.assertEqual(item, parentInfo.item);
291                                        doh.assertEqual("cities", parentInfo.attribute);
292
293                                        doh.assertTrue(parentInfo.oldValue === undefined);
294
295                                        doh.assertTrue(parentInfo.newValue === newItem);
296                                };
297
298                                //See if we can add in a new item representing the city of Cairo.
299                                //This should also call the onNew set above....
300                                var newItem1 = store.newItem({name: "Cairo", abbr: "Cairo"}, {parent: item, attribute: "cities"});
301
302                                //Attach a new onNew to validate we get expected values.
303                                store.onNew = function(newItem, parentInfo){
304                                        doh.assertEqual(item, parentInfo.item);
305                                        doh.assertEqual("cities", parentInfo.attribute);
306
307                                        console.log(parentInfo.oldValue);
308                                        doh.assertTrue(parentInfo.oldValue == newItem1);
309
310                                        doh.assertTrue(parentInfo.newValue[0] == newItem1);
311                                        doh.assertTrue(parentInfo.newValue[1] == newItem);
312                                };
313                                var newItem2 = store.newItem({name: "Banha", abbr: "Banha"}, {parent: item, attribute: "cities"});
314
315                                //Attach a new onNew to validate we get expected values.
316                                store.onNew = function(newItem, parentInfo){
317                                        doh.assertEqual(item, parentInfo.item);
318                                        doh.assertEqual("cities", parentInfo.attribute);
319
320                                        doh.assertTrue(parentInfo.oldValue[0] == newItem1);
321                                        doh.assertTrue(parentInfo.oldValue[1] == newItem2);
322
323                                        doh.assertTrue(parentInfo.newValue[0] == newItem1);
324                                        doh.assertTrue(parentInfo.newValue[1] == newItem2);
325                                        doh.assertTrue(parentInfo.newValue[2] == newItem);
326                                };
327                                var newItem3 = store.newItem({name: "Damanhur", abbr: "Damanhur"}, {parent: item, attribute: "cities"});
328                                deferred.callback(true);
329                        }
330                        function onError(error, request){
331                                deferred.errback(error);
332                        }
333                        store.fetch({query:{name:"Egypt"}, onComplete: onComplete, onError: onError});
334                        return deferred; //Object
335                },
336
337                function testWriteAPI_deleteItem(){
338                        // summary:
339                        //              Simple test of the deleteItem API
340                        // description:
341                        //              Simple test of the deleteItem API
342                        var store = new dojo.data.ItemFileWriteStore(tests.data.readOnlyItemFileTestTemplates.getTestData("countries"));
343
344                        var deferred = new doh.Deferred();
345
346                        var onError = function(error, request){
347                                deferred.errback(error);
348                        };
349
350                        var onComplete = function(items, request){
351                                doh.assertEqual(1, items.length);
352                                var item = items[0];
353                                doh.assertTrue(store.containsValue(item, "name", "Egypt"));
354                                doh.assertTrue(store.isDirty(item) === false);
355                                doh.assertTrue(!store.isDirty());
356                                store.deleteItem(item);
357                                doh.assertTrue(store.isDirty(item));
358                                doh.assertTrue(store.isDirty());
359                                var onCompleteToo = function(itemsToo, requestToo){
360                                        doh.assertEqual(0, itemsToo.length);
361                                        deferred.callback(true);
362                                };
363                                store.fetch({query:{name:"Egypt"}, onComplete: onCompleteToo, onError: onError});
364                        };
365                        store.fetch({query:{name:"Egypt"}, onComplete: onComplete, onError: onError});
366                        return deferred; //Object
367                },
368                function testWriteAPI_isDirty(){
369                        // summary:
370                        //              Simple test of the isDirty API
371                        // description:
372                        //              Simple test of the isDirty API
373                        var store = new dojo.data.ItemFileWriteStore(tests.data.readOnlyItemFileTestTemplates.getTestData("countries"));
374
375                        var deferred = new doh.Deferred();
376                        function onComplete(items, request){
377                                doh.assertEqual(1, items.length);
378                                var item = items[0];
379                                doh.assertTrue(store.containsValue(item, "name", "Egypt"));
380                                store.setValue(item, "name", "Egypt 2");
381                                doh.assertTrue(store.getValue(item, "name") == "Egypt 2");
382                                doh.assertTrue(store.isDirty(item));
383                                deferred.callback(true);
384                        }
385                        function onError(error, request){
386                                deferred.errback(error);
387                        }
388                        store.fetch({query:{name:"Egypt"}, onComplete: onComplete, onError: onError});
389                        return deferred; //Object
390                },
391                function testWriteAPI_revert(){
392                        // summary:
393                        //              Simple test of the revert API
394                        // description:
395                        //              Simple test of the revert API
396                        var store = new dojo.data.ItemFileWriteStore(tests.data.readOnlyItemFileTestTemplates.getTestData("countries"));
397
398                        var deferred = new doh.Deferred();
399
400                        var onError = function(error, request){
401                                deferred.errback(error);
402                        };
403
404                        var onComplete = function(items, request){
405                                doh.assertEqual(1, items.length);
406                                var item = items[0];
407                                doh.assertTrue(store.containsValue(item, "name", "Egypt"));
408                                doh.assertTrue(store.isDirty(item) === false);
409                                doh.assertTrue(!store.isDirty());
410                                store.setValue(item, "name", "Egypt 2");
411                                doh.assertTrue(store.getValue(item, "name") == "Egypt 2");
412                                doh.assertTrue(store.isDirty(item));
413                                doh.assertTrue(store.isDirty());
414                                store.revert();
415
416                                //Fetch again to see if it reset the state.
417                                var onCompleteToo = function(itemsToo, requestToo){
418                                        doh.assertEqual(1, itemsToo.length);
419                                        var itemToo = itemsToo[0];
420                                        doh.assertTrue(store.containsValue(itemToo, "name", "Egypt"));
421                                        deferred.callback(true);
422                                };
423                                store.fetch({query:{name:"Egypt"}, onComplete: onCompleteToo, onError: onError});
424                        };
425                        store.fetch({query:{name:"Egypt"}, onComplete: onComplete, onError: onError});
426                        return deferred; //Object
427                },
428                function testWriteAPI_save(){
429                        // summary:
430                        //              Simple test of the save API
431                        // description:
432                        //              Simple test of the save API
433                        var store = new dojo.data.ItemFileWriteStore(tests.data.readOnlyItemFileTestTemplates.getTestData("countries"));
434
435                        var deferred = new doh.Deferred();
436                        function onError(error){
437                                deferred.errback(error);
438                        }
439                        function onItem(item){
440                                store.setValue(item, "capital", "New Cairo");
441                                function onComplete(){
442                                        deferred.callback(true);
443                                }
444                                store.save({onComplete:onComplete, onError:onError});
445                        }
446                        store.fetchItemByIdentity({identity:"eg", onItem:onItem, onError:onError});
447                        return deferred; //Object
448                },
449                function testWriteAPI_saveVerifyState(){
450                        // summary:
451                        //              Simple test of the save API
452                        // description:
453                        //              Simple test of the save API
454                        var store = new dojo.data.ItemFileWriteStore(tests.data.readOnlyItemFileTestTemplates.getTestData("countries"));
455
456                        var deferred = new doh.Deferred();
457                        function onError(error){
458                                deferred.errback(error);
459                        }
460                        function onItem(item){
461                                store.setValue(item, "capital", "New Cairo");
462                                function onComplete(){
463                                        //Check internal state.  Note:  Users should NOT do this, this is a UT verification
464                                        //of internals in this case.  Ref tracker: #4394
465                                        doh.assertTrue(!store._saveInProgress);
466                                        deferred.callback(true);
467                                }
468                                store.save({onComplete:onComplete, onError:onError});
469                        }
470                        store.fetchItemByIdentity({identity:"eg", onItem:onItem, onError:onError});
471                        return deferred; //Object
472                },
473                function testWriteAPI_saveEverything(){
474                        // summary:
475                        //              Simple test of the save API
476                        // description:
477                        //              Simple test of the save API
478                        var store = new dojo.data.ItemFileWriteStore(tests.data.readOnlyItemFileTestTemplates.getTestData("countries"));
479                        var egypt;
480
481                        var deferred = new doh.Deferred();
482                        var onError = function(error){
483                                deferred.errback(error);
484                        };
485
486                        store._saveEverything = function(saveCompleteCallback, saveFailedCallback, newFileContentString){
487                                var struct = dojo.fromJson(newFileContentString);
488                                doh.assertEqual(struct.identifier, store.getIdentityAttributes(egypt)[0]);
489                                doh.assertEqual(struct.label, store.getLabelAttributes(egypt)[0]);
490                                doh.assertEqual(struct.items.length, 7);
491
492                                var cloneStore = new dojo.data.ItemFileWriteStore({data:struct});
493                                var onItemClone = function(itemClone){
494                                        var egyptClone = itemClone;
495                                        doh.assertEqual(store.getIdentityAttributes(egypt)[0], cloneStore.getIdentityAttributes(egyptClone)[0]);
496                                        doh.assertEqual(store.getLabelAttributes(egypt)[0], cloneStore.getLabelAttributes(egyptClone)[0]);
497                                        doh.assertEqual(store.getValue(egypt, "name"), cloneStore.getValue(egyptClone, "name"));
498                                };
499                                cloneStore.fetchItemByIdentity({identity:"eg", onItem:onItemClone, onError:onError});
500                                saveCompleteCallback();
501                        };
502                        var onItem = function(item){
503                                egypt = item;
504                                var onComplete = function(){
505                                        deferred.callback(true);
506                                };
507                                store.setValue(egypt, "capital", "New Cairo");
508                                store.save({onComplete:onComplete, onError:onError});
509                        };
510                        store.fetchItemByIdentity({identity:"eg", onItem:onItem, onError:onError});
511                        return deferred; //Object
512                },
513                function testWriteAPI_saveEverything_HierarchyOff(){
514                        // summary:
515                        //              Simple test of the save API
516                        // description:
517                        //              Simple test of the save API
518                        var store = new dojo.data.ItemFileWriteStore(tests.data.readOnlyItemFileTestTemplates.getTestData("geography_hierarchy_small"));
519                        store.hierarchical = false;
520                        var africa;
521
522                        var deferred = new doh.Deferred();
523                        var onError = function(error){
524                                deferred.errback(error);
525                        };
526
527                        store._saveEverything = function(saveCompleteCallback, saveFailedCallback, newFileContentString){
528                                var struct = dojo.fromJson(newFileContentString);
529                                doh.assertEqual(struct.items.length, 3);
530                                var cloneStore = new dojo.data.ItemFileWriteStore({data:struct, hierarchical: false});
531                                var onItemClone = function(items, request){
532                                        var africaClone = items[0];
533                                        doh.assertEqual(store.getValue(africa, "name"), cloneStore.getValue(africaClone, "name"));
534                                };
535                                cloneStore.fetch({query: {name:"Africa"}, onComplete:onItemClone, onError:onError, queryOptions: {deep: true}});
536                                saveCompleteCallback();
537                        };
538                        var onComplete = function(items, request){
539                                africa = items[0];
540                                var onComplete = function(){
541                                        deferred.callback(true);
542                                };
543                                store.setValue(africa, "size", "HUGE!");
544                                store.save({onComplete:onComplete, onError:onError});
545                        };
546                        store.fetch({query: {name:"Africa"}, onComplete:onComplete, onError:onError, queryOptions: {deep: true}});
547                        return deferred; //Object
548                },
549                function testWriteAPI_saveEverything_withDateType(){
550                        // summary:
551                        //              Simple test of the save API     with a non-atomic type (Date) that has a type mapping.
552                        // description:
553                        //              Simple test of the save API     with a non-atomic type (Date) that has a type mapping.
554                        var store = new dojo.data.ItemFileWriteStore(tests.data.readOnlyItemFileTestTemplates.getTestData("countries"));
555
556                        var deferred = new doh.Deferred();
557                        store._saveEverything = function(saveCompleteCallback, saveFailedCallback, newFileContentString){
558
559                                //Now load the new data into a datastore and validate that it stored the date right.
560                                var dataset = dojo.fromJson(newFileContentString);
561                                var newStore = new dojo.data.ItemFileWriteStore({data: dataset});
562
563                                function gotItem(item){
564                                        var independenceDate = newStore.getValue(item,"independence");
565                                        doh.assertTrue(independenceDate instanceof Date);
566                                        doh.assertTrue(dojo.date.compare(new Date(1993,4,24), independenceDate, "date") === 0);
567                                        saveCompleteCallback();
568                                }
569                                function failed(error, request){
570                                        deferred.errback(error);
571                                        saveFailedCallback();
572                                }
573                                newStore.fetchItemByIdentity({identity:"eg", onItem:gotItem, onError:failed});
574                        };
575
576                        var onError = function(error){
577                                deferred.errback(error);
578                        };
579                        var onItem = function(item){
580                                var onComplete = function(){
581                                        deferred.callback(true);
582                                };
583                                store.setValue(item, "independence", new Date(1993,4,24));
584                                store.save({onComplete:onComplete, onError:onError});
585                        };
586                        store.fetchItemByIdentity({identity:"eg", onItem:onItem, onError:onError});
587                        return deferred; //Object
588                },
589                function testWriteAPI_saveEverything_withCustomColorTypeSimple(){
590                        // summary:
591                        //              Simple test of the save API     with a non-atomic type (dojo.Color) that has a type mapping.
592                        // description:
593                        //              Simple test of the save API     with a non-atomic type (dojo.Color) that has a type mapping.
594
595                        //Set up the store basics:  What data it has, and what to do when save is called for saveEverything
596                        //And how to map the 'Color' type in and out of the format.
597                        //(Test of saving all to a some location...)
598                        var dataset = {
599                                identifier:'name',
600                                items: [
601                                        { name:'Kermit', species:'frog', color:{_type:'Color', _value:'green'} },
602                                        { name:'Beaker', hairColor:{_type:'Color', _value:'red'} }
603                                ]
604                        };
605
606                        var customTypeMap = {'Color': dojo.Color };
607
608                        var store = new dojo.data.ItemFileWriteStore({
609                                        data:dataset,
610                                        typeMap: customTypeMap
611                        });
612
613                        var deferred = new doh.Deferred();
614                        store._saveEverything = function(saveCompleteCallback, saveFailedCallback, newFileContentString){
615                                //Now load the new data into a datastore and validate that it stored the Color right.
616                                var dataset = dojo.fromJson(newFileContentString);
617                                var newStore = new dojo.data.ItemFileWriteStore({data: dataset, typeMap: customTypeMap});
618
619                                var deferred = new doh.Deferred();
620                                function gotItem(item){
621                                        var hairColor = newStore.getValue(item,"hairColor");
622                                        doh.assertTrue(hairColor instanceof dojo.Color);
623                                        doh.assertEqual("rgba(255, 255, 0, 1)", hairColor.toString());
624                                        saveCompleteCallback();
625                                }
626                                function failed(error, request){
627                                        deferred.errback(error);
628                                        saveFailedCallback();
629                                }
630                                newStore.fetchItemByIdentity({identity:"Animal", onItem:gotItem, onError:failed});
631                        };
632
633                        //Add a new item with a color type, then save it.
634            var onError = function(error){
635                                deferred.errback(error);
636                        };
637                        var onComplete = function(){
638                                deferred.callback(true);
639                        };
640
641                        var animal = store.newItem({name: "Animal", hairColor: new dojo.Color("yellow")});
642                        store.save({onComplete:onComplete, onError:onError});
643                        return deferred; //Object
644                },
645                function testWriteAPI_saveEverything_withCustomColorTypeGeneral(){
646                        // summary:
647                        //              Simple test of the save API     with a non-atomic type (dojo.Color) that has a type mapping.
648                        // description:
649                        //              Simple test of the save API     with a non-atomic type (dojo.Color) that has a type mapping.
650
651                        //Set up the store basics:  What data it has, and what to do when save is called for saveEverything
652                        //And how to map the 'Color' type in and out of the format.
653                        //(Test of saving all to a some location...)
654                        var dataset = {
655                                identifier:'name',
656                                items: [
657                                        { name:'Kermit', species:'frog', color:{_type:'Color', _value:'green'} },
658                                        { name:'Beaker', hairColor:{_type:'Color', _value:'red'} }
659                                ]
660                        };
661
662                        var customTypeMap = {'Color':   {
663                                                                                                type: dojo.Color,
664                                                                                                deserialize: function(value){
665                                                                                                        return new dojo.Color(value);
666                                                                                                },
667                                                                                                serialize: function(obj){
668                                                                                                        return obj.toString();
669                                                                                                }
670                                                                                        }
671                                                                };
672                        var store = new dojo.data.ItemFileWriteStore({
673                                        data:dataset,
674                                        typeMap: customTypeMap
675                        });
676
677                        var deferred = new doh.Deferred();
678                        store._saveEverything = function(saveCompleteCallback, saveFailedCallback, newFileContentString){
679                                //Now load the new data into a datastore and validate that it stored the Color right.
680                                var dataset = dojo.fromJson(newFileContentString);
681                                var newStore = new dojo.data.ItemFileWriteStore({data: dataset, typeMap: customTypeMap});
682
683                                var gotItem = function(item){
684                                        var hairColor = newStore.getValue(item,"hairColor");
685                                        doh.assertTrue(hairColor instanceof dojo.Color);
686                                        doh.assertEqual("rgba(255, 255, 0, 1)", hairColor.toString());
687                                        saveCompleteCallback();
688                                };
689                                var failed = function(error, request){
690                                        deferred.errback(error);
691                                        saveFailedCallback();
692                                };
693                                newStore.fetchItemByIdentity({identity:"Animal", onItem:gotItem, onError:failed});
694                        };
695
696                        //Add a new item with a color type, then save it.
697            var onError = function(error){
698                                deferred.errback(error);
699                        };
700                        var onComplete = function(){
701                                deferred.callback(true);
702                        };
703
704                        var animal = store.newItem({name: "Animal", hairColor: new dojo.Color("yellow")});
705                        store.save({onComplete:onComplete, onError:onError});
706                        return deferred; //Object
707                },
708                function testWriteAPI_newItem_revert(){
709                        // summary:
710                        //              Test for bug #5357.  Ensure that the revert properly nulls the identity position
711                        //              for a new item after revert.
712                        var args = {data: {
713                                label:"name",
714                                items:[
715                                        {name:'Ecuador', capital:'Quito'},
716                                        {name:'Egypt', capital:'Cairo'},
717                                        {name:'El Salvador', capital:'San Salvador'},
718                                        {name:'Equatorial Guinea', capital:'Malabo'},
719                                        {name:'Eritrea', capital:'Asmara'},
720                                        {name:'Estonia', capital:'Tallinn'},
721                                        {name:'Ethiopia', capital:'Addis Ababa'}
722                                ]
723                        } };
724                        var store = new dojo.data.ItemFileWriteStore(args);
725
726                        var newCountry = store.newItem({name: "Utopia", capitol: "Perfect"});
727
728                        //DO NOT ACCESS THIS WAY.  THESE ARE INTERNAL VARIABLES.  DOING THIS FOR TEST PURPOSES.
729                        var itemEntryNum = newCountry[store._itemNumPropName];
730                        doh.assertTrue(store._arrayOfAllItems[itemEntryNum] === newCountry);
731                        store.revert();
732                        doh.assertTrue(store._arrayOfAllItems[itemEntryNum] === null);
733                },
734                function testWriteAPI_new_modify_revert(){
735                        // summary:
736                        //              Test of a new item, modify it, then revert, to ensure the state remains consistent.  Added due to #9022.
737                        // description:
738                        //              Test of a new item, modify it, then revert, to ensure the state remains consistent.  Added due to #9022.
739                        var store = new dojo.data.ItemFileWriteStore(tests.data.readOnlyItemFileTestTemplates.getTestData("countries"));
740
741                        var deferred = new doh.Deferred();
742                        doh.assertTrue(!store.isDirty());
743
744                        var onError = function(error, request){
745                                deferred.errback(error);
746                        };
747
748                        var intialFetch = function(items, request){
749                                var initialCount = items.length;
750                                var canada = store.newItem({name: "Canada", abbr:"ca", capital:"Ottawa"});
751                                store.setValue(canada, "someattribute", "modified a new item!");
752                                var afterNewFetch = function(items, request){
753                                        var afterNewCount = items.length;
754                                        doh.assertEqual(afterNewCount, (initialCount + 1));
755                                        store.revert();
756                                        var afterRevertFetch = function(items, request){
757                                                var afterRevertCount = items.length;
758                                                doh.assertEqual(afterRevertCount, initialCount);
759                                                deferred.callback(true);
760                                        };
761                                        store.fetch({onComplete: afterRevertFetch, onError: onError});
762                                };
763                                store.fetch({onComplete: afterNewFetch, onError: onError});
764                        };
765                        store.fetch({onComplete: intialFetch, onError: onError});
766                        return deferred; //Object
767                },
768                function testWriteAPI_new_modify_delete_revert(){
769                        // summary:
770                        //              Test of a new item, modify it, delete it, then revert, to ensure the state remains consistent.  Added due to #9022.
771                        // description:
772                        //              Test of a new item, modify it, delete it, then revert, to ensure the state remains consistent.  Added due to #9022.
773                        var store = new dojo.data.ItemFileWriteStore(tests.data.readOnlyItemFileTestTemplates.getTestData("countries"));
774                        var i;
775                        var found = false;
776
777                        var deferred = new doh.Deferred();
778                        doh.assertTrue(!store.isDirty());
779
780                        var onError = function(error, request){
781                                deferred.errback(error);
782                        };
783
784                        var intialFetch = function(items, request){
785                                var initialCount = items.length;
786                                var canada = store.newItem({name: "Canada", abbr:"ca", capital:"Ottawa"});
787                                store.setValue(canada, "someattribute", "modified a new item!");
788
789                                // check that after new and modify, the total items count goes up by one.
790                                var afterNewFetch = function(items, request){
791                                        var afterNewCount = items.length;
792                                        doh.assertEqual(afterNewCount, (initialCount + 1));
793                                        store.deleteItem(canada);
794
795                                        //Check that after delete, the total items count goes back to initial count.
796                                        //Also verify the item with abbr of ca is gone.
797                                        var afterDeleteFetch = function(items, request){
798                                                var afterDeleteCount = items.length;
799                                                doh.assertEqual(initialCount, afterDeleteCount);
800
801                                                for(i=0; i < items.length; i++){
802                                                        found = (store.getIdentity(items[i]) === "ca");
803                                                        if(found){
804                                                                break;
805                                                        }
806                                                }
807                                                if(found){
808                                                        deferred.errback(new Error("Error: Found the supposedly deleted item!"));
809                                                }else{
810                                                        store.revert();
811                                                        //Check that after revert, we still have the same item count as the
812                                                        //original fetch.  Also verify the item with abbr of ca is gone.
813                                                        var afterRevertFetch = function(items, request){
814                                                                var afterRevertCount = items.length;
815                                                                doh.assertEqual(afterRevertCount, initialCount);
816                                                                for(i=0; i < items.length; i++){
817                                                                        found = (store.getIdentity(items[i]) === "ca");
818                                                                        if(found){
819                                                                                break;
820                                                                        }
821                                                                }
822                                                                if(found){
823                                                                        deferred.errback(new Error("Error: Found the 'new' item after revert!"));
824                                                                }else{
825                                                                        deferred.callback(true);
826                                                                }
827                                                        };
828                                                        store.fetch({onComplete: afterRevertFetch, onError: onError});
829                                                }
830                                        };
831                                        store.fetch({onComplete: afterDeleteFetch, onError: onError});
832                                };
833                                store.fetch({onComplete: afterNewFetch, onError: onError});
834                        };
835                        store.fetch({onComplete: intialFetch, onError: onError});
836                        return deferred; //Object
837                },
838                function testNotificationAPI_onSet(){
839                        // summary:
840                        //              Simple test of the onSet API
841                        // description:
842                        //              Simple test of the onSet API
843                        var store = new dojo.data.ItemFileWriteStore(tests.data.readOnlyItemFileTestTemplates.getTestData("countries"));
844
845                        var deferred = new doh.Deferred();
846                        function onError(error){
847                                deferred.errback(error);
848                        }
849                        function onItem(fetchedItem){
850                                var egypt = fetchedItem;
851                                var connectHandle = null;
852                                function setValueHandler(item, attribute, oldValue, newValue){
853                                        doh.assertTrue(store.isItem(item));
854                                        doh.assertTrue(item == egypt);
855                                        doh.assertTrue(attribute == "capital");
856                                        doh.assertTrue(oldValue == "Cairo");
857                                        doh.assertTrue(newValue == "New Cairo");
858                                        deferred.callback(true);
859                                        dojo.disconnect(connectHandle);
860                                }
861                                connectHandle = dojo.connect(store, "onSet", setValueHandler);
862                                store.setValue(egypt, "capital", "New Cairo");
863                        }
864                        store.fetchItemByIdentity({identity:"eg", onItem:onItem, onError:onError});
865                },
866                function testNotificationAPI_onNew(){
867                        // summary:
868                        //              Simple test of the onNew API
869                        // description:
870                        //              Simple test of the onNew API
871                        var store = new dojo.data.ItemFileWriteStore(tests.data.readOnlyItemFileTestTemplates.getTestData("countries"));
872
873                        var deferred = new doh.Deferred();
874                        var connectHandle = null;
875                        function newItemHandler(item){
876                                doh.assertTrue(store.isItem(item));
877                                doh.assertTrue(store.getValue(item, "name") == "Canada");
878                                deferred.callback(true);
879                                dojo.disconnect(connectHandle);
880                        }
881                        connectHandle = dojo.connect(store, "onNew", newItemHandler);
882                        var canada = store.newItem({name:"Canada", abbr:"ca", capital:"Ottawa"});
883                },
884                function testNotificationAPI_onDelete(){
885                        // summary:
886                        //              Simple test of the onDelete API
887                        // description:
888                        //              Simple test of the onDelete API
889                        var store = new dojo.data.ItemFileWriteStore(tests.data.readOnlyItemFileTestTemplates.getTestData("countries"));
890
891                        var deferred = new doh.Deferred();
892                        function onError(error){
893                                deferred.errback(error);
894                        }
895                        function onItem(fetchedItem){
896                                var egypt = fetchedItem;
897                                var connectHandle = null;
898                                function deleteItemHandler(item){
899                                        doh.assertTrue(store.isItem(item) === false);
900                                        doh.assertTrue(item == egypt);
901                                        deferred.callback(true);
902                                        dojo.disconnect(connectHandle);
903                                }
904                                connectHandle = dojo.connect(store, "onDelete", deleteItemHandler);
905                                store.deleteItem(egypt);
906                        }
907                        store.fetchItemByIdentity({identity:"eg", onItem:onItem, onError:onError});
908                },
909                function testReadAPI_functionConformanceToo(){
910                        // summary:
911                        //              Simple test read API conformance.  Checks to see all declared functions are actual functions on the instances.
912                        // description:
913                        //              Simple test read API conformance.  Checks to see all declared functions are actual functions on the instances.
914                        var testStore = new dojo.data.ItemFileWriteStore(tests.data.readOnlyItemFileTestTemplates.getTestData("countries"));
915                        var readApi = new dojo.data.api.Read();
916                        var passed = true;
917
918                        for(var functionName in readApi){
919                                var member = readApi[functionName];
920                                //Check that all the 'Read' defined functions exist on the test store.
921                                if(typeof member === "function"){
922                                        var testStoreMember = testStore[functionName];
923                                        if(!(typeof testStoreMember === "function")){
924                                                passed = false;
925                                                break;
926                                        }
927                                }
928                        }
929                        doh.assertTrue(passed);
930                },
931                function testWriteAPI_functionConformance(){
932                        // summary:
933                        //              Simple test write API conformance.  Checks to see all declared functions are actual functions on the instances.
934                        // description:
935                        //              Simple test write API conformance.  Checks to see all declared functions are actual functions on the instances.
936                        var testStore = new dojo.data.ItemFileWriteStore(tests.data.readOnlyItemFileTestTemplates.getTestData("countries"));
937                        var writeApi = new dojo.data.api.Write();
938                        var passed = true;
939
940                        for(var functionName in writeApi){
941                                var member = writeApi[functionName];
942                                //Check that all the 'Write' defined functions exist on the test store.
943                                if(typeof member === "function"){
944                                        var testStoreMember = testStore[functionName];
945                                        if(!(typeof testStoreMember === "function")){
946                                                passed = false;
947                                                break;
948                                        }
949                                }
950                        }
951                        doh.assertTrue(passed);
952                },
953                function testNotificationAPI_functionConformance(){
954                        // summary:
955                        //              Simple test Notification API conformance.  Checks to see all declared functions are actual functions on the instances.
956                        // description:
957                        //              Simple test Notification API conformance.  Checks to see all declared functions are actual functions on the instances.
958                        var testStore = new dojo.data.ItemFileWriteStore(tests.data.readOnlyItemFileTestTemplates.getTestData("countries"));
959                        var api = new dojo.data.api.Notification();
960                        var passed = true;
961
962                        for(var functionName in api){
963                                var member = api[functionName];
964                                //Check that all the 'Write' defined functions exist on the test store.
965                                if(typeof member === "function"){
966                                        var testStoreMember = testStore[functionName];
967                                        if(!(typeof testStoreMember === "function")){
968                                                passed = false;
969                                                break;
970                                        }
971                                }
972                        }
973                        doh.assertTrue(passed);
974                },
975                function testIdentityAPI_noIdentifierSpecified(){
976                        // summary:
977                        //              Test for bug #3873. Given a datafile that does not specify an
978                        //              identifier, make sure ItemFileWriteStore auto-creates identities
979                        //              that are unique even after calls to deleteItem() and newItem()
980                        var args = {data: {
981                                label:"name",
982                                items:[
983                                        {name:'Ecuador', capital:'Quito'},
984                                        {name:'Egypt', capital:'Cairo'},
985                                        {name:'El Salvador', capital:'San Salvador'},
986                                        {name:'Equatorial Guinea', capital:'Malabo'},
987                                        {name:'Eritrea', capital:'Asmara'},
988                                        {name:'Estonia', capital:'Tallinn'},
989                                        {name:'Ethiopia', capital:'Addis Ababa'}
990                                ]
991                        } };
992                        var store = new dojo.data.ItemFileWriteStore(args);
993                        var deferred = new doh.Deferred();
994
995                        var onError = function(error, request){
996                                deferred.errback(error);
997                        };
998                        var onComplete = function(items, request){
999                                doh.assertEqual(7, items.length);
1000
1001                                var lastItem = items[(items.length - 1)];
1002                                var idOfLastItem = store.getIdentity(lastItem);
1003                                store.deleteItem(lastItem);
1004                                store.newItem({name:'Canada', capital:'Ottawa'});
1005
1006                                var onCompleteAgain = function(itemsAgain, requestAgain){
1007                                        doh.assertEqual(7, itemsAgain.length);
1008                                        var identitiesInUse = {};
1009                                        for(var i = 0; i < itemsAgain.length; ++i){
1010                                                var item = itemsAgain[i];
1011                                                var id = store.getIdentity(item);
1012                                                if(identitiesInUse.hasOwnProperty(id)){
1013                                                        // there should not already be an entry for this id
1014                                                        doh.assertTrue(false);
1015                                                }else{
1016                                                        // we want to add the entry now
1017                                                        identitiesInUse[id] = item;
1018                                                }
1019                                        }
1020                                        deferred.callback(true);
1021                                };
1022                                store.fetch({onComplete:onCompleteAgain, onError:onError});
1023                        };
1024
1025                        store.fetch({onComplete:onComplete, onError:onError});
1026                        return deferred;
1027                },
1028                function testIdentityAPI_noIdentifierSpecified_revert(){
1029                        // summary:
1030                        //              Test for bug #4691  Given a datafile that does not specify an
1031                        //              identifier, make sure ItemFileWriteStore auto-creates identities
1032                        //              that are unique even after calls to deleteItem() and newItem()
1033                        var args = {data: {
1034                                label:"name",
1035                                items:[
1036                                        {name:'Ecuador', capital:'Quito'},
1037                                        {name:'Egypt', capital:'Cairo'},
1038                                        {name:'El Salvador', capital:'San Salvador'},
1039                                        {name:'Equatorial Guinea', capital:'Malabo'},
1040                                        {name:'Eritrea', capital:'Asmara'},
1041                                        {name:'Estonia', capital:'Tallinn'},
1042                                        {name:'Ethiopia', capital:'Addis Ababa'}
1043                                ]
1044                        } };
1045                        var store = new dojo.data.ItemFileWriteStore(args);
1046                        var deferred = new doh.Deferred();
1047
1048                        var onError = function(error, request){
1049                                deferred.errback(error);
1050                        };
1051                        var onComplete = function(items, request){
1052                                doh.assertEqual(7, items.length);
1053
1054                                var lastItem = items[(items.length - 1)];
1055                                var idOfLastItem = store.getIdentity(lastItem);
1056                                store.deleteItem(lastItem);
1057                                store.newItem({name:'Canada', capital:'Ottawa'});
1058
1059                                var onCompleteAgain = function(itemsAgain, requestAgain){
1060                                        doh.assertEqual(7, itemsAgain.length);
1061                                        var identitiesInUse = {};
1062                                        for(var i = 0; i < itemsAgain.length; ++i){
1063                                                var item = itemsAgain[i];
1064                                                var id = store.getIdentity(item);
1065                                                if(identitiesInUse.hasOwnProperty(id)){
1066                                                        // there should not already be an entry for this id
1067                                                        doh.assertTrue(false);
1068                                                }else{
1069                                                        // we want to add the entry now
1070                                                        identitiesInUse[id] = item;
1071                                                }
1072                                        }
1073                                        //Last test, revert everything and check item sizes.
1074                                        store.revert();
1075
1076                                        //Now call fetch again and verify store state.
1077                                        var revertComplete = function(itemsReverted, request){
1078                                                doh.assertEqual(7, itemsReverted.length);
1079                                                deferred.callback(true);
1080                                        };
1081                                        store.fetch({onComplete:revertComplete, onError:onError});
1082                                };
1083                                store.fetch({onComplete:onCompleteAgain, onError:onError});
1084                        };
1085                        store.fetch({onComplete:onComplete, onError:onError});
1086                        return deferred;
1087                },
1088                function testReferenceIntegrity_checkReferences(){
1089                        // summary:
1090                        //              Simple test to verify the references were properly resolved.
1091                        // description:
1092                        //              Simple test to verify the references were properly resolved.
1093
1094                        var store = new dojo.data.ItemFileWriteStore(tests.data.ItemFileWriteStore.getTestData("reference_integrity"));
1095
1096                        var deferred = new doh.Deferred();
1097                        var onError = function(error, request){
1098                                deferred.errback(error);
1099                        };
1100                        var onComplete = function(items, request){
1101
1102                                var item10 = null;
1103                                var item1  = null;
1104                                var item3  = null;
1105                                var item5  = null;
1106
1107                                var i;
1108                                for (i = 0; i < items.length; i++){
1109                                        var ident = store.getIdentity(items[i]);
1110                                        if (ident === 10){
1111                                                item10 = items[i];
1112                                        }else if (ident === 1){
1113                                                item1 = items[i];
1114                                        }else if (ident === 3){
1115                                                item3 = items[i];
1116                                        }else if (ident === 5){
1117                                                item5 = items[i];
1118                                        }
1119                                }
1120                                var friends = store.getValues(item10, "friends");
1121                                doh.assertTrue(friends !== null);
1122                                doh.assertTrue(friends !== undefined);
1123
1124                                doh.assertTrue(store.isItem(item10));
1125                                doh.assertTrue(store.isItem(item1));
1126                                doh.assertTrue(store.isItem(item3));
1127                                doh.assertTrue(store.isItem(item5));
1128                                var found = 0;
1129                                try{
1130                                        for (i = 0; i < friends.length; i++){
1131                                                if (i === 0){
1132                                                        doh.assertTrue(store.isItem(friends[i]));
1133                                                        doh.assertEqual(friends[i], item1);
1134                                                        doh.assertEqual(store.getIdentity(friends[i]), 1);
1135                                                        found++;
1136                                                }else if (i === 1){
1137                                                        doh.assertTrue(store.isItem(friends[i]));
1138                                                        doh.assertEqual(friends[i], item3);
1139                                                        doh.assertEqual(store.getIdentity(friends[i]), 3);
1140                                                        found++;
1141                                                }else if (i === 2){
1142                                                        doh.assertTrue(store.isItem(friends[i]));
1143                                                        doh.assertEqual(friends[i], item5);
1144                                                        doh.assertEqual(store.getIdentity(friends[i]), 5);
1145                                                        found++;
1146                                                }
1147                                        }
1148                                }catch(e){
1149                                        doh.errback(e);
1150                                }
1151                                doh.assertEqual(3, found);
1152                                deferred.callback(true);
1153                        };
1154                        store.fetch({onError: onError, onComplete: onComplete});
1155                        return deferred;
1156                },
1157                function testReferenceIntegrity_deleteReferencedItem(){
1158                        // summary:
1159                        //              Simple test to verify the references were properly deleted.
1160                        // description:
1161                        //              Simple test to verify the references were properly deleted.
1162
1163                        var store = new dojo.data.ItemFileWriteStore(tests.data.ItemFileWriteStore.getTestData("reference_integrity"));
1164
1165                        var deferred = new doh.Deferred();
1166                        var passed = true;
1167                        function onError(error, request){
1168                                deferred.errback(error);
1169                        }
1170                        function onItem(item, request){
1171                                try{
1172                                        console.log("Before delete map state is: " + dojo.toJson(item[store._reverseRefMap]));
1173                                        store.deleteItem(item);
1174                                        console.log("After delete map state is: " + dojo.toJson(item[store._reverseRefMap]));
1175                                        function verifyRefDelete(items, request){
1176                                                var passed = true;
1177                                                for(var i = 0; i < items.length; i++){
1178                                                        var curItem = items[i];
1179                                                        var attributes = store.getAttributes(curItem);
1180                                                        for(var j = 0; j < attributes.length; j++){
1181                                                                var values = store.getValues(curItem, attributes[j]);
1182                                                                var badRef = false;
1183                                                                for(var k = 0; k < values.length; k++){
1184                                                                        var value = values[k];
1185                                                                        try{
1186                                                                                var id = store.getIdentity(value);
1187                                                                                if(id == 10){
1188                                                                                        badRef = true;
1189                                                                                        break;
1190                                                                                }
1191                                                                        }catch(e){/*Not an item, even a dead one, just eat it.*/}
1192                                                                }
1193                                                                if(badRef){
1194                                                                        deferred.errback(new Error("Found a reference remaining to a deleted item.  Failure."));
1195                                                                        passed = false;
1196                                                                        break;
1197                                                                }
1198                                                        }
1199                                                }
1200                                                if(passed){
1201                                                        deferred.callback(true);
1202                                                }
1203                                        }
1204                                        store.fetch({onComplete: verifyRefDelete, onError: onError});
1205                                }catch(error){
1206                                        deferred.errback(error);
1207                                }
1208                        }
1209                        store.fetchItemByIdentity({identity: 10, onError: onError, onItem: onItem});
1210                        return deferred;
1211                },
1212                function testReferenceIntegrity_deleteReferencedItemThenRevert(){
1213                        // summary:
1214                        //              Simple test to verify the references were properly deleted.
1215                        // description:
1216                        //              Simple test to verify the references were properly deleted.
1217
1218                        var store = new dojo.data.ItemFileWriteStore(tests.data.ItemFileWriteStore.getTestData("reference_integrity"));
1219
1220                        var deferred = new doh.Deferred();
1221                        var passed = true;
1222                        function onError(error, request){
1223                                deferred.errback(error);
1224                        }
1225                        function onItem(item, request){
1226                                try{
1227                                        //DO NOT EVER ACCESS THESE VARIABLES LIKE THIS!
1228                                        //THIS IS FOR TESTING INTERNAL STATE!
1229                                        console.log("Map before delete:");
1230                                        store._dumpReferenceMap();
1231                                        var beforeDelete = dojo.toJson(item[store._reverseRefMap]);
1232                                        store.deleteItem(item);
1233                                        console.log("Map after delete:");
1234                                        store._dumpReferenceMap();
1235                                        var afterDelete = dojo.toJson(item[store._reverseRefMap]);
1236                                        store.revert();
1237                                        console.log("Map after revert:");
1238                                        store._dumpReferenceMap();
1239                                        var afterRevert = dojo.toJson(item[store._reverseRefMap]);
1240                                        doh.assertTrue(afterRevert === beforeDelete);
1241                                }catch(e){
1242                                        deferred.errback(e);
1243                                        passed = false;
1244                                }
1245                                if(passed){
1246                                        deferred.callback(true);
1247                                }
1248                        }
1249                        store.fetchItemByIdentity({identity: 10, onError: onError, onItem: onItem});
1250                        return deferred;
1251                },
1252                function testReferenceIntegrity_deleteMultipleItemsWithReferencesAndRevert(){
1253                        // summary:
1254                        //              Simple test to verify that a flow of deleting items with references and reverting does not damage the internal structure.
1255                        //              Created for tracker bug: #5743
1256                        // description:
1257                        //              Simple test to verify that a flow of deleting items with references and reverting does not damage the internal structure.
1258                        //              Created for tracker bug: #5743
1259
1260                        var store = new dojo.data.ItemFileWriteStore(tests.data.readOnlyItemFileTestTemplates.getTestData("countries_references"));
1261
1262                        var deferred = new doh.Deferred();
1263                        var passed = true;
1264                        function onError(error, request){
1265                                deferred.errback(error);
1266                                doh.assertTrue(false);
1267                        }
1268                        function onItem(item, request){
1269                                //Save off the located item, then locate another one (peer to Egypt)
1270                                doh.assertTrue(store.isItem(item));
1271                                var egypt = item;
1272
1273                                function onItem2(item, request){
1274                                        doh.assertTrue(store.isItem(item));
1275                                        var nairobi = item;
1276
1277                                        //Delete them
1278                                        store.deleteItem(egypt);
1279                                        store.deleteItem(nairobi);
1280                                        try{
1281                                                //Revert, then do a fetch.  If the internals have been damaged, this will generally
1282                                                //cause onError to fire instead of onComplete.
1283                                                store.revert();
1284                                                function onComplete(items, request){
1285                                                        deferred.callback(true);
1286                                                }
1287                                                store.fetch({query: {name: "*"}, start: 0, count: 20, onComplete: onComplete, onError: onError});
1288                                        }catch(e){
1289                                                deferred.errback(e);
1290                                        }
1291                                }
1292                                store.fetchItemByIdentity({identity: "Nairobi", onError: onError, onItem: onItem2});
1293                        }
1294                        store.fetchItemByIdentity({identity: "Egypt", onError: onError, onItem: onItem});
1295                        return deferred;
1296                },
1297                function testReferenceIntegrity_removeReferenceFromAttribute(){
1298                        // summary:
1299                        //              Simple test to verify the reference removal updates the internal map.
1300                        // description:
1301                        //              Simple test to verify the reference removal updates the internal map.
1302
1303                        var store = new dojo.data.ItemFileWriteStore(tests.data.ItemFileWriteStore.getTestData("reference_integrity"));
1304
1305                        var deferred = new doh.Deferred();
1306                        var passed = true;
1307                        function onError(error, request){
1308                                deferred.errback(error);
1309                                doh.assertTrue(false);
1310                        }
1311                        function onItem(item, request){
1312                                try{
1313                                        store.setValues(item, "friends", [null]);
1314
1315                                        function onItem2(item10, request){
1316                                                //DO NOT EVER ACCESS THESE VARIABLES LIKE THIS!
1317                                                //THIS IS FOR TESTING INTERNAL STATE!
1318                                                var refMap = item10[store._reverseRefMap];
1319                                                store._dumpReferenceMap();
1320
1321                                                console.log("MAP for Item 10 is: " + dojo.toJson(refMap));
1322
1323                                                //Assert there is no reference to item 10 in item 11's attribute 'friends'.
1324                                                doh.assertTrue(!refMap["11"]["friends"]);
1325                                                store.setValues(item, "siblings", [0, 1, 2]);
1326                                                //Assert there are no more references to 10 in 11.  Ergo, "11"  should be a 'undefined' attribute for the map of items referencing '10'..
1327                                                doh.assertTrue(!refMap["11"]);
1328                                                deferred.callback(true);
1329                                        }
1330                                        store.fetchItemByIdentity({identity: 10, onError: onError, onItem: onItem2});
1331
1332                                }catch(e){
1333                                        console.debug(e);
1334                                        deferred.errback(e);
1335                                        doh.assertTrue(false);
1336                                }
1337                        }
1338                        store.fetchItemByIdentity({identity: 11, onError: onError, onItem: onItem});
1339                        return deferred;
1340                },
1341                function testReferenceIntegrity_deleteReferencedItemNonParent(){
1342                        // summary:
1343                        //              Simple test to verify the references to a non-parent item was properly deleted.
1344                        // description:
1345                        //              Simple test to verify the references to a non-parent item was properly deleted.
1346
1347                        var store = new dojo.data.ItemFileWriteStore(tests.data.ItemFileWriteStore.getTestData("reference_integrity"));
1348
1349                        var deferred = new doh.Deferred();
1350                        var passed = true;
1351                        function onError(error, request){
1352                                deferred.errback(error);
1353                        }
1354                        function onItem(item, request){
1355                                try{
1356                                        console.log("Reference state for item 16 is: " + dojo.toJson(item[store._reverseRefMap]));
1357                                        store.deleteItem(item);
1358                                        function verifyRefDelete(items, request){
1359                                                var passed = true;
1360                                                for(var i = 0; i < items.length; i++){
1361                                                        var curItem = items[i];
1362                                                        var attributes = store.getAttributes(curItem);
1363                                                        for(var j = 0; j < attributes.length; j++){
1364                                                                var values = store.getValues(curItem, attributes[j]);
1365                                                                var badRef = false;
1366                                                                for(var k = 0; k < values.length; k++){
1367                                                                        var value = values[k];
1368                                                                        try{
1369                                                                                var id = store.getIdentity(value);
1370                                                                                if(id == 16){
1371                                                                                        badRef = true;
1372                                                                                        break;
1373                                                                                }
1374                                                                        }catch(e){/*Not an item, even a dead one, just eat it.*/}
1375                                                                }
1376                                                                if(badRef){
1377                                                                        deferred.errback(new Error("Found a reference remaining to a deleted item.  Failure."));
1378                                                                        passed = false;
1379                                                                        break;
1380                                                                }
1381                                                        }
1382                                                }
1383                                                if(passed){
1384                                                        deferred.callback(true);
1385                                                }
1386                                        }
1387                                        store.fetch({onComplete: verifyRefDelete, onError: onError});
1388                                }catch(error){
1389                                        deferred.errback(error);
1390                                }
1391                        }
1392                        store.fetchItemByIdentity({identity: 16, onError: onError, onItem: onItem});
1393                        return deferred;
1394                },
1395                function testReferenceIntegrity_addReferenceToAttribute(){
1396                        // summary:
1397                        //              Simple test to verify the reference additions can happen.
1398                        // description:
1399                        //              Simple test to verify the reference additions can happen.
1400
1401                        var store = new dojo.data.ItemFileWriteStore(tests.data.ItemFileWriteStore.getTestData("reference_integrity"));
1402
1403                        var deferred = new doh.Deferred();
1404                        var passed = true;
1405                        function onError(error, request){
1406                                deferred.errback(error);
1407                                doh.assertTrue(false);
1408                        }
1409                        function onComplete(items, request){
1410
1411                                doh.assertTrue(items.length > 2);
1412
1413                                var item1 = items[0];
1414                                var item2 = items[1];
1415
1416                                //DO NOT EVER ACCESS THESE VARIABLES LIKE THIS!
1417                                //THIS IS FOR TESTING INTERNAL STATE!
1418                                console.log("Map state for Item 1 is: " + dojo.toJson(item1[store._reverseRefMap]));
1419                                console.log("Map state for Item 2 is: " + dojo.toJson(item2[store._reverseRefMap]));
1420
1421                                store.setValue(item1, "siblings", item2);
1422
1423                                //Emit the current map state for inspection.
1424                                console.log("Map state for Item 1 is: " + dojo.toJson(item1[store._reverseRefMap]));
1425                                console.log("Map state for Item 2 is: " + dojo.toJson(item2[store._reverseRefMap]));
1426
1427                                doh.assertTrue(item2[store._reverseRefMap] !== null);
1428
1429                                //Assert there is a recorded reference to item 2 in item 1's attribute 'sibling'.
1430                                doh.assertTrue(item2[store._reverseRefMap][store.getIdentity(item1)]["siblings"]);
1431
1432                                deferred.callback(true);
1433                        }
1434                        store.fetch({onError: onError, onComplete: onComplete});
1435                        return deferred;
1436                },
1437                function testReferenceIntegrity_newItemWithParentReference(){
1438                        // summary:
1439                        //              Simple test to verify that newItems with a parent properly record the parent's reference in the map.
1440                        // description:
1441                        //              Simple test to verify that newItems with a parent properly record the parent's reference in the map.
1442
1443                        var store = new dojo.data.ItemFileWriteStore(tests.data.ItemFileWriteStore.getTestData("reference_integrity"));
1444
1445                        var deferred = new doh.Deferred();
1446                        var passed = true;
1447                        function onError(error, request){
1448                                deferred.errback(error);
1449                                doh.assertTrue(false);
1450                        }
1451                        function onItem(item, request){
1452                                try{
1453                                        //Create a new item and set its parent to item 10's uncle attribute.
1454                                        var newItem = store.newItem({id: 17, name: "Item 17"}, {parent: item, attribute: "uncles"});
1455
1456                                        //DO NOT EVER ACCESS THESE VARIABLES LIKE THIS!
1457                                        //THIS IS FOR TESTING INTERNAL STATE!
1458                                        //Look up the references to 17, as item 10 has one now on attribute 'uncles'
1459                                        var refs = newItem[store._reverseRefMap];
1460
1461                                        //Assert there is a reference from 10 to item 17, on attribute uncle
1462                                        doh.assertTrue(refs["10"]["uncles"]);
1463
1464                                        console.log("State of map of item 17 after newItem: " + dojo.toJson(refs));
1465                                }catch(e){
1466                                        console.debug(e);
1467                                        deferred.errback(e);
1468                                        doh.assertTrue(false);
1469                                        passed = false;
1470                                }
1471                                if(passed){
1472                                        deferred.callback(true);
1473                                }
1474                        }
1475                        store.fetchItemByIdentity({identity: 10, onError: onError, onItem: onItem});
1476                        return deferred;
1477                },
1478                function testReferenceIntegrity_newItemWithReferenceToExistingItem(){
1479                        // summary:
1480                        //              Simple test to verify that a new item with references to existing items properly record the references in the map.
1481                        // description:
1482                        //              Simple test to verify that a new item with references to existing items properly record the references in the map.
1483
1484                        var store = new dojo.data.ItemFileWriteStore(tests.data.ItemFileWriteStore.getTestData("reference_integrity"));
1485
1486                        var deferred = new doh.Deferred();
1487                        var passed = true;
1488                        function onError(error, request){
1489                                deferred.errback(error);
1490                                doh.assertTrue(false);
1491                        }
1492                        function onItem(item, request){
1493                                try{
1494                                        //DO NOT EVER ACCESS THESE VARIABLES LIKE THIS!
1495                                        //THIS IS FOR TESTING INTERNAL STATE!
1496                                        console.log("State of reference map to item 10 before newItem: " + dojo.toJson(item[store._reverseRefMap]));
1497
1498                                        //Create a new item and set its parent to item 10's uncle attribute.
1499                                        var newItem = store.newItem({id: 17, name: "Item 17", friends: [item]});
1500
1501                                        //DO NOT EVER ACCESS THESE VARIABLES LIKE THIS!
1502                                        //THIS IS FOR TESTING INTERNAL STATE!
1503                                        //Look up the references to 10, as item 17 has one on friends now.
1504                                        var refs = item[store._reverseRefMap];
1505
1506                                        //Assert there is a reference from 15 to item 10, on attribute friends
1507                                        doh.assertTrue(refs["17"]["friends"]);
1508
1509                                        console.log("State of reference map to item 10 after newItem: " + dojo.toJson(refs));
1510                                }catch(e){
1511                                        console.debug(e);
1512                                        deferred.errback(e);
1513                                        doh.assertTrue(false);
1514                                        passed = false;
1515                                }
1516                                if(passed){
1517                                        deferred.callback(true);
1518                                }
1519                        }
1520                        store.fetchItemByIdentity({identity: 10, onError: onError, onItem: onItem});
1521                        return deferred;
1522                },
1523                function testReferenceIntegrity_disableReferenceIntegrity(){
1524                        // summary:
1525                        //              Simple test to verify reference integrity can be disabled.
1526                        // description:
1527                        //              Simple test to verify reference integrity can be disabled.
1528
1529                        var params = tests.data.ItemFileWriteStore.getTestData("reference_integrity");
1530                        params.referenceIntegrity = false;
1531                        var store = new dojo.data.ItemFileWriteStore(params);
1532
1533                        var deferred = new doh.Deferred();
1534                        function onError(error, request){
1535                                deferred.errback(error);
1536                                doh.assertTrue(false);
1537                        }
1538                        function onItem(item, request){
1539                                //DO NOT EVER ACCESS THESE VARIABLES LIKE THIS!
1540                                //THIS IS FOR TESTING INTERNAL STATE!
1541                                if(item[store._reverseRefMap] === undefined){
1542                                        deferred.callback(true);
1543                                }else{
1544                                        deferred.errback(new Error("Disabling of reference integrity failed."));
1545                                }
1546                        }
1547                        store.fetchItemByIdentity({identity: 10, onError: onError, onItem: onItem});
1548                        return deferred;
1549                },
1550                function testReadAPI_close_dirty_failure(){
1551                        // summary:
1552                        //              Function to test the close api properly clears the store for reload when clearOnClose is set.
1553                        if (dojo.isBrowser){
1554                                var params = tests.data.readOnlyItemFileTestTemplates.getTestData("countries");
1555                                params.clearOnClose = true;
1556                                params.urlPreventCache = true;
1557                                var store = new dojo.data.ItemFileWriteStore(params);
1558
1559                                var d = new doh.Deferred();
1560                                var onItem = function(item){
1561                                        var error = null;
1562                                        try {
1563                                                doh.assertTrue(item !== null);
1564                                                var ec = item;
1565                                                var val = store.getValue(ec, "name");
1566                                                doh.assertEqual("Ecuador", val);
1567                                                var newItem = store.newItem({abbr: "foo", name: "bar"});
1568
1569                                                //Should throw an error...
1570                                                store.close();
1571                                        }catch (e){
1572                                                error = e;
1573                                        }
1574                                        if (error === null){
1575                                                d.errback(new Error("Store was dirty, should have thrown an error on close!"));
1576                                        }else{
1577                                                d.callback(true);
1578                                        }
1579                                };
1580                                var onError = function(errData){
1581                                        d.errback(errData);
1582                                };
1583                                store.fetchItemByIdentity({identity:"ec", onItem:onItem, onError:onError});
1584                                return d; // Deferred
1585                        }
1586                }
1587        ]
1588);
1589
1590
1591});
Note: See TracBrowser for help on using the repository browser.