- );
- }
- }
-
- const container = document.createElement('div');
- const instance = render(, container);
-
- // We need it to be in the body to test native event dispatching.
- document.body.appendChild(container);
-
- // Focus the field so we can later blur it.
- // Don't remove unless you've verified the fix in #8240 is still covered.
- instance.a.focus();
- setUntrackedValue.call(instance.a, 'giraffe');
- // This must use the native event dispatching. If we simulate, we will
- // bypass the lazy event attachment system so we won't actually test this.
- dispatchEventOnNode(instance.a, 'change');
- dispatchEventOnNode(instance.a, 'blur');
-
- expect(instance.a.value).toBe('giraffe');
- expect(instance.switchedFocus).toBe(true);
-
- document.body.removeChild(container);
- });
-
- it('should control values in reentrant events with different targets', () => {
- class ControlledInputs extends React.Component {
- state = { value: 'lion' };
- a = null;
- b = null;
- change(newValue) {
- // This click will change the checkbox's value to false. Then it will
- // invoke an inner change event. When we finally, flush, we need to
- // reset the checkbox's value to true since that is its controlled
- // value.
- this.b.click();
- }
- render() {
- return (
-
- );
- }
- }
-
- const container = document.createElement('div');
- const instance = render(, container);
-
- // We need it to be in the body to test native event dispatching.
- document.body.appendChild(container);
-
- setUntrackedValue.call(instance.a, 'giraffe');
- // This must use the native event dispatching. If we simulate, we will
- // bypass the lazy event attachment system so we won't actually test this.
- dispatchEventOnNode(instance.a, 'input');
-
- expect(instance.a.value).toBe('lion');
- expect(instance.b.checked).toBe(true);
-
- document.body.removeChild(container);
- });
-
- describe('switching text inputs between numeric and string numbers', () => {
- it('does change the number 2 to "2.0" with no change handler', () => {
- let stub = ;
- stub = ReactTestUtils.renderIntoDocument(stub);
- const node = findDOMNode(stub);
-
- node.value = '2.0';
-
- ReactTestUtils.Simulate.change(stub);
-
- expect(node.getAttribute('value')).toBe('2');
- expect(node.value).toBe('2');
- });
-
- it('does change the string "2" to "2.0" with no change handler', () => {
- let stub = ;
- stub = ReactTestUtils.renderIntoDocument(stub);
- const node = findDOMNode(stub);
-
- node.value = '2.0';
-
- ReactTestUtils.Simulate.change(stub);
-
- expect(node.getAttribute('value')).toBe('2');
- expect(node.value).toBe('2');
- });
-
- it('changes the number 2 to "2.0" using a change handler', () => {
- class Stub extends React.Component {
- state = {
- value: 2,
- };
- onChange = event => {
- this.setState({ value: event.target.value });
- };
- render() {
- const { value } = this.state;
-
- return ;
- }
- }
-
- const stub = ReactTestUtils.renderIntoDocument();
- const node = findDOMNode(stub);
-
- node.value = '2.0';
-
- ReactTestUtils.Simulate.change(node);
-
- expect(node.getAttribute('value')).toBe('2.0');
- expect(node.value).toBe('2.0');
- });
- });
-
- it('does change the string ".98" to "0.98" with no change handler', () => {
- spyOnDev(console, 'error');
- class Stub extends React.Component {
- state = {
- value: '.98',
- };
- render() {
- return ;
- }
- }
-
- const stub = ReactTestUtils.renderIntoDocument();
- const node = findDOMNode(stub);
- stub.setState({ value: '0.98' });
-
- expect(node.value).toEqual('0.98');
- if (__DEV__) {
- expect(console.error.calls.count()).toBe(1);
- expect(console.error.calls.argsFor(0)[0]).toContain(
- 'You provided a `value` prop to a form field ' +
- 'without an `onChange` handler.',
- );
- }
- });
-
- it('performs a state change from "" to 0', () => {
- class Stub extends React.Component {
- state = {
- value: '',
- };
- render() {
- return ;
- }
- }
-
- const stub = ReactTestUtils.renderIntoDocument();
- const node = findDOMNode(stub);
- stub.setState({ value: 0 });
-
- expect(node.value).toEqual('0');
- });
-
- it('distinguishes precision for extra zeroes in string number values', () => {
- spyOnDev(console, 'error');
- class Stub extends React.Component {
- state = {
- value: '3.0000',
- };
- render() {
- return ;
- }
- }
-
- const stub = ReactTestUtils.renderIntoDocument();
- const node = findDOMNode(stub);
- stub.setState({ value: '3' });
-
- expect(node.value).toEqual('3');
- if (__DEV__) {
- expect(console.error.calls.count()).toBe(1);
- expect(console.error.calls.argsFor(0)[0]).toContain(
- 'You provided a `value` prop to a form field ' +
- 'without an `onChange` handler.',
- );
- }
- });
-
- it('should display `defaultValue` of number 0', () => {
- let stub = ;
- stub = ReactTestUtils.renderIntoDocument(stub);
- const node = findDOMNode(stub);
-
- expect(node.getAttribute('value')).toBe('0');
- expect(node.value).toBe('0');
- });
-
- it('only assigns defaultValue if it changes', () => {
- class Test extends React.Component {
- render() {
- return ;
- }
- }
-
- const component = ReactTestUtils.renderIntoDocument();
- const node = findDOMNode(component);
-
- Object.defineProperty(node, 'defaultValue', {
- get() {
- return '0';
- },
- set(value) {
- throw new Error(
- `defaultValue was assigned ${value}, but it did not change!`,
- );
- },
- });
-
- component.forceUpdate();
- });
-
- it('should display "true" for `defaultValue` of `true`', () => {
- let stub = ;
- stub = ReactTestUtils.renderIntoDocument(stub);
- const node = findDOMNode(stub);
-
- expect(node.value).toBe('true');
- });
-
- it('should display "false" for `defaultValue` of `false`', () => {
- let stub = ;
- stub = ReactTestUtils.renderIntoDocument(stub);
- const node = findDOMNode(stub);
-
- expect(node.value).toBe('false');
- });
-
- it('should update `defaultValue` for uncontrolled input', () => {
- const container = document.createElement('div');
-
- const node = render(, container);
-
- expect(node.value).toBe('0');
-
- render(, container);
-
- expect(node.value).toBe('0');
- expect(node.defaultValue).toBe('1');
- });
-
- it('should update `defaultValue` for uncontrolled date/time input', () => {
- const container = document.createElement('div');
-
- const node = render(
- ,
- container,
- );
-
- expect(node.value).toBe('1980-01-01');
-
- render(, container);
-
- expect(node.value).toBe('1980-01-01');
- expect(node.defaultValue).toBe('2000-01-01');
-
- render(, container);
- });
-
- it('should take `defaultValue` when changing to uncontrolled input', () => {
- spyOnDev(console, 'error');
- const container = document.createElement('div');
- const node = render(
- ,
- container,
- );
- expect(node.value).toBe('0');
- render(, container);
- expect(node.value).toBe('0');
-
- if (__DEV__) {
- expect(console.error.calls.count()).toBe(1);
- expect(console.error.calls.argsFor(0)[0]).toContain(
- 'A component is changing a controlled input of type ' +
- 'text to be uncontrolled.',
- );
- }
- });
-
- it('should render defaultValue for SSR', () => {
- const markup = ReactDOMServer.renderToString(
- ,
- );
- const div = document.createElement('div');
- div.innerHTML = markup;
- expect(div.firstChild.getAttribute('value')).toBe('1');
- expect(div.firstChild.getAttribute('defaultValue')).toBe(null);
- });
-
- it('should render value for SSR', () => {
- const element = {}} />;
- const markup = ReactDOMServer.renderToString(element);
- const div = document.createElement('div');
- div.innerHTML = markup;
- expect(div.firstChild.getAttribute('value')).toBe('1');
- expect(div.firstChild.getAttribute('defaultValue')).toBe(null);
- });
-
- it('should render name attribute if it is supplied', () => {
- const container = document.createElement('div');
- const node = render(, container);
- expect(node.name).toBe('name');
- expect(container.firstChild.getAttribute('name')).toBe('name');
- });
-
- it('should render name attribute if it is supplied for SSR', () => {
- const element = ;
- const markup = ReactDOMServer.renderToString(element);
- const div = document.createElement('div');
- div.innerHTML = markup;
- expect(div.firstChild.getAttribute('name')).toBe('name');
- });
-
- it('should not render name attribute if it is not supplied', () => {
- const container = document.createElement('div');
- render(, container);
- expect(container.firstChild.getAttribute('name')).toBe(null);
- });
-
- it('should not render name attribute if it is not supplied for SSR', () => {
- const element = ;
- const markup = ReactDOMServer.renderToString(element);
- const div = document.createElement('div');
- div.innerHTML = markup;
- expect(div.firstChild.getAttribute('name')).toBe(null);
- });
-
- it('should display "foobar" for `defaultValue` of `objToString`', () => {
- const objToString = {
- toString: function() {
- return 'foobar';
- },
- };
-
- let stub = ;
- stub = ReactTestUtils.renderIntoDocument(stub);
- const node = findDOMNode(stub);
-
- expect(node.value).toBe('foobar');
- });
-
- it('should display `value` of number 0', () => {
- let stub = ;
- stub = ReactTestUtils.renderIntoDocument(stub);
- const node = findDOMNode(stub);
-
- expect(node.value).toBe('0');
- });
-
- it('should allow setting `value` to `true`', () => {
- const container = document.createElement('div');
- let stub = ;
- const node = render(stub, container);
-
- expect(node.value).toBe('yolo');
-
- stub = render(
- ,
- container,
- );
- expect(node.value).toEqual('true');
- });
-
- it('should allow setting `value` to `false`', () => {
- const container = document.createElement('div');
- let stub = ;
- const node = render(stub, container);
-
- expect(node.value).toBe('yolo');
-
- stub = render(
- ,
- container,
- );
- expect(node.value).toEqual('false');
- });
-
- it('should allow setting `value` to `objToString`', () => {
- const container = document.createElement('div');
- let stub = ;
- const node = render(stub, container);
-
- expect(node.value).toBe('foo');
-
- const objToString = {
- toString: function() {
- return 'foobar';
- },
- };
- stub = render(
- ,
- container,
- );
- expect(node.value).toEqual('foobar');
- });
-
- it('should not incur unnecessary DOM mutations', () => {
- const container = document.createElement('div');
- render( {}} />, container);
-
- const node = container.firstChild;
- let nodeValue = 'a';
- const nodeValueSetter = jest.genMockFn();
- Object.defineProperty(node, 'value', {
- get: function() {
- return nodeValue;
- },
- set: nodeValueSetter.mockImplementation(function(newValue) {
- nodeValue = newValue;
- }),
- });
-
- render( {}} />, container);
- expect(nodeValueSetter.mock.calls.length).toBe(0);
-
- render( {}} />, container);
- expect(nodeValueSetter.mock.calls.length).toBe(1);
- });
-
- it('should not incur unnecessary DOM mutations for numeric type conversion', () => {
- const container = document.createElement('div');
- render( {}} />, container);
-
- const node = container.firstChild;
- let nodeValue = '0';
- const nodeValueSetter = jest.genMockFn();
- Object.defineProperty(node, 'value', {
- get: function() {
- return nodeValue;
- },
- set: nodeValueSetter.mockImplementation(function(newValue) {
- nodeValue = newValue;
- }),
- });
-
- render( {}} />, container);
- expect(nodeValueSetter.mock.calls.length).toBe(0);
- });
-
- it('should not incur unnecessary DOM mutations for the boolean type conversion', () => {
- const container = document.createElement('div');
- render( {}} />, container);
-
- const node = container.firstChild;
- let nodeValue = 'true';
- const nodeValueSetter = jest.genMockFn();
- Object.defineProperty(node, 'value', {
- get: function() {
- return nodeValue;
- },
- set: nodeValueSetter.mockImplementation(function(newValue) {
- nodeValue = newValue;
- }),
- });
-
- render( {}} />, container);
- expect(nodeValueSetter.mock.calls.length).toBe(0);
- });
-
- it('should properly control a value of number `0`', () => {
- let stub = ;
- stub = ReactTestUtils.renderIntoDocument(stub);
- const node = findDOMNode(stub);
-
- node.value = 'giraffe';
- ReactTestUtils.Simulate.change(node);
- expect(node.value).toBe('0');
- });
-
- it('should properly control 0.0 for a text input', () => {
- let stub = ;
- stub = ReactTestUtils.renderIntoDocument(stub);
- const node = findDOMNode(stub);
-
- node.value = '0.0';
- ReactTestUtils.Simulate.change(node, { target: { value: '0.0' } });
- expect(node.value).toBe('0');
- });
-
- it('should properly control 0.0 for a number input', () => {
- let stub = ;
- stub = ReactTestUtils.renderIntoDocument(stub);
- const node = findDOMNode(stub);
-
- node.value = '0.0';
- ReactTestUtils.Simulate.change(node, { target: { value: '0.0' } });
- expect(node.value).toBe('0.0');
- });
-
- it('should properly transition from an empty value to 0', function() {
- const container = document.createElement('div');
-
- render(, container);
- render(, container);
-
- const node = container.firstChild;
-
- expect(node.value).toBe('0');
- expect(node.defaultValue).toBe('0');
- });
-
- it('should properly transition from 0 to an empty value', function() {
- const container = document.createElement('div');
-
- render(, container);
- render(, container);
-
- const node = container.firstChild;
-
- expect(node.value).toBe('');
- expect(node.defaultValue).toBe('');
- });
-
- it('should properly transition a text input from 0 to an empty 0.0', function() {
- const container = document.createElement('div');
-
- render(, container);
- render(, container);
-
- const node = container.firstChild;
-
- expect(node.value).toBe('0.0');
- expect(node.defaultValue).toBe('0.0');
- });
-
- it('should properly transition a number input from "" to 0', function() {
- const container = document.createElement('div');
-
- render(, container);
- render(, container);
-
- const node = container.firstChild;
-
- expect(node.value).toBe('0');
- expect(node.defaultValue).toBe('0');
- });
-
- it('should properly transition a number input from "" to "0"', function() {
- const container = document.createElement('div');
-
- render(, container);
- render(, container);
-
- const node = container.firstChild;
-
- expect(node.value).toBe('0');
- expect(node.defaultValue).toBe('0');
- });
-
- it('should have the correct target value', () => {
- let handled = false;
- const handler = function(event) {
- expect(event.target.nodeName).toBe('INPUT');
- handled = true;
- };
- const stub = ;
- const container = document.createElement('div');
- const node = render(stub, container);
-
- setUntrackedValue.call(node, 'giraffe');
-
- const fakeNativeEvent = function() {};
- fakeNativeEvent.target = node;
- fakeNativeEvent.path = [node, container];
- ReactTestUtils.simulateNativeEventOnNode('topInput', node, fakeNativeEvent);
-
- expect(handled).toBe(true);
- });
-
- it('should not set a value for submit buttons unnecessarily', () => {
- let stub = ;
- stub = ReactTestUtils.renderIntoDocument(stub);
- const node = findDOMNode(stub);
-
- // The value shouldn't be '', or else the button will have no text; it
- // should have the default "Submit" or "Submit Query" label. Most browsers
- // report this as not having a `value` attribute at all; IE reports it as
- // the actual label that the user sees.
- expect(
- !node.hasAttribute('value') || node.getAttribute('value').length > 0,
- ).toBe(true);
- });
-
- it('should control radio buttons', () => {
- class RadioGroup extends React.Component {
- render() {
- return (
-
-
- A
-
- B
-
-
- );
- }
- }
-
- const stub = ReactTestUtils.renderIntoDocument();
- const aNode = stub.refs.a;
- const bNode = stub.refs.b;
- const cNode = stub.refs.c;
-
- expect(aNode.checked).toBe(true);
- expect(bNode.checked).toBe(false);
- // c is in a separate form and shouldn't be affected at all here
- expect(cNode.checked).toBe(true);
-
- bNode.checked = true;
- // This next line isn't necessary in a proper browser environment, but
- // jsdom doesn't uncheck the others in a group (which makes this whole test
- // a little less effective)
- aNode.checked = false;
- expect(cNode.checked).toBe(true);
-
- // Now let's run the actual ReactDOMInput change event handler
- ReactTestUtils.Simulate.change(bNode);
-
- // The original state should have been restored
- expect(aNode.checked).toBe(true);
- expect(cNode.checked).toBe(true);
- });
-
- it('should check the correct radio when the selected name moves', () => {
- class App extends React.Component {
- state = {
- updated: false,
- };
- onClick = () => {
- this.setState({ updated: true });
- };
- render() {
- const { updated } = this.state;
- const radioName = updated ? 'secondName' : 'firstName';
- return (
-