<!DOCTYPE html>
<title>IDBObjectStore.openKeyCursor()</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="support.js"></script>
<script>
function store_test(func, name) {
  indexeddb_test(
    function(t, db, tx) {
      var store = db.createObjectStore("store");
      for (var i = 0; i < 10; ++i) {
        store.put("value: " + i, i);
      }
    },
    function(t, db) {
      var tx = db.transaction("store");
      var store = tx.objectStore("store");
      func(t, db, tx, store);
    }, name);
}

store_test(function(t, db, tx, store) {
    var expected = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
    var actual = [];
    var request = store.openKeyCursor();
    request.onsuccess = t.step_func(function() {
        var cursor = request.result;
        if (!cursor)
            return;
        assert_equals(cursor.direction, "next");
        assert_false("value" in cursor);
        assert_equals(indexedDB.cmp(cursor.key, cursor.primaryKey), 0);
        actual.push(cursor.key);
        cursor.continue();
    });

    tx.onabort = t.unreached_func("transaction aborted");
    tx.oncomplete = t.step_func(function() {
        assert_array_equals(expected, actual, "keys should match");
        t.done();
    });

}, "IDBObjectStore.openKeyCursor() - forward iteration");

store_test(function(t, db, tx, store) {
    var expected = [9, 8, 7, 6, 5, 4, 3, 2, 1, 0];
    var actual = [];
    var request = store.openKeyCursor(null, "prev");
    request.onsuccess = t.step_func(function() {
        var cursor = request.result;
        if (!cursor)
            return;
        assert_equals(cursor.direction, "prev");
        assert_false("value" in cursor);
        assert_equals(indexedDB.cmp(cursor.key, cursor.primaryKey), 0);
        actual.push(cursor.key);
        cursor.continue();
    });

    tx.onabort = t.unreached_func("transaction aborted");
    tx.oncomplete = t.step_func(function() {
        assert_array_equals(expected, actual, "keys should match");
        t.done();
    });

}, "IDBObjectStore.openKeyCursor() - reverse iteration");

store_test(function(t, db, tx, store) {
    var expected = [4, 5, 6];
    var actual = [];
    var request = store.openKeyCursor(IDBKeyRange.bound(4, 6));
    request.onsuccess = t.step_func(function() {
        var cursor = request.result;
        if (!cursor)
            return;
        assert_equals(cursor.direction, "next");
        assert_false("value" in cursor);
        assert_equals(indexedDB.cmp(cursor.key, cursor.primaryKey), 0);
        actual.push(cursor.key);
        cursor.continue();
    });

    tx.onabort = t.unreached_func("transaction aborted");
    tx.oncomplete = t.step_func(function() {
        assert_array_equals(expected, actual, "keys should match");
        t.done();
    });

}, "IDBObjectStore.openKeyCursor() - forward iteration with range");

store_test(function(t, db, tx, store) {
    var expected = [6, 5, 4];
    var actual = [];
    var request = store.openKeyCursor(IDBKeyRange.bound(4, 6), "prev");
    request.onsuccess = t.step_func(function() {
        var cursor = request.result;
        if (!cursor)
            return;
        assert_equals(cursor.direction, "prev");
        assert_false("value" in cursor);
        assert_equals(indexedDB.cmp(cursor.key, cursor.primaryKey), 0);
        actual.push(cursor.key);
        cursor.continue();
    });

    tx.onabort = t.unreached_func("transaction aborted");
    tx.oncomplete = t.step_func(function() {
        assert_array_equals(expected, actual, "keys should match");
        t.done();
    });

}, "IDBObjectStore.openKeyCursor() - reverse iteration with range");

store_test(function(t, db, tx, store) {
    assert_throws_dom("DataError", function() { store.openKeyCursor(NaN); },
        "openKeyCursor should throw on invalid number key");
    assert_throws_dom("DataError", function() { store.openKeyCursor(new Date(NaN)); },
        "openKeyCursor should throw on invalid date key");
    assert_throws_dom("DataError", function() {
        var cycle = [];
        cycle.push(cycle);
        store.openKeyCursor(cycle);
    }, "openKeyCursor should throw on invalid array key");
    assert_throws_dom("DataError", function() { store.openKeyCursor({}); },
        "openKeyCursor should throw on invalid key type");
    setTimeout(t.step_func(function() {
        assert_throws_dom("TransactionInactiveError", function() { store.openKeyCursor(); },
            "openKeyCursor should throw if transaction is inactive");
        t.done();
    }), 0);

}, "IDBObjectStore.openKeyCursor() - invalid inputs");
</script>
