prefer-expect-assertions.js 1.9 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
'use strict';

const { getDocsUrl } = require('./util');

const ruleMsg =
  'Every test should have either `expect.assertions(<number of assertions>)` or `expect.hasAssertions()` as its first expression';

const validateArguments = expression => {
  return (
    expression.arguments &&
    expression.arguments.length === 1 &&
    Number.isInteger(expression.arguments[0].value)
  );
};

const isExpectAssertionsOrHasAssertionsCall = expression => {
  try {
    const expectAssertionOrHasAssertionCall =
      expression.type === 'CallExpression' &&
      expression.callee.type === 'MemberExpression' &&
      expression.callee.object.name === 'expect' &&
      (expression.callee.property.name === 'assertions' ||
        expression.callee.property.name === 'hasAssertions');

    if (expression.callee.property.name === 'assertions') {
      return expectAssertionOrHasAssertionCall && validateArguments(expression);
    }
    return expectAssertionOrHasAssertionCall;
  } catch (e) {
    return false;
  }
};

const getFunctionFirstLine = functionBody => {
  return functionBody[0] && functionBody[0].expression;
};

const isFirstLineExprStmt = functionBody => {
  return functionBody[0] && functionBody[0].type === 'ExpressionStatement';
};

const reportMsg = (context, node) => {
  context.report({
    message: ruleMsg,
    node,
  });
};

module.exports = {
  meta: {
    docs: {
      url: getDocsUrl(__filename),
    },
  },
  create(context) {
    return {
      'CallExpression[callee.name=/^(it|test)$/][arguments.1.body.body]'(node) {
        const testFuncBody = node.arguments[1].body.body;

        if (!isFirstLineExprStmt(testFuncBody)) {
          reportMsg(context, node);
        } else {
          const testFuncFirstLine = getFunctionFirstLine(testFuncBody);
          if (!isExpectAssertionsOrHasAssertionsCall(testFuncFirstLine)) {
            reportMsg(context, node);
          }
        }
      },
    };
  },
};