19d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org// Copyright 2014 the V8 project authors. All rights reserved.
29d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org// Use of this source code is governed by a BSD-style license that can be
39d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org// found in the LICENSE file.
49d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org
59d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org// Flags: --expose-debug-as debug --allow-natives-syntax
69d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org
79d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org// Test debug events when an exception is thrown inside a Promise, which is
89d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org// caught by a custom promise, which throws a new exception in its reject
99d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org// handler. We expect two Exception debug events:
109d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org//  1) when the exception is thrown in the promise q.
119d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org//  2) when the custom reject closure in MyPromise throws an exception.
129d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org
139d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.orgDebug = debug.Debug;
149d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org
159d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.orgvar expected_events = 2;
169d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.orgvar log = [];
179d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org
189d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.orgvar p = new Promise(function(resolve, reject) {
199d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org  log.push("resolve");
209d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org  resolve();
219d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org});
229d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org
239d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.orgfunction MyPromise(resolver) {
249d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org  var reject = function() {
259d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org    log.push("throw in reject");
269d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org    throw new Error("reject");  // event
279d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org  };
289d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org  var resolve = function() { };
299d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org  log.push("construct");
309d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org  resolver(resolve, reject);
319d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org};
329d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org
339d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.orgMyPromise.prototype = new Promise(function() {});
349d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.orgp.constructor = MyPromise;
359d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org
369d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.orgvar q = p.chain(
379d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org  function() {
389d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org    log.push("throw caught");
399d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org    throw new Error("caught");  // event
409d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org  });
419d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org
429d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.orgfunction listener(event, exec_state, event_data, data) {
439d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org  try {
449d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org    if (event == Debug.DebugEvent.Exception) {
459d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org      expected_events--;
469d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org      assertTrue(expected_events >= 0);
479d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org      if (expected_events == 1) {
489d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org        assertEquals(["resolve", "construct", "end main",
499d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org                      "throw caught"], log);
509d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org        assertEquals("caught", event_data.exception().message);
519d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org      } else if (expected_events == 0) {
529d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org        assertEquals("reject", event_data.exception().message);
539d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org      } else {
549d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org        assertUnreachable();
559d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org      }
568640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org      assertSame(q, event_data.promise());
579d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org      assertTrue(exec_state.frame(0).sourceLineText().indexOf('// event') > 0);
589d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org    }
599d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org  } catch (e) {
609d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org    %AbortJS(e + "\n" + e.stack);
619d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org  }
629d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org}
639d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org
649d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.orgDebug.setBreakOnUncaughtException();
659d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.orgDebug.setListener(listener);
669d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org
679d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.orglog.push("end main");
689d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org
699d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.orgfunction testDone(iteration) {
709d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org  function checkResult() {
719d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org    try {
729d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org      assertTrue(iteration < 10);
739d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org      if (expected_events === 0) {
749d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org        assertEquals(["resolve", "construct", "end main",
759d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org                      "throw caught", "throw in reject"], log);
769d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org      } else {
779d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org        testDone(iteration + 1);
789d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org      }
799d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org    } catch (e) {
809d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org      %AbortJS(e + "\n" + e.stack);
819d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org    }
829d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org  }
839d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org
849d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org  // Run testDone through the Object.observe processing loop.
859d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org  var dummy = {};
869d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org  Object.observe(dummy, checkResult);
879d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org  dummy.dummy = dummy;
889d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org}
899d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org
909d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.orgtestDone(0);
91