dom/indexedDB/test/test_multientry.html
author Jonas Sicking <jonas@sicking.cc>
Sun, 04 Dec 2011 09:39:01 -0800
changeset 81995 0de28e40259f83d5e29613f6a7946ff3147e81c7
parent 81806 513428a937004e6de2abdffefb18339a8c6e4c5f
child 84417 4dd520a2dab09603a51919908379e89bdf0b9226
permissions -rw-r--r--
Bug 692630: Support multi-entry indexes. r=bent

<!--
  Any copyright is dedicated to the Public Domain.
  http://creativecommons.org/publicdomain/zero/1.0/
-->
<html>
<head>
  <title>Indexed Database Property Test</title>

  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>

  <script type="text/javascript;version=1.7">
    function testSteps()
    {
      // Test object stores

      let openRequest = mozIndexedDB.open(window.location.pathname, 1);
      openRequest.onerror = errorHandler;
      openRequest.onupgradeneeded = grabEventAndContinueHandler;
      openRequest.onsuccess = unexpectedSuccessHandler;
      let event = yield;
      let db = event.target.result;
      db.onerror = errorHandler;
      let tests =
        [{ add:     { x: 1, id: 1 },
           indexes:[{ v: 1, k: 1 }] },
         { add:     { x: [2, 3], id: 2 },
           indexes:[{ v: 1, k: 1 },
                    { v: 2, k: 2 },
                    { v: 3, k: 2 }] },
         { put:     { x: [2, 4], id: 1 },
           indexes:[{ v: 2, k: 1 },
                    { v: 2, k: 2 },
                    { v: 3, k: 2 },
                    { v: 4, k: 1 }] },
         { add:     { x: [5, 6, 5, -2, 3], id: 3 },
           indexes:[{ v:-2, k: 3 },
                    { v: 2, k: 1 },
                    { v: 2, k: 2 },
                    { v: 3, k: 2 },
                    { v: 3, k: 3 },
                    { v: 4, k: 1 },
                    { v: 5, k: 3 },
                    { v: 6, k: 3 }] },
         { delete:  IDBKeyRange.bound(1, 3),
           indexes:[] },
         { put:     { x: ["food", {}, false, undefined, /x/, [73, false]], id: 2 },
           indexes:[{ v: "food", k: 2 }] },
         { add:     { x: [{}, /x/, -12, "food", null, [false], undefined], id: 3 },
           indexes:[{ v: -12, k: 3 },
                    { v: "food", k: 2 },
                    { v: "food", k: 3 }] },
         { put:     { x: [], id: 2 },
           indexes:[{ v: -12, k: 3 },
                    { v: "food", k: 3 }] },
         { put:     { x: { y: 3 }, id: 3 },
           indexes:[] },
         { add:     { x: false, id: 7 },
           indexes:[] },
         { delete:  IDBKeyRange.lowerBound(0),
           indexes:[] },
        ];

      let store = db.createObjectStore("mystore", { keyPath: "id" });
      let index = store.createIndex("myindex", "x", { multiEntry: true });
      is(index.multiEntry, true, "index created with multiEntry");

      let i;
      for (i = 0; i < tests.length; ++i) {
        let test = tests[i];
        let testName = " for " + JSON.stringify(test);
        let req;
        if (test.add) {
          req = store.add(test.add);
        }
        else if (test.put) {
          req = store.put(test.put);
        }
        else if (test.delete) {
          req = store.delete(test.delete);
        }
        else {
          ok(false, "borked test");
        }
        req.onsuccess = grabEventAndContinueHandler;
        let e = yield;
        
        req = index.openKeyCursor();
        req.onsuccess = grabEventAndContinueHandler;
        for (let j = 0; j < test.indexes.length; ++j) {
          e = yield;
          is(req.result.key, test.indexes[j].v, "found expected index key at index " + j + testName);
          is(req.result.primaryKey, test.indexes[j].k, "found expected index primary key at index " + j + testName);
          req.result.continue();
        }
        e = yield;
        is(req.result, undefined, "exhausted indexes");

        let tempIndex = store.createIndex("temp index", "x", { multiEntry: true });
        req = tempIndex.openKeyCursor();
        req.onsuccess = grabEventAndContinueHandler;
        for (let j = 0; j < test.indexes.length; ++j) {
          e = yield;
          is(req.result.key, test.indexes[j].v, "found expected temp index key at index " + j + testName);
          is(req.result.primaryKey, test.indexes[j].k, "found expected temp index primary key at index " + j + testName);
          req.result.continue();
        }
        e = yield;
        is(req.result, undefined, "exhausted temp index");
        store.deleteIndex("temp index");
      }

      // Unique indexes
      tests =
        [{ add:     { x: 1, id: 1 },
           indexes:[{ v: 1, k: 1 }] },
         { add:     { x: [2, 3], id: 2 },
           indexes:[{ v: 1, k: 1 },
                    { v: 2, k: 2 },
                    { v: 3, k: 2 }] },
         { put:     { x: [2, 4], id: 3 },
           fail:    true },
         { put:     { x: [1, 4], id: 1 },
           indexes:[{ v: 1, k: 1 },
                    { v: 2, k: 2 },
                    { v: 3, k: 2 },
                    { v: 4, k: 1 }] },
         { add:     { x: [5, 0, 5, 5, 5], id: 3 },
           indexes:[{ v: 0, k: 3 },
                    { v: 1, k: 1 },
                    { v: 2, k: 2 },
                    { v: 3, k: 2 },
                    { v: 4, k: 1 },
                    { v: 5, k: 3 }] },
         { delete:  IDBKeyRange.bound(1, 2),
           indexes:[{ v: 0, k: 3 },
                    { v: 5, k: 3 }] },
         { add:     { x: [0, 6], id: 8 },
           fail:    true },
         { add:     { x: 5, id: 8 },
           fail:    true },
         { put:     { x: 0, id: 8 },
           fail:    true },
        ];

      store.deleteIndex("myindex");
      index = store.createIndex("myindex", "x", { multiEntry: true, unique: true });
      is(index.multiEntry, true, "index created with multiEntry");

      let i;
      let indexes;
      for (i = 0; i < tests.length; ++i) {
        let test = tests[i];
        let testName = " for " + JSON.stringify(test);
        let req;
        if (test.add) {
          req = store.add(test.add);
        }
        else if (test.put) {
          req = store.put(test.put);
        }
        else if (test.delete) {
          req = store.delete(test.delete);
        }
        else {
          ok(false, "borked test");
        }
        
        if (!test.fail) {
          req.onsuccess = grabEventAndContinueHandler;
          let e = yield;
          indexes = test.indexes;
        }
        else {
          req.onsuccess = unexpectedSuccessHandler;
          req.onerror = grabEventAndContinueHandler;
          ok(true, "waiting for error");
          let e = yield;
          ok(true, "got error: " + e.type);
          e.preventDefault();
          e.stopPropagation();
        }

        let e;
        req = index.openKeyCursor();
        req.onsuccess = grabEventAndContinueHandler;
        for (let j = 0; j < indexes.length; ++j) {
          e = yield;
          is(req.result.key, indexes[j].v, "found expected index key at index " + j + testName);
          is(req.result.primaryKey, indexes[j].k, "found expected index primary key at index " + j + testName);
          req.result.continue();
        }
        e = yield;
        is(req.result, undefined, "exhausted indexes");

        let tempIndex = store.createIndex("temp index", "x", { multiEntry: true, unique: true });
        req = tempIndex.openKeyCursor();
        req.onsuccess = grabEventAndContinueHandler;
        for (let j = 0; j < indexes.length; ++j) {
          e = yield;
          is(req.result.key, indexes[j].v, "found expected temp index key at index " + j + testName);
          is(req.result.primaryKey, indexes[j].k, "found expected temp index primary key at index " + j + testName);
          req.result.continue();
        }
        e = yield;
        is(req.result, undefined, "exhausted temp index");
        store.deleteIndex("temp index");
      }


      openRequest.onsuccess = grabEventAndContinueHandler;
      yield;

      let trans = db.transaction(["mystore"], IDBTransaction.READ_WRITE);
      store = trans.objectStore("mystore");
      index = store.index("myindex");
      is(index.multiEntry, true, "index still is multiEntry");
      trans.oncomplete = grabEventAndContinueHandler;
      yield;

      finishTest();
      yield;
    }
  </script>
  <script type="text/javascript;version=1.7" src="helpers.js"></script>
</head>

<body onload="runTest();"></body>

</html>