<!DOCTYPE html>
<title>IDBCursor asyncness</title>
<link rel="author" href="mailto:odinho@opera.com" title="Odin Hørthe Omdal">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="support.js"></script>

<script>

    var db, open;

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

            objStore.add("data",  1);
            objStore.add("data2", 2);
        };
    },
    { explicit_done: true });


    open.onsuccess = function() {


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

            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, "data")
                        assert_equals(cursor.key, 1)
                        cursor.advance(1)
                        assert_equals(cursor.value, "data")
                        assert_equals(cursor.key, 1)
                        break

                    case 1:
                        assert_equals(cursor.value, "data2")
                        assert_equals(cursor.key, 2)
                        cursor.advance(1)
                        assert_equals(cursor.value, "data2")
                        assert_equals(cursor.key, 2)
                        break

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

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


        async_test(document.title + " - continue").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, 2, 'count');
                    this.done();
                    return;
                }
                var cursor = e.target.result;

                switch(count) {
                    case 0:
                        assert_equals(cursor.value, "data")
                        assert_equals(cursor.key,   "data")
                        assert_equals(cursor.primaryKey, 1)
                        cursor.continue("data2")
                        assert_equals(cursor.value, "data")
                        assert_equals(cursor.key,   "data")
                        assert_equals(cursor.primaryKey, 1)
                        break

                    case 1:
                        assert_equals(cursor.value, "data2")
                        assert_equals(cursor.key,   "data2")
                        assert_equals(cursor.primaryKey, 2)
                        cursor.continue()
                        assert_equals(cursor.value, "data2")
                        assert_equals(cursor.key,   "data2")
                        assert_equals(cursor.primaryKey, 2)
                        break

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

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


        async_test(document.title + " - fresh advance still async").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, 2, 'count');
                    this.done();
                    return;
                }
                var cursor = e.target.result;
                cursor.advance(1)

                switch(count) {
                    case 0:
                        assert_equals(cursor.value, "data")
                        assert_equals(cursor.key,   "data")
                        assert_equals(cursor.primaryKey, 1)
                        break

                    case 1:
                        assert_equals(cursor.value, "data2")
                        assert_equals(cursor.key,   "data2")
                        assert_equals(cursor.primaryKey, 2)
                        break

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

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


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

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

                switch(count) {
                    case 0:
                        assert_equals(cursor.value, "data")
                        assert_equals(cursor.key, 1)
                        break

                    case 1:
                        assert_equals(cursor.value, "data2")
                        assert_equals(cursor.key, 2)
                        break

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

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

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

</script>

<div id=log></div>
