<!doctype html>
<html>
<head>
<script src="../../resources/js-test-pre.js"></script>
<script src="../../http/tests/inspector/resources/protocol-test.js"></script>
<script>

function runFor(func, millis) {
    let start = Date.now();
    do {
        func();
    } while (Date.now() - start < millis);
}

function foo() {
    let bar = function() {
        for (let i = 0; i < 10000; i++) {
            i++;
            i--;
        }
    };
    noInline(bar);
    bar();
}
noInline(foo);

function test()
{
    let suite = ProtocolTest.createAsyncSuite("ScriptProfiler.Samples.NamedFunctionExpression");

    suite.addTestCase({
        name: "Sampling Profiler basic",
        description: "Sample some basic code.",
        test(resolve, reject) {
            InspectorProtocol.awaitEvent({event: "ScriptProfiler.trackingComplete"}).then((messageObject) => {
                let tree = WI.CallingContextTree.__test_makeTreeFromProtocolMessageObject(messageObject);
                let trace = [
                    {name: "bar"},
                    {name: "foo"},
                    {name: "runFor"}
                ];
                ProtocolTest.expectThat(tree.__test_matchesStackTrace(trace), "Should have seen stacktrace:\n" + JSON.stringify(trace, undefined, 2));
                resolve();
            });

            InspectorProtocol.sendCommand("ScriptProfiler.startTracking", {includeSamples: true});
            ProtocolTest.evaluateInPage("runFor(foo, 100)");
            InspectorProtocol.sendCommand('ScriptProfiler.stopTracking', {});
        }
    });

    suite.runTestCasesAndFinish();
}
</script>
</head>
<body onload="runTest()">
</body>
</html>
