|
9 | 9 |
|
10 | 10 | 'use strict'; |
11 | 11 |
|
| 12 | +type ValueTracker = { |
| 13 | + getValue(): string, |
| 14 | + setValue(value: string): void, |
| 15 | + stopTracking(): void, |
| 16 | +}; |
| 17 | +type WrapperState = {_valueTracker: ?ValueTracker}; |
| 18 | +type ElementWithValueTracker = (HTMLInputElement | HTMLTextAreaElement) & |
| 19 | + WrapperState; |
| 20 | + |
12 | 21 | describe('ReactDOMComponent', () => { |
13 | 22 | var React; |
14 | 23 | var ReactTestUtils; |
@@ -829,31 +838,8 @@ describe('ReactDOMComponent', () => { |
829 | 838 |
|
830 | 839 | describe('mountComponent', () => { |
831 | 840 | var mountComponent; |
832 | | - var getTracker = (node: any) => { |
833 | | - var descriptor = Object.getOwnPropertyDescriptor( |
834 | | - node.constructor.prototype, |
835 | | - 'value', |
836 | | - ); |
837 | | - |
838 | | - var currentValue = '' + node.value; |
839 | | - |
840 | | - Object.defineProperty(node, 'value', { |
841 | | - enumerable: descriptor.enumerable, |
842 | | - configurable: true, |
843 | | - get: () => { |
844 | | - return descriptor.get.call(this); |
845 | | - }, |
846 | | - set: value => { |
847 | | - currentValue = '' + value; |
848 | | - descriptor.set.call(this, value); |
849 | | - }, |
850 | | - }); |
851 | | - |
852 | | - return { |
853 | | - getValue() { |
854 | | - return currentValue; |
855 | | - }, |
856 | | - }; |
| 841 | + var getTracker = (node: ElementWithValueTracker): ?ValueTracker => { |
| 842 | + return node._valueTracker; |
857 | 843 | }; |
858 | 844 |
|
859 | 845 | beforeEach(() => { |
@@ -1175,14 +1161,38 @@ describe('ReactDOMComponent', () => { |
1175 | 1161 | container, |
1176 | 1162 | ); |
1177 | 1163 | var tracker = getTracker(inst); |
| 1164 | + expect(tracker).toBeTruthy(); |
| 1165 | + expect(tracker.getValue()).toEqual('foo'); |
| 1166 | + |
| 1167 | + inst.defaultValue = 'new foo'; |
| 1168 | + expect(tracker.getValue()).not.toEqual('new foo'); |
1178 | 1169 | expect(tracker.getValue()).toEqual('foo'); |
| 1170 | + |
| 1171 | + inst.value = 'bar'; |
| 1172 | + expect(tracker.getValue()).toEqual('bar'); |
| 1173 | + |
| 1174 | + // even if the value changes to empty string, should not return to defaultValue |
| 1175 | + inst.value = ''; |
| 1176 | + expect(tracker.getValue()).toEqual(''); |
1179 | 1177 | }); |
1180 | 1178 |
|
1181 | 1179 | it('should track textarea values', () => { |
1182 | 1180 | var container = document.createElement('div'); |
1183 | 1181 | var inst = ReactDOM.render(<textarea defaultValue="foo" />, container); |
1184 | 1182 | var tracker = getTracker(inst); |
| 1183 | + expect(tracker).toBeTruthy(); |
1185 | 1184 | expect(tracker.getValue()).toEqual('foo'); |
| 1185 | + |
| 1186 | + inst.defaultValue = 'new foo'; |
| 1187 | + expect(tracker.getValue()).not.toEqual('new foo'); |
| 1188 | + expect(tracker.getValue()).toEqual('foo'); |
| 1189 | + |
| 1190 | + inst.value = 'bar'; |
| 1191 | + expect(tracker.getValue()).toEqual('bar'); |
| 1192 | + |
| 1193 | + // even if the value changes to empty string, should not return to defaultValue |
| 1194 | + inst.value = ''; |
| 1195 | + expect(tracker.getValue()).toEqual(''); |
1186 | 1196 | }); |
1187 | 1197 |
|
1188 | 1198 | it('should throw for children on void elements', () => { |
|
0 commit comments