import { describe, it, expect } from "vitest";
import { expectNoPxInStyleObject, expectNoPxInStyleString } from "./styleInvariants";
import {
  computeFormInputExportTokens,
  computeFormSelectExportTokens,
  computeFormCheckboxExportTokens,
  computeFormRadioExportTokens,
  computeFormInputEditorTokens,
  computeFormSelectEditorTokens,
  computeFormOptionGroupEditorTokens,
  computeFormInputPublicTokens,
  computeFormSelectPublicTokens,
  computeFormCheckboxPublicTokens,
  computeFormRadioPublicTokens,
  computeFormControllerPublicTokens,
  computeFormBlockExportTokens,
} from "@/features/editor/utils/formHelpers";
import type {
  Block,
  FormBlockProps,
  FormInputBlockProps,
  FormSelectBlockProps,
  FormCheckboxBlockProps,
  FormRadioBlockProps,
} from "@/features/editor/state/editorStore";

const baseInput: FormInputBlockProps = {
  label: "이름",
  formFieldName: "name",
};

const baseSelect: FormSelectBlockProps = {
  label: "플랜",
  formFieldName: "plan",
  options: [],
};

const baseCheckbox: FormCheckboxBlockProps = {
  groupLabel: "옵션",
  formFieldName: "options",
  options: [],
};

const baseRadio: FormRadioBlockProps = {
  groupLabel: "선택",
  formFieldName: "choice",
  options: [],
};

describe("formHelpers.computeFormInputExportTokens", () => {
  it("텍스트 색상/배경/테두리/패딩/너비/둥글기 스타일을 계산해야 한다", () => {
    const tokens = computeFormInputExportTokens({
      ...baseInput,
      textColorCustom: "  #ff0000  ",
      fillColorCustom: "  #111827  ",
      strokeColorCustom: "  #4b5563  ",
      paddingX: 8,
      paddingY: 4,
      widthMode: "fixed",
      widthPx: 300,
      borderRadius: "lg",
    });

    expect(tokens.labelStyleAttr).toBe(' style="color:#ff0000"');
    expect(tokens.inputStyleAttr).toContain("color:#ff0000");
    expect(tokens.inputStyleAttr).toContain("background-color:#111827");
    expect(tokens.inputStyleAttr).toContain("border-color:#4b5563");
    expect(tokens.inputStyleAttr).toContain("padding-left:0.5em");
    expect(tokens.inputStyleAttr).toContain("padding-right:0.5em");
    expect(tokens.inputStyleAttr).toContain("padding-top:0.25em");
    expect(tokens.inputStyleAttr).toContain("padding-bottom:0.25em");
    expect(tokens.inputStyleAttr).toContain("width:18.75em");
    expect(tokens.inputStyleAttr).toContain("border-radius:6px");

    // Export 인풋 스타일에는 border-radius 등의 예외를 제외하고 px 단위가 포함되지 않아야 한다.
    expectNoPxInStyleString(tokens.inputStyleAttr, {
      allowPatterns: [/border-radius:\d+px/, /border-width:\d+px/],
    });
  });

  it("스타일 값이 없으면 style 속성이 비어 있어야 한다", () => {
    const tokens = computeFormInputExportTokens(baseInput);
    expect(tokens.labelStyleAttr).toBe("");
    expect(tokens.inputStyleAttr).toBe(' style="border-radius:4px"');
  });
});

describe("formHelpers.computeFormSelectExportTokens", () => {
  it("텍스트 색상/배경/테두리/패딩/너비/둥글기 스타일을 계산해야 한다", () => {
    const tokens = computeFormSelectExportTokens({
      ...baseSelect,
      textColorCustom: "  #00ff00  ",
      fillColorCustom: "  #020617  ",
      strokeColorCustom: "  #64748b  ",
      paddingX: 12,
      paddingY: 6,
      widthMode: "fixed",
      widthPx: 240,
      borderRadius: "full",
    });

    expect(tokens.labelStyleAttr).toBe(' style="color:#00ff00"');
    expect(tokens.selectStyleAttr).toContain("color:#00ff00");
    expect(tokens.selectStyleAttr).toContain("background-color:#020617");
    expect(tokens.selectStyleAttr).toContain("border-color:#64748b");
    expect(tokens.selectStyleAttr).toContain("padding-left:0.75em");
    expect(tokens.selectStyleAttr).toContain("padding-right:0.75em");
    expect(tokens.selectStyleAttr).toContain("padding-top:0.375em");
    expect(tokens.selectStyleAttr).toContain("padding-bottom:0.375em");
    expect(tokens.selectStyleAttr).toContain("width:15em");
    expect(tokens.selectStyleAttr).toContain("border-radius:9999px");

    // Export 셀렉트 스타일에는 border-radius 등의 예외를 제외하고 px 단위가 포함되지 않아야 한다.
    expectNoPxInStyleString(tokens.selectStyleAttr, {
      allowPatterns: [/border-radius:\d+px/, /border-width:\d+px/],
    });
  });

  it("스타일 값이 없으면 style 속성이 비어 있어야 한다", () => {
    const tokens = computeFormSelectExportTokens(baseSelect);
    expect(tokens.labelStyleAttr).toBe("");
    expect(tokens.selectStyleAttr).toBe(' style="border-radius:4px"');
  });
});

