prefer-lowercase-title.js 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", {
  3. value: true
  4. });
  5. exports.default = void 0;
  6. var _utils = require("./utils");
  7. const hasStringAsFirstArgument = node => node.arguments[0] && (0, _utils.isStringNode)(node.arguments[0]);
  8. const populateIgnores = ignore => {
  9. const ignores = [];
  10. if (ignore.includes(_utils.DescribeAlias.describe)) {
  11. ignores.push(...Object.keys(_utils.DescribeAlias));
  12. }
  13. if (ignore.includes(_utils.TestCaseName.test)) {
  14. ignores.push(...Object.keys(_utils.TestCaseName).filter(k => k.endsWith(_utils.TestCaseName.test)));
  15. }
  16. if (ignore.includes(_utils.TestCaseName.it)) {
  17. ignores.push(...Object.keys(_utils.TestCaseName).filter(k => k.endsWith(_utils.TestCaseName.it)));
  18. }
  19. return ignores;
  20. };
  21. var _default = (0, _utils.createRule)({
  22. name: __filename,
  23. meta: {
  24. type: 'suggestion',
  25. docs: {
  26. description: 'Enforce lowercase test names',
  27. category: 'Best Practices',
  28. recommended: false
  29. },
  30. fixable: 'code',
  31. messages: {
  32. unexpectedLowercase: '`{{ method }}`s should begin with lowercase'
  33. },
  34. schema: [{
  35. type: 'object',
  36. properties: {
  37. ignore: {
  38. type: 'array',
  39. items: {
  40. enum: [_utils.DescribeAlias.describe, _utils.TestCaseName.test, _utils.TestCaseName.it]
  41. },
  42. additionalItems: false
  43. },
  44. allowedPrefixes: {
  45. type: 'array',
  46. items: {
  47. type: 'string'
  48. },
  49. additionalItems: false
  50. },
  51. ignoreTopLevelDescribe: {
  52. type: 'boolean',
  53. default: false
  54. }
  55. },
  56. additionalProperties: false
  57. }]
  58. },
  59. defaultOptions: [{
  60. ignore: [],
  61. allowedPrefixes: [],
  62. ignoreTopLevelDescribe: false
  63. }],
  64. create(context, [{
  65. ignore = [],
  66. allowedPrefixes = [],
  67. ignoreTopLevelDescribe
  68. }]) {
  69. const ignores = populateIgnores(ignore);
  70. let numberOfDescribeBlocks = 0;
  71. return {
  72. CallExpression(node) {
  73. const jestFnCall = (0, _utils.parseJestFnCall)(node, context);
  74. if (!jestFnCall || !hasStringAsFirstArgument(node)) {
  75. return;
  76. }
  77. if (jestFnCall.type === 'describe') {
  78. numberOfDescribeBlocks++;
  79. if (ignoreTopLevelDescribe && numberOfDescribeBlocks === 1) {
  80. return;
  81. }
  82. } else if (jestFnCall.type !== 'test') {
  83. return;
  84. }
  85. const [firstArg] = node.arguments;
  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() || ignores.includes(jestFnCall.name)) {
  92. return;
  93. }
  94. context.report({
  95. messageId: 'unexpectedLowercase',
  96. node: node.arguments[0],
  97. data: {
  98. method: jestFnCall.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.isTypeOfJestFnCall)(node, context, ['describe'])) {
  110. numberOfDescribeBlocks--;
  111. }
  112. }
  113. };
  114. }
  115. });
  116. exports.default = _default;