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

Commit 05aa0a0

Browse files
committed
Merge pull request #77 from lab-coop/tests
Adding initial unit tests from @ryanalane.
2 parents a7b44d1 + bc725ff commit 05aa0a0

File tree

14 files changed

+330
-22
lines changed

14 files changed

+330
-22
lines changed

.babelrc

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"env": {
3+
"test": {
4+
"presets": ["es2015", "stage-0", "react"]
5+
}
6+
}
7+
}

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
examples/**/*-bundle.js
22
node_modules/
3+
coverage/

README.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,13 @@ Stuff we need help with:
1515
pretty lean, on purpose, apps should style this however they'd like)
1616
- tests (eventually)
1717

18+
# Tests!
1819

20+
Run them:
21+
`npm test`
22+
23+
Write them:
24+
`lib/__tests__/Autocomplete-test.js`
25+
26+
Check your work:
27+
`npm run coverage`

examples/async-data/app.css

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,8 @@ body {
77
.example {
88
padding: 0 25px;
99
}
10+
11+
label {
12+
display: block;
13+
margin: 5px 0;
14+
}

examples/async-data/app.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import React from 'react'
22
import Autocomplete from '../../lib/index'
3-
import { getStates, matchStateToTerm, sortStates, styles, fakeRequest } from '../utils'
3+
import { getStates, matchStateToTerm, sortStates, styles, fakeRequest } from '../../lib/utils'
44

55
let App = React.createClass({
66

@@ -24,6 +24,8 @@ let App = React.createClass({
2424
</p>
2525

2626
<Autocomplete
27+
labelText="Choose a state from the US"
28+
inputProps={{name: "US state"}}
2729
ref="autocomplete"
2830
items={this.state.unitedStates}
2931
getItemValue={(item) => item.name}

examples/custom-menu/app.css

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,8 @@ body {
77
.example {
88
padding: 0 25px;
99
}
10+
11+
label {
12+
display: block;
13+
margin: 5px 0;
14+
}

examples/custom-menu/app.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import React from 'react'
22
import Autocomplete from '../../lib/index'
3-
import { getStates, matchStateToTerm, sortStates, styles, fakeRequest } from '../utils'
3+
import { getStates, matchStateToTerm, sortStates, styles, fakeRequest } from '../../lib/utils'
44

55
let App = React.createClass({
66

@@ -21,6 +21,8 @@ let App = React.createClass({
2121
letter of the alphabet.
2222
</p>
2323
<Autocomplete
24+
labelText="Choose a state from the US"
25+
inputProps={{name: "US state"}}
2426
items={this.state.unitedStates}
2527
getItemValue={(item) => item.name}
2628
onSelect={() => this.setState({ unitedStates: [] }) }

examples/static-data/app.css

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,8 @@ body {
77
.example {
88
padding: 0 25px;
99
}
10+
11+
label {
12+
display: block;
13+
margin: 5px 0;
14+
}

examples/static-data/app.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import React from 'react'
2-
import { getStates, matchStateToTerm, sortStates, styles } from '../utils'
2+
import { getStates, matchStateToTerm, sortStates, styles } from '../../lib/utils'
33
import Autocomplete from '../../lib/index'
44

55
let App = React.createClass({
@@ -15,6 +15,8 @@ let App = React.createClass({
1515

1616
<Autocomplete
1717
initialValue="Ma"
18+
labelText="Choose a state from the US"
19+
inputProps={{name: "US state"}}
1820
items={getStates()}
1921
getItemValue={(item) => item.name}
2022
shouldItemRender={matchStateToTerm}

lib/Autocomplete.js

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
const React = require('react')
2+
const lodash = require('lodash')
23
const scrollIntoView = require('dom-scroll-into-view')
34

45
let _debugStates = []
@@ -12,12 +13,14 @@ let Autocomplete = React.createClass({
1213
shouldItemRender: React.PropTypes.func,
1314
renderItem: React.PropTypes.func.isRequired,
1415
menuStyle: React.PropTypes.object,
15-
inputProps: React.PropTypes.object
16+
inputProps: React.PropTypes.object,
17+
labelText: React.PropTypes.string
1618
},
1719

1820
getDefaultProps () {
1921
return {
2022
inputProps: {},
23+
labelText: '',
2124
onChange () {},
2225
onSelect (value, item) {},
2326
renderMenu (items, value, style) {
@@ -46,6 +49,7 @@ let Autocomplete = React.createClass({
4649
},
4750

4851
componentWillMount () {
52+
this.id = lodash.uniqueId('autocomplete-');
4953
this._ignoreBlur = false
5054
this._performAutoCompleteOnUpdate = false
5155
this._performAutoCompleteOnKeyUp = false
@@ -103,7 +107,7 @@ let Autocomplete = React.createClass({
103107
},
104108

105109
keyDownHandlers: {
106-
ArrowDown () {
110+
ArrowDown (event) {
107111
event.preventDefault()
108112
var { highlightedIndex } = this.state
109113
var index = (
@@ -133,18 +137,19 @@ let Autocomplete = React.createClass({
133137

134138
Enter (event) {
135139
if (this.state.isOpen === false) {
136-
// already selected this, do nothing
140+
// menu is closed so there is no selection to accept -> do nothing
137141
return
138142
}
139143
else if (this.state.highlightedIndex == null) {
140-
// hit enter after focus but before typing anything so no autocomplete attempt yet
144+
// input has focus but no menu item is selected + enter is hit -> close the menu, highlight whatever's in input
141145
this.setState({
142146
isOpen: false
143147
}, () => {
144148
this.refs.input.select()
145149
})
146150
}
147151
else {
152+
// text entered + menu item has been highlighted + enter is hit -> update value to that of selected menu item, close the menu
148153
var item = this.getFilteredItems()[this.state.highlightedIndex]
149154
this.setState({
150155
value: this.props.getItemValue(item),
@@ -216,10 +221,10 @@ let Autocomplete = React.createClass({
216221
setMenuPositions () {
217222
var node = this.refs.input
218223
var rect = node.getBoundingClientRect()
219-
var computedStyle = getComputedStyle(node)
220-
var marginBottom = parseInt(computedStyle.marginBottom, 10)
221-
var marginLeft = parseInt(computedStyle.marginLeft, 10)
222-
var marginRight = parseInt(computedStyle.marginRight, 10)
224+
var computedStyle = global.window.getComputedStyle(node)
225+
var marginBottom = parseInt(computedStyle.marginBottom, 10) || 0;
226+
var marginLeft = parseInt(computedStyle.marginLeft, 10) || 0;
227+
var marginRight = parseInt(computedStyle.marginRight, 10) || 0;
223228
this.setState({
224229
menuTop: rect.bottom + marginBottom,
225230
menuLeft: rect.left + marginLeft,
@@ -297,8 +302,11 @@ let Autocomplete = React.createClass({
297302
state: this.state
298303
})
299304
}
300-
return (
305+
return (
301306
<div style={{display: 'inline-block'}}>
307+
<label htmlFor={this.id} ref="label">
308+
{this.props.labelText}
309+
</label>
302310
<input
303311
{...this.props.inputProps}
304312
role="combobox"
@@ -311,6 +319,7 @@ let Autocomplete = React.createClass({
311319
onKeyUp={(event) => this.handleKeyUp(event)}
312320
onClick={this.handleInputClick}
313321
value={this.state.value}
322+
id={this.id}
314323
/>
315324
{this.state.isOpen && this.renderMenu()}
316325
{this.props.debug && (

0 commit comments

Comments
 (0)