describe("formHelpers.computeFormCheckboxExportTokens", () => {
  it("텍스트 색상/배경/테두리/패딩/둥글기 스타일을 계산해야 한다", () => {
    const tokens = computeFormCheckboxExportTokens({
      ...baseCheckbox,
      textColorCustom: "  #38bdf8  ",
      fillColorCustom: "  #0f172a  ",
      strokeColorCustom: "  #e5e7eb  ",
      paddingX: 10,
      paddingY: 5,
      borderRadius: "sm",
    });

    expect(tokens.labelStyleAttr).toBe(' style="color:#38bdf8"');
    expect(tokens.optionStyleAttr).toContain("color:#38bdf8");
    expect(tokens.optionStyleAttr).toContain("background-color:#0f172a");
    expect(tokens.optionStyleAttr).toContain("border-color:#e5e7eb");
    expect(tokens.optionStyleAttr).toContain("border-width:1px");
    expect(tokens.optionStyleAttr).toContain("border-style:solid");
    expect(tokens.optionStyleAttr).toContain("padding-left:0.625em");
    expect(tokens.optionStyleAttr).toContain("padding-right:0.625em");
    expect(tokens.optionStyleAttr).toContain("padding-top:0.3125em");
    expect(tokens.optionStyleAttr).toContain("padding-bottom:0.3125em");
    expect(tokens.optionStyleAttr).toContain("border-radius:2px");

    // Export 체크박스 옵션 스타일에는 border/border-radius 를 제외하고 px 단위가 포함되지 않아야 한다.
    expectNoPxInStyleString(tokens.optionStyleAttr, {
      allowPatterns: [/border-radius:\d+px/, /border-width:\d+px/],
    });
  });

  it("스타일 값이 없으면 style 속성이 비어 있어야 한다", () => {
    const tokens = computeFormCheckboxExportTokens(baseCheckbox);
    expect(tokens.labelStyleAttr).toBe("");
    expect(tokens.optionStyleAttr).toBe(' style="border-radius:4px"');
  });
});

describe("formHelpers.computeFormRadioExportTokens", () => {
  it("체크박스와 동일한 규칙으로 옵션 스타일을 계산해야 한다", () => {
    const tokens = computeFormRadioExportTokens({
      ...baseRadio,
      textColorCustom: "  #fbbf24  ",
      fillColorCustom: "  #111827  ",
      strokeColorCustom: "  #facc15  ",
      paddingX: 4,
      paddingY: 2,
      borderRadius: "md",
    });

    expect(tokens.labelStyleAttr).toBe(' style="color:#fbbf24"');
    expect(tokens.optionStyleAttr).toContain("color:#fbbf24");
    expect(tokens.optionStyleAttr).toContain("background-color:#111827");
    expect(tokens.optionStyleAttr).toContain("border-color:#facc15");
    expect(tokens.optionStyleAttr).toContain("border-width:1px");
    expect(tokens.optionStyleAttr).toContain("border-style:solid");
    expect(tokens.optionStyleAttr).toContain("padding-left:0.25em");
    expect(tokens.optionStyleAttr).toContain("padding-right:0.25em");
    expect(tokens.optionStyleAttr).toContain("padding-top:0.125em");
    expect(tokens.optionStyleAttr).toContain("padding-bottom:0.125em");
    expect(tokens.optionStyleAttr).toContain("border-radius:4px");

    // Export 라디오 옵션 스타일에는 border/border-radius 를 제외하고 px 단위가 포함되지 않아야 한다.
    expectNoPxInStyleString(tokens.optionStyleAttr, {
      allowPatterns: [/border-radius:\d+px/, /border-width:\d+px/],
    });
  });
});

