<html>
<head>
<link rel="stylesheet" href="../../fast/js/resources/js-test-style.css">
<script src="../../fast/js/resources/js-test-pre.js"></script>
<script src="../../fast/js/resources/js-test-post-function.js"></script>
<script src="resources/shared.js"></script>
</head>
<body>
<p id="description"></p>
<div id="console"></div>
<script>

description("Test IndexedDB's cursor skips deleted entries.");
if (window.layoutTestController)
    layoutTestController.waitUntilDone();

var names = ['Alpha', 'Bravo', 'Charlie', 'Delta', 'Echo', 'Foxtrot', 'Golf',
             'Hotel', 'India', 'Juliet', 'Kilo', 'Lima', 'Mike', 'November',
             'Oscar', 'Papa', 'Quebec', 'Romeo', 'Sierra', 'Tango', 'Uniform',
             'Victor', 'Whiskey', 'X-ray', 'Yankee', 'Zulu'];

test();

function test()
{
    request = evalAndLog("webkitIndexedDB.open('cursor-skip-deleted')");
    request.onsuccess = openSuccess;
    request.onerror = unexpectedErrorCallback;
}

function openSuccess()
{
    var db = evalAndLog("db = event.target.result");

    request = evalAndLog("db.setVersion('new version')");
    request.onsuccess = setVersionSuccess;
    request.onerror = unexpectedErrorCallback;
}

function setVersionSuccess()
{
    debug("setVersionSuccess():");
    window.trans = evalAndLog("trans = event.target.result");
    shouldBeTrue("trans !== null");
    trans.onabort = unexpectedAbortCallback;
    trans.oncomplete = basicCursorTest;

    deleteAllObjectStores(db);

    var objectStore = evalAndLog("objectStore = db.createObjectStore('store', {keyPath: 'id'})");
    evalAndLog("objectStore.createIndex('nameIndex', 'name')");
    resetObjectStore(function() {});
}

var silentErrorHandler = function() { event.preventDefault(); }

function resetObjectStore(callback)
{
    debug("\nresetObjectStore():");
    if (callback === undefined)
        callback = function () {};

    var objectStore = trans.objectStore('store');
    for (var i = 0; i < names.length; i++)
        objectStore.delete(i).onerror = silentErrorHandler;
    for (var i = 0; i < names.length; i++)
        objectStore.add({id: i, name: names[i]}).onerror = unexpectedErrorCallback;

    debug("");
    callback();
}

function contains(arr, obj)
{
    for (var i = 0; i < arr.length; i++) {
        if (arr[i] == obj)
            return true;
    }
    return false;
}

var cursor;
var deleted;
var seen;

function testCursor(deleteList, createCursorCommand, callback)
{
    debug("\ntestCursor():");
    deleted = [];
    seen = [];

    // Create the cursor.
    request = evalAndLog(createCursorCommand);

    request.onerror = unexpectedErrorCallback;
    request.onsuccess = function () {
        if (event.target.result == null) {
            // Make sure we have seen every non-deleted item.
            for (var i = 0; i < names.length; i++) {
                if (contains(deleted, i))
                    continue;

                if (!contains(seen, i))
                    testFailed("Cursor did not see item with id: " + i);
            }

            // Make sure we used every rule in |deleteList|.
            for (var i = 0; i < deleteList.length; i++) {
                if (!contains(seen, deleteList[i].id))
                    testFailed("deleteList rule with id: " + deleteList[i].id + " was never used.");
            }

            debug("");
            callback();
            return;
        }

        cursor = event.target.result;
        debug(event.target.result.value.id + ": " + event.target.result.value.name);
        seen.push(event.target.result.value.id);

        // Make sure we don't see any deleted items.
        if (contains(deleted, event.target.result.value.id))
            testFailed("Cursor hit previously deleted element.");

        for (var i = 0; i < deleteList.length; i++) {
            if (event.target.result.value.id == deleteList[i].id) {
                // Delete objects targeted by this id.
                var targets = deleteList[i].targets;
                for (var j = 0; j < targets.length; j++) {
                    deleted.push(targets[j]);
                    request = evalAndLog("request = trans.objectStore('store').delete(" + targets[j] + ")");
                    request.onerror = unexpectedErrorCallback;
                    if (j == targets.length - 1)
                        request.onsuccess = function() { cursor.continue(); }
                }
                return;
            }
        }

        cursor.continue();
    }
}

function basicCursorTest()
{
    debug("basicCursorTest()");

    evalAndLog("trans = db.transaction([], webkitIDBTransaction.READ_WRITE)");
    trans.onabort = unexpectedAbortCallback;
    trans.oncomplete = transactionComplete;

    var deletes = [{id: 1, targets: [0]},
                   {id: 2, targets: [names.length - 1]},
                   {id: 3, targets: [5,6,7]},
                   {id: 10, targets: [10]},
                   {id: 12, targets: [13]},
                   {id: 15, targets: [14]},
                   {id: 20, targets: [17,18]}
                   ];

    testCursor(deletes, "trans.objectStore('store').openCursor(webkitIDBKeyRange.lowerBound(0))", function() { resetObjectStore(reverseCursorTest); });
}

function reverseCursorTest()
{
    debug("reverseCursorTest():");

    var deletes = [{id: 24, targets: [names.length - 1]},
                   {id: 23, targets: [0]},
                   {id: 22, targets: [20, 19, 18]},
                   {id: 15, targets: [15]},
                   {id: 13, targets: [12]},
                   {id: 10, targets: [11]},
                   {id: 5, targets: [7,8]}
                   ];


    testCursor(deletes, "trans.objectStore('store').openCursor(webkitIDBKeyRange.lowerBound(0), webkitIDBCursor.PREV)", function() { resetObjectStore(indexCursorTest); });
}

function indexCursorTest()
{
    debug("indexCursorTest():");

    var deletes = [{id: 1, targets: [0]},
                   {id: 2, targets: [names.length - 1]},
                   {id: 3, targets: [5,6,7]},
                   {id: 10, targets: [10]},
                   {id: 12, targets: [13]},
                   {id: 15, targets: [14]},
                   {id: 20, targets: [17,18]}
                   ];

    testCursor(deletes, "trans.objectStore('store').index('nameIndex').openCursor(webkitIDBKeyRange.lowerBound('Alpha'))", function() { });
}

function transactionComplete()
{
    debug("transactionComplete():");
    done();
}

var successfullyParsed = true;

</script>
</body>
</html>
