Skip to content

Commit

Permalink
Backport input fix (facebook#8575)
Browse files Browse the repository at this point in the history
* Only fire input value change events when the value changes (facebook#5746)

* Allow simulated native events to propagate

fixes facebook#7211 fixes facebook#6822 fixes facebook#6614

we should make sure it doesn't break facebook#3926 any worse (or works with facebook#8438)
  • Loading branch information
jquense authored and flarnie committed Jun 7, 2017
1 parent 2044e1b commit f82d323
Show file tree
Hide file tree
Showing 8 changed files with 640 additions and 103 deletions.
165 changes: 165 additions & 0 deletions src/renderers/dom/client/__tests__/inputValueTracking-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
/**
* Copyright 2013-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
* @emails react-core
*/
'use strict';

var React = require('React');
var ReactTestUtils = require('ReactTestUtils');
var inputValueTracking = require('inputValueTracking');

describe('inputValueTracking', function() {
var input, checkbox, mockComponent;

beforeEach(function() {
input = document.createElement('input');
input.type = 'text';
checkbox = document.createElement('input');
checkbox.type = 'checkbox';
mockComponent = { _hostNode: input, _wrapperState: {} };
});

it('should attach tracker to wrapper state', function() {
inputValueTracking.track(mockComponent);

expect(
mockComponent._wrapperState.hasOwnProperty('valueTracker')
).toBe(true);
});

it('should define `value` on the instance node', function() {
inputValueTracking.track(mockComponent);

expect(
input.hasOwnProperty('value')
).toBe(true);
});

it('should define `checked` on the instance node', function() {
mockComponent._hostNode = checkbox;
inputValueTracking.track(mockComponent);

expect(checkbox.hasOwnProperty('checked')).toBe(true);
});

it('should initialize with the current value', function() {
input.value ='foo';

inputValueTracking.track(mockComponent);

var tracker = mockComponent._wrapperState.valueTracker;

expect(tracker.getValue()).toEqual('foo');
});

it('should initialize with the current `checked`', function() {
mockComponent._hostNode = checkbox;
checkbox.checked = true;
inputValueTracking.track(mockComponent);

var tracker = mockComponent._wrapperState.valueTracker;

expect(tracker.getValue()).toEqual('true');
});

it('should track value changes', function() {
input.value ='foo';

inputValueTracking.track(mockComponent);

var tracker = mockComponent._wrapperState.valueTracker;

input.value ='bar';
expect(tracker.getValue()).toEqual('bar');
});

it('should tracked`checked` changes', function() {
mockComponent._hostNode = checkbox;
checkbox.checked = true;
inputValueTracking.track(mockComponent);

var tracker = mockComponent._wrapperState.valueTracker;

checkbox.checked = false;
expect(tracker.getValue()).toEqual('false');
});

it('should update value manually', function() {
input.value ='foo';
inputValueTracking.track(mockComponent);

var tracker = mockComponent._wrapperState.valueTracker;

tracker.setValue('bar');
expect(tracker.getValue()).toEqual('bar');
});

it('should coerce value to a string', function() {
input.value ='foo';
inputValueTracking.track(mockComponent);

var tracker = mockComponent._wrapperState.valueTracker;

tracker.setValue(500);
expect(tracker.getValue()).toEqual('500');
});

it('should update value if it changed and return result', function() {
inputValueTracking.track(mockComponent);
input.value ='foo';

var tracker = mockComponent._wrapperState.valueTracker;

expect(
inputValueTracking.updateValueIfChanged(mockComponent)
).toBe(false);

tracker.setValue('bar');

expect(
inputValueTracking.updateValueIfChanged(mockComponent)
).toBe(true);

expect(tracker.getValue()).toEqual('foo');
});

it('should track value and return true when updating untracked instance', function() {
input.value ='foo';

expect(
inputValueTracking.updateValueIfChanged(mockComponent)
)
.toBe(true);

var tracker = mockComponent._wrapperState.valueTracker;
expect(tracker.getValue()).toEqual('foo');
});

it('should return tracker from node', function() {
var node = ReactTestUtils.renderIntoDocument(<input type="text" defaultValue="foo" />);
var tracker = inputValueTracking._getTrackerFromNode(node);
expect(tracker.getValue()).toEqual('foo');
});

it('should stop tracking', function() {
inputValueTracking.track(mockComponent);

expect(
mockComponent._wrapperState.hasOwnProperty('valueTracker')
).toBe(true);

inputValueTracking.stopTracking(mockComponent);

expect(
mockComponent._wrapperState.hasOwnProperty('valueTracker')
).toBe(false);

expect(input.hasOwnProperty('value')).toBe(false);
});
});

0 comments on commit f82d323

Please sign in to comment.