consistent-test-it.js 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  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 buildFixer = (callee, nodeName, preferredTestKeyword) => fixer => [fixer.replaceText(callee.type === _experimentalUtils.AST_NODE_TYPES.MemberExpression ? callee.object : callee, getPreferredNodeName(nodeName, preferredTestKeyword))];
  9. var _default = (0, _utils.createRule)({
  10. name: __filename,
  11. meta: {
  12. docs: {
  13. category: 'Best Practices',
  14. description: 'Have control over `test` and `it` usages',
  15. recommended: false
  16. },
  17. fixable: 'code',
  18. messages: {
  19. consistentMethod: "Prefer using '{{ testKeyword }}' instead of '{{ oppositeTestKeyword }}'",
  20. consistentMethodWithinDescribe: "Prefer using '{{ testKeywordWithinDescribe }}' instead of '{{ oppositeTestKeyword }}' within describe"
  21. },
  22. schema: [{
  23. type: 'object',
  24. properties: {
  25. fn: {
  26. enum: [_utils.TestCaseName.it, _utils.TestCaseName.test]
  27. },
  28. withinDescribe: {
  29. enum: [_utils.TestCaseName.it, _utils.TestCaseName.test]
  30. }
  31. },
  32. additionalProperties: false
  33. }],
  34. type: 'suggestion'
  35. },
  36. defaultOptions: [{
  37. fn: _utils.TestCaseName.test,
  38. withinDescribe: _utils.TestCaseName.it
  39. }],
  40. create(context) {
  41. const configObj = context.options[0] || {};
  42. const testKeyword = configObj.fn || _utils.TestCaseName.test;
  43. const testKeywordWithinDescribe = configObj.withinDescribe || configObj.fn || _utils.TestCaseName.it;
  44. let describeNestingLevel = 0;
  45. return {
  46. CallExpression(node) {
  47. const nodeName = (0, _utils.getNodeName)(node.callee);
  48. if (!nodeName) {
  49. return;
  50. }
  51. if ((0, _utils.isDescribeCall)(node)) {
  52. describeNestingLevel++;
  53. }
  54. const funcNode = node.callee.type === _experimentalUtils.AST_NODE_TYPES.TaggedTemplateExpression ? node.callee.tag : node.callee.type === _experimentalUtils.AST_NODE_TYPES.CallExpression ? node.callee.callee : node.callee;
  55. if ((0, _utils.isTestCaseCall)(node) && describeNestingLevel === 0 && !nodeName.includes(testKeyword)) {
  56. const oppositeTestKeyword = getOppositeTestKeyword(testKeyword);
  57. context.report({
  58. messageId: 'consistentMethod',
  59. node: node.callee,
  60. data: {
  61. testKeyword,
  62. oppositeTestKeyword
  63. },
  64. fix: buildFixer(funcNode, nodeName, testKeyword)
  65. });
  66. }
  67. if ((0, _utils.isTestCaseCall)(node) && describeNestingLevel > 0 && !nodeName.includes(testKeywordWithinDescribe)) {
  68. const oppositeTestKeyword = getOppositeTestKeyword(testKeywordWithinDescribe);
  69. context.report({
  70. messageId: 'consistentMethodWithinDescribe',
  71. node: node.callee,
  72. data: {
  73. testKeywordWithinDescribe,
  74. oppositeTestKeyword
  75. },
  76. fix: buildFixer(funcNode, nodeName, testKeywordWithinDescribe)
  77. });
  78. }
  79. },
  80. 'CallExpression:exit'(node) {
  81. if ((0, _utils.isDescribeCall)(node)) {
  82. describeNestingLevel--;
  83. }
  84. }
  85. };
  86. }
  87. });
  88. exports.default = _default;
  89. function getPreferredNodeName(nodeName, preferredTestKeyword) {
  90. if (nodeName === _utils.TestCaseName.fit) {
  91. return 'test.only';
  92. }
  93. return nodeName.startsWith('f') || nodeName.startsWith('x') ? nodeName.charAt(0) + preferredTestKeyword : preferredTestKeyword;
  94. }
  95. function getOppositeTestKeyword(test) {
  96. if (test === _utils.TestCaseName.test) {
  97. return _utils.TestCaseName.it;
  98. }
  99. return _utils.TestCaseName.test;
  100. }