common.js 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. const mustCallChecks = [];
  2. function runCallChecks(exitCode) {
  3. if (exitCode !== 0) return;
  4. const failed = mustCallChecks.filter(function(context) {
  5. return context.actual !== context.expected;
  6. });
  7. failed.forEach(function(context) {
  8. console.log('Mismatched %s function calls. Expected %d, actual %d.',
  9. context.name,
  10. context.expected,
  11. context.actual);
  12. console.log(context.stack.split('\n').slice(2).join('\n'));
  13. });
  14. if (failed.length) process.exit(1);
  15. }
  16. exports.mustCall = function(fn, expected) {
  17. if (typeof fn === 'number') {
  18. expected = fn;
  19. fn = noop;
  20. } else if (fn === undefined) {
  21. fn = noop;
  22. }
  23. if (expected === undefined)
  24. expected = 1;
  25. else if (typeof expected !== 'number')
  26. throw new TypeError(`Invalid expected value: ${expected}`);
  27. const context = {
  28. expected: expected,
  29. actual: 0,
  30. stack: (new Error()).stack,
  31. name: fn.name || '<anonymous>'
  32. };
  33. // add the exit listener only once to avoid listener leak warnings
  34. if (mustCallChecks.length === 0) process.on('exit', runCallChecks);
  35. mustCallChecks.push(context);
  36. return function() {
  37. context.actual++;
  38. return fn.apply(this, arguments);
  39. };
  40. };
  41. // Crash the process on unhandled rejections.
  42. exports.crashOnUnhandledRejection = function() {
  43. process.on('unhandledRejection',
  44. (err) => process.nextTick(() => { throw err; }));
  45. };