describe("formHelpers - editor tokens", () => {
  it("computeFormInputEditorTokens: 에디터 인풋 필드 스타일을 계산해야 한다", () => {
    const tokens = computeFormInputEditorTokens({
      ...baseInput,
      textColorCustom: "#ff0000",
      fillColorCustom: "#123456",
      strokeColorCustom: "#654321",
      widthMode: "fixed",
      widthPx: 240,
      borderRadius: "full",
      align: "center",
      labelLayout: "stacked",
    } as any);

    expect(tokens.fieldStyle.color).toBe("#ff0000");
    expect(tokens.fieldStyle.backgroundColor).toBe("#123456");
    expect(tokens.fieldStyle.borderColor).toBe("#654321");
    expect(tokens.fieldStyle.width).toBe("240px");
    expect(tokens.fieldStyle.borderRadius).toBe(9999);
  });

  it("computeFormSelectEditorTokens: 에디터 셀렉트 필드 스타일을 계산해야 한다", () => {
    const tokens = computeFormSelectEditorTokens({
      ...baseSelect,
      textColorCustom: "#ff0000",
      fillColorCustom: "#123456",
      strokeColorCustom: "#654321",
      widthMode: "fixed",
      widthPx: 260,
      borderRadius: "lg",
      paddingX: 12,
      paddingY: 6,
      fontSizeCustom: "14px",
      lineHeightCustom: "20px",
      letterSpacingCustom: "1px",
    } as any);

    expect(tokens.fieldStyle.color).toBe("#ff0000");
    expect(tokens.fieldStyle.backgroundColor).toBe("#123456");
    expect(tokens.fieldStyle.borderColor).toBe("#654321");
    expect(tokens.fieldStyle.width).toBe("260px");
    expect(tokens.fieldStyle.borderRadius).toBe(9999);
    expect(tokens.fieldStyle.paddingInline).toBe("12px");
    expect(tokens.fieldStyle.paddingBlock).toBe("6px");
    expect(tokens.fieldStyle.fontSize).toBe("14px");
    expect(tokens.fieldStyle.lineHeight).toBe("20px");
    expect(tokens.fieldStyle.letterSpacing).toBe("1px");
  });

  it("computeFormOptionGroupEditorTokens: 에디터 라디오/체크박스 그룹 필드 스타일을 계산해야 한다", () => {
    const tokens = computeFormOptionGroupEditorTokens({
      ...baseRadio,
      textColorCustom: "#ff0000",
      fillColorCustom: "#123456",
      strokeColorCustom: "#654321",
      widthMode: "fixed",
      widthPx: 280,
      borderRadius: "lg",
      paddingX: 8,
      paddingY: 4,
      fontSizeCustom: "15px",
      lineHeightCustom: "22px",
      letterSpacingCustom: "0.5px",
    } as any);

    expect(tokens.fieldStyle.color).toBe("#ff0000");
    expect(tokens.fieldStyle.backgroundColor).toBe("#123456");
    expect(tokens.fieldStyle.borderColor).toBe("#654321");
    expect(tokens.fieldStyle.width).toBe("280px");
    expect(tokens.fieldStyle.borderRadius).toBe(9999);
    expect(tokens.fieldStyle.paddingInline).toBe("8px");
    expect(tokens.fieldStyle.paddingBlock).toBe("4px");
    expect(tokens.fieldStyle.fontSize).toBe("15px");
    expect(tokens.fieldStyle.lineHeight).toBe("22px");
    expect(tokens.fieldStyle.letterSpacing).toBe("0.5px");
  });
});

