<html>
<head>
<script src="../http/tests/inspector/inspector-test.js"></script>
<script type="text/javascript">

function initialize_ProgressBarTest()
{

InspectorTest.MockProgressIndicator = function()
{
}

InspectorTest.MockProgressIndicator.prototype = {
    // Implementation of WebInspector.Progress interface.
    isCanceled: function()
    {
        return this._isCanceled;
    },

    done: function()
    {
        InspectorTest.addResult("progress indicator: done");
    },

    setTotalWork: function(totalWork)
    {
        this._totalWork = totalWork;
    },

    setWorked: function(worked, title)
    {
        this._worked = worked;
        if (typeof title !== "undefined")
            this._title = title;
    },

    setTitle: function(title)
    {
        this._title = title;
    },

    // Test methods.
    cancel: function()
    {
        this._isCanceled = true;
    },

    dump: function()
    {
        const roundFactor = 10000;

        var worked = this._worked;
        var totalWork = this._totalWork;

        if (typeof worked === "number")
            worked = Math.round(worked * roundFactor) / roundFactor;
        if (typeof totalWork === "number")
            totalWork = Math.round(totalWork * roundFactor) / roundFactor;

        InspectorTest.addResult("progress: `" + this._title + "' " + worked + " out of " + totalWork + " done.");
    }
}

}

var test = function()
{
    (function testOneSubProgress()
    {
        var indicator = new InspectorTest.MockProgressIndicator();
        var composite = new WebInspector.CompositeProgress(indicator);
        var subProgress = composite.createSubProgress();

        InspectorTest.addResult("Testing CompositeProgress with a single subprogress:");
        indicator.dump();
        subProgress.setTitle("cuckooing");
        subProgress.setWorked(10);
        indicator.dump();
        subProgress.setTotalWork(100);
        indicator.dump();
        subProgress.setWorked(20, "meowing");
        indicator.dump();
        subProgress.done();
        indicator.dump();
    })();

    (function testMultipleSubProgresses()
    {
        var indicator = new InspectorTest.MockProgressIndicator();
        var composite = new WebInspector.CompositeProgress(indicator);
        var subProgress1 = composite.createSubProgress();
        var subProgress2 = composite.createSubProgress(3);

        InspectorTest.addResult("Testing CompositeProgress with multiple subprogresses:");
        indicator.dump();

        subProgress1.setTitle("cuckooing");
        subProgress1.setTotalWork(100);
        subProgress1.setWorked(20);
        indicator.dump();

        subProgress2.setWorked(10);
        indicator.dump();

        subProgress2.setTotalWork(10);
        subProgress2.setWorked(3, "barking");
        indicator.dump();

        subProgress1.setWorked(50, "meowing");
        subProgress2.setWorked(5);
        indicator.dump();

        subProgress2.done();
        indicator.dump();

        subProgress1.done();
        indicator.dump();
    })();

    (function testCancel()
    {
        var indicator = new InspectorTest.MockProgressIndicator();
        var composite = new WebInspector.CompositeProgress(indicator);
        var subProgress1 = composite.createSubProgress();

        InspectorTest.addResult("Testing isCanceled:");
        InspectorTest.assertTrue(!subProgress1.isCanceled(), "progress should not be canceled");
        indicator.cancel();
        InspectorTest.assertTrue(subProgress1.isCanceled(), "progress should be canceled");
    })();

    (function testNested()
    {
        var indicator = new InspectorTest.MockProgressIndicator();
        var composite0 = new WebInspector.CompositeProgress(indicator);
        var subProgress01 = composite0.createSubProgress();
        var composite1 = new WebInspector.CompositeProgress(subProgress01);
        var subProgress11 = composite1.createSubProgress(10); // Weight should have no effect.

        InspectorTest.addResult("Testing nested subprogresses:");
        indicator.dump();

        subProgress11.setWorked(10);
        indicator.dump();

        subProgress11.setTotalWork(100);
        indicator.dump();

        subProgress11.setWorked(50, "meowing");
        indicator.dump();

        InspectorTest.assertTrue(!subProgress11.isCanceled());
        indicator.cancel();
        InspectorTest.assertTrue(subProgress11.isCanceled());

        subProgress11.done();
        indicator.dump();
    })();

    InspectorTest.completeTest();
}

</script>
</head>
<body onload="runTest()">
<p>Tests inspector's composite progress bar.</p>
</body>
</html>
