require-hook.js 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", {
  3. value: true
  4. });
  5. exports.default = void 0;
  6. var _experimentalUtils = require("@typescript-eslint/experimental-utils");
  7. var _utils = require("./utils");
  8. const isJestFnCall = node => {
  9. var _getNodeName;
  10. if ((0, _utils.isDescribeCall)(node) || (0, _utils.isTestCaseCall)(node) || (0, _utils.isHook)(node)) {
  11. return true;
  12. }
  13. return !!((_getNodeName = (0, _utils.getNodeName)(node)) !== null && _getNodeName !== void 0 && _getNodeName.startsWith('jest.'));
  14. };
  15. const isNullOrUndefined = node => {
  16. return node.type === _experimentalUtils.AST_NODE_TYPES.Literal && node.value === null || (0, _utils.isIdentifier)(node, 'undefined');
  17. };
  18. const shouldBeInHook = (node, allowedFunctionCalls = []) => {
  19. switch (node.type) {
  20. case _experimentalUtils.AST_NODE_TYPES.ExpressionStatement:
  21. return shouldBeInHook(node.expression, allowedFunctionCalls);
  22. case _experimentalUtils.AST_NODE_TYPES.CallExpression:
  23. return !(isJestFnCall(node) || allowedFunctionCalls.includes((0, _utils.getNodeName)(node)));
  24. case _experimentalUtils.AST_NODE_TYPES.VariableDeclaration:
  25. {
  26. if (node.kind === 'const') {
  27. return false;
  28. }
  29. return node.declarations.some(({
  30. init
  31. }) => init !== null && !isNullOrUndefined(init));
  32. }
  33. default:
  34. return false;
  35. }
  36. };
  37. var _default = (0, _utils.createRule)({
  38. name: __filename,
  39. meta: {
  40. docs: {
  41. category: 'Best Practices',
  42. description: 'Require setup and teardown code to be within a hook',
  43. recommended: false
  44. },
  45. messages: {
  46. useHook: 'This should be done within a hook'
  47. },
  48. type: 'suggestion',
  49. schema: [{
  50. type: 'object',
  51. properties: {
  52. allowedFunctionCalls: {
  53. type: 'array',
  54. items: {
  55. type: 'string'
  56. }
  57. }
  58. },
  59. additionalProperties: false
  60. }]
  61. },
  62. defaultOptions: [{
  63. allowedFunctionCalls: []
  64. }],
  65. create(context) {
  66. var _context$options$;
  67. const {
  68. allowedFunctionCalls
  69. } = (_context$options$ = context.options[0]) !== null && _context$options$ !== void 0 ? _context$options$ : {};
  70. const checkBlockBody = body => {
  71. for (const statement of body) {
  72. if (shouldBeInHook(statement, allowedFunctionCalls)) {
  73. context.report({
  74. node: statement,
  75. messageId: 'useHook'
  76. });
  77. }
  78. }
  79. };
  80. return {
  81. Program(program) {
  82. checkBlockBody(program.body);
  83. },
  84. CallExpression(node) {
  85. if (!(0, _utils.isDescribeCall)(node) || node.arguments.length < 2) {
  86. return;
  87. }
  88. const [, testFn] = node.arguments;
  89. if (!(0, _utils.isFunction)(testFn) || testFn.body.type !== _experimentalUtils.AST_NODE_TYPES.BlockStatement) {
  90. return;
  91. }
  92. checkBlockBody(testFn.body.body);
  93. }
  94. };
  95. }
  96. });
  97. exports.default = _default;