describe("formHelpers - public tokens", () => {
	it("computeFormInputPublicTokens: 퍼블릭 인풋 필드 스타일을 계산해야 한다", () => {
		const tokens = computeFormInputPublicTokens({
			...baseInput,
			align: "center",
			widthMode: "fixed",
			widthPx: 320,
			paddingX: 16,
			paddingY: 8,
			textColorCustom: "#112233",
			fillColorCustom: "#123456",
			strokeColorCustom: "#ff0000",
			borderRadius: "lg",
		} as any);

		expect(tokens.wrapperLayoutClass).toBe("flex flex-col gap-1");
		expect(tokens.widthClass).toBe("");
		expect(tokens.inputStyle.textAlign).toBe("center");
		expect(tokens.inputStyle.width).toBe("20em");
		expect(tokens.inputStyle.paddingInline).toBe("1em");
		expect(tokens.inputStyle.paddingBlock).toBe("0.5em");
		expect(tokens.inputStyle.color).toBe("#112233");
		expect(tokens.inputStyle.backgroundColor).toBe("#123456");
		expect(tokens.inputStyle.borderColor).toBe("#ff0000");
		expect(tokens.inputStyle.borderRadius).toBe("6px");

		// 퍼블릭 인풋 토큰 스타일에는 borderRadius/borderWidth 를 제외하고 px 단위가 없어야 한다.
		expectNoPxInStyleObject(tokens.wrapperStyle);
		expectNoPxInStyleObject(tokens.inputStyle, { allowKeys: ["borderRadius", "borderWidth"] });
	});

	it("computeFormSelectPublicTokens: 퍼블릭 셀렉트 필드 스타일을 계산해야 한다", () => {
		const tokens = computeFormSelectPublicTokens({
			...baseSelect,
			widthMode: "fixed",
			widthPx: 240,
			paddingX: 16,
			paddingY: 8,
			textColorCustom: "#00ff00",
			fillColorCustom: "#123456",
			strokeColorCustom: "#ff0000",
			borderRadius: "lg",
		} as any);

		expect(tokens.widthClass).toBe("");
		expect(tokens.wrapperStyle.width).toBe("15em");
		expect(tokens.selectStyle.paddingInline).toBe("1em");
		expect(tokens.selectStyle.paddingBlock).toBe("0.5em");
		expect(tokens.selectStyle.color).toBe("#00ff00");
		expect(tokens.selectStyle.backgroundColor).toBe("#123456");
		expect(tokens.selectStyle.borderColor).toBe("#ff0000");
		expect(tokens.selectStyle.borderRadius).toBe("6px");

		// 퍼블릭 셀렉트 토큰 스타일에는 borderRadius/borderWidth 를 제외하고 px 단위가 없어야 한다.
		expectNoPxInStyleObject(tokens.wrapperStyle);
		expectNoPxInStyleObject(tokens.selectStyle, { allowKeys: ["borderRadius", "borderWidth"] });
	});

	it("computeFormCheckboxPublicTokens: 퍼블릭 체크박스 그룹 스타일을 계산해야 한다", () => {
		const tokens = computeFormCheckboxPublicTokens({
			...baseCheckbox,
			widthMode: "fixed",
			widthPx: 320,
			paddingX: 8,
			paddingY: 4,
			optionGapPx: 16,
			textColorCustom: "#ffffff",
			fillColorCustom: "#123456",
			strokeColorCustom: "#ff0000",
			borderRadius: "lg",
		} as any);

		expect(tokens.widthClass).toBe("");
		expect(tokens.groupStyle.width).toBe("20em");
		expect(tokens.optionsStyle.rowGap).toBe("1em");
		expect(tokens.optionContainerStyle.paddingInline).toBe("0.5em");
		expect(tokens.optionContainerStyle.paddingBlock).toBe("0.25em");
		expect(tokens.optionContainerStyle.backgroundColor).toBe("#123456");
		expect(tokens.optionContainerStyle.borderColor).toBe("#ff0000");
		expect(tokens.optionContainerStyle.borderWidth).toBe("1px");
		expect(tokens.optionContainerStyle.borderStyle).toBe("solid");
		expect(tokens.optionContainerStyle.borderRadius).toBe("6px");
		expect(tokens.groupTextStyle.color).toBe("#ffffff");
		expect(tokens.optionTextStyle.color).toBe("#ffffff");

		// 퍼블릭 체크박스 토큰 스타일에는 borderRadius/borderWidth 를 제외하고 px 단위가 없어야 한다.
		expectNoPxInStyleObject(tokens.groupStyle);
		expectNoPxInStyleObject(tokens.optionsStyle);
		expectNoPxInStyleObject(tokens.optionContainerStyle, { allowKeys: ["borderRadius", "borderWidth"] });
		expectNoPxInStyleObject(tokens.groupTextStyle);
		expectNoPxInStyleObject(tokens.optionTextStyle);
	});

	it("computeFormRadioPublicTokens: 퍼블릭 라디오 그룹 스타일을 계산해야 한다", () => {
		const tokens = computeFormRadioPublicTokens({
			...baseRadio,
			widthMode: "fixed",
			widthPx: 320,
			paddingX: 8,
			paddingY: 4,
			optionGapPx: 16,
			textColorCustom: "#ffffff",
			fillColorCustom: "#123456",
			strokeColorCustom: "#ff0000",
			borderRadius: "lg",
		} as any);

		expect(tokens.widthClass).toBe("");
		expect(tokens.groupStyle.width).toBe("20em");
		expect(tokens.optionsStyle.rowGap).toBe("1em");
		expect(tokens.optionContainerStyle.paddingInline).toBe("0.5em");
		expect(tokens.optionContainerStyle.paddingBlock).toBe("0.25em");
		expect(tokens.optionContainerStyle.backgroundColor).toBe("#123456");
		expect(tokens.optionContainerStyle.borderColor).toBe("#ff0000");
		expect(tokens.optionContainerStyle.borderWidth).toBe("1px");
		expect(tokens.optionContainerStyle.borderStyle).toBe("solid");
		expect(tokens.optionContainerStyle.borderRadius).toBe("6px");
		expect(tokens.groupTextStyle.color).toBe("#ffffff");
		expect(tokens.optionTextStyle.color).toBe("#ffffff");
	});
});

