<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("Tests IndexedDB's quota enforcing mechanism.");
if (window.layoutTestController) 
    layoutTestController.waitUntilDone();

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

function openSuccess()
{
    window.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;

    deleteAllObjectStores(db);

    shouldBeEqualToString("db.version", "new version");
    shouldBeEqualToString("db.name", "database-quota");
    shouldBe("db.objectStoreNames", "[]");
    shouldBe("db.objectStoreNames.length", "0");
    shouldBe("db.objectStoreNames.contains('')", "false");

    objectStore = evalAndLog('db.createObjectStore("test123")');
    checkObjectStore();
    commitAndContinue();
}

function checkObjectStore()
{
    shouldBe("db.objectStoreNames", "['test123']");
    shouldBe("db.objectStoreNames.length", "1");
    shouldBe("db.objectStoreNames.contains('')", "false");
    shouldBe("db.objectStoreNames.contains('test456')", "false");
    shouldBe("db.objectStoreNames.contains('test123')", "true");
}

function commitAndContinue()
{
    window.setTimeout(checkQuotaEnforcing, 0);
}

function checkQuotaEnforcing()
{
    var trans = evalAndLog("trans = db.transaction([], webkitIDBTransaction.READ_WRITE)");
    trans.onabort = testComplete;
    trans.oncomplete = unexpectedCompleteCallback;
    debug("Creating 'data' which contains 64K of data");
    window.data = "X";
    for (var i = 0; i < 16; i++)
        data += data;
    shouldBe("data.length", "65536");
    window.dataAdded = 0;
    window.store = evalAndLog("store = trans.objectStore('test123')");
    addData();
}

function addData()
{
    if (dataAdded < 5 * 1024 * 1024) {
        if (dataAdded > 0)
            store = event.target.source;
    } else {
        testFailed("added more than quota");
        done();
        return;
    }
    dataAdded += 65536;
    request = store.add({x: data}, dataAdded);
    request.onsuccess = addData;
    request.onerror = logError;
}

function logError()
{
    debug("Error function called: (" + event.code + ") " + event.message);
    evalAndLog("event.preventDefault()");
}

function testComplete()
{
    testPassed("Adding data failed due to quota error. Data added was about " + Math.round(dataAdded / 1024 / 1024) + " MB");
    done();
}

test();

var successfullyParsed = true;

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