feat(common): 添加工具

This commit is contained in:
2026-04-20 17:54:26 +08:00
parent 7ff223fa32
commit b10d613987
64 changed files with 8342 additions and 16243 deletions
+95
View File
@@ -0,0 +1,95 @@
import { describe, test, expect } from "vitest";
import { effectScope } from "vue";
import { useCalendar } from "../src/calendar";
describe("useCalendar", () => {
test("默认值", () => {
const scope = effectScope();
scope.run(() => {
const { value, show, text } = useCalendar({});
expect(value.value).toBeNull();
expect(show.value).toBe(false);
expect(text.value).toBe("请选择");
});
scope.stop();
});
test("单选模式:text 显示 value,无值时显示 placeholder", () => {
const scope = effectScope();
scope.run(() => {
const { value, text } = useCalendar({ mode: "single", placeholder: "请选日期" });
expect(text.value).toBe("请选日期");
value.value = "2024-01-15";
expect(text.value).toBe("2024-01-15");
});
scope.stop();
});
test("多选模式:text 用 separator 拼接", () => {
const scope = effectScope();
scope.run(() => {
const { value, text } = useCalendar({ mode: "multiple", separator: "-" });
expect(text.value).toBe("请选择");
value.value = ["2024-01-15", "2024-01-16"];
expect(text.value).toBe("2024-01-15-2024-01-16");
});
scope.stop();
});
test("showCalendar / hideCalendar", () => {
const scope = effectScope();
scope.run(() => {
const { show, showCalendar, hideCalendar } = useCalendar({});
expect(show.value).toBe(false);
showCalendar();
expect(show.value).toBe(true);
hideCalendar();
expect(show.value).toBe(false);
});
scope.stop();
});
test("handleConfirm 单选模式:设置 value 并关闭", () => {
const scope = effectScope();
scope.run(() => {
const { value, show, handleConfirm } = useCalendar({ mode: "single" });
show.value = true;
handleConfirm(["2024-06-01", "2024-06-02"]);
expect(value.value).toBe("2024-06-01");
expect(show.value).toBe(false);
});
scope.stop();
});
test("handleConfirm 多选模式:设置 value 数组并关闭", () => {
const scope = effectScope();
scope.run(() => {
const { value, show, handleConfirm } = useCalendar({ mode: "multiple" });
show.value = true;
handleConfirm(["2024-06-01", "2024-06-02"]);
expect(value.value).toEqual(["2024-06-01", "2024-06-02"]);
expect(show.value).toBe(false);
});
scope.stop();
});
test("handleClose 关闭弹窗", () => {
const scope = effectScope();
scope.run(() => {
const { show, handleClose } = useCalendar({});
show.value = true;
handleClose();
expect(show.value).toBe(false);
});
scope.stop();
});
test("接受初始 value", () => {
const scope = effectScope();
scope.run(() => {
const { text } = useCalendar({ value: "2024-03-10", mode: "single" });
expect(text.value).toBe("2024-03-10");
});
scope.stop();
});
});
@@ -0,0 +1,73 @@
import { describe, test, expect } from "vitest";
import { effectScope } from "vue";
import { useDateTimePicker } from "../src/datetime-picker";
describe("useDateTimePicker", () => {
test("默认值", () => {
const scope = effectScope();
scope.run(() => {
const { value, show, text } = useDateTimePicker({});
expect(value.value).toBeNull();
expect(show.value).toBe(false);
expect(text.value).toBe("请选择");
});
scope.stop();
});
test("自定义 placeholder", () => {
const scope = effectScope();
scope.run(() => {
const { text } = useDateTimePicker({ placeholder: "选择时间" });
expect(text.value).toBe("选择时间");
});
scope.stop();
});
test("有 value 时 text 显示 value", () => {
const scope = effectScope();
scope.run(() => {
const { value, text } = useDateTimePicker({ value: "2024-01-15 10:00" });
expect(text.value).toBe("2024-01-15 10:00");
value.value = "2024-06-01 08:30";
expect(text.value).toBe("2024-06-01 08:30");
});
scope.stop();
});
test("showPicker / hidePicker", () => {
const scope = effectScope();
scope.run(() => {
const { show, showPicker, hidePicker } = useDateTimePicker({});
expect(show.value).toBe(false);
showPicker();
expect(show.value).toBe(true);
hidePicker();
expect(show.value).toBe(false);
});
scope.stop();
});
test("handleConfirm 关闭弹窗(不更新 value", () => {
const scope = effectScope();
scope.run(() => {
const { value, show, handleConfirm } = useDateTimePicker({ value: "2024-01-01" });
show.value = true;
const event = { indexs: [], value: [], values: [] } as any;
handleConfirm(event);
expect(show.value).toBe(false);
expect(value.value).toBe("2024-01-01");
});
scope.stop();
});
test("handleCancel 关闭弹窗", () => {
const scope = effectScope();
scope.run(() => {
const { show, handleCancel } = useDateTimePicker({});
show.value = true;
handleCancel();
expect(show.value).toBe(false);
});
scope.stop();
});
});
@@ -0,0 +1,132 @@
import { describe, test, expect } from "vitest";
import { effectScope, nextTick } from "vue";
import { usePickerSingle } from "../src/picker-single";
const list = [
{ text: "选项A", value: "a" },
{ text: "选项B", value: "b" },
{ text: "选项C", value: "c" },
];
describe("usePickerSingle", () => {
test("默认值", () => {
const scope = effectScope();
scope.run(() => {
const { value, show, text, indexes } = usePickerSingle({});
expect(value.value).toBeNull();
expect(show.value).toBe(false);
expect(text.value).toBe("请选择");
expect(indexes.value).toEqual([null]);
});
scope.stop();
});
test("columns 是 [list]", () => {
const scope = effectScope();
scope.run(() => {
const { columns } = usePickerSingle({ list });
expect(columns.value).toEqual([list]);
});
scope.stop();
});
test("初始 value 匹配 list 时设置正确 indexes 和 text", async () => {
const scope = effectScope();
await scope.run(async () => {
const { text, indexes } = usePickerSingle({ value: "b", list });
await nextTick();
expect(indexes.value).toEqual([1]);
expect(text.value).toBe("选项B");
});
scope.stop();
});
test("初始 indexes 匹配 list 时设置正确 value 和 text", async () => {
const scope = effectScope();
await scope.run(async () => {
const { value, text } = usePickerSingle({ indexes: [2], list });
await nextTick();
expect(value.value).toBe("c");
expect(text.value).toBe("选项C");
});
scope.stop();
});
test("valueToText:根据 value 查找 text", () => {
const scope = effectScope();
scope.run(() => {
const { valueToText } = usePickerSingle({ list });
expect(valueToText("a")).toBe("选项A");
expect(valueToText("b")).toBe("选项B");
expect(valueToText("unknown")).toBe("请选择");
});
scope.stop();
});
test("showPicker / hidePicker", () => {
const scope = effectScope();
scope.run(() => {
const { show, showPicker, hidePicker } = usePickerSingle({});
expect(show.value).toBe(false);
showPicker();
expect(show.value).toBe(true);
hidePicker();
expect(show.value).toBe(false);
});
scope.stop();
});
test("handleConfirm:更新 indexes 并关闭", async () => {
const scope = effectScope();
await scope.run(async () => {
const { value, show, indexes, handleConfirm } = usePickerSingle({ list });
show.value = true;
handleConfirm({ indexs: [1], value: [list[1]], values: [list] } as any);
expect(indexes.value).toEqual([1]);
expect(show.value).toBe(false);
await nextTick();
expect(value.value).toBe("b");
});
scope.stop();
});
test("handleCancel:关闭弹窗", () => {
const scope = effectScope();
scope.run(() => {
const { show, handleCancel } = usePickerSingle({});
show.value = true;
handleCancel();
expect(show.value).toBe(false);
});
scope.stop();
});
test("modelValueget/set 代理 value", async () => {
const scope = effectScope();
await scope.run(async () => {
const { value, modelValue } = usePickerSingle({ list });
expect(modelValue.value).toEqual([null]);
modelValue.value = "c";
expect(value.value).toBe("c");
});
scope.stop();
});
test("自定义 textName 和 valueName", () => {
const customList = [
{ label: "甲", id: 1 },
{ label: "乙", id: 2 },
];
const scope = effectScope();
scope.run(() => {
const { valueToText } = usePickerSingle({
list: customList as any,
textName: "label",
valueName: "id",
});
expect(valueToText(1)).toBe("甲");
expect(valueToText(2)).toBe("乙");
});
scope.stop();
});
});
+134
View File
@@ -0,0 +1,134 @@
import { describe, test, expect } from "vitest";
import { effectScope, nextTick } from "vue";
import { usePicker } from "../src/picker";
const columns = [
[
{ text: "省A", value: "pa" },
{ text: "省B", value: "pb" },
],
[
{ text: "市A", value: "ca" },
{ text: "市B", value: "cb" },
],
];
describe("usePicker", () => {
test("默认值", async () => {
const scope = effectScope();
await scope.run(async () => {
const { value, show, text, indexes } = usePicker({});
await nextTick();
expect(value.value).toEqual([null]);
expect(show.value).toBe(false);
expect(text.value).toBe("请选择");
expect(indexes.value).toEqual([null]);
});
scope.stop();
});
test("初始 indexes 同步更新 value", async () => {
const scope = effectScope();
await scope.run(async () => {
const { value } = usePicker({ indexes: [0, 1], columns });
await nextTick();
expect(value.value).toEqual(["pa", "cb"]);
});
scope.stop();
});
test("初始 value 同步更新 indexes", async () => {
const scope = effectScope();
await scope.run(async () => {
const { indexes } = usePicker({ value: ["pb", "ca"], columns });
await nextTick();
expect(indexes.value).toEqual([1, 0]);
});
scope.stop();
});
test("text 由 indexes 和 columns 计算得出", async () => {
const scope = effectScope();
await scope.run(async () => {
const { text } = usePicker({ indexes: [0, 1], columns, separator: "/" });
await nextTick();
expect(text.value).toBe("省A/市B");
});
scope.stop();
});
test("indexes 含 null 时 text 显示 placeholder", async () => {
const scope = effectScope();
await scope.run(async () => {
const { text } = usePicker({ indexes: [null, 1], columns, placeholder: "请选择地区" });
await nextTick();
expect(text.value).toBe("请选择地区");
});
scope.stop();
});
test("handleConfirm:更新 indexes", async () => {
const scope = effectScope();
await scope.run(async () => {
const { indexes, value, handleConfirm } = usePicker({ columns });
handleConfirm({ indexs: [1, 0], value: ["pb", "ca"], values: columns } as any);
expect(indexes.value).toEqual([1, 0]);
await nextTick();
expect(value.value).toEqual(["pb", "ca"]);
});
scope.stop();
});
test("showPicker / hidePicker", () => {
const scope = effectScope();
scope.run(() => {
const { show, showPicker, hidePicker } = usePicker({});
showPicker();
expect(show.value).toBe(true);
hidePicker();
expect(show.value).toBe(false);
});
scope.stop();
});
test("columnValueToText:根据列索引和值查找 text", () => {
const scope = effectScope();
scope.run(() => {
const { columnValueToText } = usePicker({ columns });
expect(columnValueToText("pa", 0)).toBe("省A");
expect(columnValueToText("cb", 1)).toBe("市B");
expect(columnValueToText("xx", 0)).toBeUndefined();
});
scope.stop();
});
test("valueToText:返回各列 text 数组", () => {
const scope = effectScope();
scope.run(() => {
const { valueToText } = usePicker({ columns });
expect(valueToText(["pa", "cb"])).toEqual(["省A", "市B"]);
});
scope.stop();
});
test("自定义 textName 和 valueName", async () => {
const customColumns = [
[
{ label: "甲", id: 1 },
{ label: "乙", id: 2 },
],
];
const scope = effectScope();
await scope.run(async () => {
const { text } = usePicker({
columns: customColumns as any,
indexes: [0],
textName: "label",
valueName: "id",
});
await nextTick();
expect(text.value).toBe("甲");
});
scope.stop();
});
});