Bug 1816170 - Disable perftest-on-autoland cron. r=aglavic
[gecko.git] / dom / indexedDB / test / unit / test_indexes.js
bloba19f80ebc75ae3469d22fcb92bcaedd102ecfd53
1 /**
2  * Any copyright is dedicated to the Public Domain.
3  * http://creativecommons.org/publicdomain/zero/1.0/
4  */
6 var testGenerator = testSteps();
8 function* testSteps() {
9   const name = this.window ? window.location.pathname : "Splendid Test";
11   const objectStoreName = "People";
13   const objectStoreData = [
14     { key: "237-23-7732", value: { name: "Bob", height: 60, weight: 120 } },
15     { key: "237-23-7733", value: { name: "Ann", height: 52, weight: 110 } },
16     { key: "237-23-7734", value: { name: "Ron", height: 73, weight: 180 } },
17     { key: "237-23-7735", value: { name: "Sue", height: 58, weight: 130 } },
18     { key: "237-23-7736", value: { name: "Joe", height: 65, weight: 150 } },
19     { key: "237-23-7737", value: { name: "Pat", height: 65 } },
20   ];
22   const indexData = [
23     { name: "name", keyPath: "name", options: { unique: true } },
24     { name: "height", keyPath: "height", options: {} },
25     { name: "weight", keyPath: "weight", options: { unique: false } },
26   ];
28   const objectStoreDataNameSort = [
29     { key: "237-23-7733", value: { name: "Ann", height: 52, weight: 110 } },
30     { key: "237-23-7732", value: { name: "Bob", height: 60, weight: 120 } },
31     { key: "237-23-7736", value: { name: "Joe", height: 65, weight: 150 } },
32     { key: "237-23-7737", value: { name: "Pat", height: 65 } },
33     { key: "237-23-7734", value: { name: "Ron", height: 73, weight: 180 } },
34     { key: "237-23-7735", value: { name: "Sue", height: 58, weight: 130 } },
35   ];
37   const objectStoreDataWeightSort = [
38     { key: "237-23-7733", value: { name: "Ann", height: 52, weight: 110 } },
39     { key: "237-23-7732", value: { name: "Bob", height: 60, weight: 120 } },
40     { key: "237-23-7735", value: { name: "Sue", height: 58, weight: 130 } },
41     { key: "237-23-7736", value: { name: "Joe", height: 65, weight: 150 } },
42     { key: "237-23-7734", value: { name: "Ron", height: 73, weight: 180 } },
43   ];
45   const objectStoreDataHeightSort = [
46     { key: "237-23-7733", value: { name: "Ann", height: 52, weight: 110 } },
47     { key: "237-23-7735", value: { name: "Sue", height: 58, weight: 130 } },
48     { key: "237-23-7732", value: { name: "Bob", height: 60, weight: 120 } },
49     { key: "237-23-7736", value: { name: "Joe", height: 65, weight: 150 } },
50     { key: "237-23-7737", value: { name: "Pat", height: 65 } },
51     { key: "237-23-7734", value: { name: "Ron", height: 73, weight: 180 } },
52   ];
54   let request = indexedDB.open(name, 1);
55   request.onerror = errorHandler;
56   request.onupgradeneeded = grabEventAndContinueHandler;
57   request.onsuccess = grabEventAndContinueHandler;
58   let event = yield undefined;
59   let db = event.target.result;
61   let objectStore = db.createObjectStore(objectStoreName, { keyPath: null });
63   // First, add all our data to the object store.
64   let addedData = 0;
65   for (let i in objectStoreData) {
66     request = objectStore.add(objectStoreData[i].value, objectStoreData[i].key);
67     request.onerror = errorHandler;
68     request.onsuccess = function(event) {
69       if (++addedData == objectStoreData.length) {
70         testGenerator.next(event);
71       }
72     };
73   }
74   event = yield undefined;
75   // Now create the indexes.
76   for (let i in indexData) {
77     objectStore.createIndex(
78       indexData[i].name,
79       indexData[i].keyPath,
80       indexData[i].options
81     );
82   }
83   is(objectStore.indexNames.length, indexData.length, "Good index count");
84   yield undefined;
85   objectStore = db.transaction(objectStoreName).objectStore(objectStoreName);
87   // Check global properties to make sure they are correct.
88   is(objectStore.indexNames.length, indexData.length, "Good index count");
89   for (let i in indexData) {
90     let found = false;
91     for (let j = 0; j < objectStore.indexNames.length; j++) {
92       if (objectStore.indexNames.item(j) == indexData[i].name) {
93         found = true;
94         break;
95       }
96     }
97     is(found, true, "objectStore has our index");
98     let index = objectStore.index(indexData[i].name);
99     is(index.name, indexData[i].name, "Correct name");
100     is(index.objectStore.name, objectStore.name, "Correct store name");
101     is(index.keyPath, indexData[i].keyPath, "Correct keyPath");
102     is(index.unique, !!indexData[i].options.unique, "Correct unique value");
103   }
105   request = objectStore.index("name").getKey("Bob");
106   request.onerror = errorHandler;
107   request.onsuccess = grabEventAndContinueHandler;
108   event = yield undefined;
110   is(event.target.result, "237-23-7732", "Correct key returned!");
112   request = objectStore.index("name").get("Bob");
113   request.onerror = errorHandler;
114   request.onsuccess = grabEventAndContinueHandler;
115   event = yield undefined;
117   is(event.target.result.name, "Bob", "Correct name returned!");
118   is(event.target.result.height, 60, "Correct height returned!");
119   is(event.target.result.weight, 120, "Correct weight returned!");
121   ok(true, "Test group 1");
123   let keyIndex = 0;
125   request = objectStore.index("name").openKeyCursor();
126   request.onerror = errorHandler;
127   request.onsuccess = function(event) {
128     let cursor = event.target.result;
129     if (cursor) {
130       is(
131         cursor.key,
132         objectStoreDataNameSort[keyIndex].value.name,
133         "Correct key"
134       );
135       is(
136         cursor.primaryKey,
137         objectStoreDataNameSort[keyIndex].key,
138         "Correct primary key"
139       );
140       ok(!("value" in cursor), "No value");
142       cursor.continue();
144       is(
145         cursor.key,
146         objectStoreDataNameSort[keyIndex].value.name,
147         "Correct key"
148       );
149       is(
150         cursor.primaryKey,
151         objectStoreDataNameSort[keyIndex].key,
152         "Correct value"
153       );
154       ok(!("value" in cursor), "No value");
156       keyIndex++;
157     } else {
158       testGenerator.next();
159     }
160   };
161   yield undefined;
163   is(keyIndex, objectStoreData.length, "Saw all the expected keys");
165   ok(true, "Test group 2");
167   keyIndex = 0;
169   request = objectStore.index("weight").openKeyCursor(null, "next");
170   request.onerror = errorHandler;
171   request.onsuccess = function(event) {
172     let cursor = event.target.result;
173     if (cursor) {
174       is(
175         cursor.key,
176         objectStoreDataWeightSort[keyIndex].value.weight,
177         "Correct key"
178       );
179       is(
180         cursor.primaryKey,
181         objectStoreDataWeightSort[keyIndex].key,
182         "Correct value"
183       );
185       cursor.continue();
187       is(
188         cursor.key,
189         objectStoreDataWeightSort[keyIndex].value.weight,
190         "Correct key"
191       );
192       is(
193         cursor.primaryKey,
194         objectStoreDataWeightSort[keyIndex].key,
195         "Correct value"
196       );
198       keyIndex++;
199     } else {
200       testGenerator.next();
201     }
202   };
203   yield undefined;
205   is(keyIndex, objectStoreData.length - 1, "Saw all the expected keys");
207   // Check that the name index enforces its unique constraint.
208   objectStore = db
209     .transaction(objectStoreName, "readwrite")
210     .objectStore(objectStoreName);
211   request = objectStore.add(
212     { name: "Bob", height: 62, weight: 170 },
213     "237-23-7738"
214   );
215   request.addEventListener("error", new ExpectError("ConstraintError", true));
216   request.onsuccess = unexpectedSuccessHandler;
217   event = yield undefined;
219   ok(true, "Test group 3");
221   keyIndex = objectStoreDataNameSort.length - 1;
223   request = objectStore.index("name").openKeyCursor(null, "prev");
224   request.onerror = errorHandler;
225   request.onsuccess = function(event) {
226     let cursor = event.target.result;
227     if (cursor) {
228       is(
229         cursor.key,
230         objectStoreDataNameSort[keyIndex].value.name,
231         "Correct key"
232       );
233       is(
234         cursor.primaryKey,
235         objectStoreDataNameSort[keyIndex].key,
236         "Correct value"
237       );
239       cursor.continue();
241       is(
242         cursor.key,
243         objectStoreDataNameSort[keyIndex].value.name,
244         "Correct key"
245       );
246       is(
247         cursor.primaryKey,
248         objectStoreDataNameSort[keyIndex].key,
249         "Correct value"
250       );
252       keyIndex--;
253     } else {
254       testGenerator.next();
255     }
256   };
257   yield undefined;
259   is(keyIndex, -1, "Saw all the expected keys");
261   ok(true, "Test group 4");
263   keyIndex = 1;
264   let keyRange = IDBKeyRange.bound("Bob", "Ron");
266   request = objectStore.index("name").openKeyCursor(keyRange);
267   request.onerror = errorHandler;
268   request.onsuccess = function(event) {
269     let cursor = event.target.result;
270     if (cursor) {
271       is(
272         cursor.key,
273         objectStoreDataNameSort[keyIndex].value.name,
274         "Correct key"
275       );
276       is(
277         cursor.primaryKey,
278         objectStoreDataNameSort[keyIndex].key,
279         "Correct value"
280       );
282       cursor.continue();
283       keyIndex++;
284     } else {
285       testGenerator.next();
286     }
287   };
288   yield undefined;
290   is(keyIndex, 5, "Saw all the expected keys");
292   ok(true, "Test group 5");
294   keyIndex = 2;
295   keyRange = IDBKeyRange.bound("Bob", "Ron", true);
297   request = objectStore.index("name").openKeyCursor(keyRange);
298   request.onerror = errorHandler;
299   request.onsuccess = function(event) {
300     let cursor = event.target.result;
301     if (cursor) {
302       is(
303         cursor.key,
304         objectStoreDataNameSort[keyIndex].value.name,
305         "Correct key"
306       );
307       is(
308         cursor.primaryKey,
309         objectStoreDataNameSort[keyIndex].key,
310         "Correct value"
311       );
313       cursor.continue();
314       keyIndex++;
315     } else {
316       testGenerator.next();
317     }
318   };
319   yield undefined;
321   is(keyIndex, 5, "Saw all the expected keys");
323   ok(true, "Test group 6");
325   keyIndex = 1;
326   keyRange = IDBKeyRange.bound("Bob", "Ron", false, true);
328   request = objectStore.index("name").openKeyCursor(keyRange);
329   request.onerror = errorHandler;
330   request.onsuccess = function(event) {
331     let cursor = event.target.result;
332     if (cursor) {
333       is(
334         cursor.key,
335         objectStoreDataNameSort[keyIndex].value.name,
336         "Correct key"
337       );
338       is(
339         cursor.primaryKey,
340         objectStoreDataNameSort[keyIndex].key,
341         "Correct value"
342       );
344       cursor.continue();
345       keyIndex++;
346     } else {
347       testGenerator.next();
348     }
349   };
350   yield undefined;
352   is(keyIndex, 4, "Saw all the expected keys");
354   ok(true, "Test group 7");
356   keyIndex = 2;
357   keyRange = IDBKeyRange.bound("Bob", "Ron", true, true);
359   request = objectStore.index("name").openKeyCursor(keyRange);
360   request.onerror = errorHandler;
361   request.onsuccess = function(event) {
362     let cursor = event.target.result;
363     if (cursor) {
364       is(
365         cursor.key,
366         objectStoreDataNameSort[keyIndex].value.name,
367         "Correct key"
368       );
369       is(
370         cursor.primaryKey,
371         objectStoreDataNameSort[keyIndex].key,
372         "Correct value"
373       );
375       cursor.continue();
376       keyIndex++;
377     } else {
378       testGenerator.next();
379     }
380   };
381   yield undefined;
383   is(keyIndex, 4, "Saw all the expected keys");
385   ok(true, "Test group 8");
387   keyIndex = 1;
388   keyRange = IDBKeyRange.lowerBound("Bob");
390   request = objectStore.index("name").openKeyCursor(keyRange);
391   request.onerror = errorHandler;
392   request.onsuccess = function(event) {
393     let cursor = event.target.result;
394     if (cursor) {
395       is(
396         cursor.key,
397         objectStoreDataNameSort[keyIndex].value.name,
398         "Correct key"
399       );
400       is(
401         cursor.primaryKey,
402         objectStoreDataNameSort[keyIndex].key,
403         "Correct value"
404       );
406       cursor.continue();
407       keyIndex++;
408     } else {
409       testGenerator.next();
410     }
411   };
412   yield undefined;
414   is(keyIndex, objectStoreDataNameSort.length, "Saw all the expected keys");
416   ok(true, "Test group 9");
418   keyIndex = 2;
419   keyRange = IDBKeyRange.lowerBound("Bob", true);
421   request = objectStore.index("name").openKeyCursor(keyRange);
422   request.onerror = errorHandler;
423   request.onsuccess = function(event) {
424     let cursor = event.target.result;
425     if (cursor) {
426       is(
427         cursor.key,
428         objectStoreDataNameSort[keyIndex].value.name,
429         "Correct key"
430       );
431       is(
432         cursor.primaryKey,
433         objectStoreDataNameSort[keyIndex].key,
434         "Correct value"
435       );
437       cursor.continue();
438       keyIndex++;
439     } else {
440       testGenerator.next();
441     }
442   };
443   yield undefined;
445   is(keyIndex, objectStoreDataNameSort.length, "Saw all the expected keys");
447   ok(true, "Test group 10");
449   keyIndex = 0;
450   keyRange = IDBKeyRange.upperBound("Joe");
452   request = objectStore.index("name").openKeyCursor(keyRange);
453   request.onerror = errorHandler;
454   request.onsuccess = function(event) {
455     let cursor = event.target.result;
456     if (cursor) {
457       is(
458         cursor.key,
459         objectStoreDataNameSort[keyIndex].value.name,
460         "Correct key"
461       );
462       is(
463         cursor.primaryKey,
464         objectStoreDataNameSort[keyIndex].key,
465         "Correct value"
466       );
468       cursor.continue();
469       keyIndex++;
470     } else {
471       testGenerator.next();
472     }
473   };
474   yield undefined;
476   is(keyIndex, 3, "Saw all the expected keys");
478   ok(true, "Test group 11");
480   keyIndex = 0;
481   keyRange = IDBKeyRange.upperBound("Joe", true);
483   request = objectStore.index("name").openKeyCursor(keyRange);
484   request.onerror = errorHandler;
485   request.onsuccess = function(event) {
486     let cursor = event.target.result;
487     if (cursor) {
488       is(
489         cursor.key,
490         objectStoreDataNameSort[keyIndex].value.name,
491         "Correct key"
492       );
493       is(
494         cursor.primaryKey,
495         objectStoreDataNameSort[keyIndex].key,
496         "Correct value"
497       );
499       cursor.continue();
500       keyIndex++;
501     } else {
502       testGenerator.next();
503     }
504   };
505   yield undefined;
507   is(keyIndex, 2, "Saw all the expected keys");
509   ok(true, "Test group 12");
511   keyIndex = 3;
512   keyRange = IDBKeyRange.only("Pat");
514   request = objectStore.index("name").openKeyCursor(keyRange);
515   request.onerror = errorHandler;
516   request.onsuccess = function(event) {
517     let cursor = event.target.result;
518     if (cursor) {
519       is(
520         cursor.key,
521         objectStoreDataNameSort[keyIndex].value.name,
522         "Correct key"
523       );
524       is(
525         cursor.primaryKey,
526         objectStoreDataNameSort[keyIndex].key,
527         "Correct value"
528       );
530       cursor.continue();
531       keyIndex++;
532     } else {
533       testGenerator.next();
534     }
535   };
536   yield undefined;
538   is(keyIndex, 4, "Saw all the expected keys");
540   ok(true, "Test group 13");
542   keyIndex = 0;
544   request = objectStore.index("name").openCursor();
545   request.onerror = errorHandler;
546   request.onsuccess = function(event) {
547     let cursor = event.target.result;
548     if (cursor) {
549       is(
550         cursor.key,
551         objectStoreDataNameSort[keyIndex].value.name,
552         "Correct key"
553       );
554       is(
555         cursor.primaryKey,
556         objectStoreDataNameSort[keyIndex].key,
557         "Correct primary key"
558       );
559       is(
560         cursor.value.name,
561         objectStoreDataNameSort[keyIndex].value.name,
562         "Correct name"
563       );
564       is(
565         cursor.value.height,
566         objectStoreDataNameSort[keyIndex].value.height,
567         "Correct height"
568       );
569       if ("weight" in cursor.value) {
570         is(
571           cursor.value.weight,
572           objectStoreDataNameSort[keyIndex].value.weight,
573           "Correct weight"
574         );
575       }
577       cursor.continue();
579       is(
580         cursor.key,
581         objectStoreDataNameSort[keyIndex].value.name,
582         "Correct key"
583       );
584       is(
585         cursor.primaryKey,
586         objectStoreDataNameSort[keyIndex].key,
587         "Correct primary key"
588       );
589       is(
590         cursor.value.name,
591         objectStoreDataNameSort[keyIndex].value.name,
592         "Correct name"
593       );
594       is(
595         cursor.value.height,
596         objectStoreDataNameSort[keyIndex].value.height,
597         "Correct height"
598       );
599       if ("weight" in cursor.value) {
600         is(
601           cursor.value.weight,
602           objectStoreDataNameSort[keyIndex].value.weight,
603           "Correct weight"
604         );
605       }
607       keyIndex++;
608     } else {
609       testGenerator.next();
610     }
611   };
612   yield undefined;
614   is(keyIndex, objectStoreDataNameSort.length, "Saw all the expected keys");
616   ok(true, "Test group 14");
618   keyIndex = objectStoreDataNameSort.length - 1;
620   request = objectStore.index("name").openCursor(null, "prev");
621   request.onerror = errorHandler;
622   request.onsuccess = function(event) {
623     let cursor = event.target.result;
624     if (cursor) {
625       is(
626         cursor.key,
627         objectStoreDataNameSort[keyIndex].value.name,
628         "Correct key"
629       );
630       is(
631         cursor.primaryKey,
632         objectStoreDataNameSort[keyIndex].key,
633         "Correct primary key"
634       );
635       is(
636         cursor.value.name,
637         objectStoreDataNameSort[keyIndex].value.name,
638         "Correct name"
639       );
640       is(
641         cursor.value.height,
642         objectStoreDataNameSort[keyIndex].value.height,
643         "Correct height"
644       );
645       if ("weight" in cursor.value) {
646         is(
647           cursor.value.weight,
648           objectStoreDataNameSort[keyIndex].value.weight,
649           "Correct weight"
650         );
651       }
653       cursor.continue();
655       is(
656         cursor.key,
657         objectStoreDataNameSort[keyIndex].value.name,
658         "Correct key"
659       );
660       is(
661         cursor.primaryKey,
662         objectStoreDataNameSort[keyIndex].key,
663         "Correct primary key"
664       );
665       is(
666         cursor.value.name,
667         objectStoreDataNameSort[keyIndex].value.name,
668         "Correct name"
669       );
670       is(
671         cursor.value.height,
672         objectStoreDataNameSort[keyIndex].value.height,
673         "Correct height"
674       );
675       if ("weight" in cursor.value) {
676         is(
677           cursor.value.weight,
678           objectStoreDataNameSort[keyIndex].value.weight,
679           "Correct weight"
680         );
681       }
683       keyIndex--;
684     } else {
685       testGenerator.next();
686     }
687   };
688   yield undefined;
690   is(keyIndex, -1, "Saw all the expected keys");
692   ok(true, "Test group 15");
694   keyIndex = 1;
695   keyRange = IDBKeyRange.bound("Bob", "Ron");
697   request = objectStore.index("name").openCursor(keyRange);
698   request.onerror = errorHandler;
699   request.onsuccess = function(event) {
700     let cursor = event.target.result;
701     if (cursor) {
702       is(
703         cursor.key,
704         objectStoreDataNameSort[keyIndex].value.name,
705         "Correct key"
706       );
707       is(
708         cursor.primaryKey,
709         objectStoreDataNameSort[keyIndex].key,
710         "Correct primary key"
711       );
712       is(
713         cursor.value.name,
714         objectStoreDataNameSort[keyIndex].value.name,
715         "Correct name"
716       );
717       is(
718         cursor.value.height,
719         objectStoreDataNameSort[keyIndex].value.height,
720         "Correct height"
721       );
722       if ("weight" in cursor.value) {
723         is(
724           cursor.value.weight,
725           objectStoreDataNameSort[keyIndex].value.weight,
726           "Correct weight"
727         );
728       }
730       cursor.continue();
732       is(
733         cursor.key,
734         objectStoreDataNameSort[keyIndex].value.name,
735         "Correct key"
736       );
737       is(
738         cursor.primaryKey,
739         objectStoreDataNameSort[keyIndex].key,
740         "Correct primary key"
741       );
742       is(
743         cursor.value.name,
744         objectStoreDataNameSort[keyIndex].value.name,
745         "Correct name"
746       );
747       is(
748         cursor.value.height,
749         objectStoreDataNameSort[keyIndex].value.height,
750         "Correct height"
751       );
752       if ("weight" in cursor.value) {
753         is(
754           cursor.value.weight,
755           objectStoreDataNameSort[keyIndex].value.weight,
756           "Correct weight"
757         );
758       }
760       keyIndex++;
761     } else {
762       testGenerator.next();
763     }
764   };
765   yield undefined;
767   is(keyIndex, 5, "Saw all the expected keys");
769   ok(true, "Test group 16");
771   keyIndex = 2;
772   keyRange = IDBKeyRange.bound("Bob", "Ron", true);
774   request = objectStore.index("name").openCursor(keyRange);
775   request.onerror = errorHandler;
776   request.onsuccess = function(event) {
777     let cursor = event.target.result;
778     if (cursor) {
779       is(
780         cursor.key,
781         objectStoreDataNameSort[keyIndex].value.name,
782         "Correct key"
783       );
784       is(
785         cursor.primaryKey,
786         objectStoreDataNameSort[keyIndex].key,
787         "Correct primary key"
788       );
789       is(
790         cursor.value.name,
791         objectStoreDataNameSort[keyIndex].value.name,
792         "Correct name"
793       );
794       is(
795         cursor.value.height,
796         objectStoreDataNameSort[keyIndex].value.height,
797         "Correct height"
798       );
799       if ("weight" in cursor.value) {
800         is(
801           cursor.value.weight,
802           objectStoreDataNameSort[keyIndex].value.weight,
803           "Correct weight"
804         );
805       }
807       cursor.continue();
809       is(
810         cursor.key,
811         objectStoreDataNameSort[keyIndex].value.name,
812         "Correct key"
813       );
814       is(
815         cursor.primaryKey,
816         objectStoreDataNameSort[keyIndex].key,
817         "Correct primary key"
818       );
819       is(
820         cursor.value.name,
821         objectStoreDataNameSort[keyIndex].value.name,
822         "Correct name"
823       );
824       is(
825         cursor.value.height,
826         objectStoreDataNameSort[keyIndex].value.height,
827         "Correct height"
828       );
829       if ("weight" in cursor.value) {
830         is(
831           cursor.value.weight,
832           objectStoreDataNameSort[keyIndex].value.weight,
833           "Correct weight"
834         );
835       }
837       keyIndex++;
838     } else {
839       testGenerator.next();
840     }
841   };
842   yield undefined;
844   is(keyIndex, 5, "Saw all the expected keys");
846   ok(true, "Test group 17");
848   keyIndex = 1;
849   keyRange = IDBKeyRange.bound("Bob", "Ron", false, true);
851   request = objectStore.index("name").openCursor(keyRange);
852   request.onerror = errorHandler;
853   request.onsuccess = function(event) {
854     let cursor = event.target.result;
855     if (cursor) {
856       is(
857         cursor.key,
858         objectStoreDataNameSort[keyIndex].value.name,
859         "Correct key"
860       );
861       is(
862         cursor.primaryKey,
863         objectStoreDataNameSort[keyIndex].key,
864         "Correct primary key"
865       );
866       is(
867         cursor.value.name,
868         objectStoreDataNameSort[keyIndex].value.name,
869         "Correct name"
870       );
871       is(
872         cursor.value.height,
873         objectStoreDataNameSort[keyIndex].value.height,
874         "Correct height"
875       );
876       if ("weight" in cursor.value) {
877         is(
878           cursor.value.weight,
879           objectStoreDataNameSort[keyIndex].value.weight,
880           "Correct weight"
881         );
882       }
884       cursor.continue();
886       is(
887         cursor.key,
888         objectStoreDataNameSort[keyIndex].value.name,
889         "Correct key"
890       );
891       is(
892         cursor.primaryKey,
893         objectStoreDataNameSort[keyIndex].key,
894         "Correct primary key"
895       );
896       is(
897         cursor.value.name,
898         objectStoreDataNameSort[keyIndex].value.name,
899         "Correct name"
900       );
901       is(
902         cursor.value.height,
903         objectStoreDataNameSort[keyIndex].value.height,
904         "Correct height"
905       );
906       if ("weight" in cursor.value) {
907         is(
908           cursor.value.weight,
909           objectStoreDataNameSort[keyIndex].value.weight,
910           "Correct weight"
911         );
912       }
914       keyIndex++;
915     } else {
916       testGenerator.next();
917     }
918   };
919   yield undefined;
921   is(keyIndex, 4, "Saw all the expected keys");
923   ok(true, "Test group 18");
925   keyIndex = 2;
926   keyRange = IDBKeyRange.bound("Bob", "Ron", true, true);
928   request = objectStore.index("name").openCursor(keyRange);
929   request.onerror = errorHandler;
930   request.onsuccess = function(event) {
931     let cursor = event.target.result;
932     if (cursor) {
933       is(
934         cursor.key,
935         objectStoreDataNameSort[keyIndex].value.name,
936         "Correct key"
937       );
938       is(
939         cursor.primaryKey,
940         objectStoreDataNameSort[keyIndex].key,
941         "Correct primary key"
942       );
943       is(
944         cursor.value.name,
945         objectStoreDataNameSort[keyIndex].value.name,
946         "Correct name"
947       );
948       is(
949         cursor.value.height,
950         objectStoreDataNameSort[keyIndex].value.height,
951         "Correct height"
952       );
953       if ("weight" in cursor.value) {
954         is(
955           cursor.value.weight,
956           objectStoreDataNameSort[keyIndex].value.weight,
957           "Correct weight"
958         );
959       }
961       cursor.continue();
963       is(
964         cursor.key,
965         objectStoreDataNameSort[keyIndex].value.name,
966         "Correct key"
967       );
968       is(
969         cursor.primaryKey,
970         objectStoreDataNameSort[keyIndex].key,
971         "Correct primary key"
972       );
973       is(
974         cursor.value.name,
975         objectStoreDataNameSort[keyIndex].value.name,
976         "Correct name"
977       );
978       is(
979         cursor.value.height,
980         objectStoreDataNameSort[keyIndex].value.height,
981         "Correct height"
982       );
983       if ("weight" in cursor.value) {
984         is(
985           cursor.value.weight,
986           objectStoreDataNameSort[keyIndex].value.weight,
987           "Correct weight"
988         );
989       }
991       keyIndex++;
992     } else {
993       testGenerator.next();
994     }
995   };
996   yield undefined;
998   is(keyIndex, 4, "Saw all the expected keys");
1000   ok(true, "Test group 19");
1002   keyIndex = 4;
1003   keyRange = IDBKeyRange.bound("Bob", "Ron");
1005   request = objectStore.index("name").openCursor(keyRange, "prev");
1006   request.onerror = errorHandler;
1007   request.onsuccess = function(event) {
1008     let cursor = event.target.result;
1009     if (cursor) {
1010       is(
1011         cursor.key,
1012         objectStoreDataNameSort[keyIndex].value.name,
1013         "Correct key"
1014       );
1015       is(
1016         cursor.primaryKey,
1017         objectStoreDataNameSort[keyIndex].key,
1018         "Correct primary key"
1019       );
1020       is(
1021         cursor.value.name,
1022         objectStoreDataNameSort[keyIndex].value.name,
1023         "Correct name"
1024       );
1025       is(
1026         cursor.value.height,
1027         objectStoreDataNameSort[keyIndex].value.height,
1028         "Correct height"
1029       );
1030       if ("weight" in cursor.value) {
1031         is(
1032           cursor.value.weight,
1033           objectStoreDataNameSort[keyIndex].value.weight,
1034           "Correct weight"
1035         );
1036       }
1038       cursor.continue();
1040       is(
1041         cursor.key,
1042         objectStoreDataNameSort[keyIndex].value.name,
1043         "Correct key"
1044       );
1045       is(
1046         cursor.primaryKey,
1047         objectStoreDataNameSort[keyIndex].key,
1048         "Correct primary key"
1049       );
1050       is(
1051         cursor.value.name,
1052         objectStoreDataNameSort[keyIndex].value.name,
1053         "Correct name"
1054       );
1055       is(
1056         cursor.value.height,
1057         objectStoreDataNameSort[keyIndex].value.height,
1058         "Correct height"
1059       );
1060       if ("weight" in cursor.value) {
1061         is(
1062           cursor.value.weight,
1063           objectStoreDataNameSort[keyIndex].value.weight,
1064           "Correct weight"
1065         );
1066       }
1068       keyIndex--;
1069     } else {
1070       testGenerator.next();
1071     }
1072   };
1073   yield undefined;
1075   is(keyIndex, 0, "Saw all the expected keys");
1077   ok(true, "Test group 20");
1079   // Test "nextunique"
1080   keyIndex = 3;
1081   keyRange = IDBKeyRange.only(65);
1083   request = objectStore.index("height").openKeyCursor(keyRange, "next");
1084   request.onerror = errorHandler;
1085   request.onsuccess = function(event) {
1086     let cursor = event.target.result;
1087     if (cursor) {
1088       is(
1089         cursor.key,
1090         objectStoreDataHeightSort[keyIndex].value.height,
1091         "Correct key"
1092       );
1093       is(
1094         cursor.primaryKey,
1095         objectStoreDataHeightSort[keyIndex].key,
1096         "Correct value"
1097       );
1099       cursor.continue();
1100       keyIndex++;
1101     } else {
1102       testGenerator.next();
1103     }
1104   };
1105   yield undefined;
1107   is(keyIndex, 5, "Saw all the expected keys");
1109   ok(true, "Test group 21");
1111   keyIndex = 3;
1112   keyRange = IDBKeyRange.only(65);
1114   request = objectStore.index("height").openKeyCursor(keyRange, "nextunique");
1115   request.onerror = errorHandler;
1116   request.onsuccess = function(event) {
1117     let cursor = event.target.result;
1118     if (cursor) {
1119       is(
1120         cursor.key,
1121         objectStoreDataHeightSort[keyIndex].value.height,
1122         "Correct key"
1123       );
1124       is(
1125         cursor.primaryKey,
1126         objectStoreDataHeightSort[keyIndex].key,
1127         "Correct value"
1128       );
1130       cursor.continue();
1131       keyIndex++;
1132     } else {
1133       testGenerator.next();
1134     }
1135   };
1136   yield undefined;
1138   is(keyIndex, 4, "Saw all the expected keys");
1140   ok(true, "Test group 21.5");
1142   keyIndex = 5;
1144   request = objectStore.index("height").openKeyCursor(null, "prev");
1145   request.onerror = errorHandler;
1146   request.onsuccess = function(event) {
1147     let cursor = event.target.result;
1148     if (cursor) {
1149       is(
1150         cursor.key,
1151         objectStoreDataHeightSort[keyIndex].value.height,
1152         "Correct key"
1153       );
1154       is(
1155         cursor.primaryKey,
1156         objectStoreDataHeightSort[keyIndex].key,
1157         "Correct value"
1158       );
1160       cursor.continue();
1161       keyIndex--;
1162     } else {
1163       testGenerator.next();
1164     }
1165   };
1166   yield undefined;
1168   is(keyIndex, -1, "Saw all the expected keys");
1170   ok(true, "Test group 22");
1172   keyIndex = 5;
1174   request = objectStore.index("height").openKeyCursor(null, "prevunique");
1175   request.onerror = errorHandler;
1176   request.onsuccess = function(event) {
1177     let cursor = event.target.result;
1178     if (cursor) {
1179       is(
1180         cursor.key,
1181         objectStoreDataHeightSort[keyIndex].value.height,
1182         "Correct key"
1183       );
1184       is(
1185         cursor.primaryKey,
1186         objectStoreDataHeightSort[keyIndex].key,
1187         "Correct value"
1188       );
1190       cursor.continue();
1191       if (keyIndex == 5) {
1192         keyIndex--;
1193       }
1194       keyIndex--;
1195     } else {
1196       testGenerator.next();
1197     }
1198   };
1199   yield undefined;
1201   is(keyIndex, -1, "Saw all the expected keys");
1203   ok(true, "Test group 23");
1205   keyIndex = 3;
1206   keyRange = IDBKeyRange.only(65);
1208   request = objectStore.index("height").openCursor(keyRange, "next");
1209   request.onerror = errorHandler;
1210   request.onsuccess = function(event) {
1211     let cursor = event.target.result;
1212     if (cursor) {
1213       is(
1214         cursor.key,
1215         objectStoreDataHeightSort[keyIndex].value.height,
1216         "Correct key"
1217       );
1218       is(
1219         cursor.primaryKey,
1220         objectStoreDataHeightSort[keyIndex].key,
1221         "Correct primary key"
1222       );
1223       is(
1224         cursor.value.name,
1225         objectStoreDataHeightSort[keyIndex].value.name,
1226         "Correct name"
1227       );
1228       is(
1229         cursor.value.height,
1230         objectStoreDataHeightSort[keyIndex].value.height,
1231         "Correct height"
1232       );
1233       if ("weight" in cursor.value) {
1234         is(
1235           cursor.value.weight,
1236           objectStoreDataHeightSort[keyIndex].value.weight,
1237           "Correct weight"
1238         );
1239       }
1241       cursor.continue();
1242       keyIndex++;
1243     } else {
1244       testGenerator.next();
1245     }
1246   };
1247   yield undefined;
1249   is(keyIndex, 5, "Saw all the expected keys");
1251   ok(true, "Test group 24");
1253   keyIndex = 3;
1254   keyRange = IDBKeyRange.only(65);
1256   request = objectStore.index("height").openCursor(keyRange, "nextunique");
1257   request.onerror = errorHandler;
1258   request.onsuccess = function(event) {
1259     let cursor = event.target.result;
1260     if (cursor) {
1261       is(
1262         cursor.key,
1263         objectStoreDataHeightSort[keyIndex].value.height,
1264         "Correct key"
1265       );
1266       is(
1267         cursor.primaryKey,
1268         objectStoreDataHeightSort[keyIndex].key,
1269         "Correct primary key"
1270       );
1271       is(
1272         cursor.value.name,
1273         objectStoreDataHeightSort[keyIndex].value.name,
1274         "Correct name"
1275       );
1276       is(
1277         cursor.value.height,
1278         objectStoreDataHeightSort[keyIndex].value.height,
1279         "Correct height"
1280       );
1281       if ("weight" in cursor.value) {
1282         is(
1283           cursor.value.weight,
1284           objectStoreDataHeightSort[keyIndex].value.weight,
1285           "Correct weight"
1286         );
1287       }
1289       cursor.continue();
1290       keyIndex++;
1291     } else {
1292       testGenerator.next();
1293     }
1294   };
1295   yield undefined;
1297   is(keyIndex, 4, "Saw all the expected keys");
1299   ok(true, "Test group 24.5");
1301   keyIndex = 5;
1303   request = objectStore.index("height").openCursor(null, "prev");
1304   request.onerror = errorHandler;
1305   request.onsuccess = function(event) {
1306     let cursor = event.target.result;
1307     if (cursor) {
1308       is(
1309         cursor.key,
1310         objectStoreDataHeightSort[keyIndex].value.height,
1311         "Correct key"
1312       );
1313       is(
1314         cursor.primaryKey,
1315         objectStoreDataHeightSort[keyIndex].key,
1316         "Correct primary key"
1317       );
1318       is(
1319         cursor.value.name,
1320         objectStoreDataHeightSort[keyIndex].value.name,
1321         "Correct name"
1322       );
1323       is(
1324         cursor.value.height,
1325         objectStoreDataHeightSort[keyIndex].value.height,
1326         "Correct height"
1327       );
1328       if ("weight" in cursor.value) {
1329         is(
1330           cursor.value.weight,
1331           objectStoreDataHeightSort[keyIndex].value.weight,
1332           "Correct weight"
1333         );
1334       }
1336       cursor.continue();
1337       keyIndex--;
1338     } else {
1339       testGenerator.next();
1340     }
1341   };
1342   yield undefined;
1344   is(keyIndex, -1, "Saw all the expected keys");
1346   ok(true, "Test group 25");
1348   keyIndex = 5;
1350   request = objectStore.index("height").openCursor(null, "prevunique");
1351   request.onerror = errorHandler;
1352   request.onsuccess = function(event) {
1353     let cursor = event.target.result;
1354     if (cursor) {
1355       is(
1356         cursor.key,
1357         objectStoreDataHeightSort[keyIndex].value.height,
1358         "Correct key"
1359       );
1360       is(
1361         cursor.primaryKey,
1362         objectStoreDataHeightSort[keyIndex].key,
1363         "Correct primary key"
1364       );
1365       is(
1366         cursor.value.name,
1367         objectStoreDataHeightSort[keyIndex].value.name,
1368         "Correct name"
1369       );
1370       is(
1371         cursor.value.height,
1372         objectStoreDataHeightSort[keyIndex].value.height,
1373         "Correct height"
1374       );
1375       if ("weight" in cursor.value) {
1376         is(
1377           cursor.value.weight,
1378           objectStoreDataHeightSort[keyIndex].value.weight,
1379           "Correct weight"
1380         );
1381       }
1383       cursor.continue();
1384       if (keyIndex == 5) {
1385         keyIndex--;
1386       }
1387       keyIndex--;
1388     } else {
1389       testGenerator.next();
1390     }
1391   };
1392   yield undefined;
1394   is(keyIndex, -1, "Saw all the expected keys");
1396   ok(true, "Test group 26");
1398   keyIndex = 0;
1400   request = objectStore.index("name").openKeyCursor();
1401   request.onerror = errorHandler;
1402   request.onsuccess = function(event) {
1403     let cursor = event.target.result;
1404     if (cursor) {
1405       is(
1406         cursor.key,
1407         objectStoreDataNameSort[keyIndex].value.name,
1408         "Correct key"
1409       );
1410       is(
1411         cursor.primaryKey,
1412         objectStoreDataNameSort[keyIndex].key,
1413         "Correct value"
1414       );
1416       let nextKey = !keyIndex ? "Pat" : undefined;
1418       cursor.continue(nextKey);
1420       is(
1421         cursor.key,
1422         objectStoreDataNameSort[keyIndex].value.name,
1423         "Correct key"
1424       );
1425       is(
1426         cursor.primaryKey,
1427         objectStoreDataNameSort[keyIndex].key,
1428         "Correct value"
1429       );
1431       if (!keyIndex) {
1432         keyIndex = 3;
1433       } else {
1434         keyIndex++;
1435       }
1436     } else {
1437       testGenerator.next();
1438     }
1439   };
1440   yield undefined;
1442   is(keyIndex, objectStoreData.length, "Saw all the expected keys");
1444   ok(true, "Test group 27");
1446   keyIndex = 0;
1448   request = objectStore.index("name").openKeyCursor();
1449   request.onerror = errorHandler;
1450   request.onsuccess = function(event) {
1451     let cursor = event.target.result;
1452     if (cursor) {
1453       is(
1454         cursor.key,
1455         objectStoreDataNameSort[keyIndex].value.name,
1456         "Correct key"
1457       );
1458       is(
1459         cursor.primaryKey,
1460         objectStoreDataNameSort[keyIndex].key,
1461         "Correct value"
1462       );
1464       let nextKey = !keyIndex ? "Flo" : undefined;
1466       cursor.continue(nextKey);
1468       is(
1469         cursor.key,
1470         objectStoreDataNameSort[keyIndex].value.name,
1471         "Correct key"
1472       );
1473       is(
1474         cursor.primaryKey,
1475         objectStoreDataNameSort[keyIndex].key,
1476         "Correct value"
1477       );
1479       keyIndex += keyIndex ? 1 : 2;
1480     } else {
1481       testGenerator.next();
1482     }
1483   };
1484   yield undefined;
1486   is(keyIndex, objectStoreData.length, "Saw all the expected keys");
1488   ok(true, "Test group 28");
1490   keyIndex = 0;
1492   request = objectStore.index("name").openCursor();
1493   request.onerror = errorHandler;
1494   request.onsuccess = function(event) {
1495     let cursor = event.target.result;
1496     if (cursor) {
1497       is(
1498         cursor.key,
1499         objectStoreDataNameSort[keyIndex].value.name,
1500         "Correct key"
1501       );
1502       is(
1503         cursor.primaryKey,
1504         objectStoreDataNameSort[keyIndex].key,
1505         "Correct primary key"
1506       );
1507       is(
1508         cursor.value.name,
1509         objectStoreDataNameSort[keyIndex].value.name,
1510         "Correct name"
1511       );
1512       is(
1513         cursor.value.height,
1514         objectStoreDataNameSort[keyIndex].value.height,
1515         "Correct height"
1516       );
1517       if ("weight" in cursor.value) {
1518         is(
1519           cursor.value.weight,
1520           objectStoreDataNameSort[keyIndex].value.weight,
1521           "Correct weight"
1522         );
1523       }
1525       let nextKey = !keyIndex ? "Pat" : undefined;
1527       cursor.continue(nextKey);
1529       is(
1530         cursor.key,
1531         objectStoreDataNameSort[keyIndex].value.name,
1532         "Correct key"
1533       );
1534       is(
1535         cursor.primaryKey,
1536         objectStoreDataNameSort[keyIndex].key,
1537         "Correct primary key"
1538       );
1539       is(
1540         cursor.value.name,
1541         objectStoreDataNameSort[keyIndex].value.name,
1542         "Correct name"
1543       );
1544       is(
1545         cursor.value.height,
1546         objectStoreDataNameSort[keyIndex].value.height,
1547         "Correct height"
1548       );
1549       if ("weight" in cursor.value) {
1550         is(
1551           cursor.value.weight,
1552           objectStoreDataNameSort[keyIndex].value.weight,
1553           "Correct weight"
1554         );
1555       }
1557       if (!keyIndex) {
1558         keyIndex = 3;
1559       } else {
1560         keyIndex++;
1561       }
1562     } else {
1563       testGenerator.next();
1564     }
1565   };
1566   yield undefined;
1568   is(keyIndex, objectStoreDataNameSort.length, "Saw all the expected keys");
1570   ok(true, "Test group 29");
1572   keyIndex = 0;
1574   request = objectStore.index("name").openCursor();
1575   request.onerror = errorHandler;
1576   request.onsuccess = function(event) {
1577     let cursor = event.target.result;
1578     if (cursor) {
1579       is(
1580         cursor.key,
1581         objectStoreDataNameSort[keyIndex].value.name,
1582         "Correct key"
1583       );
1584       is(
1585         cursor.primaryKey,
1586         objectStoreDataNameSort[keyIndex].key,
1587         "Correct primary key"
1588       );
1589       is(
1590         cursor.value.name,
1591         objectStoreDataNameSort[keyIndex].value.name,
1592         "Correct name"
1593       );
1594       is(
1595         cursor.value.height,
1596         objectStoreDataNameSort[keyIndex].value.height,
1597         "Correct height"
1598       );
1599       if ("weight" in cursor.value) {
1600         is(
1601           cursor.value.weight,
1602           objectStoreDataNameSort[keyIndex].value.weight,
1603           "Correct weight"
1604         );
1605       }
1607       let nextKey = !keyIndex ? "Flo" : undefined;
1609       cursor.continue(nextKey);
1611       is(
1612         cursor.key,
1613         objectStoreDataNameSort[keyIndex].value.name,
1614         "Correct key"
1615       );
1616       is(
1617         cursor.primaryKey,
1618         objectStoreDataNameSort[keyIndex].key,
1619         "Correct primary key"
1620       );
1621       is(
1622         cursor.value.name,
1623         objectStoreDataNameSort[keyIndex].value.name,
1624         "Correct name"
1625       );
1626       is(
1627         cursor.value.height,
1628         objectStoreDataNameSort[keyIndex].value.height,
1629         "Correct height"
1630       );
1631       if ("weight" in cursor.value) {
1632         is(
1633           cursor.value.weight,
1634           objectStoreDataNameSort[keyIndex].value.weight,
1635           "Correct weight"
1636         );
1637       }
1639       keyIndex += keyIndex ? 1 : 2;
1640     } else {
1641       testGenerator.next();
1642     }
1643   };
1644   yield undefined;
1646   is(keyIndex, objectStoreDataNameSort.length, "Saw all the expected keys");
1648   finishTest();