@@ -401,6 +401,72 @@ 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 ()->Set (
426+ context,
427+ v8::String::NewFromUtf8Literal (isolate_, " mustCall" ),
428+ must_call).Check ();
429+
430+ v8::Local<v8::Function> eval_in_env =
431+ node::LoadEnvironment (*env, " return eval;" )
432+ .ToLocalChecked ()
433+ .As <v8::Function>();
434+
435+ v8::Local<v8::Value> queue_microtask =
436+ v8::String::NewFromUtf8Literal (
437+ isolate_, " Promise.resolve().then(() => mustCall(1));" );
438+ eval_in_env->Call (context,
439+ v8::Null (isolate_),
440+ 1 ,
441+ &queue_microtask).ToLocalChecked ();
442+ EXPECT_TRUE (callback_calls.empty ());
443+ (*env)->RunAndClearNativeImmediates ();
444+ EXPECT_TRUE (callback_calls.empty ());
445+
446+ context->GetMicrotaskQueue ()->PerformCheckpoint (isolate_);
447+ EXPECT_EQ (callback_calls, (IntVec { 1 }));
448+ callback_calls.clear ();
449+
450+ queue_microtask =
451+ v8::String::NewFromUtf8Literal (
452+ isolate_, " Promise.resolve().then(() => mustCall(2));" );
453+ eval_in_env->Call (context,
454+ v8::Null (isolate_),
455+ 1 ,
456+ &queue_microtask).ToLocalChecked ();
457+ EXPECT_TRUE (callback_calls.empty ());
458+
459+ bool native_immediate_called = false ;
460+ (*env)->SetImmediate ([&](node::Environment* env_arg) {
461+ EXPECT_EQ (env_arg, *env);
462+ native_immediate_called = true ;
463+ }, node::CallbackFlags::kRefed );
464+
465+ (*env)->RunAndClearNativeImmediates ();
466+ EXPECT_TRUE (native_immediate_called);
467+ EXPECT_EQ (callback_calls, (IntVec { 2 }));
468+ }
469+
404470static char hello[] = " hello" ;
405471
406472TEST_F (EnvironmentTest, BufferWithFreeCallbackIsDetached) {
0 commit comments