current commit
251117.12 · test: ensure assertions are reached on more tests
// Flags: --expose-internals
'use strict';

const common = require('../common');
const { hideStackFrames, codes } = require('internal/errors');
const { validateInteger } = require('internal/validators');
const assert = require('assert');

{
  // Test that the a built-in error has the correct name and message.
  function a() {
    b();
  }

  function b() {
    c();
  }

  const c = hideStackFrames(function() {
    throw new Error('test');
  });

  try {
    a();
  } catch (e) {
    assert.strictEqual(e.name, 'Error');
    assert.strictEqual(e.message, 'test');
  }
}

{
  // Test that validator errors have the correct name and message.
  try {
    validateInteger('2', 'test');
  } catch (e) {
    assert.strictEqual(e.name, 'TypeError');
    assert.strictEqual(e.message, 'The "test" argument must be of type number. Received type string (\'2\')');
  }
}

{
  // Test that validator fn is not in the stack trace.

  function a(value) {
    validateInteger(value, 'test');
  }
  try {
    a('2');
  } catch (e) {
    assert.strictEqual(Error.stackTraceLimit, 10);
    const stack = e.stack.split('\n');
    assert.doesNotMatch(stack[1], /validateInteger/);
    assert.match(stack[1], /at a/);
  }
}

{
  // Test that the stack trace is hidden for normal unnamed functions.
  function a() {
    b();
  }

  function b() {
    c();
  }

  const c = hideStackFrames(function() {
    throw new Error('test');
  });

  try {
    a();
  } catch (e) {
    assert.strictEqual(Error.stackTraceLimit, 10);
    const stack = e.stack.split('\n');
    assert.doesNotMatch(stack[1], /at c/);
    assert.match(stack[1], /at b/);
    assert.strictEqual(Error.stackTraceLimit, 10);
  }
}

{
  // Test that the stack trace is hidden for normal functions.
  function a() {
    b();
  }

  function b() {
    c();
  }

  const c = hideStackFrames(function c() {
    throw new Error('test');
  });

  try {
    a();
  } catch (e) {
    assert.strictEqual(Error.stackTraceLimit, 10);
    const stack = e.stack.split('\n');
    assert.doesNotMatch(stack[1], /at c/);
    assert.match(stack[1], /at b/);
    assert.strictEqual(Error.stackTraceLimit, 10);
  }
}

{
  // Test that the stack trace is hidden for arrow functions.
  function a() {
    b();
  }

  function b() {
    c();
  }

  const c = hideStackFrames(() => {
    throw new Error('test');
  });

  try {
    a();
  } catch (e) {
    assert.strictEqual(Error.stackTraceLimit, 10);
    const stack = e.stack.split('\n');
    assert.doesNotMatch(stack[1], /at c/);
    assert.match(stack[1], /at b/);
    assert.strictEqual(Error.stackTraceLimit, 10);
  }
}

{
  // Creating a new Error object without stack trace, then throwing it
  // should get a stack trace by hideStackFrames.
  function a() {
    b();
  }

  function b() {
    c();
  }

  const c = hideStackFrames(function() {
    throw new Error('test');
  });

  try {
    a();
  } catch (e) {
    assert.strictEqual(Error.stackTraceLimit, 10);
    const stack = e.stack.split('\n');
    assert.doesNotMatch(stack[1], /at c/);
    assert.match(stack[1], /at b/);
    assert.strictEqual(Error.stackTraceLimit, 10);
  }
}

{
  const ERR_ACCESS_DENIED = codes.ERR_ACCESS_DENIED;
  // Creating a new Error object without stack trace, then throwing it
  // should get a stack trace by hideStackFrames.
  function a() {
    b();
  }

  function b() {
    c();
  }

  const c = hideStackFrames(function() {
    throw new ERR_ACCESS_DENIED.NoStackError('test');
  });

  try {
    a();
  } catch (e) {
    assert.strictEqual(Error.stackTraceLimit, 10);
    const stack = e.stack.split('\n');
    assert.doesNotMatch(stack[1], /at c/);
    assert.match(stack[1], /at b/);
    assert.strictEqual(Error.stackTraceLimit, 10);
  }
}

{
  // Creating a new Error object with stack trace, then throwing it
  // should get a stack trace by hideStackFrames.
  function a() {
    b();
  }

  const b = hideStackFrames(function b() {
    c();
  });

  const c = hideStackFrames(function() {
    throw new Error('test');
  });

  try {
    a();
  } catch (e) {
    assert.strictEqual(Error.stackTraceLimit, 10);
    const stack = e.stack.split('\n');
    assert.match(stack[1], /at a/);
    assert.strictEqual(Error.stackTraceLimit, 10);
  }
}

{
  // Binding passes the value of this to the wrapped function.
  function a() {
    b.bind({ key: 'value' })();
  }

  const b = hideStackFrames(common.mustCall(function b() {
    assert.strictEqual(this.key, 'value');
  }));

  a();
}

{
  // Binding passes the value of this to the withoutStackTrace function.
  let called = false;
  function a() {
    b.withoutStackTrace.bind({ key: 'value' })();
  }

  const b = hideStackFrames(common.mustCall(function b() {
    assert.strictEqual(this.key, 'value');
    called = true;
  }));

  a();

  assert.strictEqual(called, true);
}