| Index: test/cctest/test-api.cc
|
| diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc
|
| index bf2ef23ffaea84e18e353369ed031017bcd31092..1da986dc57d6f5e1dd6324153272230a257002a7 100644
|
| --- a/test/cctest/test-api.cc
|
| +++ b/test/cctest/test-api.cc
|
| @@ -17618,6 +17618,243 @@ TEST(RethrowBogusErrorStackTrace) {
|
| }
|
|
|
|
|
| +v8::PromiseRejectEvent reject_event = v8::kPromiseRejectWithNoHandler;
|
| +int promise_reject_counter = 0;
|
| +int promise_revoke_counter = 0;
|
| +
|
| +void PromiseRejectCallback(v8::Handle<v8::Promise> promise,
|
| + v8::Handle<v8::Value> value,
|
| + v8::PromiseRejectEvent event) {
|
| + if (event == v8::kPromiseRejectWithNoHandler) {
|
| + promise_reject_counter++;
|
| + CcTest::global()->Set(v8_str("rejected"), promise);
|
| + CcTest::global()->Set(v8_str("value"), value);
|
| + } else {
|
| + promise_revoke_counter++;
|
| + CcTest::global()->Set(v8_str("revoked"), promise);
|
| + CHECK(value.IsEmpty());
|
| + }
|
| +}
|
| +
|
| +
|
| +v8::Handle<v8::Promise> GetPromise(const char* name) {
|
| + return v8::Handle<v8::Promise>::Cast(CcTest::global()->Get(v8_str(name)));
|
| +}
|
| +
|
| +
|
| +v8::Handle<v8::Value> RejectValue() {
|
| + return CcTest::global()->Get(v8_str("value"));
|
| +}
|
| +
|
| +
|
| +void ResetPromiseStates() {
|
| + promise_reject_counter = 0;
|
| + promise_revoke_counter = 0;
|
| + CcTest::global()->Set(v8_str("rejected"), v8_str(""));
|
| + CcTest::global()->Set(v8_str("value"), v8_str(""));
|
| + CcTest::global()->Set(v8_str("revoked"), v8_str(""));
|
| +}
|
| +
|
| +
|
| +TEST(PromiseRejectCallback) {
|
| + LocalContext env;
|
| + v8::Isolate* isolate = env->GetIsolate();
|
| + v8::HandleScope scope(isolate);
|
| +
|
| + isolate->SetPromiseRejectCallback(PromiseRejectCallback);
|
| +
|
| + ResetPromiseStates();
|
| +
|
| + // Create promise p0.
|
| + CompileRun(
|
| + "var reject; \n"
|
| + "var p0 = new Promise( \n"
|
| + " function(res, rej) { \n"
|
| + " reject = rej; \n"
|
| + " } \n"
|
| + "); \n");
|
| + CHECK(!GetPromise("p0")->HasRejectHandler());
|
| + CHECK_EQ(0, promise_reject_counter);
|
| + CHECK_EQ(0, promise_revoke_counter);
|
| +
|
| + // Add resolve handler (and default reject handler) to p0.
|
| + CompileRun("var p1 = p0.then(function(){});");
|
| + CHECK(GetPromise("p0")->HasRejectHandler());
|
| + CHECK(!GetPromise("p1")->HasRejectHandler());
|
| + CHECK_EQ(0, promise_reject_counter);
|
| + CHECK_EQ(0, promise_revoke_counter);
|
| +
|
| + // Reject p0.
|
| + CompileRun("reject('ppp');");
|
| + CHECK(GetPromise("p0")->HasRejectHandler());
|
| + CHECK(!GetPromise("p1")->HasRejectHandler());
|
| + CHECK_EQ(1, promise_reject_counter);
|
| + CHECK_EQ(0, promise_revoke_counter);
|
| + CHECK_EQ(v8::kPromiseRejectWithNoHandler, reject_event);
|
| + CHECK(GetPromise("rejected")->Equals(GetPromise("p1")));
|
| + CHECK(RejectValue()->Equals(v8_str("ppp")));
|
| +
|
| + // Reject p0 again. Callback is not triggered again.
|
| + CompileRun("reject();");
|
| + CHECK(GetPromise("p0")->HasRejectHandler());
|
| + CHECK(!GetPromise("p1")->HasRejectHandler());
|
| + CHECK_EQ(1, promise_reject_counter);
|
| + CHECK_EQ(0, promise_revoke_counter);
|
| +
|
| + // Add resolve handler to p1.
|
| + CompileRun("var p2 = p1.then(function(){});");
|
| + CHECK(GetPromise("p0")->HasRejectHandler());
|
| + CHECK(GetPromise("p1")->HasRejectHandler());
|
| + CHECK(!GetPromise("p2")->HasRejectHandler());
|
| + CHECK_EQ(2, promise_reject_counter);
|
| + CHECK_EQ(1, promise_revoke_counter);
|
| + CHECK(GetPromise("rejected")->Equals(GetPromise("p2")));
|
| + CHECK(RejectValue()->Equals(v8_str("ppp")));
|
| + CHECK(GetPromise("revoked")->Equals(GetPromise("p1")));
|
| +
|
| + ResetPromiseStates();
|
| +
|
| + // Create promise q0.
|
| + CompileRun(
|
| + "var q0 = new Promise( \n"
|
| + " function(res, rej) { \n"
|
| + " reject = rej; \n"
|
| + " } \n"
|
| + "); \n");
|
| + CHECK(!GetPromise("q0")->HasRejectHandler());
|
| + CHECK_EQ(0, promise_reject_counter);
|
| + CHECK_EQ(0, promise_revoke_counter);
|
| +
|
| + // Add reject handler to q0.
|
| + CompileRun("var q1 = q0.catch(function() {});");
|
| + CHECK(GetPromise("q0")->HasRejectHandler());
|
| + CHECK(!GetPromise("q1")->HasRejectHandler());
|
| + CHECK_EQ(0, promise_reject_counter);
|
| + CHECK_EQ(0, promise_revoke_counter);
|
| +
|
| + // Reject q0.
|
| + CompileRun("reject('qq')");
|
| + CHECK(GetPromise("q0")->HasRejectHandler());
|
| + CHECK(!GetPromise("q1")->HasRejectHandler());
|
| + CHECK_EQ(0, promise_reject_counter);
|
| + CHECK_EQ(0, promise_revoke_counter);
|
| +
|
| + // Add a new reject handler, which rejects by returning Promise.reject().
|
| + CompileRun(
|
| + "var q2 = q0.catch( \n"
|
| + " function() { \n"
|
| + " return Promise.reject('qqq'); \n"
|
| + " } \n"
|
| + "); \n");
|
| + CHECK(GetPromise("q0")->HasRejectHandler());
|
| + CHECK(!GetPromise("q1")->HasRejectHandler());
|
| + CHECK(!GetPromise("q2")->HasRejectHandler());
|
| + CHECK_EQ(1, promise_reject_counter);
|
| + CHECK_EQ(0, promise_revoke_counter);
|
| + CHECK(GetPromise("rejected")->Equals(GetPromise("q2")));
|
| + CHECK(RejectValue()->Equals(v8_str("qqq")));
|
| +
|
| + // Add a reject handler to the resolved q1, which rejects by throwing.
|
| + CompileRun(
|
| + "var q3 = q1.then( \n"
|
| + " function() { \n"
|
| + " throw 'qqqq'; \n"
|
| + " } \n"
|
| + "); \n");
|
| + CHECK(GetPromise("q0")->HasRejectHandler());
|
| + CHECK(GetPromise("q1")->HasRejectHandler());
|
| + CHECK(!GetPromise("q2")->HasRejectHandler());
|
| + CHECK(!GetPromise("q3")->HasRejectHandler());
|
| + CHECK_EQ(2, promise_reject_counter);
|
| + CHECK_EQ(0, promise_revoke_counter);
|
| + CHECK(GetPromise("rejected")->Equals(GetPromise("q3")));
|
| + CHECK(RejectValue()->Equals(v8_str("qqqq")));
|
| +
|
| + ResetPromiseStates();
|
| +
|
| + // Create promise r0, which has three handlers, two of which handle rejects.
|
| + CompileRun(
|
| + "var r0 = new Promise( \n"
|
| + " function(res, rej) { \n"
|
| + " reject = rej; \n"
|
| + " } \n"
|
| + "); \n"
|
| + "var r1 = r0.catch(function() {}); \n"
|
| + "var r2 = r0.then(function() {}); \n"
|
| + "var r3 = r0.then(function() {}, \n"
|
| + " function() {}); \n");
|
| + CHECK(GetPromise("r0")->HasRejectHandler());
|
| + CHECK(!GetPromise("r1")->HasRejectHandler());
|
| + CHECK(!GetPromise("r2")->HasRejectHandler());
|
| + CHECK(!GetPromise("r3")->HasRejectHandler());
|
| + CHECK_EQ(0, promise_reject_counter);
|
| + CHECK_EQ(0, promise_revoke_counter);
|
| +
|
| + // Reject r0.
|
| + CompileRun("reject('rrr')");
|
| + CHECK(GetPromise("r0")->HasRejectHandler());
|
| + CHECK(!GetPromise("r1")->HasRejectHandler());
|
| + CHECK(!GetPromise("r2")->HasRejectHandler());
|
| + CHECK(!GetPromise("r3")->HasRejectHandler());
|
| + CHECK_EQ(1, promise_reject_counter);
|
| + CHECK_EQ(0, promise_revoke_counter);
|
| + CHECK(GetPromise("rejected")->Equals(GetPromise("r2")));
|
| + CHECK(RejectValue()->Equals(v8_str("rrr")));
|
| +
|
| + // Add reject handler to r2.
|
| + CompileRun("var r4 = r2.catch(function() {});");
|
| + CHECK(GetPromise("r0")->HasRejectHandler());
|
| + CHECK(!GetPromise("r1")->HasRejectHandler());
|
| + CHECK(GetPromise("r2")->HasRejectHandler());
|
| + CHECK(!GetPromise("r3")->HasRejectHandler());
|
| + CHECK(!GetPromise("r4")->HasRejectHandler());
|
| + CHECK_EQ(1, promise_reject_counter);
|
| + CHECK_EQ(1, promise_revoke_counter);
|
| + CHECK(GetPromise("revoked")->Equals(GetPromise("r2")));
|
| + CHECK(RejectValue()->Equals(v8_str("rrr")));
|
| +
|
| + // Add reject handlers to r4.
|
| + CompileRun("var r5 = r4.then(function() {}, function() {});");
|
| + CHECK(GetPromise("r0")->HasRejectHandler());
|
| + CHECK(!GetPromise("r1")->HasRejectHandler());
|
| + CHECK(GetPromise("r2")->HasRejectHandler());
|
| + CHECK(!GetPromise("r3")->HasRejectHandler());
|
| + CHECK(GetPromise("r4")->HasRejectHandler());
|
| + CHECK(!GetPromise("r5")->HasRejectHandler());
|
| + CHECK_EQ(1, promise_reject_counter);
|
| + CHECK_EQ(1, promise_revoke_counter);
|
| +
|
| + ResetPromiseStates();
|
| +
|
| + // Create promise s0, which has three handlers, none of which handle rejects.
|
| + CompileRun(
|
| + "var s0 = new Promise( \n"
|
| + " function(res, rej) { \n"
|
| + " reject = rej; \n"
|
| + " } \n"
|
| + "); \n"
|
| + "var s1 = s0.then(function() {}); \n"
|
| + "var s2 = s0.then(function() {}); \n"
|
| + "var s3 = s0.then(function() {}); \n");
|
| + CHECK(GetPromise("s0")->HasRejectHandler());
|
| + CHECK(!GetPromise("s1")->HasRejectHandler());
|
| + CHECK(!GetPromise("s2")->HasRejectHandler());
|
| + CHECK(!GetPromise("s3")->HasRejectHandler());
|
| + CHECK_EQ(0, promise_reject_counter);
|
| + CHECK_EQ(0, promise_revoke_counter);
|
| +
|
| + // Reject s0.
|
| + CompileRun("reject('sss')");
|
| + CHECK(GetPromise("s0")->HasRejectHandler());
|
| + CHECK(!GetPromise("s1")->HasRejectHandler());
|
| + CHECK(!GetPromise("s2")->HasRejectHandler());
|
| + CHECK(!GetPromise("s3")->HasRejectHandler());
|
| + CHECK_EQ(3, promise_reject_counter);
|
| + CHECK_EQ(0, promise_revoke_counter);
|
| + CHECK(RejectValue()->Equals(v8_str("sss")));
|
| +}
|
| +
|
| +
|
| void AnalyzeStackOfEvalWithSourceURL(
|
| const v8::FunctionCallbackInfo<v8::Value>& args) {
|
| v8::HandleScope scope(args.GetIsolate());
|
|
|