describe("formHelpers.computeFormControllerPublicTokens", () => {
	it("fieldIds 를 기반으로 컨트롤러 필드를 매핑하고 레이아웃/submitLabel 을 계산해야 한다", () => {
		const formBlock: Block = {
			id: "form-1",
			type: "form",
			props: {
				kind: "contact",
				submitTarget: "internal",
				fieldIds: ["input-1", "checkbox-1"],
				submitButtonId: "btn-1",
				formWidthMode: "fixed",
				formWidthPx: 320,
				marginYPx: 32,
				backgroundColorCustom: "  #123456  ",
			} as FormBlockProps,
		} as Block;

		const inputBlock: Block = {
			id: "input-1",
			type: "formInput",
			props: {
				label: "이름",
				formFieldName: "name",
				inputType: "email",
				required: true,
			} as any,
		} as Block;

		const checkboxBlock: Block = {
			id: "checkbox-1",
			type: "formCheckbox",
			props: {
				groupLabel: "옵션",
				formFieldName: "options",
				required: true,
				groupLabelMode: "image",
				groupLabelImageUrl: "https://example.com/group.png",
				options: [
					{ label: "A", value: "a" },
					{ label: "B", value: "b" },
				],
			} as any,
		} as Block;

		const buttonBlock: Block = {
			id: "btn-1",
			type: "button",
			props: {
				label: "컨트롤러 버튼",
			} as any,
		} as Block;

		const blocks: Block[] = [formBlock, inputBlock, checkboxBlock, buttonBlock];

		const tokens = computeFormControllerPublicTokens(formBlock, blocks);

		expect(tokens.fields).toHaveLength(2);
		const inputField = tokens.fields[0];
		const checkboxField = tokens.fields[1];

		expect(inputField.id).toBe("input-1");
		expect(inputField.name).toBe("name");
		expect(inputField.label).toBe("이름");
		expect(inputField.type).toBe("text");
		expect(inputField.required).toBe(true);

		expect(checkboxField.id).toBe("checkbox-1");
		expect(checkboxField.name).toBe("options");
		expect(checkboxField.label).toBe("옵션");
		expect(checkboxField.type).toBe("checkbox");
		expect(checkboxField.required).toBe(true);
		expect(checkboxField.options).toHaveLength(2);
		expect(checkboxField.groupLabelMode).toBe("image");
		expect(checkboxField.groupLabelImageUrl).toBe("https://example.com/group.png");

		expect(tokens.formClassName).toBe("space-y-3");
		// FormBlock 은 이제 레이아웃/배경 스타일을 가지지 않는 순수 컨트롤러이므로,
		// formStyle 은 항상 빈 객체여야 한다.
		expect(tokens.formStyle).toEqual({});

		expect(tokens.submitLabel).toBe("컨트롤러 버튼");
	});

	it("fields 가 있을 때는 fields 를 사용하고, 없으면 빈 배열을 반환해야 한다", () => {
		const formWithFields: Block = {
			id: "form-2",
			type: "form",
			props: {
				kind: "contact",
				submitTarget: "internal",
				fields: [
					{
						id: "f1",
						name: "email",
						label: "이메일",
						type: "email",
						required: true,
					},
				],
			} as FormBlockProps,
		} as Block;

		const tokensWithFields = computeFormControllerPublicTokens(formWithFields, [formWithFields]);

		expect(tokensWithFields.fields).toHaveLength(1);
		expect(tokensWithFields.fields[0].id).toBe("f1");
		expect(tokensWithFields.fields[0].name).toBe("email");
		expect(tokensWithFields.fields[0].label).toBe("이메일");
		expect(tokensWithFields.fields[0].type).toBe("email");
		expect(tokensWithFields.fields[0].required).toBe(true);

		const formFallback: Block = {
			id: "form-3",
			type: "form",
			props: {
				kind: "contact",
				submitTarget: "internal",
			} as FormBlockProps,
		} as Block;

		const tokensFallback = computeFormControllerPublicTokens(formFallback, [formFallback]);

		expect(tokensFallback.fields).toHaveLength(0);
	});
});

