Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(621)

Unified Diff: test/cctest/test-api.cc

Issue 2575313002: [promisehook] Implement PromiseHook (Closed)
Patch Set: rebase + add comments Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
Download patch
« no previous file with comments | « src/wasm/wasm-module.cc ('k') | test/cctest/test-code-stub-assembler.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: test/cctest/test-api.cc
diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc
index 1fb5e5620a684dba9a23af511eaffcf54e10a47b..ca2c8dea063c4fca55ad398b7e1c8897f15900b6 100644
--- a/test/cctest/test-api.cc
+++ b/test/cctest/test-api.cc
@@ -18139,6 +18139,290 @@ TEST(InlineScriptWithSourceURLInStackTrace) {
CHECK(CompileRunWithOrigin(code.start(), "url", 0, 1)->IsUndefined());
}
+void SetPromise(const char* name, v8::Local<v8::Promise> promise) {
+ CcTest::global()
+ ->Set(CcTest::isolate()->GetCurrentContext(), v8_str(name), promise)
+ .FromJust();
+}
+
+class PromiseHookData {
+ public:
+ int before_hook_count = 0;
+ int after_hook_count = 0;
+ int promise_hook_count = 0;
+ int parent_promise_count = 0;
+ bool check_value = true;
+ std::string promise_hook_value;
+
+ void Reset() {
+ before_hook_count = 0;
+ after_hook_count = 0;
+ promise_hook_count = 0;
+ parent_promise_count = 0;
+ check_value = true;
+ promise_hook_value = "";
+ }
+};
+
+PromiseHookData* promise_hook_data;
+
+void CustomPromiseHook(v8::PromiseHookType type, v8::Local<v8::Promise> promise,
+ v8::Local<v8::Value> parentPromise) {
+ promise_hook_data->promise_hook_count++;
+ switch (type) {
+ case v8::PromiseHookType::kInit:
+ SetPromise("init", promise);
+
+ if (!parentPromise->IsUndefined()) {
+ promise_hook_data->parent_promise_count++;
+ SetPromise("parent", v8::Local<v8::Promise>::Cast(parentPromise));
+ }
+
+ break;
+ case v8::PromiseHookType::kResolve:
+ SetPromise("resolve", promise);
+ break;
+ case v8::PromiseHookType::kBefore:
+ promise_hook_data->before_hook_count++;
+ CHECK(promise_hook_data->before_hook_count >
+ promise_hook_data->after_hook_count);
+ CHECK(CcTest::global()
+ ->Get(CcTest::isolate()->GetCurrentContext(), v8_str("value"))
+ .ToLocalChecked()
+ ->Equals(CcTest::isolate()->GetCurrentContext(), v8_str(""))
+ .FromJust());
+ SetPromise("before", promise);
+ break;
+ case v8::PromiseHookType::kAfter:
+ promise_hook_data->after_hook_count++;
+ CHECK(promise_hook_data->after_hook_count <=
+ promise_hook_data->before_hook_count);
+ if (promise_hook_data->check_value) {
+ CHECK(
+ CcTest::global()
+ ->Get(CcTest::isolate()->GetCurrentContext(), v8_str("value"))
+ .ToLocalChecked()
+ ->Equals(CcTest::isolate()->GetCurrentContext(),
+ v8_str(promise_hook_data->promise_hook_value.c_str()))
+ .FromJust());
+ }
+ SetPromise("after", promise);
+ break;
+ }
+}
+
+TEST(PromiseHook) {
+ LocalContext env;
+ v8::Isolate* isolate = env->GetIsolate();
+ v8::HandleScope scope(isolate);
+
+ v8::Local<v8::Object> global = CcTest::global();
+ v8::Local<v8::Context> context = CcTest::isolate()->GetCurrentContext();
+
+ promise_hook_data = new PromiseHookData();
+ promise_hook_data->promise_hook_value = "fulfilled";
+ const char* source =
+ "var resolve, value = ''; \n"
+ "var p = new Promise(r => resolve = r); \n";
+
+ isolate->SetPromiseHook(CustomPromiseHook);
+
+ CompileRun(source);
+ auto init_promise = global->Get(context, v8_str("init")).ToLocalChecked();
+ CHECK(GetPromise("p")->Equals(env.local(), init_promise).FromJust());
+ CHECK_EQ(1, promise_hook_data->promise_hook_count);
+ CHECK_EQ(0, promise_hook_data->parent_promise_count);
+
+ CompileRun("var p1 = p.then(() => { value = 'fulfilled'; }); \n");
+ init_promise = global->Get(context, v8_str("init")).ToLocalChecked();
+ auto parent_promise = global->Get(context, v8_str("parent")).ToLocalChecked();
+ CHECK(GetPromise("p1")->Equals(env.local(), init_promise).FromJust());
+ CHECK(GetPromise("p")->Equals(env.local(), parent_promise).FromJust());
+ CHECK_EQ(2, promise_hook_data->promise_hook_count);
+ CHECK_EQ(1, promise_hook_data->parent_promise_count);
+
+ CompileRun("resolve(); \n");
+ auto resolve_promise =
+ global->Get(context, v8_str("resolve")).ToLocalChecked();
+ auto before_promise = global->Get(context, v8_str("before")).ToLocalChecked();
+ auto after_promise = global->Get(context, v8_str("after")).ToLocalChecked();
+ CHECK(GetPromise("p")->Equals(env.local(), before_promise).FromJust());
+ CHECK(GetPromise("p")->Equals(env.local(), after_promise).FromJust());
+ CHECK(GetPromise("p1")->Equals(env.local(), resolve_promise).FromJust());
+ CHECK_EQ(6, promise_hook_data->promise_hook_count);
+
+ promise_hook_data->Reset();
+ promise_hook_data->promise_hook_value = "rejected";
+ source =
+ "var reject, value = ''; \n"
+ "var p = new Promise((_, r) => reject = r); \n";
+
+ CompileRun(source);
+ init_promise = global->Get(context, v8_str("init")).ToLocalChecked();
+ CHECK(GetPromise("p")->Equals(env.local(), init_promise).FromJust());
+ CHECK_EQ(1, promise_hook_data->promise_hook_count);
+ CHECK_EQ(0, promise_hook_data->parent_promise_count);
+
+ CompileRun("var p1 = p.catch(() => { value = 'rejected'; }); \n");
+ init_promise = global->Get(context, v8_str("init")).ToLocalChecked();
+ parent_promise = global->Get(context, v8_str("parent")).ToLocalChecked();
+ CHECK(GetPromise("p1")->Equals(env.local(), init_promise).FromJust());
+ CHECK(GetPromise("p")->Equals(env.local(), parent_promise).FromJust());
+ CHECK_EQ(2, promise_hook_data->promise_hook_count);
+ CHECK_EQ(1, promise_hook_data->parent_promise_count);
+
+ CompileRun("reject(); \n");
+ resolve_promise = global->Get(context, v8_str("resolve")).ToLocalChecked();
+ before_promise = global->Get(context, v8_str("before")).ToLocalChecked();
+ after_promise = global->Get(context, v8_str("after")).ToLocalChecked();
+ CHECK(GetPromise("p")->Equals(env.local(), before_promise).FromJust());
+ CHECK(GetPromise("p")->Equals(env.local(), after_promise).FromJust());
+ CHECK(GetPromise("p1")->Equals(env.local(), resolve_promise).FromJust());
+ CHECK_EQ(6, promise_hook_data->promise_hook_count);
+
+ promise_hook_data->Reset();
+ promise_hook_data->promise_hook_value = "Promise.resolve";
+ source =
+ "var value = ''; \n"
+ "var p = Promise.resolve('Promise.resolve'); \n";
+
+ CompileRun(source);
+ init_promise = global->Get(context, v8_str("init")).ToLocalChecked();
+ CHECK(GetPromise("p")->Equals(env.local(), init_promise).FromJust());
+ // init hook and resolve hook
+ CHECK_EQ(2, promise_hook_data->promise_hook_count);
+ CHECK_EQ(0, promise_hook_data->parent_promise_count);
+ resolve_promise = global->Get(context, v8_str("resolve")).ToLocalChecked();
+ CHECK(GetPromise("p")->Equals(env.local(), resolve_promise).FromJust());
+
+ CompileRun("var p1 = p.then((v) => { value = v; }); \n");
+ init_promise = global->Get(context, v8_str("init")).ToLocalChecked();
+ resolve_promise = global->Get(context, v8_str("resolve")).ToLocalChecked();
+ parent_promise = global->Get(context, v8_str("parent")).ToLocalChecked();
+ before_promise = global->Get(context, v8_str("before")).ToLocalChecked();
+ after_promise = global->Get(context, v8_str("after")).ToLocalChecked();
+ CHECK(GetPromise("p1")->Equals(env.local(), init_promise).FromJust());
+ CHECK(GetPromise("p1")->Equals(env.local(), resolve_promise).FromJust());
+ CHECK(GetPromise("p")->Equals(env.local(), parent_promise).FromJust());
+ CHECK(GetPromise("p")->Equals(env.local(), before_promise).FromJust());
+ CHECK(GetPromise("p")->Equals(env.local(), after_promise).FromJust());
+ CHECK_EQ(6, promise_hook_data->promise_hook_count);
+ CHECK_EQ(1, promise_hook_data->parent_promise_count);
+
+ promise_hook_data->Reset();
+ source =
+ "var resolve, value = ''; \n"
+ "var p = new Promise((_, r) => resolve = r); \n";
+
+ CompileRun(source);
+ init_promise = global->Get(context, v8_str("init")).ToLocalChecked();
+ CHECK(GetPromise("p")->Equals(env.local(), init_promise).FromJust());
+ CHECK_EQ(1, promise_hook_data->promise_hook_count);
+ CHECK_EQ(0, promise_hook_data->parent_promise_count);
+
+ CompileRun("resolve(); \n");
+ resolve_promise = global->Get(context, v8_str("resolve")).ToLocalChecked();
+ CHECK(GetPromise("p")->Equals(env.local(), resolve_promise).FromJust());
+ CHECK_EQ(2, promise_hook_data->promise_hook_count);
+
+ promise_hook_data->Reset();
+ source =
+ "var reject, value = ''; \n"
+ "var p = new Promise((_, r) => reject = r); \n";
+
+ CompileRun(source);
+ init_promise = global->Get(context, v8_str("init")).ToLocalChecked();
+ CHECK(GetPromise("p")->Equals(env.local(), init_promise).FromJust());
+ CHECK_EQ(1, promise_hook_data->promise_hook_count);
+ CHECK_EQ(0, promise_hook_data->parent_promise_count);
+
+ CompileRun("reject(); \n");
+ resolve_promise = global->Get(context, v8_str("resolve")).ToLocalChecked();
+ CHECK(GetPromise("p")->Equals(env.local(), resolve_promise).FromJust());
+ CHECK_EQ(2, promise_hook_data->promise_hook_count);
+
+ promise_hook_data->Reset();
+ // This test triggers after callbacks right after each other, so
+ // lets just check the value at the end.
+ promise_hook_data->check_value = false;
+ promise_hook_data->promise_hook_value = "Promise.all";
+ source =
+ "var resolve, value = ''; \n"
+ "var tempPromise = new Promise(r => resolve = r); \n"
+ "var p = Promise.all([tempPromise]);\n "
+ "var p1 = p.then(v => value = v[0]); \n";
+
+ CompileRun(source);
+ // 1) init hook (tempPromise)
+ // 2) init hook (p)
+ // 3) init hook (throwaway Promise in Promise.all, p)
+ // 4) init hook (p1, p)
+ CHECK_EQ(4, promise_hook_data->promise_hook_count);
+ CHECK_EQ(2, promise_hook_data->parent_promise_count);
+
+ promise_hook_data->promise_hook_value = "Promise.all";
+ CompileRun("resolve('Promise.all'); \n");
+ resolve_promise = global->Get(context, v8_str("resolve")).ToLocalChecked();
+ CHECK(GetPromise("p1")->Equals(env.local(), resolve_promise).FromJust());
+ // 5) resolve hook (tempPromise)
+ // 6) resolve hook (throwaway Promise in Promise.all)
+ // 6) before hook (throwaway Promise in Promise.all)
+ // 7) after hook (throwaway Promise in Promise.all)
+ // 8) before hook (p)
+ // 9) after hook (p)
+ // 10) resolve hook (p1)
+ // 11) before hook (p1)
+ // 12) after hook (p1)
+ CHECK_EQ(12, promise_hook_data->promise_hook_count);
+ CHECK(CcTest::global()
+ ->Get(CcTest::isolate()->GetCurrentContext(), v8_str("value"))
+ .ToLocalChecked()
+ ->Equals(CcTest::isolate()->GetCurrentContext(),
+ v8_str(promise_hook_data->promise_hook_value.c_str()))
+ .FromJust());
+
+ promise_hook_data->Reset();
+ // This test triggers after callbacks right after each other, so
+ // lets just check the value at the end.
+ promise_hook_data->check_value = false;
+ promise_hook_data->promise_hook_value = "Promise.race";
+ source =
+ "var resolve, value = ''; \n"
+ "var tempPromise = new Promise(r => resolve = r); \n"
+ "var p = Promise.race([tempPromise]);\n "
+ "var p1 = p.then(v => value = v); \n";
+
+ CompileRun(source);
+ // 1) init hook (tempPromise)
+ // 2) init hook (p)
+ // 3) init hook (throwaway Promise in Promise.race, p)
+ // 4) init hook (p1, p)
+ CHECK_EQ(4, promise_hook_data->promise_hook_count);
+ CHECK_EQ(2, promise_hook_data->parent_promise_count);
+
+ promise_hook_data->promise_hook_value = "Promise.race";
+ CompileRun("resolve('Promise.race'); \n");
+ resolve_promise = global->Get(context, v8_str("resolve")).ToLocalChecked();
+ CHECK(GetPromise("p1")->Equals(env.local(), resolve_promise).FromJust());
+ // 5) resolve hook (tempPromise)
+ // 6) resolve hook (throwaway Promise in Promise.race)
+ // 6) before hook (throwaway Promise in Promise.race)
+ // 7) after hook (throwaway Promise in Promise.race)
+ // 8) before hook (p)
+ // 9) after hook (p)
+ // 10) resolve hook (p1)
+ // 11) before hook (p1)
+ // 12) after hook (p1)
+ CHECK_EQ(12, promise_hook_data->promise_hook_count);
+ CHECK(CcTest::global()
+ ->Get(CcTest::isolate()->GetCurrentContext(), v8_str("value"))
+ .ToLocalChecked()
+ ->Equals(CcTest::isolate()->GetCurrentContext(),
+ v8_str(promise_hook_data->promise_hook_value.c_str()))
+ .FromJust());
+
+ delete promise_hook_data;
+}
void AnalyzeStackOfDynamicScriptWithSourceURL(
const v8::FunctionCallbackInfo<v8::Value>& args) {
« no previous file with comments | « src/wasm/wasm-module.cc ('k') | test/cctest/test-code-stub-assembler.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698