Skip to content

Commit

Permalink
fix(type): maxlength handling over multiple type() calls (#283)
Browse files Browse the repository at this point in the history
Co-authored-by: Greg Shtilman <gshtilma@yahoo-inc.com>
  • Loading branch information
9still and Greg Shtilman committed May 17, 2020
1 parent b470e26 commit 85546ec
Show file tree
Hide file tree
Showing 3 changed files with 109 additions and 5 deletions.
56 changes: 55 additions & 1 deletion __tests__/react/type.js
Expand Up @@ -159,7 +159,7 @@ describe("userEvent.type", () => {
);

it.each(["input", "textarea"])(
"should type text in <%s> up to maxLength if provided",
"should enter text in <%s> up to maxLength if provided",
(type) => {
const onChange = jest.fn();
const onKeyDown = jest.fn();
Expand Down Expand Up @@ -208,4 +208,58 @@ describe("userEvent.type", () => {
expect(onKeyUp).not.toHaveBeenCalled();
}
);

it.each(["input", "textarea"])(
"should append text in <%s> up to maxLength if provided",
(type) => {
const onChange = jest.fn();
const onKeyDown = jest.fn();
const onKeyPress = jest.fn();
const onKeyUp = jest.fn();
const maxLength = 10;

const { getByTestId } = render(
React.createElement(type, {
"data-testid": "input",
onChange,
onKeyDown,
onKeyPress,
onKeyUp,
maxLength,
})
);

const text1 = "superlong";
const text2 = "text";
const text = text1 + text2;
const slicedText = text.slice(0, maxLength);

const inputEl = getByTestId("input");

userEvent.type(inputEl, text1);
userEvent.type(inputEl, text2);

expect(inputEl).toHaveProperty("value", slicedText);
expect(onChange).toHaveBeenCalledTimes(slicedText.length);
expect(onKeyPress).toHaveBeenCalledTimes(text.length);
expect(onKeyDown).toHaveBeenCalledTimes(text.length);
expect(onKeyUp).toHaveBeenCalledTimes(text.length);

inputEl.value = "";
onChange.mockClear();
onKeyPress.mockClear();
onKeyDown.mockClear();
onKeyUp.mockClear();

userEvent.type(inputEl, text, {
allAtOnce: true,
});

expect(inputEl).toHaveProperty("value", slicedText);
expect(onChange).toHaveBeenCalledTimes(1);
expect(onKeyPress).not.toHaveBeenCalled();
expect(onKeyDown).not.toHaveBeenCalled();
expect(onKeyUp).not.toHaveBeenCalled();
}
);
});
50 changes: 49 additions & 1 deletion __tests__/vue/type.js
Expand Up @@ -147,7 +147,7 @@ describe("userEvent.type", () => {
);

it.each(["input", "textarea"])(
"should type text in <%s> up to maxLength if provided",
"should enter text in <%s> up to maxLength if provided",
(type) => {
const input = jest.fn();
const keydown = jest.fn();
Expand Down Expand Up @@ -189,4 +189,52 @@ describe("userEvent.type", () => {
expect(keyup).not.toHaveBeenCalled();
}
);

it.each(["input", "textarea"])(
"should append text in <%s> up to maxLength if provided",
(type) => {
const input = jest.fn();
const keydown = jest.fn();
const keypress = jest.fn();
const keyup = jest.fn();
const maxLength = 10;

const { getByTestId } = renderComponent(
type,
{ input, keydown, keypress, keyup },
{ maxLength }
);

const text1 = "superlong";
const text2 = "text";
const text = text1 + text2;
const slicedText = text.slice(0, maxLength);

const inputEl = getByTestId("input");

userEvent.type(inputEl, text1);
userEvent.type(inputEl, text2);

expect(inputEl).toHaveProperty("value", slicedText);
expect(keydown).toHaveBeenCalledTimes(text.length);
expect(keypress).toHaveBeenCalledTimes(text.length);
expect(keyup).toHaveBeenCalledTimes(text.length);

inputEl.value = "";
input.mockClear();
keydown.mockClear();
keypress.mockClear();
keyup.mockClear();

userEvent.type(inputEl, text, {
allAtOnce: true,
});

expect(inputEl).toHaveProperty("value", slicedText);
expect(input).toHaveBeenCalledTimes(1);
expect(keydown).not.toHaveBeenCalled();
expect(keypress).not.toHaveBeenCalled();
expect(keyup).not.toHaveBeenCalled();
}
);
});
8 changes: 5 additions & 3 deletions src/index.js
Expand Up @@ -236,11 +236,13 @@ const userEvent = {
};
const opts = Object.assign(defaultOpts, userOpts);

const computedText =
element.maxLength > 0 ? text.slice(0, element.maxLength) : text;

const previousText = element.value;

const computedText =
element.maxLength > 0
? text.slice(0, Math.max(element.maxLength - previousText.length, 0))
: text;

if (opts.allAtOnce) {
if (element.readOnly) return;
fireEvent.input(element, {
Expand Down

0 comments on commit 85546ec

Please sign in to comment.