diff --git a/src/dom/components/ReactDOMSelect.js b/src/dom/components/ReactDOMSelect.js
index 0709eaf5b1..22a7b2e3d2 100644
--- a/src/dom/components/ReactDOMSelect.js
+++ b/src/dom/components/ReactDOMSelect.js
@@ -58,11 +58,9 @@ function selectValueType(props, propName, componentName) {
*/
function updateOptions() {
/*jshint validthis:true */
- if (this.props.value == null) {
- return;
- }
+ var value = this.props.value != null ? this.props.value : this.state.value;
var options = this.getDOMNode().options;
- var selectedValue = '' + this.props.value;
+ var selectedValue = '' + value;
for (var i = 0, l = options.length; i < l; i++) {
var selected = this.props.multiple ?
diff --git a/src/dom/components/__tests__/ReactDOMSelect-test.js b/src/dom/components/__tests__/ReactDOMSelect-test.js
new file mode 100644
index 0000000000..9c8cb08751
--- /dev/null
+++ b/src/dom/components/__tests__/ReactDOMSelect-test.js
@@ -0,0 +1,157 @@
+/**
+ * Copyright 2013 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @jsx React.DOM
+ * @emails react-core
+ */
+
+"use strict";
+
+/*jshint evil:true */
+
+describe('ReactDOMSelect', function() {
+ var React;
+ var ReactTestUtils;
+
+ var renderSelect;
+
+ beforeEach(function() {
+ React = require('React');
+ ReactTestUtils = require('ReactTestUtils');
+
+ renderSelect = function(component) {
+ var stub = ReactTestUtils.renderIntoDocument(component);
+ var node = stub.getDOMNode();
+ return node;
+ };
+ });
+
+ it('should allow setting `defaultValue`', function() {
+ var stub =
+ ;
+ var node = renderSelect(stub);
+
+ expect(node.value).toBe('giraffe');
+
+ // Changing `defaultValue` should do nothing.
+ stub.setProps({defaultValue: 'gorilla'});
+ expect(node.value).toEqual('giraffe');
+ });
+
+ it('should allow setting `defaultValue` with multiple', function() {
+ var stub =
+ ;
+ var node = renderSelect(stub);
+
+ expect(node.options[0].selected).toBe(false); // monkey
+ expect(node.options[1].selected).toBe(true); // giraffe
+ expect(node.options[2].selected).toBe(true); // gorilla
+
+ // Changing `defaultValue` should do nothing.
+ stub.setProps({defaultValue: ['monkey']});
+
+ expect(node.options[0].selected).toBe(false); // monkey
+ expect(node.options[1].selected).toBe(true); // giraffe
+ expect(node.options[2].selected).toBe(true); // gorilla
+ });
+
+ it('should allow setting `value`', function() {
+ var stub =
+ ;
+ var node = renderSelect(stub);
+
+ expect(node.value).toBe('giraffe');
+
+ // Changing the `value` prop should change the selected option.
+ stub.setProps({value: 'gorilla'});
+ expect(node.value).toEqual('gorilla');
+ });
+
+ it('should allow setting `value` with multiple', function() {
+ var stub =
+ ;
+ var node = renderSelect(stub);
+
+ expect(node.options[0].selected).toBe(false); // monkey
+ expect(node.options[1].selected).toBe(true); // giraffe
+ expect(node.options[2].selected).toBe(true); // gorilla
+
+ // Changing the `value` prop should change the selected options.
+ stub.setProps({value: ['monkey']});
+
+ expect(node.options[0].selected).toBe(true); // monkey
+ expect(node.options[1].selected).toBe(false); // giraffe
+ expect(node.options[2].selected).toBe(false); // gorilla
+ });
+
+ it('should allow switching to multiple', function() {
+ var stub =
+ ;
+ var node = renderSelect(stub);
+
+ expect(node.options[0].selected).toBe(false); // monkey
+ expect(node.options[1].selected).toBe(true); // giraffe
+ expect(node.options[2].selected).toBe(false); // gorilla
+
+ // When making it multiple, giraffe should still be selected
+ stub.setProps({multiple: true, defaultValue: null});
+
+ expect(node.options[0].selected).toBe(false); // monkey
+ expect(node.options[1].selected).toBe(true); // giraffe
+ expect(node.options[2].selected).toBe(false); // gorilla
+ });
+
+ it('should allow switching from multiple', function() {
+ var stub =
+ ;
+ var node = renderSelect(stub);
+
+ expect(node.options[0].selected).toBe(false); // monkey
+ expect(node.options[1].selected).toBe(true); // giraffe
+ expect(node.options[2].selected).toBe(true); // gorilla
+
+ // When removing multiple, giraffe should still be selected (but gorilla
+ // will no longer be)
+ stub.setProps({multiple: false, defaultValue: null});
+
+ expect(node.options[0].selected).toBe(false); // monkey
+ expect(node.options[1].selected).toBe(true); // giraffe
+ expect(node.options[2].selected).toBe(false); // gorilla
+ });
+});