Software Engineer R/GA
@nackjicholsonn
github:nackjicholson
willieviseoae@gmail.com
william.vaughn@rga.com
How will we possibly deal with all the well organized, carefully named, comprehensible small things?!
Data => Display
Interaction => Action
import assert from 'assert';
describe('What unit aspect are you testing?', () => {
it('What should the unit do?', () => {
const actual = 'What is the actual output?';
const expected = 'What do you expect the output to be?';
assert.equal(actual, expected, 'Describe to me what happened here.');
});
});5 Questions
import assert from 'assert';
import shout from './shout';
describe('shout', () => {
it('should uppercase a string', () => {
// "Arrange"
const str = 'foobar';
// "Act"
const actual = shout(str);
const expected = 'FOOBAR';
// "Assert"
assert.equal(actual, expected, 'returns str uppercased');
});
});shout should uppercase a string
Does it display the props we give it?
Does it respond to user interactions?
Stateless Functional Component
<div id="robot-sounds-wrapper">
<label for="robot-sounds-select">Robot Sounds:</label>
<select id="robot-sounds-select" name="robot-sounds-select">
<option value="beep">beep</option>
<option value="boop" selected >boop</option>
</select>
</div>{
id: 'robot-sounds'
labelText: 'Robot Sounds:'
defaultValue: 'boop',
onSelection: (value) => { /* do something with value */ }
}Props
HTML
import $ from 'teaspoon';
import assert from 'assert';
import React from 'react';
import { spy } from 'sinon';
import SelectControl from './SelectControl';
describe('app/components/SelectControl', () => {
it('should render wrapper div');
it('should render label with labelText prop');
it('should render children prop within select list');
it('should be able to select a default option');
it('should handle selection changes via onSelection callback prop');
});it('should render wrapper div', () => {
// "Arrange"
const props = { id: 'foo' };
// "Act"
const actual = $(<SelectControl {...props} />)
.render()
.find('div[id=foo-wrapper]')
.length;
const expected = 1;
// "Assert"
assert.equal(actual, expected, 'rendered 1 wrapper div based on id prop');
});import React from 'react';
export default function SelectControl(props) {
return <div id={`${props.id}-wrapper`}></div>;
}it('should render label with labelText prop', () => {
const props = { id: 'foo', labelText: 'test.labelText' };
const actual = $(<SelectControl {...props} />)
.render()
.find('div > label[htmlFor=foo-select]')
.text();
const expected = 'test.labelText';
assert.equal(actual, expected, 'label rendered with text from labelText prop');
});import React from 'react';
export default function SelectControl(props) {
return (
<div id={`${props.id}-wrapper`}>
<label htmlFor={`${props.id}-select`}>{props.labelText}</label>
</div>
);
}it('should render children prop within select list', () => {
const props = { id: 'foo' };
const component = (
<SelectControl {...props}>
<option value="alpha.value">alpha.text</option>
<option value="bravo.value">bravo.text</option>
<option value="charlie.value">charlie.text</option>
</SelectControl>
);
const $options = $(component)
.render()
.find('div > select[id=foo-select] option');
const actual = $options
.map(optionNode => [optionNode.value, optionNode.text])
.get();
const expected = [
['alpha.value', 'alpha.text'],
['bravo.value', 'bravo.text'],
['charlie.value', 'charlie.text']
];
assert.deepEqual(actual, expected, 'rendered option children within select list');
});import React from 'react';
export default function SelectControl(props) {
return (
<div id={`${props.id}-wrapper`}>
<label htmlFor={`${props.id}-select`}>{props.labelText}</label>
<select id={`${props.id}-select`} name={`${props.id}-select`}>
{props.children}
</select>
</div>
);
}import React from 'react';
export default function SelectControl(props) {
const { id, children, labelText } = props;
const wrapperId = `${id}-wrapper`;
const selectId = `${id}-select`;
return (
<div id={wrapperId}>
<label htmlFor={selectId}>{labelText}</label>
<select id={selectId} name={selectId}>
{children}
</select>
</div>
);
}
it('should be able to select a default option', () => {
const props = { id: 'foo', defaultValue: 'bravo.value' };
const component = (
<SelectControl {...props}>
<option value="alpha.value">alpha.text</option>
<option value="bravo.value">bravo.text</option>
<option value="charlie.value">charlie.text</option>
</SelectControl>
);
const $options = $(component)
.render()
.find('div > select[id=foo-select] option');
const checkedOption = $options
.get()
.find(optionNode => optionNode.selected);
const actual = checkedOption.value;
const expected = 'bravo.value';
assert.equal(actual, expected, 'selected the option via defaultValue prop');
});import React from 'react';
export default function SelectControl(props) {
const { id, children, defaultValue, labelText } = props;
const wrapperId = `${id}-wrapper`;
const selectId = `${id}-select`;
return (
<div id={wrapperId}>
<label htmlFor={selectId}>{labelText}</label>
<select id={selectId} name={selectId} defaultValue={defaultValue}>
{children}
</select>
</div>
);
}
it('should handle selection changes via onSelection callback prop', () => {
const props = { id: 'foo', onSelection: spy() };
$(<SelectControl {...props} />)
.render()
.find('div > select[id=foo-select]')
.trigger('change', { target: { value: 'bingo' } });
assert(props.onSelection.calledOnce, 'onSelection callback prop called once');
const actual = props.onSelection.args[0];
const expected = ['bingo'];
assert.deepEqual(
actual,
expected,
'onSelection callback called with change value'
);
});import React from 'react';
export default function SelectControl(props) {
const { id, children, defaultValue, labelText, onSelection } = props;
const wrapperId = `${id}-wrapper`;
const selectId = `${id}-select`;
function handleChange(event) {
onSelection(event.target.value);
}
return (
<div id={wrapperId}>
<label htmlFor={selectId}>{labelText}</label>
<select
id={selectId}
name={selectId}
defaultValue={defaultValue}
onChange={handleChange}
>
{children}
</select>
</div>
);
}
@nackjicholsonn