@ 261106.2
current
'use strict';

const common = require('../../common');
const assert = require('assert');
const binding = require(`./build/${common.buildType}/binding`);
const async_hooks = require('async_hooks');

binding.runSubclassTest();

const kObjectTag = Symbol('kObjectTag');
const rootAsyncId = async_hooks.executionAsyncId();

const bindingUids = [];
let expectedTriggerId;
let before = 0;
let after = 0;
let destroy = 0;

async_hooks.createHook({
  init: common.mustCall((id, type, triggerAsyncId, resource) => {
    assert.strictEqual(typeof id, 'number');
    assert.strictEqual(typeof resource, 'object');
    assert(id > 1);
    if (type === 'foobär') {
      assert.strictEqual(resource.kObjectTag, kObjectTag);
      assert.strictEqual(triggerAsyncId, expectedTriggerId);
      bindingUids.push(id);
    }
  }, 7),

  before(id) {
    if (bindingUids.includes(id)) before++;
  },

  after(id) {
    if (bindingUids.includes(id)) after++;
  },

  destroy(id) {
    if (bindingUids.includes(id)) destroy++;
  },
}).enable();

for (const call of [binding.callViaFunction,
                    binding.callViaString,
                    binding.callViaUtf8Name]) {
  for (const passedTriggerId of [undefined, 12345]) {
    let uid;
    const object = {
      methöd(arg) {
        // eslint-disable-next-line node-core/must-call-assert
        assert.strictEqual(this, object);
        // eslint-disable-next-line node-core/must-call-assert
        assert.strictEqual(arg, 42);
        // eslint-disable-next-line node-core/must-call-assert
        assert.strictEqual(async_hooks.executionAsyncId(), uid);
        return 'baz';
      },
      kObjectTag,
    };

    if (passedTriggerId === undefined)
      expectedTriggerId = rootAsyncId;
    else
      expectedTriggerId = passedTriggerId;

    const resource = binding.createAsyncResource(object, passedTriggerId);
    uid = bindingUids[bindingUids.length - 1];

    const ret = call(resource);
    assert.strictEqual(ret, 'baz');
    assert.strictEqual(binding.getResource(resource), object);
    assert.strictEqual(binding.getAsyncId(resource), uid);
    assert.strictEqual(binding.getTriggerAsyncId(resource), expectedTriggerId);

    binding.destroyAsyncResource(resource);
  }
}

setImmediate(common.mustCall(() => {
  assert.strictEqual(bindingUids.length, 6);
  assert.strictEqual(before, bindingUids.length);
  assert.strictEqual(after, bindingUids.length);
  assert.strictEqual(destroy, bindingUids.length);
}));