diff --git a/example/example.js b/example/example.js index e1cf532..285b1f4 100644 --- a/example/example.js +++ b/example/example.js @@ -1,9 +1,9 @@ var React = require('react') var SelectBox = React.createFactory(require('../lib/select-box')) -var div = React.createElement.bind(null,'div') -var option = React.createElement.bind(null,'option') -var h1 = React.createElement.bind(null,'h1') +var div = React.createFactory('div') +var option = React.createFactory('option') +var h1 = React.createFactory('h1') var Example = React.createFactory(React.createClass({displayName: 'Example', getInitialState: function () { diff --git a/karma.conf.js b/karma.conf.js index 7317cf8..5294dcc 100644 --- a/karma.conf.js +++ b/karma.conf.js @@ -20,7 +20,7 @@ module.exports = function(config) { colors: true } }, - reporters: [ 'progress' ], + reporters: [ 'mocha' ], port: 9876, colors: true, autoWatch: true, @@ -30,6 +30,7 @@ module.exports = function(config) { plugins: [ require("karma-mocha"), require("karma-chai"), + require("karma-mocha-reporter"), require("karma-firefox-launcher"), require("karma-webpack") ] diff --git a/lib/select-box.js b/lib/select-box.js index 2cf3694..17296a2 100644 --- a/lib/select-box.js +++ b/lib/select-box.js @@ -2,12 +2,12 @@ var React = require('react/addons') -var div = React.createElement.bind(null, 'div') -var button = React.createElement.bind(null, 'button') -var a = React.createElement.bind(null, 'a') -var select = React.createElement.bind(null, 'select') -var option = React.createElement.bind(null ,'option') -var label = React.createElement.bind(null, 'label') +var div = React.createFactory('div') +var button = React.createFactory('button') +var a = React.createFactory('a') +var select = React.createFactory('select') +var option = React.createFactory('option') +var label = React.createFactory('label') var idInc = 0 diff --git a/package.json b/package.json index 4a19779..b4bad36 100644 --- a/package.json +++ b/package.json @@ -38,6 +38,7 @@ "karma-chai": "^0.1.0", "karma-firefox-launcher": "^0.1.3", "karma-mocha": "^0.1.6", + "karma-mocha-reporter": "^1.0.3", "karma-webpack": "^1.2.1", "mocha": "^1.21.3", "react": "^0.12.0", diff --git a/test/select-box.spec.js b/test/select-box.spec.js index 20bbde9..bb6088e 100644 --- a/test/select-box.spec.js +++ b/test/select-box.spec.js @@ -1,153 +1,219 @@ -var SelectBox = require('../lib/select-box') var React = require('react/addons') var TestUtils = React.addons.TestUtils +var SelectBox = React.createFactory(require('../lib/select-box')) describe('SelectBox component', function () { - + var selectBox var options + var testOptions = [ + { value: 'red', label: 'Red' }, + { value: 'green', label: 'Green' }, + { value: 'blue', label: 'Blue' }, + ] + + function makeSelectBox(multi) { + var args = testOptions.map(function (option) { + return React.DOM.option({value: option.value}, option.label) + }) - beforeEach(function () { - testOptions = [ - { value: 'red', label: 'Red' }, - { value: 'green', label: 'Green' }, - { value: 'blue', label: 'Blue' }, - ] - - var args = testOptions.map(function (option) { - return React.DOM.option({value: option.value}, option.label) - }) + args.unshift({ + label: 'foo', + value: null, + multiple: multi !== true ? false : multi, + onChange: function() {} + }) - args.unshift({ - label: 'foo', - value: null, - onChange: function() {} - }) + return TestUtils.renderIntoDocument(SelectBox.apply(null, args)) + } - selectBox = TestUtils.renderIntoDocument(SelectBox.apply(null, args)) - }) - - it('should render the label when no value is selected', function () { - var label = TestUtils.scryRenderedDOMComponentsWithClass( + function scryRenderedDOMComponentsWithClass(name) { + return TestUtils.scryRenderedDOMComponentsWithClass( selectBox, - 'react-select-box-label' + name ) - label.should.have.length(1) - label[0].getDOMNode().textContent.should.equal(selectBox.props.label) - }) + } + + describe('Single select mode', function () { + + beforeEach(function () { + selectBox = makeSelectBox() + }) - it('should render the label for the selected value', function (done) { - selectBox.setProps({ value: testOptions[0].value }, function () { - var label = TestUtils.scryRenderedDOMComponentsWithClass( - selectBox, - 'react-select-box-label' - ) + it('should render the label when no value is selected', function () { + var label = scryRenderedDOMComponentsWithClass('react-select-box-label') label.should.have.length(1) - label[0].getDOMNode().textContent.should.equal(testOptions[0].label) - done() + label[0].getDOMNode().textContent.should.equal(selectBox.props.label) + }) + + it('should render the label when no value is selected', function () { + var label = scryRenderedDOMComponentsWithClass('react-select-box-label') + label.should.have.length(1) + label[0].getDOMNode().textContent.should.equal(selectBox.props.label) }) - }) - it('should not render the clear button with no value selected', function (done) { - selectBox.setProps({ value: null }, function () { - var clear = TestUtils.scryRenderedDOMComponentsWithClass( - selectBox, - 'react-select-box-clear' - ) - clear.should.have.length(0) - done() + it('should render the label for the selected value', function (done) { + selectBox.setProps({ value: testOptions[0].value }, function () { + var label = scryRenderedDOMComponentsWithClass('react-select-box-label') + label.should.have.length(1) + label[0].getDOMNode().textContent.should.equal(testOptions[0].label) + done() + }) + }) + + it('should not render the clear button with no value selected', function (done) { + selectBox.setProps({ value: null }, function () { + var clear = scryRenderedDOMComponentsWithClass('react-select-box-clear') + clear.should.have.length(0) + done() + }) }) - }) - it('should render the clear button with a selected value', function (done) { - selectBox.setProps({ value: testOptions[0].value }, function () { - var clear = TestUtils.scryRenderedDOMComponentsWithClass( - selectBox, - 'react-select-box-clear' - ) - clear.should.have.length(1) - done() + it('should render the clear button with a selected value', function (done) { + selectBox.setProps({ value: testOptions[0].value }, function () { + var clear = scryRenderedDOMComponentsWithClass('react-select-box-clear') + clear.should.have.length(1) + done() + }) }) - }) - it('should add hidden class to options when state.open is false', function (done) { - selectBox.setState({ open: false }, function () { - var options = TestUtils.scryRenderedDOMComponentsWithClass( - selectBox, - 'react-select-box-options' - ) - options.should.have.length(1) - options[0].getDOMNode().className.should.match(/hidden/) - done() + it('should add hidden class to options when state.open is false', function (done) { + selectBox.setState({ open: false }, function () { + var options = scryRenderedDOMComponentsWithClass('react-select-box-options') + options.should.have.length(1) + options[0].getDOMNode().className.should.match(/hidden/) + done() + }) }) - }) - it('should render options', function (done) { - selectBox.setState({ open: true }, function () { - var options = TestUtils.scryRenderedDOMComponentsWithClass( - selectBox, - 'react-select-box-options' - ) - options.should.have.length(1) - done() + it('should render options', function (done) { + selectBox.setState({ open: true }, function () { + var options = scryRenderedDOMComponentsWithClass('react-select-box-options') + options.should.have.length(1) + done() + }) }) - }) - it('should show an option for each option in props.options', function (done) { - selectBox.setState({ open: true }, function () { - var options = TestUtils.scryRenderedDOMComponentsWithClass( - selectBox, - 'react-select-box-option' - ) - options.should.have.length(options.length) - options.forEach(function (option, i) { - option.getDOMNode().textContent.should.equal(testOptions[i].label) + it('should show an option for each option in props.options', function (done) { + selectBox.setState({ open: true }, function () { + var options = scryRenderedDOMComponentsWithClass('react-select-box-option') + options.should.have.length(options.length) + options.forEach(function (option, i) { + option.getDOMNode().textContent.should.equal(testOptions[i].label) + }) + done() }) - done() }) + + describe("Toggle options list open/closed", function() { + var selectBoxElement + + beforeEach(function() { + selectBoxElement = TestUtils.findRenderedDOMComponentWithClass( + selectBox, + 'react-select-box' + ) + }) + + it('should close an open options list when select box is clicked', function(done) { + // Start with open options list + selectBox.setState({ open: true }, function () { + // Simulate a click on the select box (element with class tag `react-select-box`) + TestUtils.Simulate.click(selectBoxElement) + // Re-render component (to ensure state change occured) + selectBox.forceUpdate(function() { + // Check if it is closed + selectBox.state.open.should.equal(false) + // End test + done() + }) + }) + }) + + it('should open a closed options list when select box is clicked', function(done) { + // Start with closed options list + selectBox.setState({ open: false }, function () { + // Simulate a click on the select box (element with class tag `react-select-box`) + TestUtils.Simulate.click(selectBoxElement) + // Re-render component (to ensure state change occured) + selectBox.forceUpdate(function() { + // Check if it is open + selectBox.state.open.should.equal(true) + // End test + done() + }) + }) + }) + + it('should close an open select box when focused and ESC key is pressed', function(done) { + selectBox.setState({ open: true }, function () { + // Simulate focus event on selectBox + TestUtils.Simulate.focus(selectBoxElement) + // Simulate pressing escape key + TestUtils.Simulate.keyDown(selectBoxElement, {keyCode: 27, which: 27}) + // Re-render component (to ensure state change occured) + selectBox.forceUpdate(function() { + // Check that it is closed + selectBox.state.open.should.equal(false) + // End test + done() + }) + }) + }) + + it('should open a closed select box when focused and ENTER key is pressed', function(done) { + selectBox.setState({ open: false }, function () { + // Simulate focus event on selectBox + TestUtils.Simulate.focus(selectBoxElement) + // Simulate pressing down arrow key + TestUtils.Simulate.keyDown(selectBoxElement, {keyCode: 40, which: 40}) + // Re-render component (to ensure state change occured) + selectBox.forceUpdate(function() { + // Check that it is open + selectBox.state.open.should.equal(true) + // End test + done() + }) + }) + }) + + }) + }) - describe("Toggle options list open/closed when select box is clicked", function() { - var selectBoxElement + describe('Multi-select mode', function () { + var testValues - beforeEach(function() { - selectBoxElement = TestUtils.findRenderedDOMComponentWithClass( - selectBox, - 'react-select-box' - ) + beforeEach(function () { + testValues = [testOptions[0].value, testOptions[1].value]; + selectBox = makeSelectBox(true) }) - it('should close options list when select box is clicked on (if options list is already open)', function(done) { - // Start with open options list - selectBox.setState({ open: true }, function () { - // Simulate a click on the select box (element with class tag `react-select-box`) - TestUtils.Simulate.click(selectBoxElement) - // Re-render component (to ensure state change occured) - selectBox.forceUpdate(function() { - // Check if it is closed - selectBox.state.open.should.equal(false) - // End test - done() - }) + it('should render the label for muliple selected values', function (done) { + var expectedLabel = testOptions[0].label + ', ' + testOptions[1].label; + + selectBox.setProps({ value: testValues }, function () { + var label = scryRenderedDOMComponentsWithClass('react-select-box-label') + label.should.have.length(1) + label[0].getDOMNode().textContent.should.equal(expectedLabel) + done() }) }) - it('should open options list when select box is clicked on (if options list is closed)', function(done) { - // Start with closed options list - selectBox.setState({ open: false }, function () { - // Simulate a click on the select box (element with class tag `react-select-box`) - TestUtils.Simulate.click(selectBoxElement) - // Re-render component (to ensure state change occured) - selectBox.forceUpdate(function() { - // Check if it is open - selectBox.state.open.should.equal(true) - // End test - done() + it('should show all selected options', function (done) { + selectBox.setProps({ value: testValues }, function () { + selectBox.setState({ open: true }, function () { + selectBox.forceUpdate(function() { + var label = scryRenderedDOMComponentsWithClass('react-select-box-option-selected') + label.should.have.length(testValues.length) + selectBox.state.open.should.equal(true) + done() + }) }) }) }) }) -}) \ No newline at end of file +})