<html>
<head>
<script src="../http/tests/inspector/inspector-test.js"></script>
<script>
function addItem(key,value)
{
    localStorage.setItem(key,value);
}

function removeItem(key)
{
    localStorage.removeItem(key);
}

function clear()
{
    localStorage.clear();
}

function test()
{
    var storage = null;
    var rootNode = null;
    var count = 1;

    // Resources panel must be visible
    WebInspector.showPanel("resources");

    function dumpDataGrid()
    {
        var nodes = rootNode.children;
        var rows = [];
        for (var i = 0; i < nodes.length; ++i) {
            var node = nodes[i];
            if (node._data.key.length)
                rows.push(node._data.key + node._data.value);
        }
        rows.sort();
        InspectorTest.addResult("KeyValue pairs: [" + rows.join() + "]");
    }

    var nextDOMStorageClearHandler = null;
    InspectorTest.addSniffer(WebInspector.DOMStorageDispatcher.prototype, "domStorageItemsCleared", function() {
        if (nextDOMStorageClearHandler) {
            var handler = nextDOMStorageClearHandler;
            nextDOMStorageClearHandler = null;
            handler();
        } else
            InspectorTest.addResult("ERROR: domStorageItemsCleared event without handler");
    }, true);

    var nextDOMStorageAddHandler = null;
    InspectorTest.addSniffer(WebInspector.DOMStorageDispatcher.prototype, "domStorageItemAdded", function() {
        if (nextDOMStorageAddHandler) {
            var handler = nextDOMStorageAddHandler;
            nextDOMStorageAddHandler = null;
            handler();
        } else
            InspectorTest.addResult("ERROR: domStorageItemAdded event without handler");
    }, true);

    var nextDOMStorageRemoveHandler = null;
    InspectorTest.addSniffer(WebInspector.DOMStorageDispatcher.prototype, "domStorageItemRemoved", function() {
        if (nextDOMStorageRemoveHandler) {
            var handler = nextDOMStorageRemoveHandler;
            nextDOMStorageRemoveHandler = null;
            handler();
        } else
            InspectorTest.addResult("ERROR: domStorageItemRemoved event without handler");
    }, true);

    InspectorTest.runTestSuite([
        function initialize(next)
        {
            function didClear(result)
            {
                InspectorTest.addResult("Initialized localStorage by clearing entries");
                next();
            }

            nextDOMStorageClearHandler = didClear;

            InspectorTest.evaluateInPage("clear()");
        },

        function updateLocalStorageView(next)
        {
            function localStorageViewUpdated()
            {
                rootNode = WebInspector.panels.resources._domStorageViews.get(storage)._dataGrid.rootNode();
                InspectorTest.addResult("Resource Panel with localStorage view updated");
                next();
            }

            var didFindStorage = false;

            var storages = WebInspector.domStorageModel.storages();
            for (var i = 0; i < storages.length; ++i) {
                storage = storages[i];
                if (storage.isLocalStorage) {
                    WebInspector.panels.resources._showDOMStorage(storage);
                    InspectorTest.runAfterPendingDispatches(localStorageViewUpdated);
                    didFindStorage = true;
                    break;
                }
            }

            if (!didFindStorage)
                InspectorTest.addResult("did not find local storage");
        },

        function addItemTest(next)
        {
            function viewUpdatedAfterAddition()
            {
                rootNode = WebInspector.panels.resources._domStorageViews.get(storage)._dataGrid.rootNode();
                dumpDataGrid();
                if (count < 6)
                    addItemTest(next);
                else
                    next();
            }

            nextDOMStorageAddHandler = viewUpdatedAfterAddition;

            InspectorTest.addResult("addItem('a"+count+"','=value"+count+"')");
            InspectorTest.evaluateInPage("addItem('a"+count+"','=value"+count+"')");
            count++;
        },

        function removeItemTest(next)
        {
            function viewUpdatedAfterRemoval()
            {
                rootNode = WebInspector.panels.resources._domStorageViews.get(storage)._dataGrid.rootNode();
                dumpDataGrid();
                if (count > 4)
                    removeItemTest(next);
                else
                    next();
            }

            nextDOMStorageRemoveHandler = viewUpdatedAfterRemoval;

            --count;
            InspectorTest.addResult("removeItem('a"+count+"')");
            InspectorTest.evaluateInPage("removeItem('a"+count+"')");
        },

        function clearTest(next)
        {
            function viewUpdatedAfterClear()
            {
                rootNode = WebInspector.panels.resources._domStorageViews.get(storage)._dataGrid.rootNode();
                dumpDataGrid();
                next();
            }

            nextDOMStorageClearHandler = viewUpdatedAfterClear;

            InspectorTest.addResult("clear()");
            InspectorTest.evaluateInPage("clear()");
        }
    ]);
}
</script>
</head>
<body onload="runTest()">
<p>Test that storage panel is present and that it contains correct data whenever localStorage is updated.</p>
</body>
</html>
