示例#1
0
function getErrMessage(call) {
  const filename = call.getFileName();
  const line = call.getLineNumber() - 1;
  const column = call.getColumnNumber() - 1;
  const identifier = `${filename}${line}${column}`;

  if (errorCache.has(identifier)) {
    return errorCache.get(identifier);
  }

  // Skip Node.js modules!
  if (filename.endsWith('.js') && NativeModule.exists(filename.slice(0, -3))) {
    errorCache.set(identifier, undefined);
    return;
  }

  let fd, message;
  try {
    fd = openSync(filename, 'r', 0o666);
    const buffers = getBuffer(fd, line);
    const code = Buffer.concat(buffers).toString('utf8');
    // Lazy load acorn.
    const { parseExpressionAt } = require('internal/deps/acorn/dist/acorn');
    const nodes = parseExpressionAt(code, column);
    // Node type should be "CallExpression" and some times
    // "SequenceExpression".
    const node = nodes.type === 'CallExpression' ? nodes : nodes.expressions[0];
    const name = node.callee.name;
    // Calling `ok` with .apply or .call is uncommon but we use a simple
    // safeguard nevertheless.
    if (name !== 'apply' && name !== 'call') {
    // Only use `assert` and `assert.ok` to reference the "real API" and
    // not user defined function names.
      const ok = name === 'ok' ? '.ok' : '';
      const args = node.arguments;
      message = code
        .slice(args[0].start, args[args.length - 1].end)
        .replace(escapeSequencesRegExp, escapeFn);
      if (EOL === '\r\n') {
        message = message.replace(/\r\n/g, '\n');
      }
      message = 'The expression evaluated to a falsy value:' +
        `\n\n  assert${ok}(${message})\n`;
    }
    // Make sure to always set the cache! No matter if the message is
    // undefined or not
    errorCache.set(identifier, message);

    return message;

  } catch (e) {
  // Invalidate cache to prevent trying to read this part again.
    errorCache.set(identifier, undefined);
  } finally {
    if (fd !== undefined)
      closeSync(fd);
  }
}
示例#2
0
// Do not try to check Node.js modules.
{
  const e = new EventEmitter();

  e.on('hello', assert);

  let threw = false;
  try {
    e.emit('hello', false);
  } catch (err) {
    const frames = err.stack.split('\n');
    const [, filename, line, column] = frames[1].match(/\((.+):(\d+):(\d+)\)/);
    // Reset the cache to check again
    const size = errorCache.size;
    errorCache.delete(`${filename}${line - 1}${column - 1}`);
    assert.strictEqual(errorCache.size, size - 1);
    const data = `${'\n'.repeat(line - 1)}${' '.repeat(column - 1)}` +
                 'ok(failed(badly));';
    try {
      writeFileSync(filename, data);
      assert.throws(
        () => e.emit('hello', false),
        {
          message: 'false == true'
        }
      );
      threw = true;
    } finally {
      unlinkSync(filename);
    }