/** * @fileoverview Enforce onmouseover/onmouseout are accompanied * by onfocus/onblur. * @author Ethan Cohen */ // ----------------------------------------------------------------------------- // Requirements // ----------------------------------------------------------------------------- import { RuleTester } from 'eslint'; import parserOptionsMapper from '../../__util__/parserOptionsMapper'; import parsers from '../../__util__/helpers/parsers'; import rule from '../../../src/rules/mouse-events-have-key-events'; // ----------------------------------------------------------------------------- // Tests // ----------------------------------------------------------------------------- const ruleTester = new RuleTester(); const mouseOverError = { message: 'onMouseOver must be accompanied by onFocus for accessibility.', type: 'JSXAttribute', }; const pointerEnterError = { message: 'onPointerEnter must be accompanied by onFocus for accessibility.', type: 'JSXAttribute', }; const mouseOutError = { message: 'onMouseOut must be accompanied by onBlur for accessibility.', type: 'JSXAttribute', }; const pointerLeaveError = { message: 'onPointerLeave must be accompanied by onBlur for accessibility.', type: 'JSXAttribute', }; ruleTester.run('mouse-events-have-key-events', rule, { valid: parsers.all([].concat( { code: '
void 0} onFocus={() => void 0} />;' }, { code: '
void 0} onFocus={() => void 0} {...props} />;', }, { code: '
;' }, { code: '
;', }, { code: '
;' }, { code: '
{}} />' }, { code: '
{}} />' }, { code: '
void 0} onBlur={() => void 0} />' }, { code: '
void 0} onBlur={() => void 0} {...props} />' }, { code: '
' }, { code: '
' }, { code: '' }, { code: ' {}} />' }, { code: ' {}} />' }, { code: ' {}} />' }, { code: ' {}} />' }, { code: ' {}} {...props} />' }, { code: ' {}} {...props} />' }, { code: ' {}} {...props} />' }, { code: ' {}} {...props} />' }, /* Passing in empty options doesn't check any event handlers */ { code: '
{}} onMouseOut={() => {}} />', options: [{ hoverInHandlers: [], hoverOutHandlers: [] }], }, /* Passing in custom handlers */ { code: '
{}} onFocus={() => {}} />', options: [{ hoverInHandlers: ['onMouseOver'] }], }, { code: '
{}} onFocus={() => {}} />', options: [{ hoverInHandlers: ['onMouseEnter'] }], }, { code: '
{}} onBlur={() => {}} />', options: [{ hoverOutHandlers: ['onMouseOut'] }], }, { code: '
{}} onBlur={() => {}} />', options: [{ hoverOutHandlers: ['onMouseLeave'] }], }, { code: '
{}} onMouseOut={() => {}} />', options: [ { hoverInHandlers: ['onPointerEnter'], hoverOutHandlers: ['onPointerLeave'] }, ], }, /* Custom options only checks the handlers passed in */ { code: '
{}} />', options: [{ hoverOutHandlers: ['onPointerLeave'] }], }, )).map(parserOptionsMapper), invalid: parsers.all([].concat( { code: '
void 0} />;', errors: [mouseOverError] }, { code: '
void 0} />', errors: [mouseOutError] }, { code: '
void 0} onFocus={undefined} />;', errors: [mouseOverError], }, { code: '
void 0} onBlur={undefined} />', errors: [mouseOutError], }, { code: '
void 0} {...props} />', errors: [mouseOverError], }, { code: '
void 0} {...props} />', errors: [mouseOutError], }, /* Custom options */ { code: '
{}} onMouseOut={() => {}} />', options: [ { hoverInHandlers: ['onMouseOver'], hoverOutHandlers: ['onMouseOut'] }, ], errors: [mouseOverError, mouseOutError], }, { code: '
{}} onPointerLeave={() => {}} />', options: [ { hoverInHandlers: ['onPointerEnter'], hoverOutHandlers: ['onPointerLeave'] }, ], errors: [pointerEnterError, pointerLeaveError], }, { code: '
{}} />', options: [{ hoverInHandlers: ['onMouseOver'] }], errors: [mouseOverError], }, { code: '
{}} />', options: [{ hoverInHandlers: ['onPointerEnter'] }], errors: [pointerEnterError], }, { code: '
{}} />', options: [{ hoverOutHandlers: ['onMouseOut'] }], errors: [mouseOutError], }, { code: '
{}} />', options: [{ hoverOutHandlers: ['onPointerLeave'] }], errors: [pointerLeaveError], }, )).map(parserOptionsMapper), });