no-await-sync-events.js 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. exports.RULE_NAME = void 0;
  4. const utils_1 = require("@typescript-eslint/utils");
  5. const create_testing_library_rule_1 = require("../create-testing-library-rule");
  6. const node_utils_1 = require("../node-utils");
  7. const USER_EVENT_ASYNC_EXCEPTIONS = ['type', 'keyboard'];
  8. const VALID_EVENT_MODULES = ['fire-event', 'user-event'];
  9. exports.RULE_NAME = 'no-await-sync-events';
  10. exports.default = (0, create_testing_library_rule_1.createTestingLibraryRule)({
  11. name: exports.RULE_NAME,
  12. meta: {
  13. type: 'problem',
  14. docs: {
  15. description: 'Disallow unnecessary `await` for sync events',
  16. recommendedConfig: {
  17. dom: false,
  18. angular: false,
  19. react: false,
  20. vue: false,
  21. marko: false,
  22. },
  23. },
  24. messages: {
  25. noAwaitSyncEvents: '`{{ name }}` is sync and does not need `await` operator',
  26. },
  27. schema: [
  28. {
  29. type: 'object',
  30. properties: {
  31. eventModules: {
  32. type: 'array',
  33. minItems: 1,
  34. items: {
  35. enum: VALID_EVENT_MODULES,
  36. },
  37. },
  38. },
  39. additionalProperties: false,
  40. },
  41. ],
  42. },
  43. defaultOptions: [{ eventModules: VALID_EVENT_MODULES }],
  44. create(context, [options], helpers) {
  45. const { eventModules = VALID_EVENT_MODULES } = options;
  46. let hasDelayDeclarationOrAssignmentGTZero;
  47. return {
  48. VariableDeclaration(node) {
  49. hasDelayDeclarationOrAssignmentGTZero = node.declarations.some((property) => utils_1.ASTUtils.isIdentifier(property.id) &&
  50. property.id.name === 'delay' &&
  51. (0, node_utils_1.isLiteral)(property.init) &&
  52. property.init.value &&
  53. property.init.value > 0);
  54. },
  55. AssignmentExpression(node) {
  56. if (utils_1.ASTUtils.isIdentifier(node.left) &&
  57. node.left.name === 'delay' &&
  58. (0, node_utils_1.isLiteral)(node.right) &&
  59. node.right.value !== null) {
  60. hasDelayDeclarationOrAssignmentGTZero = node.right.value > 0;
  61. }
  62. },
  63. 'AwaitExpression > CallExpression'(node) {
  64. var _a;
  65. const simulateEventFunctionIdentifier = (0, node_utils_1.getDeepestIdentifierNode)(node);
  66. if (!simulateEventFunctionIdentifier) {
  67. return;
  68. }
  69. const isUserEventMethod = helpers.isUserEventMethod(simulateEventFunctionIdentifier);
  70. const isFireEventMethod = helpers.isFireEventMethod(simulateEventFunctionIdentifier);
  71. const isSimulateEventMethod = isUserEventMethod || isFireEventMethod;
  72. if (!isSimulateEventMethod) {
  73. return;
  74. }
  75. if (isFireEventMethod && !eventModules.includes('fire-event')) {
  76. return;
  77. }
  78. if (isUserEventMethod && !eventModules.includes('user-event')) {
  79. return;
  80. }
  81. const lastArg = node.arguments[node.arguments.length - 1];
  82. const hasDelayProperty = (0, node_utils_1.isObjectExpression)(lastArg) &&
  83. lastArg.properties.some((property) => (0, node_utils_1.isProperty)(property) &&
  84. utils_1.ASTUtils.isIdentifier(property.key) &&
  85. property.key.name === 'delay');
  86. const hasDelayLiteralGTZero = (0, node_utils_1.isObjectExpression)(lastArg) &&
  87. lastArg.properties.some((property) => (0, node_utils_1.isProperty)(property) &&
  88. utils_1.ASTUtils.isIdentifier(property.key) &&
  89. property.key.name === 'delay' &&
  90. (0, node_utils_1.isLiteral)(property.value) &&
  91. !!property.value.value &&
  92. property.value.value > 0);
  93. const simulateEventFunctionName = simulateEventFunctionIdentifier.name;
  94. if (USER_EVENT_ASYNC_EXCEPTIONS.includes(simulateEventFunctionName) &&
  95. hasDelayProperty &&
  96. (hasDelayDeclarationOrAssignmentGTZero || hasDelayLiteralGTZero)) {
  97. return;
  98. }
  99. const eventModuleName = (_a = (0, node_utils_1.getPropertyIdentifierNode)(node)) === null || _a === void 0 ? void 0 : _a.name;
  100. const eventFullName = eventModuleName
  101. ? `${eventModuleName}.${simulateEventFunctionName}`
  102. : simulateEventFunctionName;
  103. context.report({
  104. node,
  105. messageId: 'noAwaitSyncEvents',
  106. data: {
  107. name: eventFullName,
  108. },
  109. });
  110. },
  111. };
  112. },
  113. });