Skip to content
This repository was archived by the owner on Jun 19, 2018. It is now read-only.

Commit 2f09c70

Browse files
committed
Add more tests
1 parent 40ce26e commit 2f09c70

File tree

4 files changed

+57
-85
lines changed

4 files changed

+57
-85
lines changed

src/Field/__tests__/controlGroup.spec.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Fragment, createElement } from 'react';
1+
import { createElement } from 'react';
22
import { configure, shallow } from 'enzyme';
33
import Adapter from 'enzyme-adapter-react-16';
44

@@ -26,11 +26,11 @@ test('derives state from props', () => {
2626
expect(colorProps.value.every(v => checkedValues.has(v))).toBeTruthy;
2727
});
2828

29-
test('renders a fragment', () => {
29+
test('renders a div', () => {
3030
const props = { ...colorProps };
3131
const wrapper = shallow(<ControlGroup {...props} />);
3232

33-
expect(wrapper.type()).toEqual(Fragment);
33+
expect(wrapper.type()).toEqual('div');
3434
});
3535

3636
test('renders a child for each option', () => {

src/Field/__tests__/field.spec.js

Lines changed: 27 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -6,38 +6,48 @@ import Field from '../field';
66

77
configure({ adapter: new Adapter() });
88

9-
test('renders a div', () => {
9+
test('renders a div by default', () => {
1010
const children = 'abc';
1111
const wrapper = shallow(<Field>{children}</Field>);
1212

1313
expect(wrapper.type()).toEqual('div');
1414
});
1515

16-
test('renders children and a message', () => {
17-
const props = { children: 'a', message: 'b' };
16+
test('renders a label when `singular` is `true`', () => {
17+
const children = 'abc';
18+
const props = { children, singular: true };
1819
const wrapper = shallow(<Field {...props} />);
1920

20-
expect(wrapper.childAt(0).text()).toEqual(props.children);
21-
expect(wrapper.childAt(1).text()).toEqual(props.message);
21+
expect(wrapper.type()).toEqual('label');
2222
});
2323

24-
test('renders an empty message element by default', () => {
25-
const props = { children: 'a' };
26-
const wrapper = shallow(<Field {...props} />);
24+
test('renders `label` as a span', () => {
25+
const props = { children: 'a', label: 'b' };
26+
const wrapper = shallow(<Field {...props} />).childAt(0);
2727

28-
expect(wrapper.childAt(1).type()).toEqual('p');
28+
expect(wrapper.childAt(0).type()).toEqual('span');
29+
expect(wrapper.childAt(0).text()).toEqual(props.label);
2930
});
3031

31-
test('renders a control', () => {
32-
const props = { type: 'text' };
33-
const wrapper = shallow(<Field {...props} />);
32+
test('renders `message` as a paragraph', () => {
33+
const props = { children: 'a', message: 'b' };
34+
const wrapper = shallow(<Field {...props} />).childAt(0);
3435

35-
expect(wrapper.childAt(0).type()).toEqual('label');
36+
expect(wrapper.childAt(2).type()).toEqual('p');
37+
expect(wrapper.childAt(2).text()).toEqual(props.message);
3638
});
3739

38-
test('renders a control group', () => {
39-
const props = { options: [], type: 'radio' };
40-
const wrapper = shallow(<Field {...props} />);
40+
test('renders `children` between label and message', () => {
41+
const props = { children: 'a' };
42+
const wrapper = shallow(<Field {...props} />).childAt(0);
43+
44+
expect(wrapper.childAt(1).text()).toEqual(props.children);
45+
});
46+
47+
test('renders `children` as provided', () => {
48+
const child = <span>abc</span>;
49+
const field = <Field>{child}</Field>;
50+
const wrapper = shallow(field).childAt(0);
4151

42-
expect(wrapper.childAt(0).type()).toEqual('div');
52+
expect(wrapper.contains(child)).toBe(true);
4353
});

src/Field/controlGroup.js

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Component, Fragment, createElement } from 'react';
1+
import { Component, createElement } from 'react';
22
import PropTypes from 'prop-types';
33

44
import Switch from './switch';
@@ -34,28 +34,34 @@ class ControlGroup extends Component {
3434
checkedValues: new Set()
3535
};
3636

37-
render() {
37+
get children() {
3838
const { checkedValues } = this.state;
3939
const { classes, name, options, type } = this.props;
4040
const sharedProps = { name, type, onChange: this.handleChange };
4141

42-
const children = options.map(({ label, value, ...inputProps }) => {
42+
return options.map(({ id, label, value, ...inputProps }) => {
4343
const isChecked = checkedValues.has(value);
4444

4545
return (
46-
<label key={value} className={classes.option}>
46+
<label key={value} htmlFor={id} className={classes.option}>
4747
<span className={classes.label}>{label}</span>
4848
<Switch
4949
{...sharedProps}
5050
{...inputProps}
51+
id={id}
5152
value={value}
5253
checked={isChecked}
5354
/>
5455
</label>
5556
);
5657
});
58+
}
59+
60+
render() {
61+
const { children, props } = this;
62+
const { classes } = props;
5763

58-
return <Fragment>{children}</Fragment>;
64+
return <div className={classes.root}>{children}</div>;
5965
}
6066

6167
handleChange = (name, value, isChecked) => {

src/Field/field.js

Lines changed: 16 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -1,90 +1,46 @@
1-
import { Component, createElement } from 'react';
1+
import { Component, Fragment, createElement } from 'react';
22
import PropTypes from 'prop-types';
33

4-
import Control from './control';
5-
import ControlGroup from './controlGroup';
6-
7-
const groupTypes = ['checkbox', 'radio'];
8-
const isGroupType = type => groupTypes.includes(type);
9-
104
class Field extends Component {
115
static propTypes = {
126
classes: PropTypes.shape({
13-
control: PropTypes.string,
14-
controls: PropTypes.string,
15-
group: PropTypes.string,
167
label: PropTypes.string,
178
message: PropTypes.string,
189
root: PropTypes.string
1910
}),
2011
label: PropTypes.node,
2112
message: PropTypes.node,
22-
type: PropTypes.string,
23-
value: PropTypes.any
13+
singular: PropTypes.bool
2414
};
2515

2616
static defaultProps = {
2717
classes: {}
2818
};
2919

3020
get children() {
31-
const { children, type } = this.props;
32-
33-
if (children) {
34-
return children;
35-
}
36-
37-
return isGroupType(type) ? this.controlGroup : this.control;
38-
}
39-
40-
get control() {
41-
const { classes, label, type, value } = this.props;
42-
const controlProps = { type, value };
43-
44-
return (
45-
<label className={classes.control}>
46-
<span className={classes.label}>{label}</span>
47-
<Control {...controlProps} onChange={this.handleChange} />
48-
</label>
49-
);
50-
}
51-
52-
get controlGroup() {
53-
const { classes, label, options, type, value } = this.props;
54-
const controlProps = { options, type, value };
21+
const { classes, children, label, message } = this.props;
5522

5623
return (
57-
<div className={classes.controls}>
58-
<span className={classes.label}>{label}</span>
59-
<div className={classes.group}>
60-
<ControlGroup
61-
{...controlProps}
62-
onChange={this.handleChange}
63-
/>
64-
</div>
65-
</div>
24+
<Fragment>
25+
<span key={label} className={classes.label}>
26+
{label}
27+
</span>
28+
{children}
29+
<p key={message} className={classes.message}>
30+
{message}
31+
</p>
32+
</Fragment>
6633
);
6734
}
6835

6936
render() {
7037
const { children, props } = this;
71-
const { classes, message } = props;
38+
const { classes, singular } = props;
39+
const elementType = singular ? 'label' : 'div';
40+
const elementProps = { className: classes.root };
7241

73-
return (
74-
<div className={classes.root}>
75-
{children}
76-
<p className={classes.message}>{message}</p>
77-
</div>
78-
);
42+
return createElement(elementType, elementProps, children);
7943
}
80-
81-
handleChange = (name, value) => {
82-
const { onChange } = this.props;
83-
84-
if (onChange) {
85-
onChange(name, value);
86-
}
87-
};
8844
}
8945

9046
export default Field;

0 commit comments

Comments
 (0)