1'use strict';
2// Flags: --expose-gc
3
4const common = require('../../common');
5const test_finalizer = require(`./build/${common.buildType}/test_finalizer`);
6const assert = require('assert');
7
8// The goal of this test is to show that we can run "pure" finalizers in the
9// current JS loop tick. Thus, we do not use common.gcUntil function works
10// asynchronously using micro tasks.
11// We use IIFE for the obj scope instead of {} to be compatible with
12// non-V8 JS engines that do not support scoped variables.
13(() => {
14  const obj = {};
15  test_finalizer.addFinalizer(obj);
16})();
17
18for (let i = 0; i < 10; ++i) {
19  global.gc();
20  if (test_finalizer.getFinalizerCallCount() === 1) {
21    break;
22  }
23}
24
25assert.strictEqual(test_finalizer.getFinalizerCallCount(), 1);
26
27// The finalizer that access JS cannot run synchronously. They are run in the
28// next JS loop tick. Thus, we must use common.gcUntil.
29async function runAsyncTests() {
30  // We do not use common.mustCall() because we want to see the finalizer
31  // called in response to GC and not as a part of env destruction.
32  let js_is_called = false;
33  // We use IIFE for the obj scope instead of {} to be compatible with
34  // non-V8 JS engines that do not support scoped variables.
35  (() => {
36    const obj = {};
37    test_finalizer.addFinalizerWithJS(obj, () => { js_is_called = true; });
38  })();
39  await common.gcUntil('ensure JS finalizer called',
40                       () => (test_finalizer.getFinalizerCallCount() === 2));
41  assert(js_is_called);
42}
43runAsyncTests();
44