-
-
Notifications
You must be signed in to change notification settings - Fork 112
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: added focusable matcher (#395)
- Loading branch information
Showing
6 changed files
with
182 additions
and
46 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
/* eslint-disable react/prop-types, react/no-multi-comp */ | ||
import React, { Component } from 'react'; | ||
import { mount } from 'enzyme'; | ||
import toBeFocusable from './../toBeFocusable'; | ||
|
||
const Button = () => <button />; | ||
const Input = (props) => { | ||
const { onClick, onFocus, onBlur } = props; | ||
return <input onClick={onClick} onFocus={onFocus} onBlur={onBlur} />; | ||
}; | ||
class ButtonIcon extends Component { | ||
constructor(props) { | ||
super(props); | ||
this.buttonRef = React.createRef(); | ||
} | ||
|
||
focus() { | ||
this.buttonRef.current.focus(); | ||
} | ||
|
||
click() { | ||
this.buttonRef.current.click(); | ||
} | ||
|
||
blur() { | ||
this.buttonRef.current.blur(); | ||
} | ||
|
||
render() { | ||
return <button ref={this.buttonRef} />; | ||
} | ||
} | ||
class FocusableInput extends Component { | ||
constructor(props) { | ||
super(props); | ||
this.buttonRef = React.createRef(); | ||
} | ||
|
||
focus() { | ||
this.buttonRef.current.focus(); | ||
} | ||
|
||
click() { | ||
this.buttonRef.current.click(); | ||
} | ||
|
||
blur() { | ||
this.buttonRef.current.blur(); | ||
} | ||
|
||
render() { | ||
const { onClick, onFocus, onBlur } = this.props; | ||
return <button ref={this.buttonRef} onClick={onClick} onFocus={onFocus} onBlur={onBlur} />; | ||
} | ||
} | ||
const components = [ | ||
mount(<Button />), | ||
mount(<Input />), | ||
mount(<ButtonIcon />), | ||
]; | ||
|
||
describe('toBeFocusable', () => { | ||
it('should return the right data when any component is passed', () => { | ||
expect(toBeFocusable()).toEqual({ | ||
message: expect.any(Function), | ||
pass: false, | ||
}); | ||
}); | ||
it('should return the right message when any component is passed', () => { | ||
expect(toBeFocusable().message()).toBe('You need to pass a component returned by mount or shallow enzyme\'s methods to check whether it is focusable or not.'); | ||
}); | ||
it('should return the right data when the component is not mounted by enzyme', () => { | ||
expect(toBeFocusable(Button)).toEqual({ | ||
message: expect.any(Function), | ||
pass: false, | ||
}); | ||
}); | ||
it('should return the right message when the component is not mounted by enzyme', () => { | ||
expect(toBeFocusable(<Button />).message()).toBe('You need to pass a component returned by mount or shallow enzyme\'s methods to check whether it is focusable or not.'); | ||
}); | ||
it('should return the right data when the component is not focusable', () => { | ||
components.forEach(component => expect(toBeFocusable(component)).toEqual({ | ||
message: expect.any(Function), | ||
pass: false, | ||
})); | ||
}); | ||
it('should return the right message when the component is not focusable', () => { | ||
components.forEach(component => expect(toBeFocusable(component).message()) | ||
.toBe(`Expected ${component.name()} to be focusable but it is not.`)); | ||
}); | ||
it('should return the right data when the component is focusable', () => { | ||
const component = mount(<FocusableInput />); | ||
expect(toBeFocusable(component)).toEqual({ | ||
message: '', | ||
pass: true, | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
import { eachShouldBeOneOrFunction } from './../utils'; | ||
|
||
describe('eachShouldBeOneOrFunction', () => { | ||
it('should return true when all items in the array passed are 1 or function', () => { | ||
const results = [1, 1, 1, 'function', 'function']; | ||
expect(eachShouldBeOneOrFunction(results)).toBe(true); | ||
}); | ||
it('should return false when one item in the array passed is not 1 or function', () => { | ||
const results = [ | ||
[1, 1, 0, 'function', 'function'], | ||
[1, 1, 1, '', 'function'], | ||
[1, 1, 1, 'object', 'function'], | ||
[1, 1, 1, undefined, 'function'], | ||
[2, 1, 1, 'function', 'function'], | ||
[1, 1, null, 'function', 'function'], | ||
[1, 1, [], 'function', 'function'], | ||
[1, 1, 1, {}, 'function'], | ||
]; | ||
results.forEach(result => expect(eachShouldBeOneOrFunction(result)).toBe(false)); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
import { eachShouldBeOneOrFunction } from './utils'; | ||
|
||
function isMountedByEnzyme(component) { | ||
return typeof component.setProps === 'function' | ||
&& typeof component.simulate === 'function' | ||
&& typeof component.instance === 'function'; | ||
} | ||
|
||
export default function toBeFocusable(component) { | ||
if (component && isMountedByEnzyme(component)) { | ||
const onClickMockFn = jest.fn(); | ||
const onBlurMockFn = jest.fn(); | ||
const onFocusMockFn = jest.fn(); | ||
|
||
component.setProps({ | ||
onClick: onClickMockFn, | ||
onBlur: onBlurMockFn, | ||
onFocus: onFocusMockFn, | ||
}); | ||
|
||
component.simulate('click'); | ||
component.simulate('blur'); | ||
component.simulate('focus'); | ||
const instance = component.instance(); | ||
|
||
const results = [ | ||
onClickMockFn.mock.calls.length, | ||
onFocusMockFn.mock.calls.length, | ||
onBlurMockFn.mock.calls.length, | ||
instance ? typeof instance.click : null, | ||
instance ? typeof instance.focus : null, | ||
instance ? typeof instance.blur : null, | ||
]; | ||
|
||
if (eachShouldBeOneOrFunction(results)) { | ||
return { | ||
message: '', | ||
pass: true, | ||
}; | ||
} | ||
return { | ||
message: () => `Expected ${component.name()} to be focusable but it is not.`, | ||
pass: false, | ||
}; | ||
} | ||
return { | ||
message: () => 'You need to pass a component returned by mount or shallow enzyme\'s methods to check whether it is focusable or not.', | ||
pass: false, | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
/* eslint-disable import/prefer-default-export */ | ||
|
||
export function eachShouldBeOneOrFunction(results) { | ||
return results.every(result => result === 1 || result === 'function'); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters