prefer-screen-queries.js 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. "use strict";
  2. var __spreadArray = (this && this.__spreadArray) || function (to, from) {
  3. for (var i = 0, il = from.length, j = to.length; i < il; i++, j++)
  4. to[j] = from[i];
  5. return to;
  6. };
  7. Object.defineProperty(exports, "__esModule", { value: true });
  8. exports.RULE_NAME = void 0;
  9. var experimental_utils_1 = require("@typescript-eslint/experimental-utils");
  10. var utils_1 = require("../utils");
  11. var node_utils_1 = require("../node-utils");
  12. exports.RULE_NAME = 'prefer-screen-queries';
  13. var ALLOWED_RENDER_PROPERTIES_FOR_DESTRUCTURING = [
  14. 'container',
  15. 'baseElement',
  16. ];
  17. var ALL_QUERIES_COMBINATIONS_REGEXP = utils_1.ALL_QUERIES_COMBINATIONS.join('|');
  18. function usesContainerOrBaseElement(node) {
  19. var secondArgument = node.arguments[1];
  20. return (node_utils_1.isObjectExpression(secondArgument) &&
  21. secondArgument.properties.some(function (property) {
  22. return node_utils_1.isProperty(property) &&
  23. node_utils_1.isIdentifier(property.key) &&
  24. ALLOWED_RENDER_PROPERTIES_FOR_DESTRUCTURING.includes(property.key.name);
  25. }));
  26. }
  27. exports.default = experimental_utils_1.ESLintUtils.RuleCreator(utils_1.getDocsUrl)({
  28. name: exports.RULE_NAME,
  29. meta: {
  30. type: 'suggestion',
  31. docs: {
  32. description: 'Suggest using screen while using queries',
  33. category: 'Best Practices',
  34. recommended: false,
  35. },
  36. messages: {
  37. preferScreenQueries: 'Use screen to query DOM elements, `screen.{{ name }}`',
  38. },
  39. fixable: null,
  40. schema: [],
  41. },
  42. defaultOptions: [],
  43. create: function (context) {
  44. var _a;
  45. function reportInvalidUsage(node) {
  46. context.report({
  47. node: node,
  48. messageId: 'preferScreenQueries',
  49. data: {
  50. name: node.name,
  51. },
  52. });
  53. }
  54. var queriesRegex = new RegExp(ALL_QUERIES_COMBINATIONS_REGEXP);
  55. var queriesDestructuredInWithinDeclaration = [];
  56. var withinDeclaredVariables = [];
  57. return _a = {
  58. VariableDeclarator: function (node) {
  59. if (!node_utils_1.isCallExpression(node.init) || !node_utils_1.isIdentifier(node.init.callee)) {
  60. return;
  61. }
  62. var isWithinFunction = node.init.callee.name === 'within';
  63. var usesRenderOptions = node.init.callee.name === 'render' &&
  64. usesContainerOrBaseElement(node.init);
  65. if (!isWithinFunction && !usesRenderOptions) {
  66. return;
  67. }
  68. if (node_utils_1.isObjectPattern(node.id)) {
  69. var identifiers = node.id.properties
  70. .filter(function (property) {
  71. return node_utils_1.isProperty(property) &&
  72. node_utils_1.isIdentifier(property.key) &&
  73. queriesRegex.test(property.key.name);
  74. })
  75. .map(function (property) {
  76. return property.key.name;
  77. });
  78. queriesDestructuredInWithinDeclaration.push.apply(queriesDestructuredInWithinDeclaration, identifiers);
  79. return;
  80. }
  81. if (node_utils_1.isIdentifier(node.id)) {
  82. withinDeclaredVariables.push(node.id.name);
  83. }
  84. }
  85. },
  86. _a["CallExpression > Identifier[name=/^" + ALL_QUERIES_COMBINATIONS_REGEXP + "$/]"] = function (node) {
  87. if (!queriesDestructuredInWithinDeclaration.some(function (queryName) { return queryName === node.name; })) {
  88. reportInvalidUsage(node);
  89. }
  90. },
  91. _a["MemberExpression > Identifier[name=/^" + ALL_QUERIES_COMBINATIONS_REGEXP + "$/]"] = function (node) {
  92. function isIdentifierAllowed(name) {
  93. return __spreadArray(['screen'], withinDeclaredVariables).includes(name);
  94. }
  95. if (node_utils_1.isIdentifier(node) &&
  96. node_utils_1.isMemberExpression(node.parent) &&
  97. node_utils_1.isCallExpression(node.parent.object) &&
  98. node_utils_1.isIdentifier(node.parent.object.callee) &&
  99. node.parent.object.callee.name !== 'within' &&
  100. node.parent.object.callee.name === 'render' &&
  101. !usesContainerOrBaseElement(node.parent.object)) {
  102. reportInvalidUsage(node);
  103. return;
  104. }
  105. if (node_utils_1.isMemberExpression(node.parent) &&
  106. node_utils_1.isIdentifier(node.parent.object) &&
  107. !isIdentifierAllowed(node.parent.object.name)) {
  108. reportInvalidUsage(node);
  109. }
  110. },
  111. _a;
  112. },
  113. });