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