materialuiupgraded
Version:
Material-UI's workspace package
426 lines (362 loc) • 12.9 kB
JavaScript
import React from 'react';
import { assert } from 'chai';
import { spy } from 'sinon';
import { createShallow, createMount, getClasses, unwrap } from '../test-utils';
import SwitchBase from './SwitchBase';
import IconButton from '../IconButton';
import Icon from '../Icon';
function assertIsChecked(wrapper) {
const iconButton = wrapper.find('span').at(0);
assert.strictEqual(
iconButton.hasClass('test-class-checked'),
true,
'should have the checked class on the root node',
);
const input = wrapper.find('input');
assert.strictEqual(input.instance().checked, true);
const label = iconButton.childAt(0);
const icon = label.childAt(0);
assert.strictEqual(icon.name(), 'h2');
}
function assertIsNotChecked(wrapper) {
const iconButton = wrapper.find('span').at(0);
assert.strictEqual(
iconButton.hasClass('test-class-checked'),
false,
'should not have the checked class on the root node',
);
const input = wrapper.find('input');
assert.strictEqual(input.instance().checked, false);
const label = iconButton.childAt(0);
const icon = label.childAt(0);
assert.strictEqual(icon.name(), 'h1');
}
describe('<SwitchBase />', () => {
let shallow;
let mount;
let classes;
let SwitchBaseNaked;
const defaultProps = {
type: 'checkbox',
icon: <h1>h1</h1>,
checkedIcon: <h2>h2</h2>,
};
before(() => {
SwitchBaseNaked = unwrap(SwitchBase);
shallow = createShallow({ dive: true });
mount = createMount();
classes = getClasses(<SwitchBase {...defaultProps} />);
});
after(() => {
mount.cleanUp();
});
it('should render an IconButton', () => {
const wrapper = shallow(<SwitchBase {...defaultProps} />);
assert.strictEqual(wrapper.type(), IconButton);
});
it('should render an icon and input inside the button by default', () => {
const wrapper = shallow(<SwitchBase {...defaultProps} />);
assert.strictEqual(wrapper.childAt(0).name(), 'h1');
assert.strictEqual(wrapper.childAt(1).is('input[type="checkbox"]'), true);
});
it('should have a ripple by default', () => {
const wrapper = shallow(<SwitchBase {...defaultProps} />);
assert.strictEqual(wrapper.props().disableRipple, undefined);
});
it('should pass disableRipple={true} to IconButton', () => {
const wrapper = shallow(<SwitchBase {...defaultProps} disableRipple />);
assert.strictEqual(wrapper.props().disableRipple, true);
});
// className is put on the root node, this is a special case!
it('should render with the user and root classes', () => {
const wrapper = shallow(<SwitchBase {...defaultProps} className="woofSwitchBase" />);
assert.strictEqual(wrapper.hasClass('woofSwitchBase'), true);
assert.strictEqual(wrapper.hasClass(classes.root), true);
});
it('should spread custom props on the root node', () => {
const wrapper = shallow(<SwitchBase {...defaultProps} data-my-prop="woofSwitchBase" />);
assert.strictEqual(
wrapper.props()['data-my-prop'],
'woofSwitchBase',
'custom prop should be woofSwitchBase',
);
});
it('should pass tabIndex to the input so it can be taken out of focus rotation', () => {
const wrapper = shallow(<SwitchBase {...defaultProps} tabIndex={-1} />);
const input = wrapper.find('input');
assert.strictEqual(input.props().tabIndex, -1);
});
it('should pass value, disabled, checked, and name to the input', () => {
const props = { name: 'gender', disabled: true, value: 'male' };
const wrapper = shallow(<SwitchBase {...defaultProps} {...props} />);
const input = wrapper.find('input');
Object.keys(props).forEach(n => {
assert.strictEqual(input.props()[n], props[n]);
});
});
it('should disable the components, and render the IconButton with the disabled className', () => {
const wrapper = shallow(<SwitchBase {...defaultProps} disabled />);
assert.strictEqual(wrapper.props().disabled, true);
assert.strictEqual(wrapper.childAt(1).props().disabled, true);
});
it('should apply the custom disabled className when disabled', () => {
const disabledClassName = 'foo';
const wrapperA = shallow(
<SwitchBase {...defaultProps} disabled classes={{ disabled: disabledClassName }} />,
);
assert.strictEqual(
wrapperA.hasClass(disabledClassName),
true,
'should have the custom disabled class',
);
wrapperA.setProps({ disabled: false });
wrapperA.setProps({ checked: true });
assert.strictEqual(
wrapperA.hasClass(disabledClassName),
false,
'should not have the custom disabled class',
);
});
describe('controlled', () => {
let wrapper;
beforeEach(() => {
wrapper = mount(
<SwitchBaseNaked
{...defaultProps}
classes={{
checked: 'test-class-checked',
}}
className="test-class"
checked={false}
/>,
);
});
it('should recognize a controlled input', () => {
assert.strictEqual(
wrapper.instance().isControlled,
true,
'should set instance.isControlled to true',
);
assertIsNotChecked(wrapper);
});
it('should check the checkbox', () => {
wrapper.setProps({ checked: true });
assertIsChecked(wrapper);
});
it('should uncheck the checkbox', () => {
wrapper.setProps({ checked: true });
wrapper.setProps({ checked: false });
assertIsNotChecked(wrapper);
});
});
describe('prop: defaultChecked', () => {
it('should work uncontrolled', () => {
const wrapper = mount(<SwitchBaseNaked {...defaultProps} classes={{}} defaultChecked />);
wrapper
.find('input')
.instance()
.click();
wrapper.update();
assertIsNotChecked(wrapper);
});
});
describe('uncontrolled', () => {
let wrapper;
beforeEach(() => {
wrapper = mount(
<SwitchBaseNaked
{...defaultProps}
classes={{
checked: 'test-class-checked',
}}
className="test-class"
/>,
);
});
it('should recognize an uncontrolled input', () => {
assert.strictEqual(wrapper.instance().isControlled, false);
assertIsNotChecked(wrapper);
});
it('should check the checkbox', () => {
wrapper
.find('input')
.instance()
.click();
wrapper.update();
assertIsChecked(wrapper);
});
it('should uncheck the checkbox', () => {
wrapper
.find('input')
.instance()
.click();
wrapper
.find('input')
.instance()
.click();
wrapper.update();
assertIsNotChecked(wrapper);
});
});
describe('prop: icon', () => {
it('should render an Icon', () => {
const wrapper = shallow(<SwitchBase {...defaultProps} icon={<Icon>heart</Icon>} />);
assert.strictEqual(wrapper.childAt(0).is(Icon), true);
});
});
describe('handleInputChange()', () => {
const event = {
target: {
checked: false,
},
};
it('should call onChange exactly once with event', () => {
const handleChange = spy();
const wrapper = mount(
<SwitchBaseNaked {...defaultProps} classes={{}} onChange={handleChange} />,
);
const instance = wrapper.instance();
instance.handleInputChange(event);
assert.strictEqual(handleChange.callCount, 1);
assert.strictEqual(handleChange.calledWith(event), true);
handleChange.resetHistory();
});
describe('controlled', () => {
it('should call onChange once', () => {
const checked = true;
const handleChange = spy();
const wrapper = mount(
<SwitchBaseNaked
{...defaultProps}
classes={{}}
checked={checked}
onChange={handleChange}
/>,
);
const instance = wrapper.instance();
instance.handleInputChange(event);
assert.strictEqual(handleChange.callCount, 1);
assert.strictEqual(
handleChange.calledWith(event, !checked),
true,
'call onChange with event and !props.checked',
);
});
});
describe('not controlled no input', () => {
let checkedMock;
let wrapper;
let handleChange;
before(() => {
handleChange = spy();
wrapper = mount(<SwitchBaseNaked {...defaultProps} classes={{}} onChange={handleChange} />);
checkedMock = true;
const instance = wrapper.instance();
wrapper.setState({ checked: checkedMock });
instance.handleInputChange(event);
});
it('should call onChange exactly once', () => {
assert.strictEqual(handleChange.callCount, 1);
});
it('should call onChange with right params', () => {
assert.strictEqual(handleChange.calledWith(event, !checkedMock), true);
});
it('should change state.checked !checkedMock', () => {
assert.strictEqual(wrapper.state('checked'), !checkedMock);
});
});
describe('prop: inputProps', () => {
it('should be able to add aria', () => {
const wrapper2 = shallow(
<SwitchBase {...defaultProps} inputProps={{ 'aria-label': 'foo' }} />,
);
assert.strictEqual(wrapper2.find('input').props()['aria-label'], 'foo');
});
});
describe('prop: id', () => {
it('should be able to add id to a checkbox input', () => {
const wrapper2 = shallow(<SwitchBase {...defaultProps} type="checkbox" id="foo" />);
assert.strictEqual(wrapper2.find('input').props().id, 'foo');
});
it('should be able to add id to a radio input', () => {
const wrapper2 = shallow(<SwitchBase {...defaultProps} type="radio" id="foo" />);
assert.strictEqual(wrapper2.find('input').props().id, 'foo');
});
});
});
describe('with muiFormControl context', () => {
let wrapper;
let muiFormControl;
function setFormControlContext(muiFormControlContext) {
muiFormControl = muiFormControlContext;
wrapper.setContext({ ...wrapper.context(), muiFormControl });
}
beforeEach(() => {
wrapper = shallow(<SwitchBase {...defaultProps} />);
});
describe('enabled', () => {
beforeEach(() => {
setFormControlContext({});
});
it('should not have the disabled class', () => {
assert.strictEqual(wrapper.hasClass(classes.disabled), false);
});
it('should be overridden by props', () => {
assert.strictEqual(wrapper.hasClass(classes.disabled), false);
wrapper.setProps({ disabled: true });
assert.strictEqual(wrapper.hasClass(classes.disabled), true);
});
});
describe('disabled', () => {
beforeEach(() => {
setFormControlContext({ disabled: true });
});
it('should have the disabled class', () => {
assert.strictEqual(wrapper.hasClass(classes.disabled), true);
});
it('should honor props', () => {
assert.strictEqual(wrapper.hasClass(classes.disabled), true);
wrapper.setProps({ disabled: false });
assert.strictEqual(wrapper.hasClass(classes.disabled), false);
});
});
});
describe('prop: onFocus', () => {
it('should work', () => {
const handleFocusProps = spy();
const handleFocusContext = spy();
const wrapper = mount(
<SwitchBaseNaked {...defaultProps} classes={{}} onFocus={handleFocusProps} />,
{
context: {
muiFormControl: {
onFocus: handleFocusContext,
},
},
},
);
wrapper.find('input').simulate('focus');
assert.strictEqual(handleFocusProps.callCount, 1);
assert.strictEqual(handleFocusContext.callCount, 1);
});
});
describe('prop: onBlur', () => {
it('should work', () => {
const handleFocusProps = spy();
const handleFocusContext = spy();
const wrapper = mount(
<SwitchBaseNaked {...defaultProps} classes={{}} onBlur={handleFocusProps} />,
{
context: {
muiFormControl: {
onBlur: handleFocusContext,
},
},
},
);
wrapper.find('input').simulate('blur');
assert.strictEqual(handleFocusProps.callCount, 1);
assert.strictEqual(handleFocusContext.callCount, 1);
});
});
});