Skip to content

Commit

Permalink
fix: add debug labels to form and field atoms (#43)
Browse files Browse the repository at this point in the history
  • Loading branch information
MiroslavPetrik committed Feb 23, 2023
1 parent f8f240d commit ff29459
Show file tree
Hide file tree
Showing 4 changed files with 113 additions and 32 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@
"@testing-library/jest-dom": "^5.16.5",
"@testing-library/react": "^13.4.0",
"@testing-library/react-hooks": "^8.0.1",
"@types/node": "^18.14.0",
"@types/react": "^18.0.27",
"@types/react-dom": "^18.0.10",
"@types/testing-library__jest-dom": "^5.14.5",
Expand Down
47 changes: 21 additions & 26 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

72 changes: 71 additions & 1 deletion src/index.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { render, screen } from "@testing-library/react";
import { act as domAct, renderHook } from "@testing-library/react-hooks/dom";
import userEvent from "@testing-library/user-event";
import type { ExtractAtomValue } from "jotai";
import { Provider, createStore } from "jotai";
import { Provider, createStore, useAtomValue } from "jotai";
import { afterEach, describe, expect, it, vi } from "vitest";

import type { FieldAtom, UseForm } from ".";
Expand Down Expand Up @@ -1635,6 +1635,76 @@ describe("useSubmit()", () => {
});
});

describe("fieldAtom()", () => {
it("debugLabels contain the field name when specified", () => {
const field = fieldAtom({ value: "", name: "city" });

const {
result: { current: atoms },
} = renderHook(() => useAtomValue(field));

expect(atoms.name.debugLabel).toBe("field/name/city");
expect(atoms.value.debugLabel).toBe("field/value/city");
expect(atoms.touched.debugLabel).toBe("field/touched/city");
expect(atoms.dirty.debugLabel).toBe("field/dirty/city");
expect(atoms.validate.debugLabel).toBe("field/validate/city");
expect(atoms.validateStatus.debugLabel).toBe("field/validateStatus/city");
expect(atoms.errors.debugLabel).toBe("field/errors/city");
expect(atoms.reset.debugLabel).toBe("field/reset/city");
expect(atoms.ref.debugLabel).toBe("field/ref/city");
expect(atoms._initialValue.debugLabel).toBe("field/_initialValue/city");
expect(atoms._validateCount.debugLabel).toBe("field/_validateCount/city");
});

it("debugLabels are unnamed when field name not specified", () => {
const field = fieldAtom({ value: "" });

const {
result: { current: atoms },
} = renderHook(() => useAtomValue(field));

expect(atoms.name.debugLabel).toBe("field/name/<unnamed-field>");
expect(atoms.value.debugLabel).toBe("field/value/<unnamed-field>");
expect(atoms.touched.debugLabel).toBe("field/touched/<unnamed-field>");
expect(atoms.dirty.debugLabel).toBe("field/dirty/<unnamed-field>");
expect(atoms.validate.debugLabel).toBe("field/validate/<unnamed-field>");
expect(atoms.validateStatus.debugLabel).toBe(
"field/validateStatus/<unnamed-field>"
);
expect(atoms.errors.debugLabel).toBe("field/errors/<unnamed-field>");
expect(atoms.reset.debugLabel).toBe("field/reset/<unnamed-field>");
expect(atoms.ref.debugLabel).toBe("field/ref/<unnamed-field>");
expect(atoms._initialValue.debugLabel).toBe(
"field/_initialValue/<unnamed-field>"
);
expect(atoms._validateCount.debugLabel).toBe(
"field/_validateCount/<unnamed-field>"
);
});
});

describe("formAtom()", () => {
it("has atoms with debugLabels", () => {
const field = formAtom({});

const {
result: { current: atoms },
} = renderHook(() => useAtomValue(field));

expect(atoms.fields.debugLabel).toBe("form/fields");
expect(atoms.values.debugLabel).toBe("form/values");
expect(atoms.errors.debugLabel).toBe("form/errors");
expect(atoms.dirty.debugLabel).toBe("form/dirty");
expect(atoms.touchedFields.debugLabel).toBe("form/touchedFields");
expect(atoms.validate.debugLabel).toBe("form/validate");
expect(atoms.validateStatus.debugLabel).toBe("form/validateStatus");
expect(atoms.submit.debugLabel).toBe("form/submit");
expect(atoms.submitStatus.debugLabel).toBe("form/submitStatus");
expect(atoms.submitCount.debugLabel).toBe("form/submitCount");
expect(atoms.reset.debugLabel).toBe("form/reset");
});
});

function createTextField<Value extends string | number | readonly string[]>(
fieldAtom: FieldAtom<Value>
) {
Expand Down
25 changes: 20 additions & 5 deletions src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,7 @@ export function formAtom<Fields extends FormFields>(
set(submitResultAtom, "idle");
});

return atom({
const formAtoms = {
fields: fieldsAtom,
values: valuesAtom,
errors: errorsAtom,
Expand All @@ -327,7 +327,15 @@ export function formAtom<Fields extends FormFields>(
submitStatus: submitResultAtom,
submitCount: submitCountAtom,
reset: resetAtom,
});
};

if (typeof process !== "undefined" && process.env.NODE_ENV !== "production") {
Object.entries(formAtoms).map(([atomName, atom]) => {
atom.debugLabel = `form/${atomName}`;
});
}

return atom(formAtoms);
}

/**
Expand Down Expand Up @@ -634,7 +642,7 @@ export function fieldAtom<Value>(
set(validateResultAtom, "valid");
});

return atom({
const fieldAtoms = {
name: nameAtom,
value: valueAtom,
touched: touchedAtom,
Expand All @@ -645,9 +653,16 @@ export function fieldAtom<Value>(
reset: resetAtom,
ref: refAtom,
_initialValue: initialValueAtom,
_validateCallback: config.validate,
_validateCount: validateCountAtom,
});
};

if (typeof process !== "undefined" && process.env.NODE_ENV !== "production") {
Object.entries(fieldAtoms).map(([atomName, atom]) => {
atom.debugLabel = `field/${atomName}/${config.name ?? "<unnamed-field>"}`;
});
}

return atom({ ...fieldAtoms, _validateCallback: config.validate });
}

/**
Expand Down

0 comments on commit ff29459

Please sign in to comment.