import { describe, bench } from "vitest";
import { Field, Form } from "houseform";
import { z } from "zod";
import {
cleanup,
fireEvent,
getByTestId,
render,
} from "@testing-library/react";
import { Formik, Field as FormikField } from "formik";
import { toFormikValidationSchema } from "zod-formik-adapter";
import { FieldProps } from "formik/dist/Field";
import { Controller, useForm } from "react-hook-form";
import React, { useState } from "react";
import { zodResolver } from "@hookform/resolvers/zod";
import { ErrorMessage } from "@hookform/error-message";
const arr = Array.from({ length: 1000 }, (_, i) => i);
function HouseFormOnSubmitBenchmark() {
return (
);
}
function FormikOnSubmitBenchmark() {
return (
{}}
>
{({ submitForm }) => (
<>
{arr.map((num, i) => (
{(props: FieldProps) => (
{props.meta.error}
)}
))}
>
)}
);
}
function ReactHookFormOnSubmitBenchmark() {
const {
register,
handleSubmit,
formState: { errors },
} = useForm({
defaultValues: {
num: arr,
},
mode: "onSubmit",
resolver: zodResolver(
z.object({
num: z.array(z.number().min(3, "Must be at least three")),
})
),
});
return (
<>
{arr.map((num, i) => {
return (
);
})}
>
);
}
function ReactHookFormHeadlessOnSubmitBenchmark() {
const { control, handleSubmit } = useForm({
defaultValues: {
num: arr,
},
mode: "onSubmit",
resolver: zodResolver(
z.object({
num: z.array(z.number().min(3, "Must be at least three")),
})
),
});
return (
<>
{arr.map((num, i) => {
return (
{
return (
onChange(event.target.valueAsNumber)}
placeholder={`Number ${i}`}
/>
{error &&
{error.message}
}
);
}}
name={`num.${i}`}
/>
);
})}
>
);
}
describe("Validates onSubmit on 1,000 form items", () => {
bench(
"HouseForm",
async () => {
const { getByText, findAllByText, queryAllByText } = render(
);
if (queryAllByText("Must be at least three")?.length) {
throw "Should not be present yet";
}
fireEvent.click(getByText("Submit"));
await findAllByText("Must be at least three");
},
{
setup(task) {
task.opts.beforeEach = () => {
cleanup();
};
},
}
);
bench(
"Formik",
async () => {
const { getByText, findAllByText, queryAllByText } = render(
);
if (queryAllByText("Must be at least three")?.length) {
throw "Should not be present yet";
}
fireEvent.click(getByText("Submit"));
await findAllByText("Must be at least three");
},
{
setup(task) {
task.opts.beforeEach = () => {
cleanup();
};
},
}
);
bench(
"React Hook Form",
async () => {
const { getByText, findAllByText, queryAllByText } = render(
);
if (queryAllByText("Must be at least three")?.length) {
throw "Should not be present yet";
}
fireEvent.click(getByText("Submit"));
await findAllByText("Must be at least three");
},
{
setup(task) {
task.opts.beforeEach = () => {
cleanup();
};
},
}
);
bench(
"React Hook Form (Headless)",
async () => {
const { getByText, findAllByText, queryAllByText } = render(
);
if (queryAllByText("Must be at least three")?.length) {
throw "Should not be present yet";
}
fireEvent.click(getByText("Submit"));
await findAllByText("Must be at least three");
},
{
setup(task) {
task.opts.beforeEach = () => {
cleanup();
};
},
}
);
});