<!DOCTYPE html>
<html>
<head>
<script src="../../http/tests/inspector/resources/inspector-test.js"></script>
<script src="resources/break-on-exception-tests.js"></script>
<script>
TestPage.allowUncaughtExceptions = true;

function test()
{
    WI.debuggerManager.allExceptionsBreakpoint.disabled = false;

    let suite = InspectorTest.createAsyncSuite("BreakOnAnyException.Promise");

    function addTestCase({name, description, expression}) {
        suite.addTestCase({
            name, description,
            test(resolve, reject) {
                InspectorTest.evaluateInPage(expression);
                WI.debuggerManager.singleFireEventListener(WI.DebuggerManager.Event.Paused, (event) => {
                    let targetData = WI.debuggerManager.dataForTarget(WI.debuggerManager.activeCallFrame.target);
                    InspectorTest.expectThat(targetData.pauseReason === "exception", "Should pause for exception.");
                    let callFrame = WI.debuggerManager.activeCallFrame;
                    let name = callFrame.functionName || "<anonymous>";
                    let location = callFrame.sourceCodeLocation;
                    let line = location.lineNumber + 1;
                    let column = location.columnNumber + 1;
                    InspectorTest.log(`PAUSE AT ${name}:${line}:${column}`);
                    WI.debuggerManager.resume().then(resolve, reject);
                });
            }
        });
    }

    addTestCase({
        name: "BreakOnAnyException.Promise.ExceptionInPromiseConstructor",
        description: "Break on an exception thrown in Promise constructor.",
        expression: "setTimeout(testThrowingInPromise)",
    });

    addTestCase({
        name: "BreakOnAnyException.Promise.ExceptionInPromiseThenWithoutCatch",
        description: "Break on an exception thrown in Promise then handler with no catch handler.",
        expression: "setTimeout(testThrowingInPromiseThen)",
    });

    addTestCase({
        name: "BreakOnAnyException.Promise.ExceptionInPromiseThenWithCatch",
        description: "Break on an exception thrown in Promise then handler with a catch handler.",
        expression: "setTimeout(testThrowingInPromiseThenWithCatch)",
    });

    addTestCase({
        name: "BreakOnAnyException.Promise.ExceptionInPromiseCatch",
        description: "Break on an exception thrown in Promise catch with no then handler.",
        expression: "setTimeout(testThrowingInPromiseWithCatch)",
    });

    suite.addTestCase({
        name: "BreakOnAnyException.Promise.ExceptionInPromiseThenAndRethrownInCatch",
        description: "Break on an exception thrown in Promise then handler, and then again when rethrown in catch handler.",
        test(resolve, reject) {
            InspectorTest.evaluateInPage("setTimeout(testThrowingInPromiseWithRethrowInCatch)");

            function logPauseLocation() {
                let callFrame = WI.debuggerManager.activeCallFrame;
                let name = callFrame.functionName || "<anonymous>";
                let location = callFrame.sourceCodeLocation;
                let line = location.lineNumber + 1;
                let column = location.columnNumber + 1;
                InspectorTest.log(`PAUSE AT ${name}:${line}:${column}`);
            }

            let phase = 0;
            let listener = WI.debuggerManager.addEventListener(WI.DebuggerManager.Event.CallFramesDidChange, (event) => {
                if (!WI.debuggerManager.activeCallFrame)
                    return;

                phase++;

                let targetData = WI.debuggerManager.dataForTarget(WI.debuggerManager.activeCallFrame.target);

                // Pause at throw inside then.
                if (phase === 1) {
                    InspectorTest.expectThat(targetData.pauseReason === "exception", "Should pause for exception.");
                    logPauseLocation();
                    WI.debuggerManager.resume();
                    return;
                }

                // Pause at re-throw inside catch.
                if (phase === 2) {
                    InspectorTest.expectThat(targetData.pauseReason === "exception", "Should pause for exception.");
                    logPauseLocation();
                    WI.debuggerManager.resume().then(() => {
                        WI.debuggerManager.removeEventListener(WI.DebuggerManager.Event.CallFramesDidChange, listener);
                        resolve();
                    }, reject);
                    return;
                }
            });
        }
    });

    suite.runTestCasesAndFinish();
}
</script>
</head>
<body onload="runTest()">
<p>Checking pause locations within Promises when pausing on all exceptions.</p>
</body>
</html>
