@@ -18,6 +18,7 @@ describe('ReactDOMInput', function() {
18
18
var EventConstants ;
19
19
var React ;
20
20
var ReactDOM ;
21
+ var ReactDOMServer ;
21
22
var ReactDOMFeatureFlags ;
22
23
var ReactLink ;
23
24
var ReactTestUtils ;
@@ -27,6 +28,7 @@ describe('ReactDOMInput', function() {
27
28
EventConstants = require ( 'EventConstants' ) ;
28
29
React = require ( 'React' ) ;
29
30
ReactDOM = require ( 'ReactDOM' ) ;
31
+ ReactDOMServer = require ( 'ReactDOMServer' ) ;
30
32
ReactDOMFeatureFlags = require ( 'ReactDOMFeatureFlags' ) ;
31
33
ReactLink = require ( 'ReactLink' ) ;
32
34
ReactTestUtils = require ( 'ReactTestUtils' ) ;
@@ -38,6 +40,7 @@ describe('ReactDOMInput', function() {
38
40
stub = ReactTestUtils . renderIntoDocument ( stub ) ;
39
41
var node = ReactDOM . findDOMNode ( stub ) ;
40
42
43
+ expect ( node . getAttribute ( 'value' ) ) . toBe ( '0' ) ;
41
44
expect ( node . value ) . toBe ( '0' ) ;
42
45
} ) ;
43
46
@@ -57,6 +60,48 @@ describe('ReactDOMInput', function() {
57
60
expect ( node . value ) . toBe ( 'false' ) ;
58
61
} ) ;
59
62
63
+ it ( 'should update `defaultValue` for uncontrolled input' , function ( ) {
64
+ var container = document . createElement ( 'div' ) ;
65
+
66
+ var node = ReactDOM . render ( < input type = "text" defaultValue = "0" /> , container ) ;
67
+
68
+ expect ( node . value ) . toBe ( '0' ) ;
69
+
70
+ ReactDOM . render ( < input type = "text" defaultValue = "1" /> , container ) ;
71
+
72
+ expect ( node . value ) . toBe ( '0' ) ;
73
+ expect ( node . defaultValue ) . toBe ( '1' ) ;
74
+ } ) ;
75
+
76
+ it ( 'should take `defaultValue` when changing to uncontrolled input' , function ( ) {
77
+ var container = document . createElement ( 'div' ) ;
78
+
79
+ var node = ReactDOM . render ( < input type = "text" value = "0" readOnly = "true" /> , container ) ;
80
+
81
+ expect ( node . value ) . toBe ( '0' ) ;
82
+
83
+ ReactDOM . render ( < input type = "text" defaultValue = "1" /> , container ) ;
84
+
85
+ expect ( node . value ) . toBe ( '0' ) ;
86
+ } ) ;
87
+
88
+ it ( 'should render defaultValue for SSR' , function ( ) {
89
+ var markup = ReactDOMServer . renderToString ( < input type = "text" defaultValue = "1" /> ) ;
90
+ var div = document . createElement ( 'div' ) ;
91
+ div . innerHTML = markup ;
92
+ expect ( div . firstChild . getAttribute ( 'value' ) ) . toBe ( '1' ) ;
93
+ expect ( div . firstChild . getAttribute ( 'defaultValue' ) ) . toBe ( null ) ;
94
+ } ) ;
95
+
96
+ it ( 'should render value for SSR' , function ( ) {
97
+ var element = < input type = "text" value = "1" onChange = { function ( ) { } } /> ;
98
+ var markup = ReactDOMServer . renderToString ( element ) ;
99
+ var div = document . createElement ( 'div' ) ;
100
+ div . innerHTML = markup ;
101
+ expect ( div . firstChild . getAttribute ( 'value' ) ) . toBe ( '1' ) ;
102
+ expect ( div . firstChild . getAttribute ( 'defaultValue' ) ) . toBe ( null ) ;
103
+ } ) ;
104
+
60
105
it ( 'should display "foobar" for `defaultValue` of `objToString`' , function ( ) {
61
106
var objToString = {
62
107
toString : function ( ) {
@@ -82,8 +127,7 @@ describe('ReactDOMInput', function() {
82
127
it ( 'should allow setting `value` to `true`' , function ( ) {
83
128
var container = document . createElement ( 'div' ) ;
84
129
var stub = < input type = "text" value = "yolo" onChange = { emptyFunction } /> ;
85
- stub = ReactDOM . render ( stub , container ) ;
86
- var node = ReactDOM . findDOMNode ( stub ) ;
130
+ var node = ReactDOM . render ( stub , container ) ;
87
131
88
132
expect ( node . value ) . toBe ( 'yolo' ) ;
89
133
@@ -97,8 +141,7 @@ describe('ReactDOMInput', function() {
97
141
it ( 'should allow setting `value` to `false`' , function ( ) {
98
142
var container = document . createElement ( 'div' ) ;
99
143
var stub = < input type = "text" value = "yolo" onChange = { emptyFunction } /> ;
100
- stub = ReactDOM . render ( stub , container ) ;
101
- var node = ReactDOM . findDOMNode ( stub ) ;
144
+ var node = ReactDOM . render ( stub , container ) ;
102
145
103
146
expect ( node . value ) . toBe ( 'yolo' ) ;
104
147
@@ -112,8 +155,7 @@ describe('ReactDOMInput', function() {
112
155
it ( 'should allow setting `value` to `objToString`' , function ( ) {
113
156
var container = document . createElement ( 'div' ) ;
114
157
var stub = < input type = "text" value = "foo" onChange = { emptyFunction } /> ;
115
- stub = ReactDOM . render ( stub , container ) ;
116
- var node = ReactDOM . findDOMNode ( stub ) ;
158
+ var node = ReactDOM . render ( stub , container ) ;
117
159
118
160
expect ( node . value ) . toBe ( 'foo' ) ;
119
161
@@ -129,6 +171,29 @@ describe('ReactDOMInput', function() {
129
171
expect ( node . value ) . toEqual ( 'foobar' ) ;
130
172
} ) ;
131
173
174
+ it ( 'should not incur unnecessary DOM mutations' , function ( ) {
175
+ var container = document . createElement ( 'div' ) ;
176
+ ReactDOM . render ( < input value = "a" /> , container ) ;
177
+
178
+ var node = container . firstChild ;
179
+ var nodeValue = 'a' ;
180
+ var nodeValueSetter = jest . genMockFn ( ) ;
181
+ Object . defineProperty ( node , 'value' , {
182
+ get : function ( ) {
183
+ return nodeValue ;
184
+ } ,
185
+ set : nodeValueSetter . mockImplementation ( function ( newValue ) {
186
+ nodeValue = newValue ;
187
+ } ) ,
188
+ } ) ;
189
+
190
+ ReactDOM . render ( < input value = "a" /> , container ) ;
191
+ expect ( nodeValueSetter . mock . calls . length ) . toBe ( 0 ) ;
192
+
193
+ ReactDOM . render ( < input value = "b" /> , container ) ;
194
+ expect ( nodeValueSetter . mock . calls . length ) . toBe ( 1 ) ;
195
+ } ) ;
196
+
132
197
it ( 'should properly control a value of number `0`' , function ( ) {
133
198
var stub = < input type = "text" value = { 0 } onChange = { emptyFunction } /> ;
134
199
stub = ReactTestUtils . renderIntoDocument ( stub ) ;
@@ -390,6 +455,13 @@ describe('ReactDOMInput', function() {
390
455
391
456
} ) ;
392
457
458
+ it ( 'should update defaultValue to empty string' , function ( ) {
459
+ var container = document . createElement ( 'div' ) ;
460
+ ReactDOM . render ( < input type = "text" defaultValue = { 'foo' } /> , container ) ;
461
+ ReactDOM . render ( < input type = "text" defaultValue = { '' } /> , container ) ;
462
+ expect ( container . firstChild . defaultValue ) . toBe ( '' ) ;
463
+ } ) ;
464
+
393
465
it ( 'should throw if both checkedLink and valueLink are provided' , function ( ) {
394
466
var node = document . createElement ( 'div' ) ;
395
467
var link = new ReactLink ( true , jest . fn ( ) ) ;
@@ -609,6 +681,11 @@ describe('ReactDOMInput', function() {
609
681
'set data-reactroot' ,
610
682
'set type' ,
611
683
'set value' ,
684
+ 'set value' ,
685
+ 'set name' ,
686
+ 'set checked' ,
687
+ 'set checked' ,
688
+ 'set name' ,
612
689
] ) ;
613
690
} ) ;
614
691
0 commit comments