<!DOCTYPE html>
<title>IDBCursor.continue()</title>
<link rel="author" href="mailto:odinho@opera.com" title="Odin Hørthe Omdal">
<link rel=help href="http://dvcs.w3.org/hg/IndexedDB/raw-file/tip/Overview.html#widl-IDBCursor-continue-void-any-key">
<link rel=assert title="The next key to position this cursor at">
<script src="../../../resources/testharness.js"></script>
<script src="../../../resources/testharnessreport.js"></script>
<script src="support.js"></script>

<script>

    var db, open;
    var store = [ { value: "cupcake", key: 5 },
                  { value: "pancake", key: 3 },
                  { value: "pie",     key: 1 },
                  { value: "pie",     key: 4 },
                  { value: "taco",    key: 2 } ];

    setup(function() {
        open = indexedDB.open('testdb-' + new Date().getTime());
        open.onupgradeneeded = function(e) {
            var os, i;
            db = e.target.result;
            os = db.createObjectStore("test");
            os.createIndex("index", "");

            for (i = 0; i < store.length; i++)
                os.add(store[i].value, store[i].key);
        };
    },
    { explicit_done: true });


    open.onsuccess = function() {


        async_test(document.title + " - continues").step(function(e) {
            var count = 0;
            var rq = db.transaction("test").objectStore("test").index("index").openCursor();

            rq.onsuccess = this.step_func(function(e) {
                if (!e.target.result) {
                    assert_equals(count, 5, 'count');
                    this.done();
                    return;
                }
                var cursor = e.target.result;

                assert_equals(cursor.value, store[count].value);
                assert_equals(cursor.primaryKey, store[count].key);

                cursor.continue();

                count++;
            });
            rq.onerror = fail(this, "unexpected error")
        });


        async_test(document.title + " - with given key").step(function(e) {
            var count = 0;
            var rq = db.transaction("test").objectStore("test").index("index").openCursor();

            rq.onsuccess = this.step_func(function(e) {
                if (!e.target.result) {
                    assert_equals(count, 3, 'count');
                    this.done();
                    return;
                }
                var cursor = e.target.result;

                switch(count) {
                    case 0:
                        assert_equals(cursor.value, "cupcake");
                        assert_equals(cursor.primaryKey, 5);
                        cursor.continue("pie");
                        break;

                    case 1:
                        assert_equals(cursor.value, "pie");
                        assert_equals(cursor.primaryKey, 1);
                        cursor.continue("taco");
                        break;

                    case 2:
                        assert_equals(cursor.value, "taco");
                        assert_equals(cursor.primaryKey, 2);
                        cursor.continue();
                        break;

                    default:
                        assert_unreached("Unexpected count: " + count);
                }

                count++;
            });
            rq.onerror = fail(this, "unexpected error")
        });


        async_test(document.title + " - skip far forward").step(function(e) {
            var count = 0;
            var rq = db.transaction("test").objectStore("test").index("index")
                       .openCursor();

            rq.onsuccess = this.step_func(function(e) {
                if (!e.target.result) {
                    assert_equals(count, 1, 'count');
                    this.done();
                    return;
                }
                var cursor = e.target.result;

                switch(count) {
                    case 0:
                        assert_equals(cursor.value, "cupcake");
                        assert_equals(cursor.primaryKey, 5);
                        break;

                    default:
                        assert_unreached("Unexpected count: " + count);
                }

                count++;
                cursor.continue([]); // Arrays are always bigger than strings

            });
            rq.onerror = fail(this, "unexpected error2")
        });


        async_test(document.title + " - within range").step(function(e) {
            var count = 0;
            var rq = db.transaction("test").objectStore("test").index("index")
                       .openCursor(IDBKeyRange.lowerBound("cupcake", true));

            rq.onsuccess = this.step_func(function(e) {
                if (!e.target.result) {
                    assert_equals(count, 2, 'count');
                    this.done();
                    return;
                }
                var cursor = e.target.result;

                switch(count) {
                    case 0:
                        assert_equals(cursor.value, "pancake");
                        assert_equals(cursor.primaryKey, 3);
                        cursor.continue("pie");
                        break;

                    case 1:
                        assert_equals(cursor.value, "pie");
                        assert_equals(cursor.primaryKey, 1);
                        cursor.continue("zzz");
                        break;

                    default:
                        assert_unreached("Unexpected count: " + count);
                }

                count++;
            });
            rq.onerror = fail(this, "unexpected error1")
        });


        async_test(document.title + " - within single key range").step(function(e) {
            var count = 0;
            var rq = db.transaction("test").objectStore("test").index("index")
                       .openCursor("pancake");

            rq.onsuccess = this.step_func(function(e) {
                if (!e.target.result) {
                    assert_equals(count, 1, 'count');
                    this.done();
                    return;
                }
                var cursor = e.target.result;

                switch(count) {
                    case 0:
                        assert_equals(cursor.value, "pancake");
                        assert_equals(cursor.primaryKey, 3);
                        cursor.continue("pie");
                        break;

                    default:
                        assert_unreached("Unexpected count: " + count);
                }

                count++;
            });
            rq.onerror = fail(this, "unexpected error1")
        });


        async_test(document.title + " - within single key range, with several results").step(function(e) {
            var count = 0;
            var rq = db.transaction("test").objectStore("test").index("index")
                       .openCursor("pie");

            rq.onsuccess = this.step_func(function(e) {
                if (!e.target.result) {
                    assert_equals(count, 2, 'count');
                    this.done();
                    return;
                }
                var cursor = e.target.result;

                switch(count) {
                    case 0:
                        assert_equals(cursor.value, "pie");
                        assert_equals(cursor.primaryKey, 1);
                        cursor.continue();
                        break;

                    case 1:
                        assert_equals(cursor.value, "pie");
                        assert_equals(cursor.primaryKey, 4);
                        cursor.continue();
                        break;

                    default:
                        assert_unreached("Unexpected count: " + count);
                }

                count++;
            });
            rq.onerror = fail(this, "unexpected error1")
        });


        // Stop blocking the testing system from hereon
        done();
    }

</script>

<div id="log"></div>
