<!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>
