11cb0ef41Sopenharmony_ci'use strict';
21cb0ef41Sopenharmony_ci
31cb0ef41Sopenharmony_ciconst common = require('../common');
41cb0ef41Sopenharmony_ciconst assert = require('assert');
51cb0ef41Sopenharmony_ci
61cb0ef41Sopenharmony_ciconst {
71cb0ef41Sopenharmony_ci  createHistogram,
81cb0ef41Sopenharmony_ci  performance,
91cb0ef41Sopenharmony_ci  PerformanceObserver
101cb0ef41Sopenharmony_ci} = require('perf_hooks');
111cb0ef41Sopenharmony_ci
121cb0ef41Sopenharmony_ciconst {
131cb0ef41Sopenharmony_ci  setTimeout: sleep
141cb0ef41Sopenharmony_ci} = require('timers/promises');
151cb0ef41Sopenharmony_ci
161cb0ef41Sopenharmony_ci{
171cb0ef41Sopenharmony_ci  // Intentional non-op. Do not wrap in common.mustCall();
181cb0ef41Sopenharmony_ci  const n = performance.timerify(function noop() {});
191cb0ef41Sopenharmony_ci
201cb0ef41Sopenharmony_ci  const obs = new PerformanceObserver(common.mustCall((list) => {
211cb0ef41Sopenharmony_ci    const entries = list.getEntries();
221cb0ef41Sopenharmony_ci    const entry = entries[0];
231cb0ef41Sopenharmony_ci    assert(entry);
241cb0ef41Sopenharmony_ci    assert.strictEqual(entry.name, 'noop');
251cb0ef41Sopenharmony_ci    assert.strictEqual(entry.entryType, 'function');
261cb0ef41Sopenharmony_ci    assert.strictEqual(typeof entry.duration, 'number');
271cb0ef41Sopenharmony_ci    assert.strictEqual(typeof entry.startTime, 'number');
281cb0ef41Sopenharmony_ci    obs.disconnect();
291cb0ef41Sopenharmony_ci  }));
301cb0ef41Sopenharmony_ci  obs.observe({ entryTypes: ['function'] });
311cb0ef41Sopenharmony_ci  n();
321cb0ef41Sopenharmony_ci}
331cb0ef41Sopenharmony_ci
341cb0ef41Sopenharmony_ci{
351cb0ef41Sopenharmony_ci  // If the error throws, the error should just be bubbled up and the
361cb0ef41Sopenharmony_ci  // performance timeline entry will not be reported.
371cb0ef41Sopenharmony_ci  const obs = new PerformanceObserver(common.mustNotCall());
381cb0ef41Sopenharmony_ci  obs.observe({ entryTypes: ['function'] });
391cb0ef41Sopenharmony_ci  const n = performance.timerify(() => {
401cb0ef41Sopenharmony_ci    throw new Error('test');
411cb0ef41Sopenharmony_ci  });
421cb0ef41Sopenharmony_ci  assert.throws(() => n(), /^Error: test$/);
431cb0ef41Sopenharmony_ci  obs.disconnect();
441cb0ef41Sopenharmony_ci}
451cb0ef41Sopenharmony_ci
461cb0ef41Sopenharmony_ci{
471cb0ef41Sopenharmony_ci  class N {}
481cb0ef41Sopenharmony_ci  const n = performance.timerify(N);
491cb0ef41Sopenharmony_ci
501cb0ef41Sopenharmony_ci  const obs = new PerformanceObserver(common.mustCall((list) => {
511cb0ef41Sopenharmony_ci    const entries = list.getEntries();
521cb0ef41Sopenharmony_ci    const entry = entries[0];
531cb0ef41Sopenharmony_ci    assert.strictEqual(entry[0], 1);
541cb0ef41Sopenharmony_ci    assert.strictEqual(entry[1], 'abc');
551cb0ef41Sopenharmony_ci    assert(entry);
561cb0ef41Sopenharmony_ci    assert.strictEqual(entry.name, 'N');
571cb0ef41Sopenharmony_ci    assert.strictEqual(entry.entryType, 'function');
581cb0ef41Sopenharmony_ci    assert.strictEqual(typeof entry.duration, 'number');
591cb0ef41Sopenharmony_ci    assert.strictEqual(typeof entry.startTime, 'number');
601cb0ef41Sopenharmony_ci    obs.disconnect();
611cb0ef41Sopenharmony_ci  }));
621cb0ef41Sopenharmony_ci  obs.observe({ entryTypes: ['function'] });
631cb0ef41Sopenharmony_ci
641cb0ef41Sopenharmony_ci  new n(1, 'abc');
651cb0ef41Sopenharmony_ci}
661cb0ef41Sopenharmony_ci
671cb0ef41Sopenharmony_ci{
681cb0ef41Sopenharmony_ci  [1, {}, [], null, undefined, Infinity].forEach((input) => {
691cb0ef41Sopenharmony_ci    assert.throws(() => performance.timerify(input),
701cb0ef41Sopenharmony_ci                  {
711cb0ef41Sopenharmony_ci                    code: 'ERR_INVALID_ARG_TYPE',
721cb0ef41Sopenharmony_ci                    name: 'TypeError',
731cb0ef41Sopenharmony_ci                    message: /The "fn" argument must be of type function/
741cb0ef41Sopenharmony_ci                  });
751cb0ef41Sopenharmony_ci  });
761cb0ef41Sopenharmony_ci}
771cb0ef41Sopenharmony_ci
781cb0ef41Sopenharmony_ci// Function can be wrapped many times, also check length and name
791cb0ef41Sopenharmony_ci{
801cb0ef41Sopenharmony_ci  const m = (a, b = 1) => {};
811cb0ef41Sopenharmony_ci  const n = performance.timerify(m);
821cb0ef41Sopenharmony_ci  const o = performance.timerify(m);
831cb0ef41Sopenharmony_ci  const p = performance.timerify(n);
841cb0ef41Sopenharmony_ci  assert.notStrictEqual(n, o);
851cb0ef41Sopenharmony_ci  assert.notStrictEqual(n, p);
861cb0ef41Sopenharmony_ci  assert.notStrictEqual(o, p);
871cb0ef41Sopenharmony_ci  assert.strictEqual(n.length, m.length);
881cb0ef41Sopenharmony_ci  assert.strictEqual(n.name, 'timerified m');
891cb0ef41Sopenharmony_ci  assert.strictEqual(p.name, 'timerified timerified m');
901cb0ef41Sopenharmony_ci}
911cb0ef41Sopenharmony_ci
921cb0ef41Sopenharmony_ci(async () => {
931cb0ef41Sopenharmony_ci  const histogram = createHistogram();
941cb0ef41Sopenharmony_ci  const m = (a, b = 1) => {};
951cb0ef41Sopenharmony_ci  const n = performance.timerify(m, { histogram });
961cb0ef41Sopenharmony_ci  assert.strictEqual(histogram.max, 0);
971cb0ef41Sopenharmony_ci  for (let i = 0; i < 10; i++) {
981cb0ef41Sopenharmony_ci    n();
991cb0ef41Sopenharmony_ci    await sleep(10);
1001cb0ef41Sopenharmony_ci  }
1011cb0ef41Sopenharmony_ci  assert.notStrictEqual(histogram.max, 0);
1021cb0ef41Sopenharmony_ci  [1, '', {}, [], false].forEach((histogram) => {
1031cb0ef41Sopenharmony_ci    assert.throws(() => performance.timerify(m, { histogram }), {
1041cb0ef41Sopenharmony_ci      code: 'ERR_INVALID_ARG_TYPE'
1051cb0ef41Sopenharmony_ci    });
1061cb0ef41Sopenharmony_ci  });
1071cb0ef41Sopenharmony_ci})().then(common.mustCall());
1081cb0ef41Sopenharmony_ci
1091cb0ef41Sopenharmony_ci(async () => {
1101cb0ef41Sopenharmony_ci  const histogram = createHistogram();
1111cb0ef41Sopenharmony_ci  const m = async (a, b = 1) => {
1121cb0ef41Sopenharmony_ci    await sleep(10);
1131cb0ef41Sopenharmony_ci  };
1141cb0ef41Sopenharmony_ci  const n = performance.timerify(m, { histogram });
1151cb0ef41Sopenharmony_ci  assert.strictEqual(histogram.max, 0);
1161cb0ef41Sopenharmony_ci  for (let i = 0; i < 10; i++) {
1171cb0ef41Sopenharmony_ci    await n();
1181cb0ef41Sopenharmony_ci  }
1191cb0ef41Sopenharmony_ci  assert.notStrictEqual(histogram.max, 0);
1201cb0ef41Sopenharmony_ci  [1, '', {}, [], false].forEach((histogram) => {
1211cb0ef41Sopenharmony_ci    assert.throws(() => performance.timerify(m, { histogram }), {
1221cb0ef41Sopenharmony_ci      code: 'ERR_INVALID_ARG_TYPE'
1231cb0ef41Sopenharmony_ci    });
1241cb0ef41Sopenharmony_ci  });
1251cb0ef41Sopenharmony_ci})().then(common.mustCall());
1261cb0ef41Sopenharmony_ci
1271cb0ef41Sopenharmony_ci// Regression tests for https://github.com/nodejs/node/issues/40623
1281cb0ef41Sopenharmony_ci{
1291cb0ef41Sopenharmony_ci  assert.strictEqual(performance.timerify(function func() {
1301cb0ef41Sopenharmony_ci    return 1;
1311cb0ef41Sopenharmony_ci  })(), 1);
1321cb0ef41Sopenharmony_ci  assert.strictEqual(performance.timerify(function() {
1331cb0ef41Sopenharmony_ci    return 1;
1341cb0ef41Sopenharmony_ci  })(), 1);
1351cb0ef41Sopenharmony_ci  assert.strictEqual(performance.timerify(() => {
1361cb0ef41Sopenharmony_ci    return 1;
1371cb0ef41Sopenharmony_ci  })(), 1);
1381cb0ef41Sopenharmony_ci  class C {}
1391cb0ef41Sopenharmony_ci  const wrap = performance.timerify(C);
1401cb0ef41Sopenharmony_ci  assert.ok(new wrap() instanceof C);
1411cb0ef41Sopenharmony_ci  assert.throws(() => wrap(), {
1421cb0ef41Sopenharmony_ci    name: 'TypeError',
1431cb0ef41Sopenharmony_ci  });
1441cb0ef41Sopenharmony_ci}
145