/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @emails react-core
*/
'use strict';
var emptyFunction = require('fbjs/lib/emptyFunction');
describe('ReactDOMTextarea', () => {
var React;
var ReactDOM;
var ReactDOMServer;
var ReactTestUtils;
var renderTextarea;
beforeEach(() => {
React = require('react');
ReactDOM = require('react-dom');
ReactDOMServer = require('react-dom/server');
ReactTestUtils = require('react-dom/test-utils');
renderTextarea = function(component, container) {
if (!container) {
container = document.createElement('div');
}
var node = ReactDOM.render(component, container);
// Fixing jsdom's quirky behavior -- in reality, the parser should strip
// off the leading newline but we need to do it by hand here.
node.defaultValue = node.innerHTML.replace(/^\n/, '');
return node;
};
});
it('should allow setting `defaultValue`', () => {
var container = document.createElement('div');
var node = renderTextarea(, container);
expect(node.value).toBe('giraffe');
// Changing `defaultValue` should do nothing.
renderTextarea(, container);
expect(node.value).toEqual('giraffe');
node.value = 'cat';
renderTextarea(, container);
expect(node.value).toEqual('cat');
});
it('should display `defaultValue` of number 0', () => {
var stub = ;
var node = renderTextarea(stub);
expect(node.value).toBe('0');
});
it('should display "false" for `defaultValue` of `false`', () => {
var stub = ;
var node = renderTextarea(stub);
expect(node.value).toBe('false');
});
it('should display "foobar" for `defaultValue` of `objToString`', () => {
var objToString = {
toString: function() {
return 'foobar';
},
};
var stub = ;
var node = renderTextarea(stub);
expect(node.value).toBe('foobar');
});
it('should set defaultValue', () => {
var container = document.createElement('div');
ReactDOM.render(, container);
ReactDOM.render(, container);
ReactDOM.render(, container);
expect(container.firstChild.defaultValue).toBe('noise');
});
it('should not render value as an attribute', () => {
var stub = ;
var node = renderTextarea(stub);
expect(node.getAttribute('value')).toBe(null);
});
it('should display `value` of number 0', () => {
var stub = ;
var node = renderTextarea(stub);
expect(node.value).toBe('0');
});
it('should update defaultValue to empty string', () => {
var container = document.createElement('div');
ReactDOM.render(, container);
ReactDOM.render(, container);
expect(container.firstChild.defaultValue).toBe('');
});
it('should allow setting `value` to `giraffe`', () => {
var container = document.createElement('div');
var stub = ;
var node = renderTextarea(stub, container);
expect(node.value).toBe('giraffe');
stub = ReactDOM.render(
,
container,
);
expect(node.value).toEqual('gorilla');
});
it('should render defaultValue for SSR', () => {
var markup = ReactDOMServer.renderToString();
var div = document.createElement('div');
div.innerHTML = markup;
expect(div.firstChild.innerHTML).toBe('1');
expect(div.firstChild.getAttribute('defaultValue')).toBe(null);
});
it('should render value for SSR', () => {
var element = ;
var markup = ReactDOMServer.renderToString(element);
var div = document.createElement('div');
div.innerHTML = markup;
expect(div.firstChild.innerHTML).toBe('1');
expect(div.firstChild.getAttribute('defaultValue')).toBe(null);
});
it('should allow setting `value` to `true`', () => {
var container = document.createElement('div');
var stub = ;
var node = renderTextarea(stub, container);
expect(node.value).toBe('giraffe');
stub = ReactDOM.render(
,
container,
);
expect(node.value).toEqual('true');
});
it('should allow setting `value` to `false`', () => {
var container = document.createElement('div');
var stub = ;
var node = renderTextarea(stub, container);
expect(node.value).toBe('giraffe');
stub = ReactDOM.render(
,
container,
);
expect(node.value).toEqual('false');
});
it('should allow setting `value` to `objToString`', () => {
var container = document.createElement('div');
var stub = ;
var node = renderTextarea(stub, container);
expect(node.value).toBe('giraffe');
var objToString = {
toString: function() {
return 'foo';
},
};
stub = ReactDOM.render(
,
container,
);
expect(node.value).toEqual('foo');
});
it('should take updates to `defaultValue` for uncontrolled textarea', () => {
var container = document.createElement('div');
var node = ReactDOM.render(, container);
expect(node.value).toBe('0');
ReactDOM.render(, container);
expect(node.value).toBe('0');
});
it('should take updates to children in lieu of `defaultValue` for uncontrolled textarea', () => {
var container = document.createElement('div');
var node = ReactDOM.render(, container);
expect(node.value).toBe('0');
spyOn(console, 'error'); // deprecation warning for `children` content
ReactDOM.render(, container);
expect(node.value).toBe('0');
});
it('should not incur unnecessary DOM mutations', () => {
var container = document.createElement('div');
ReactDOM.render(, container);
var node = container.firstChild;
var nodeValue = 'a';
var nodeValueSetter = jest.genMockFn();
Object.defineProperty(node, 'value', {
get: function() {
return nodeValue;
},
set: nodeValueSetter.mockImplementation(function(newValue) {
nodeValue = newValue;
}),
});
ReactDOM.render(, container);
expect(nodeValueSetter.mock.calls.length).toBe(0);
ReactDOM.render(, container);
expect(nodeValueSetter.mock.calls.length).toBe(1);
});
it('should properly control a value of number `0`', () => {
var stub = ;
var node = renderTextarea(stub);
node.value = 'giraffe';
ReactTestUtils.Simulate.change(node);
expect(node.value).toBe('0');
});
it('should treat children like `defaultValue`', () => {
spyOn(console, 'error');
var container = document.createElement('div');
var stub = ;
var node = renderTextarea(stub, container);
expectDev(console.error.calls.count()).toBe(1);
expect(node.value).toBe('giraffe');
// Changing children should do nothing, it functions like `defaultValue`.
stub = ReactDOM.render(, container);
expect(node.value).toEqual('giraffe');
});
it('should keep value when switching to uncontrolled element if not changed', () => {
var container = document.createElement('div');
var node = renderTextarea(
,
container,
);
expect(node.value).toBe('kitten');
ReactDOM.render(, container);
expect(node.value).toEqual('kitten');
});
it('should keep value when switching to uncontrolled element if changed', () => {
var container = document.createElement('div');
var node = renderTextarea(
,
container,
);
expect(node.value).toBe('kitten');
ReactDOM.render(
,
container,
);
expect(node.value).toBe('puppies');
ReactDOM.render(, container);
expect(node.value).toEqual('puppies');
});
it('should allow numbers as children', () => {
spyOn(console, 'error');
var node = renderTextarea();
expectDev(console.error.calls.count()).toBe(1);
expect(node.value).toBe('17');
});
it('should allow booleans as children', () => {
spyOn(console, 'error');
var node = renderTextarea();
expectDev(console.error.calls.count()).toBe(1);
expect(node.value).toBe('false');
});
it('should allow objects as children', () => {
spyOn(console, 'error');
var obj = {
toString: function() {
return 'sharkswithlasers';
},
};
var node = renderTextarea();
expectDev(console.error.calls.count()).toBe(1);
expect(node.value).toBe('sharkswithlasers');
});
it('should throw with multiple or invalid children', () => {
spyOn(console, 'error');
expect(function() {
ReactTestUtils.renderIntoDocument(
,
);
}).toThrow();
expectDev(console.error.calls.count()).toBe(1);
var node;
expect(function() {
node = renderTextarea();
}).not.toThrow();
expect(node.value).toBe('[object Object]');
expectDev(console.error.calls.count()).toBe(2);
});
it('should unmount', () => {
var container = document.createElement('div');
renderTextarea(, container);
ReactDOM.unmountComponentAtNode(container);
});
it('should warn if value is null', () => {
spyOn(console, 'error');
ReactTestUtils.renderIntoDocument();
expectDev(console.error.calls.argsFor(0)[0]).toContain(
'`value` prop on `textarea` should not be null. ' +
'Consider using the empty string to clear the component or `undefined` ' +
'for uncontrolled components.',
);
ReactTestUtils.renderIntoDocument();
expectDev(console.error.calls.count()).toBe(1);
});
it('should warn if value and defaultValue are specified', () => {
spyOn(console, 'error');
ReactTestUtils.renderIntoDocument(
,
);
expectDev(console.error.calls.argsFor(0)[0]).toContain(
'Textarea elements must be either controlled or uncontrolled ' +
'(specify either the value prop, or the defaultValue prop, but not ' +
'both). Decide between using a controlled or uncontrolled textarea ' +
'and remove one of these props. More info: ' +
'https://fb.me/react-controlled-components',
);
ReactTestUtils.renderIntoDocument(
,
);
expectDev(console.error.calls.count()).toBe(1);
});
});