163 lines
12 KiB
JavaScript
163 lines
12 KiB
JavaScript
import { __assign, __rest } from "tslib";
|
|
import { setWarningCallback } from './warn';
|
|
import { warnControlledUsage, resetControlledWarnings } from './warnControlledUsage';
|
|
var warningCallback = jest.fn();
|
|
var noOp = function () { return undefined; };
|
|
var params = {
|
|
componentId: 'TestComponent1',
|
|
componentName: 'TestComponent',
|
|
valueProp: 'value',
|
|
defaultValueProp: 'defaultValue',
|
|
onChangeProp: 'onChange',
|
|
readOnlyProp: 'readOnly',
|
|
};
|
|
describe('warnControlledUsage', function () {
|
|
beforeEach(function () {
|
|
setWarningCallback(warningCallback);
|
|
});
|
|
afterEach(function () {
|
|
warningCallback.mockReset();
|
|
setWarningCallback(undefined);
|
|
resetControlledWarnings();
|
|
});
|
|
it('does not warn or throw if old props are undefined', function () {
|
|
warnControlledUsage(__assign(__assign({}, params), { props: {} }));
|
|
expect(warningCallback).toHaveBeenCalledTimes(0);
|
|
// If oldProps was defined, this would be an error for switching from uncontrolled to controlled
|
|
warnControlledUsage(__assign(__assign({}, params), { props: { value: 'test', onChange: noOp } }));
|
|
expect(warningCallback).toHaveBeenCalledTimes(0);
|
|
});
|
|
it('does not warn if uncontrolled regardless of if onChange/readOnly is provided', function () {
|
|
warnControlledUsage(__assign(__assign({}, params), { props: { defaultValue: 'test' } }));
|
|
expect(warningCallback).toHaveBeenCalledTimes(0);
|
|
warnControlledUsage(__assign(__assign({}, params), { props: {} }));
|
|
expect(warningCallback).toHaveBeenCalledTimes(0);
|
|
warnControlledUsage(__assign(__assign({}, params), { props: { defaultValue: 'test', onChange: noOp } }));
|
|
expect(warningCallback).toHaveBeenCalledTimes(0);
|
|
warnControlledUsage(__assign(__assign({}, params), { props: { onChange: noOp } }));
|
|
expect(warningCallback).toHaveBeenCalledTimes(0);
|
|
warnControlledUsage(__assign(__assign({}, params), { props: { defaultValue: 'test', readOnly: true } }));
|
|
expect(warningCallback).toHaveBeenCalledTimes(0);
|
|
warnControlledUsage(__assign(__assign({}, params), { props: { readOnly: true } }));
|
|
expect(warningCallback).toHaveBeenCalledTimes(0);
|
|
});
|
|
it('does not warn if controlled and onChange is provided', function () {
|
|
warnControlledUsage(__assign(__assign({}, params), { props: { value: 'test', onChange: noOp } }));
|
|
expect(warningCallback).toHaveBeenCalledTimes(0);
|
|
});
|
|
it('does not warn if controlled and readOnly is true', function () {
|
|
warnControlledUsage(__assign(__assign({}, params), { props: { value: 'test', readOnly: true } }));
|
|
expect(warningCallback).toHaveBeenCalledTimes(0);
|
|
});
|
|
it('warns if controlled and onChange/readOnly is not provided', function () {
|
|
warnControlledUsage(__assign(__assign({}, params), { props: { value: 'test' } }));
|
|
expect(warningCallback).toHaveBeenCalledTimes(1);
|
|
expect(warningCallback).toHaveBeenLastCalledWith("Warning: You provided a 'value' prop to a TestComponent without an 'onChange' handler. This will render a " +
|
|
"read-only field. If the field should be mutable use 'defaultValue'. Otherwise, set 'onChange' or 'readOnly'.");
|
|
// Don't re-warn
|
|
warnControlledUsage(__assign(__assign({}, params), { props: { value: 'test' } }));
|
|
expect(warningCallback).toHaveBeenCalledTimes(1);
|
|
});
|
|
it('warns if controlled and onChange is not provided (right message for component without readOnly)', function () {
|
|
var readOnlyProp = params.readOnlyProp, otherParams = __rest(params, ["readOnlyProp"]);
|
|
warnControlledUsage(__assign(__assign({}, otherParams), { props: { value: 'test' } }));
|
|
expect(warningCallback).toHaveBeenCalledTimes(1);
|
|
expect(warningCallback).toHaveBeenLastCalledWith("Warning: You provided a 'value' prop to a TestComponent without an 'onChange' handler. This will render a " +
|
|
"read-only field. If the field should be mutable use 'defaultValue'. Otherwise, set 'onChange'.");
|
|
// Don't re-warn
|
|
warnControlledUsage(__assign(__assign({}, otherParams), { props: { value: 'test' } }));
|
|
expect(warningCallback).toHaveBeenCalledTimes(1);
|
|
});
|
|
it('re-warns when componentId changes for controlled without onChange', function () {
|
|
warnControlledUsage(__assign(__assign({}, params), { props: { value: 'test' } }));
|
|
expect(warningCallback).toHaveBeenCalledTimes(1);
|
|
warnControlledUsage(__assign(__assign({}, params), { componentId: 'TestComponent2', props: { value: 'test' } }));
|
|
expect(warningCallback).toHaveBeenCalledTimes(2);
|
|
});
|
|
it('warns if controlled and readOnly is false', function () {
|
|
warnControlledUsage(__assign(__assign({}, params), { props: { value: 'test', readOnly: false } }));
|
|
expect(warningCallback).toHaveBeenCalledTimes(1);
|
|
expect(warningCallback).toHaveBeenLastCalledWith("Warning: You provided a 'value' prop to a TestComponent without an 'onChange' handler. This will render a " +
|
|
"read-only field. If the field should be mutable use 'defaultValue'. Otherwise, set 'onChange' or 'readOnly'.");
|
|
// Don't re-warn
|
|
warnControlledUsage(__assign(__assign({}, params), { props: { value: 'test', readOnly: false } }));
|
|
expect(warningCallback).toHaveBeenCalledTimes(1);
|
|
});
|
|
it('warns if both value and defaultValue are provided', function () {
|
|
warnControlledUsage(__assign(__assign({}, params), { props: { value: 'hello', defaultValue: 'world', onChange: noOp } }));
|
|
expect(warningCallback).toHaveBeenCalledTimes(1);
|
|
expect(warningCallback).toHaveBeenLastCalledWith("Warning: You provided both 'value' and 'defaultValue' to a TestComponent. Form fields 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 TestComponent and remove one of these props. " +
|
|
"More info: https://fb.me/react-controlled-components");
|
|
// Don't re-warn
|
|
warnControlledUsage(__assign(__assign({}, params), { props: { value: 'hello', defaultValue: 'world', onChange: noOp } }));
|
|
expect(warningCallback).toHaveBeenCalledTimes(1);
|
|
});
|
|
it('re-warns when componentId changes if both value and defaultValue are provided', function () {
|
|
warnControlledUsage(__assign(__assign({}, params), { props: { value: 'hello', defaultValue: 'world', onChange: noOp } }));
|
|
expect(warningCallback).toHaveBeenCalledTimes(1);
|
|
warnControlledUsage(__assign(__assign({}, params), { componentId: 'TestComponent2', props: { value: 'hello', defaultValue: 'world', onChange: noOp } }));
|
|
expect(warningCallback).toHaveBeenCalledTimes(2);
|
|
});
|
|
it('does not warn if old and new are uncontrolled', function () {
|
|
warnControlledUsage(__assign(__assign({}, params), { oldProps: { defaultValue: 'test' }, props: { defaultValue: 'test' } }));
|
|
expect(warningCallback).toHaveBeenCalledTimes(0);
|
|
warnControlledUsage(__assign(__assign({}, params), { props: {}, oldProps: {} }));
|
|
expect(warningCallback).toHaveBeenCalledTimes(0);
|
|
});
|
|
it('does not warn if old and new are controlled', function () {
|
|
warnControlledUsage(__assign(__assign({}, params), { oldProps: { value: 'world', onChange: noOp }, props: { value: 'test', onChange: noOp } }));
|
|
expect(warningCallback).toHaveBeenCalledTimes(0);
|
|
});
|
|
it('warns if old is implicitly uncontrolled and new is controlled', function () {
|
|
warnControlledUsage(__assign(__assign({}, params), { oldProps: {}, props: { value: 'test', onChange: noOp } }));
|
|
expect(warningCallback).toHaveBeenCalledTimes(1);
|
|
expect(warningCallback).toHaveBeenLastCalledWith("Warning: A component is changing an uncontrolled TestComponent to be controlled. TestComponents should not " +
|
|
"switch from controlled to uncontrolled (or vice versa). Decide between using controlled or uncontrolled " +
|
|
"for the lifetime of the component. More info: https://fb.me/react-controlled-components");
|
|
// Don't re-warn
|
|
warnControlledUsage(__assign(__assign({}, params), { oldProps: {}, props: { value: 'test', onChange: noOp } }));
|
|
expect(warningCallback).toHaveBeenCalledTimes(1);
|
|
});
|
|
it('warns if old is uncontrolled and new is controlled', function () {
|
|
warnControlledUsage(__assign(__assign({}, params), { oldProps: {}, props: { value: 'test', onChange: noOp } }));
|
|
expect(warningCallback).toHaveBeenCalledTimes(1);
|
|
expect(warningCallback).toHaveBeenLastCalledWith("Warning: A component is changing an uncontrolled TestComponent to be controlled. TestComponents should not " +
|
|
"switch from controlled to uncontrolled (or vice versa). Decide between using controlled or uncontrolled " +
|
|
"for the lifetime of the component. More info: https://fb.me/react-controlled-components");
|
|
});
|
|
it('re-warns when componentId changes if old is uncontrolled and new is controlled', function () {
|
|
warnControlledUsage(__assign(__assign({}, params), { oldProps: {}, props: { value: 'test', onChange: noOp } }));
|
|
expect(warningCallback).toHaveBeenCalledTimes(1);
|
|
warnControlledUsage(__assign(__assign({}, params), { componentId: 'TestComponent2', oldProps: {}, props: { value: 'test', onChange: noOp } }));
|
|
expect(warningCallback).toHaveBeenCalledTimes(2);
|
|
});
|
|
it('warns if old is controlled and new is implicitly uncontrolled', function () {
|
|
warnControlledUsage(__assign(__assign({}, params), { oldProps: { value: 'test', onChange: noOp }, props: {} }));
|
|
expect(warningCallback).toHaveBeenCalledTimes(1);
|
|
expect(warningCallback).toHaveBeenLastCalledWith("Warning: A component is changing a controlled TestComponent to be uncontrolled. TestComponents should not " +
|
|
"switch from controlled to uncontrolled (or vice versa). Decide between using controlled or uncontrolled " +
|
|
"for the lifetime of the component. More info: https://fb.me/react-controlled-components");
|
|
// Don't re-warn
|
|
warnControlledUsage(__assign(__assign({}, params), { oldProps: { value: 'test', onChange: noOp }, props: {} }));
|
|
expect(warningCallback).toHaveBeenCalledTimes(1);
|
|
});
|
|
it('warns if old is controlled and new is uncontrolled', function () {
|
|
warnControlledUsage(__assign(__assign({}, params), { oldProps: { value: 'hello', onChange: noOp }, props: { defaultValue: 'world' } }));
|
|
expect(warningCallback).toHaveBeenCalledTimes(1);
|
|
expect(warningCallback).toHaveBeenLastCalledWith("Warning: A component is changing a controlled TestComponent to be uncontrolled. TestComponents should not " +
|
|
"switch from controlled to uncontrolled (or vice versa). Decide between using controlled or uncontrolled " +
|
|
"for the lifetime of the component. More info: https://fb.me/react-controlled-components");
|
|
// Don't re-warn
|
|
warnControlledUsage(__assign(__assign({}, params), { oldProps: { value: 'hello', onChange: noOp }, props: { defaultValue: 'world' } }));
|
|
expect(warningCallback).toHaveBeenCalledTimes(1);
|
|
});
|
|
it('re-warns when componentId changes if old is controlled and new is implicitly uncontrolled', function () {
|
|
warnControlledUsage(__assign(__assign({}, params), { oldProps: { value: 'test', onChange: noOp }, props: {} }));
|
|
expect(warningCallback).toHaveBeenCalledTimes(1);
|
|
warnControlledUsage(__assign(__assign({}, params), { componentId: 'TestComponent2', oldProps: { value: 'test', onChange: noOp }, props: {} }));
|
|
expect(warningCallback).toHaveBeenCalledTimes(2);
|
|
});
|
|
});
|
|
//# sourceMappingURL=warnControlledUsage.test.js.map
|