From d48497c322faec69ae155c8d530c29fe618d2eab Mon Sep 17 00:00:00 2001 From: Timothy Chon Date: Mon, 27 Jul 2015 17:05:05 -0700 Subject: [PATCH 1/6] use createFactory; clean-up spec --- lib/select-box.js | 12 +++++------ test/select-box.spec.js | 46 ++++++++++++++--------------------------- 2 files changed, 22 insertions(+), 36 deletions(-) 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/test/select-box.spec.js b/test/select-box.spec.js index 20bbde9..0f0527d 100644 --- a/test/select-box.spec.js +++ b/test/select-box.spec.js @@ -1,12 +1,19 @@ -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 + function scryRenderedDOMComponentsWithClass(name) { + return TestUtils.scryRenderedDOMComponentsWithClass( + selectBox, + name + ) + } + beforeEach(function () { testOptions = [ { value: 'red', label: 'Red' }, @@ -28,20 +35,14 @@ describe('SelectBox component', function () { }) it('should render the label when no value is selected', function () { - var label = TestUtils.scryRenderedDOMComponentsWithClass( - selectBox, - 'react-select-box-label' - ) + var label = scryRenderedDOMComponentsWithClass('react-select-box-label') label.should.have.length(1) label[0].getDOMNode().textContent.should.equal(selectBox.props.label) }) 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' - ) + var label = scryRenderedDOMComponentsWithClass('react-select-box-label') label.should.have.length(1) label[0].getDOMNode().textContent.should.equal(testOptions[0].label) done() @@ -50,10 +51,7 @@ describe('SelectBox component', function () { 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' - ) + var clear = scryRenderedDOMComponentsWithClass('react-select-box-clear') clear.should.have.length(0) done() }) @@ -62,10 +60,7 @@ describe('SelectBox component', function () { 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' - ) + var clear = scryRenderedDOMComponentsWithClass('react-select-box-clear') clear.should.have.length(1) done() }) @@ -73,10 +68,7 @@ describe('SelectBox component', function () { 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' - ) + var options = scryRenderedDOMComponentsWithClass('react-select-box-options') options.should.have.length(1) options[0].getDOMNode().className.should.match(/hidden/) done() @@ -85,10 +77,7 @@ describe('SelectBox component', function () { it('should render options', function (done) { selectBox.setState({ open: true }, function () { - var options = TestUtils.scryRenderedDOMComponentsWithClass( - selectBox, - 'react-select-box-options' - ) + var options = scryRenderedDOMComponentsWithClass('react-select-box-options') options.should.have.length(1) done() }) @@ -96,10 +85,7 @@ describe('SelectBox component', function () { 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' - ) + 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) @@ -150,4 +136,4 @@ describe('SelectBox component', function () { }) -}) \ No newline at end of file +}) From b70d2cea1bc779066d56aa6e347fc19803a749fc Mon Sep 17 00:00:00 2001 From: Timothy Chon Date: Tue, 28 Jul 2015 10:38:51 -0700 Subject: [PATCH 2/6] add mocha reporter to karma output --- karma.conf.js | 3 ++- package.json | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) 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/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", From 0872f87abe4ace8db131be791f012aca4f0dc8fe Mon Sep 17 00:00:00 2001 From: Timothy Chon Date: Tue, 28 Jul 2015 12:37:00 -0700 Subject: [PATCH 3/6] use createFactory in example --- example/example.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) 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 () { From 976ef68cabd14be35e461f965205892ed2169867 Mon Sep 17 00:00:00 2001 From: Timothy Chon Date: Tue, 28 Jul 2015 16:17:48 -0700 Subject: [PATCH 4/6] tests for toggling open options via ESC/ENTER keys --- test/select-box.spec.js | 38 +++++++++++++++++++++++++++++++++++--- 1 file changed, 35 insertions(+), 3 deletions(-) diff --git a/test/select-box.spec.js b/test/select-box.spec.js index 0f0527d..ecca026 100644 --- a/test/select-box.spec.js +++ b/test/select-box.spec.js @@ -94,7 +94,7 @@ describe('SelectBox component', function () { }) }) - describe("Toggle options list open/closed when select box is clicked", function() { + describe("Toggle options list open/closed", function() { var selectBoxElement beforeEach(function() { @@ -104,7 +104,7 @@ describe('SelectBox component', function () { ) }) - it('should close options list when select box is clicked on (if options list is already open)', function(done) { + 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`) @@ -119,7 +119,7 @@ describe('SelectBox component', function () { }) }) - it('should open options list when select box is clicked on (if options list is closed)', function(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`) @@ -134,6 +134,38 @@ describe('SelectBox component', function () { }) }) + 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() + }) + }) + }) + }) }) From 1594cadd50269793f42551f526ab7216fc429d30 Mon Sep 17 00:00:00 2001 From: Timothy Chon Date: Wed, 29 Jul 2015 13:01:25 -0700 Subject: [PATCH 5/6] add label test for multi-select --- test/select-box.spec.js | 270 ++++++++++++++++++++++------------------ 1 file changed, 152 insertions(+), 118 deletions(-) diff --git a/test/select-box.spec.js b/test/select-box.spec.js index ecca026..c2c7723 100644 --- a/test/select-box.spec.js +++ b/test/select-box.spec.js @@ -3,9 +3,29 @@ 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) + }) + + args.unshift({ + label: 'foo', + value: null, + multiple: multi !== true ? false : multi, + onChange: function() {} + }) + + return TestUtils.renderIntoDocument(SelectBox.apply(null, args)) + } function scryRenderedDOMComponentsWithClass(name) { return TestUtils.scryRenderedDOMComponentsWithClass( @@ -14,156 +34,170 @@ describe('SelectBox component', function () { ) } - beforeEach(function () { - testOptions = [ - { value: 'red', label: 'Red' }, - { value: 'green', label: 'Green' }, - { value: 'blue', label: 'Blue' }, - ] + describe('Single select mode', function () { - var args = testOptions.map(function (option) { - return React.DOM.option({value: option.value}, option.label) + beforeEach(function () { + selectBox = makeSelectBox() }) - args.unshift({ - label: 'foo', - value: null, - onChange: function() {} + 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) }) - - selectBox = TestUtils.renderIntoDocument(SelectBox.apply(null, args)) - }) - - 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 render the label for the selected value', function (done) { - selectBox.setProps({ value: testOptions[0].value }, function () { + + 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 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 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 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 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 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 = scryRenderedDOMComponentsWithClass('react-select-box-options') - options.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 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) + 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() }) - done() }) - }) - describe("Toggle options list open/closed", function() { - var selectBoxElement - - beforeEach(function() { - selectBoxElement = TestUtils.findRenderedDOMComponentWithClass( - selectBox, - 'react-select-box' - ) + 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 close an open options list when select box is clicked', function(done) { - // Start with open options list + it('should show an option for each option in props.options', function (done) { 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() + 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() }) }) - 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() + 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 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 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 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() + 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('Multi-select mode', function () { + + beforeEach(function () { + selectBox = makeSelectBox(true) + }) + + it('should render the label for muliple selected values', function (done) { + var testValues = [testOptions[0].value, testOptions[1].value]; + 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() + }) }) }) From f73adbb1b1fb79bdd356adf4ed11b7cc8c1997bb Mon Sep 17 00:00:00 2001 From: Timothy Chon Date: Wed, 29 Jul 2015 16:47:52 -0700 Subject: [PATCH 6/6] test that all selected options are shown --- test/select-box.spec.js | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/test/select-box.spec.js b/test/select-box.spec.js index c2c7723..bb6088e 100644 --- a/test/select-box.spec.js +++ b/test/select-box.spec.js @@ -183,13 +183,14 @@ describe('SelectBox component', function () { }) describe('Multi-select mode', function () { + var testValues beforeEach(function () { + testValues = [testOptions[0].value, testOptions[1].value]; selectBox = makeSelectBox(true) }) it('should render the label for muliple selected values', function (done) { - var testValues = [testOptions[0].value, testOptions[1].value]; var expectedLabel = testOptions[0].label + ', ' + testOptions[1].label; selectBox.setProps({ value: testValues }, function () { @@ -200,6 +201,19 @@ describe('SelectBox component', function () { }) }) + 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() + }) + }) + }) + }) + }) })