@@ -401,6 +401,69 @@ TEST_F(EnvironmentTest, SetImmediateCleanup) {
401401 EXPECT_EQ (called_unref, 0 );
402402}
403403
404+ TEST_F (EnvironmentTest, RunAndClearNativeImmediatesSkipsEmptyScope) {
405+ const v8::HandleScope handle_scope (isolate_);
406+ const Argv argv;
407+ Env env{handle_scope, argv};
408+ v8::Local<v8::Context> context = env.context ();
409+
410+ using IntVec = std::vector<int >;
411+ IntVec callback_calls;
412+ v8::Local<v8::Function> must_call =
413+ v8::Function::New (
414+ context,
415+ [](const v8::FunctionCallbackInfo<v8::Value>& info) {
416+ IntVec* callback_calls =
417+ static_cast <IntVec*>(info.Data ().As <v8::External>()->Value (
418+ v8::kExternalPointerTypeTagDefault ));
419+ callback_calls->push_back (info[0 ].As <v8::Int32>()->Value ());
420+ },
421+ v8::External::New (isolate_,
422+ static_cast <void *>(&callback_calls),
423+ v8::kExternalPointerTypeTagDefault ))
424+ .ToLocalChecked ();
425+ context->Global ()
426+ ->Set (context,
427+ v8::String::NewFromUtf8Literal (isolate_, " mustCall" ),
428+ must_call)
429+ .Check ();
430+
431+ v8::Local<v8::Function> eval_in_env =
432+ node::LoadEnvironment (*env, " return eval;" )
433+ .ToLocalChecked ()
434+ .As <v8::Function>();
435+
436+ v8::Local<v8::Value> queue_microtask = v8::String::NewFromUtf8Literal (
437+ isolate_, " Promise.resolve().then(() => mustCall(1));" );
438+ eval_in_env->Call (context, v8::Null (isolate_), 1 , &queue_microtask)
439+ .ToLocalChecked ();
440+ EXPECT_TRUE (callback_calls.empty ());
441+ (*env)->RunAndClearNativeImmediates ();
442+ EXPECT_TRUE (callback_calls.empty ());
443+
444+ context->GetMicrotaskQueue ()->PerformCheckpoint (isolate_);
445+ EXPECT_EQ (callback_calls, (IntVec{1 }));
446+ callback_calls.clear ();
447+
448+ queue_microtask = v8::String::NewFromUtf8Literal (
449+ isolate_, " Promise.resolve().then(() => mustCall(2));" );
450+ eval_in_env->Call (context, v8::Null (isolate_), 1 , &queue_microtask)
451+ .ToLocalChecked ();
452+ EXPECT_TRUE (callback_calls.empty ());
453+
454+ bool native_immediate_called = false ;
455+ (*env)->SetImmediate (
456+ [&](node::Environment* env_arg) {
457+ EXPECT_EQ (env_arg, *env);
458+ native_immediate_called = true ;
459+ },
460+ node::CallbackFlags::kRefed );
461+
462+ (*env)->RunAndClearNativeImmediates ();
463+ EXPECT_TRUE (native_immediate_called);
464+ EXPECT_EQ (callback_calls, (IntVec{2 }));
465+ }
466+
404467static char hello[] = " hello" ;
405468
406469TEST_F (EnvironmentTest, BufferWithFreeCallbackIsDetached) {
0 commit comments