lowercase-name.js 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  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 hasStringAsFirstArgument = node => node.arguments[0] && (0, _utils.isStringNode)(node.arguments[0]);
  9. const findNodeNameAndArgument = node => {
  10. if (!((0, _utils.isTestCaseCall)(node) || (0, _utils.isDescribeCall)(node))) {
  11. return null;
  12. }
  13. if ((0, _utils.isEachCall)(node)) {
  14. if (node.parent.arguments.length > 0 && (0, _utils.isStringNode)(node.parent.arguments[0])) {
  15. return [node.callee.object.name, node.parent.arguments[0]];
  16. }
  17. return null;
  18. }
  19. if (node.callee.type !== _experimentalUtils.AST_NODE_TYPES.Identifier || !hasStringAsFirstArgument(node)) {
  20. return null;
  21. }
  22. return [node.callee.name, node.arguments[0]];
  23. };
  24. var _default = (0, _utils.createRule)({
  25. name: __filename,
  26. meta: {
  27. type: 'suggestion',
  28. docs: {
  29. description: 'Enforce lowercase test names',
  30. category: 'Best Practices',
  31. recommended: false
  32. },
  33. fixable: 'code',
  34. messages: {
  35. unexpectedLowercase: '`{{ method }}`s should begin with lowercase'
  36. },
  37. schema: [{
  38. type: 'object',
  39. properties: {
  40. ignore: {
  41. type: 'array',
  42. items: {
  43. enum: [_utils.DescribeAlias.describe, _utils.TestCaseName.test, _utils.TestCaseName.it]
  44. },
  45. additionalItems: false
  46. },
  47. allowedPrefixes: {
  48. type: 'array',
  49. items: {
  50. type: 'string'
  51. },
  52. additionalItems: false
  53. },
  54. ignoreTopLevelDescribe: {
  55. type: 'boolean',
  56. default: false
  57. }
  58. },
  59. additionalProperties: false
  60. }]
  61. },
  62. defaultOptions: [{
  63. ignore: [],
  64. allowedPrefixes: [],
  65. ignoreTopLevelDescribe: false
  66. }],
  67. create(context, [{
  68. ignore = [],
  69. allowedPrefixes = [],
  70. ignoreTopLevelDescribe
  71. }]) {
  72. let numberOfDescribeBlocks = 0;
  73. return {
  74. CallExpression(node) {
  75. if ((0, _utils.isDescribeCall)(node)) {
  76. numberOfDescribeBlocks++;
  77. if (ignoreTopLevelDescribe && numberOfDescribeBlocks === 1) {
  78. return;
  79. }
  80. }
  81. const results = findNodeNameAndArgument(node);
  82. if (!results) {
  83. return;
  84. }
  85. const [name, firstArg] = results;
  86. const description = (0, _utils.getStringValue)(firstArg);
  87. if (allowedPrefixes.some(name => description.startsWith(name))) {
  88. return;
  89. }
  90. const firstCharacter = description.charAt(0);
  91. if (!firstCharacter || firstCharacter === firstCharacter.toLowerCase() || ignore.includes(name)) {
  92. return;
  93. }
  94. context.report({
  95. messageId: 'unexpectedLowercase',
  96. node: node.arguments[0],
  97. data: {
  98. method: name
  99. },
  100. fix(fixer) {
  101. const description = (0, _utils.getStringValue)(firstArg);
  102. const rangeIgnoringQuotes = [firstArg.range[0] + 1, firstArg.range[1] - 1];
  103. const newDescription = description.substring(0, 1).toLowerCase() + description.substring(1);
  104. return [fixer.replaceTextRange(rangeIgnoringQuotes, newDescription)];
  105. }
  106. });
  107. },
  108. 'CallExpression:exit'(node) {
  109. if ((0, _utils.isDescribeCall)(node)) {
  110. numberOfDescribeBlocks--;
  111. }
  112. }
  113. };
  114. }
  115. });
  116. exports.default = _default;