Index: test/cctest/test-api.cc |
diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc |
index 66dc5a0c4ab0c8bb95f51eac826f971a448b3c66..6a9aa73fe2fc961ad3164ce4a82601718d45b650 100644 |
--- a/test/cctest/test-api.cc |
+++ b/test/cctest/test-api.cc |
@@ -17566,6 +17566,112 @@ TEST(RethrowBogusErrorStackTrace) { |
} |
+static int promise_message_counter = 0; |
+ |
+ |
+static void CheckPromiseInMessage(v8::Handle<v8::Message> message, |
+ v8::Handle<v8::Value> data) { |
+ CHECK(!message->GetPromise().IsEmpty()); |
+ v8::ScriptOrigin origin = message->GetScriptOrigin(); |
+ promise_message_counter++; |
+ if (promise_message_counter == 1) { |
+ v8::Handle<v8::Value> expected = CcTest::global()->Get(v8_str("p")); |
+ CHECK(expected->Equals(message->GetPromise())); |
+ CHECK(data->Equals(v8_str("p1"))); |
+ // The message location should point to the call site of reject. |
+ CHECK(origin.ResourceName()->Equals(v8_str("test1"))); |
+ CHECK_EQ(6, message->GetLineNumber()); |
+ } else if (promise_message_counter == 2) { |
+ v8::Handle<v8::Value> expected = CcTest::global()->Get(v8_str("q")); |
+ CHECK(expected->Equals(message->GetPromise())); |
+ CHECK(data->Equals(v8_str("q2"))); |
+ // There is no valid location when a promise is rejected by returning a |
+ // rejected promise, since the actual rejection happens in internal code. |
+ CHECK(origin.ResourceName()->IsUndefined()); |
+ CHECK_EQ(0, message->GetLineNumber()); |
+ } else { |
+ CHECK_EQ(3, promise_message_counter); |
+ v8::Handle<v8::Value> expected = CcTest::global()->Get(v8_str("r")); |
+ CHECK(expected->Equals(message->GetPromise())); |
+ CHECK(data->Equals(v8_str("r3"))); |
+ // The message location should point to the throw site. |
+ CHECK(origin.ResourceName()->Equals(v8_str("test3"))); |
+ CHECK_EQ(3, message->GetLineNumber()); |
+ } |
+} |
+ |
+ |
+TEST(PromiseMessage) { |
+ i::FLAG_report_promise_reject = true; |
+ LocalContext env; |
+ v8::Isolate* isolate = env->GetIsolate(); |
+ v8::HandleScope scope(isolate); |
+ |
+ v8::V8::AddMessageListener(CheckPromiseInMessage); |
+ promise_message_counter = 0; |
+ v8::Handle<v8::Promise> promise; |
+ |
+ // Create promise o. |
+ CompileRun( |
+ "var reject; \n" |
+ "var o = new Promise( \n" |
+ " function(res, rej) { \n" |
+ " reject = rej; \n" |
+ " } \n" |
+ "); \n"); |
+ promise = v8::Handle<v8::Promise>::Cast(CcTest::global()->Get(v8_str("o"))); |
+ CHECK(!promise->HasRejectHandler()); |
+ CHECK_EQ(0, promise_message_counter); |
+ |
+ // Add reject handler to o. |
+ CompileRun("o.catch(function() {});"); |
+ CHECK(promise->HasRejectHandler()); |
+ CHECK_EQ(0, promise_message_counter); |
+ |
+ // Reject o. We expect no message. |
+ CompileRun("reject('o0')"); |
+ CHECK(promise->HasRejectHandler()); |
+ CHECK_EQ(0, promise_message_counter); |
+ |
+ // Create Promise p, which is rejected by calling reject. |
+ CompileRun( |
+ "var p = new Promise( \n" |
+ " function(res, rej) { \n" |
+ " reject = rej; \n" |
+ " } \n" |
+ "); \n" |
+ "reject('p1'); \n //@ sourceURL=test1"); |
+ CHECK_EQ(1, promise_message_counter); |
+ // Fetch promise from container. It doesn't have a reject handler. |
+ promise = v8::Handle<v8::Promise>::Cast(CcTest::global()->Get(v8_str("p"))); |
+ CHECK(!promise->HasRejectHandler()); |
+ |
+ // Handle the rejection. Promise p should now have a reject handler. |
+ // q is rejected by returning Promise.reject(). |
+ CompileRun( |
+ "var q = p.catch( \n" |
+ " function() { \n" |
+ " return Promise.reject('q2'); \n" |
+ " } \n" |
+ "); \n //@ sourceURL=test2"); |
+ CHECK_EQ(2, promise_message_counter); |
+ CHECK(promise->HasRejectHandler()); |
+ // Fetch promise from container. It doesn't have a reject handler. |
+ promise = v8::Handle<v8::Promise>::Cast(CcTest::global()->Get(v8_str("q"))); |
+ |
+ // Handle the rejection. Promise q should now have a reject handler. |
+ // r is rejected by throwing. |
+ CompileRun( |
+ "var r = p.catch( \n" |
+ " function() { \n" |
+ " throw 'r3'; \n" |
+ " } \n" |
+ "); \n //@ sourceURL=test3"); |
+ CHECK_EQ(3, promise_message_counter); |
+ promise = v8::Handle<v8::Promise>::Cast(CcTest::global()->Get(v8_str("r"))); |
+} |
+ |
+ |
void AnalyzeStackOfEvalWithSourceURL( |
const v8::FunctionCallbackInfo<v8::Value>& args) { |
v8::HandleScope scope(args.GetIsolate()); |