1'use strict'; 2 3const common = require('../common'); 4const assert = require('assert'); 5 6const { 7 createHistogram, 8 performance, 9 PerformanceObserver 10} = require('perf_hooks'); 11 12const { 13 setTimeout: sleep 14} = require('timers/promises'); 15 16{ 17 // Intentional non-op. Do not wrap in common.mustCall(); 18 const n = performance.timerify(function noop() {}); 19 20 const obs = new PerformanceObserver(common.mustCall((list) => { 21 const entries = list.getEntries(); 22 const entry = entries[0]; 23 assert(entry); 24 assert.strictEqual(entry.name, 'noop'); 25 assert.strictEqual(entry.entryType, 'function'); 26 assert.strictEqual(typeof entry.duration, 'number'); 27 assert.strictEqual(typeof entry.startTime, 'number'); 28 obs.disconnect(); 29 })); 30 obs.observe({ entryTypes: ['function'] }); 31 n(); 32} 33 34{ 35 // If the error throws, the error should just be bubbled up and the 36 // performance timeline entry will not be reported. 37 const obs = new PerformanceObserver(common.mustNotCall()); 38 obs.observe({ entryTypes: ['function'] }); 39 const n = performance.timerify(() => { 40 throw new Error('test'); 41 }); 42 assert.throws(() => n(), /^Error: test$/); 43 obs.disconnect(); 44} 45 46{ 47 class N {} 48 const n = performance.timerify(N); 49 50 const obs = new PerformanceObserver(common.mustCall((list) => { 51 const entries = list.getEntries(); 52 const entry = entries[0]; 53 assert.strictEqual(entry[0], 1); 54 assert.strictEqual(entry[1], 'abc'); 55 assert(entry); 56 assert.strictEqual(entry.name, 'N'); 57 assert.strictEqual(entry.entryType, 'function'); 58 assert.strictEqual(typeof entry.duration, 'number'); 59 assert.strictEqual(typeof entry.startTime, 'number'); 60 obs.disconnect(); 61 })); 62 obs.observe({ entryTypes: ['function'] }); 63 64 new n(1, 'abc'); 65} 66 67{ 68 [1, {}, [], null, undefined, Infinity].forEach((input) => { 69 assert.throws(() => performance.timerify(input), 70 { 71 code: 'ERR_INVALID_ARG_TYPE', 72 name: 'TypeError', 73 message: /The "fn" argument must be of type function/ 74 }); 75 }); 76} 77 78// Function can be wrapped many times, also check length and name 79{ 80 const m = (a, b = 1) => {}; 81 const n = performance.timerify(m); 82 const o = performance.timerify(m); 83 const p = performance.timerify(n); 84 assert.notStrictEqual(n, o); 85 assert.notStrictEqual(n, p); 86 assert.notStrictEqual(o, p); 87 assert.strictEqual(n.length, m.length); 88 assert.strictEqual(n.name, 'timerified m'); 89 assert.strictEqual(p.name, 'timerified timerified m'); 90} 91 92(async () => { 93 const histogram = createHistogram(); 94 const m = (a, b = 1) => {}; 95 const n = performance.timerify(m, { histogram }); 96 assert.strictEqual(histogram.max, 0); 97 for (let i = 0; i < 10; i++) { 98 n(); 99 await sleep(10); 100 } 101 assert.notStrictEqual(histogram.max, 0); 102 [1, '', {}, [], false].forEach((histogram) => { 103 assert.throws(() => performance.timerify(m, { histogram }), { 104 code: 'ERR_INVALID_ARG_TYPE' 105 }); 106 }); 107})().then(common.mustCall()); 108 109(async () => { 110 const histogram = createHistogram(); 111 const m = async (a, b = 1) => { 112 await sleep(10); 113 }; 114 const n = performance.timerify(m, { histogram }); 115 assert.strictEqual(histogram.max, 0); 116 for (let i = 0; i < 10; i++) { 117 await n(); 118 } 119 assert.notStrictEqual(histogram.max, 0); 120 [1, '', {}, [], false].forEach((histogram) => { 121 assert.throws(() => performance.timerify(m, { histogram }), { 122 code: 'ERR_INVALID_ARG_TYPE' 123 }); 124 }); 125})().then(common.mustCall()); 126 127// Regression tests for https://github.com/nodejs/node/issues/40623 128{ 129 assert.strictEqual(performance.timerify(function func() { 130 return 1; 131 })(), 1); 132 assert.strictEqual(performance.timerify(function() { 133 return 1; 134 })(), 1); 135 assert.strictEqual(performance.timerify(() => { 136 return 1; 137 })(), 1); 138 class C {} 139 const wrap = performance.timerify(C); 140 assert.ok(new wrap() instanceof C); 141 assert.throws(() => wrap(), { 142 name: 'TypeError', 143 }); 144} 145