describe("formHelpers.computeFormBlockExportTokens", () => {
	it("fieldIds 가 있을 때 컨트롤러 필드와 폼 배경 스타일을 계산해야 한다", () => {
		const formBlock: Block = {
			id: "form-export-1",
			type: "form",
			props: {
				kind: "contact",
				submitTarget: "internal",
				fieldIds: ["input-1", "select-1"],
				fields: [],
				backgroundColorCustom: "  #123456  ",
			} as FormBlockProps,
		} as Block;

		const inputBlock: Block = {
			id: "input-1",
			type: "formInput",
			props: {
				label: "이름",
				formFieldName: "name",
				inputType: "email",
				required: true,
			} as any,
		} as Block;

		const selectBlock: Block = {
			id: "select-1",
			type: "formSelect",
			props: {
				label: "플랜",
				formFieldName: "plan",
				options: [
					{ label: "Basic", value: "basic" },
					{ label: "Pro", value: "pro" },
				],
			} as any,
		} as Block;

		const blocks: Block[] = [formBlock, inputBlock, selectBlock];

		const tokens = computeFormBlockExportTokens(formBlock, blocks);

		expect(tokens.hasControllerFields).toBe(true);
		expect(tokens.controllerFields).toHaveLength(2);
		expect(tokens.controllerFields[0].id).toBe("input-1");
		expect(tokens.controllerFields[1].id).toBe("select-1");
		expect(tokens.fallbackFields).toHaveLength(0);
		// FormBlock 은 Export 레이어에서도 컨테이너 배경/레이아웃 스타일을 가지지 않는다.
		expect(tokens.formStyleParts).toEqual([]);
	});

	it("fieldIds 가 없고 fields 가 있을 때 fallbackFields 를 사용해야 한다", () => {
		const formBlock: Block = {
			id: "form-export-2",
			type: "form",
			props: {
				kind: "contact",
				submitTarget: "internal",
				fieldIds: [],
				fields: [
					{
						id: "f1",
						name: "email",
						label: "이메일",
						type: "email",
						required: true,
					},
				],
				backgroundColorCustom: undefined,
			} as FormBlockProps,
		} as Block;

		const tokens = computeFormBlockExportTokens(formBlock, [formBlock]);

		expect(tokens.hasControllerFields).toBe(false);
		expect(tokens.controllerFields).toHaveLength(0);
		expect(tokens.fallbackFields).toHaveLength(1);
		expect(tokens.fallbackFields[0].id).toBe("f1");
		expect(tokens.formStyleParts).toEqual([]);
	});

	it("fieldIds 와 fields 가 모두 없으면 fallbackFields 도 빈 배열이어야 한다", () => {
		const formBlock: Block = {
			id: "form-export-3",
			type: "form",
			props: {
				kind: "contact",
				submitTarget: "internal",
			} as FormBlockProps,
		} as Block;

		const tokens = computeFormBlockExportTokens(formBlock, [formBlock]);

		expect(tokens.hasControllerFields).toBe(false);
		expect(tokens.controllerFields).toHaveLength(0);
		expect(tokens.fallbackFields).toHaveLength(0);
	});
});
