188 lines
5.7 KiB
TypeScript
188 lines
5.7 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
||
import {
|
||
createCustomClassObj,
|
||
convertCustomClass,
|
||
mergeClass,
|
||
} from "../src/vue-helper";
|
||
|
||
// ========== createCustomClassObj ==========
|
||
|
||
describe("createCustomClassObj", () => {
|
||
// ---------- 字符串输入 ----------
|
||
it("应将单个类名字符串转为对象", () => {
|
||
expect(createCustomClassObj("foo")).toEqual({ foo: true });
|
||
});
|
||
|
||
it("应将空格分隔的类名字符串转为对象", () => {
|
||
expect(createCustomClassObj("foo bar")).toEqual({ foo: true, bar: true });
|
||
});
|
||
|
||
it("应处理前后有空格的字符串", () => {
|
||
// trim 后 "foo bar",replace(" +"," ") 是字符串匹配不会替换连续空格
|
||
// split(" ") 产生 ["foo", "", "bar"],空字符串作为键
|
||
expect(createCustomClassObj(" foo bar ")).toEqual({ foo: true, "": true, bar: true });
|
||
});
|
||
|
||
it("应处理多个连续空格", () => {
|
||
// replace(" +", " ") 是字符串匹配而非正则,不会替换连续空格
|
||
// split(" ") 产生 ["foo", "", "", "", "bar"],重复的空字符串键只保留最后一个
|
||
expect(createCustomClassObj("foo bar")).toEqual({ foo: true, "": true, bar: true });
|
||
});
|
||
|
||
it("空字符串应返回空对象", () => {
|
||
expect(createCustomClassObj("")).toEqual({});
|
||
});
|
||
|
||
it("仅空格的字符串应返回空对象", () => {
|
||
expect(createCustomClassObj(" ")).toEqual({});
|
||
});
|
||
|
||
// ---------- 数组输入 ----------
|
||
it("应将类名数组转为对象", () => {
|
||
expect(createCustomClassObj(["foo", "bar"])).toEqual({ foo: true, bar: true });
|
||
});
|
||
|
||
it("应将单个元素的数组转为对象", () => {
|
||
expect(createCustomClassObj(["foo"])).toEqual({ foo: true });
|
||
});
|
||
|
||
it("空数组应返回空对象", () => {
|
||
expect(createCustomClassObj([])).toEqual({});
|
||
});
|
||
|
||
// ---------- 异常输入 ----------
|
||
it("传入对象应抛出 TypeError", () => {
|
||
expect(() => createCustomClassObj({} as any)).toThrow(TypeError);
|
||
});
|
||
|
||
it("传入数字应抛出 TypeError", () => {
|
||
expect(() => createCustomClassObj(123 as any)).toThrow(TypeError);
|
||
});
|
||
|
||
it("传入 null 应抛出 TypeError", () => {
|
||
expect(() => createCustomClassObj(null as any)).toThrow(TypeError);
|
||
});
|
||
|
||
it("传入 undefined 应抛出 TypeError", () => {
|
||
expect(() => createCustomClassObj(undefined as any)).toThrow(TypeError);
|
||
});
|
||
});
|
||
|
||
// ========== convertCustomClass ==========
|
||
|
||
describe("convertCustomClass", () => {
|
||
// ---------- 字符串输入 ----------
|
||
it("应将字符串转为类名对象", () => {
|
||
expect(convertCustomClass("foo bar")).toEqual({ foo: true, bar: true });
|
||
});
|
||
|
||
it("应将单个类名字符串转为对象", () => {
|
||
expect(convertCustomClass("foo")).toEqual({ foo: true });
|
||
});
|
||
|
||
it("空字符串应返回空对象", () => {
|
||
expect(convertCustomClass("")).toEqual({});
|
||
});
|
||
|
||
// ---------- 数组输入 ----------
|
||
it("应将类名数组转为对象", () => {
|
||
expect(convertCustomClass(["foo", "bar"])).toEqual({ foo: true, bar: true });
|
||
});
|
||
|
||
it("空数组应返回空对象", () => {
|
||
expect(convertCustomClass([])).toEqual({});
|
||
});
|
||
|
||
// ---------- 对象输入 ----------
|
||
it("应直接返回对象", () => {
|
||
const obj = { foo: true, bar: false };
|
||
expect(convertCustomClass(obj)).toEqual(obj);
|
||
});
|
||
|
||
it("应保留对象中值为 false 的属性", () => {
|
||
const obj = { foo: true, bar: false };
|
||
const result = convertCustomClass(obj);
|
||
expect(result).toHaveProperty("bar", false);
|
||
});
|
||
|
||
// ---------- 异常输入 ----------
|
||
it("传入数字应抛出 TypeError", () => {
|
||
expect(() => convertCustomClass(123 as any)).toThrow(TypeError);
|
||
});
|
||
|
||
it("传入 null 应抛出 TypeError", () => {
|
||
expect(() => convertCustomClass(null as any)).toThrow(TypeError);
|
||
});
|
||
|
||
it("传入 undefined 应抛出 TypeError", () => {
|
||
expect(() => convertCustomClass(undefined as any)).toThrow(TypeError);
|
||
});
|
||
|
||
it("传入布尔值应抛出 TypeError", () => {
|
||
expect(() => convertCustomClass(true as any)).toThrow(TypeError);
|
||
});
|
||
});
|
||
|
||
// ========== mergeClass ==========
|
||
|
||
describe("mergeClass", () => {
|
||
it("应合并多个字符串类名", () => {
|
||
expect(mergeClass("foo", "bar")).toEqual({ foo: true, bar: true });
|
||
});
|
||
|
||
it("应合并字符串和数组", () => {
|
||
expect(mergeClass("foo", ["bar"])).toEqual({ foo: true, bar: true });
|
||
});
|
||
|
||
it("应合并字符串、数组和对象", () => {
|
||
expect(mergeClass("foo", ["bar"], { baz: true })).toEqual({
|
||
foo: true,
|
||
bar: true,
|
||
baz: true,
|
||
});
|
||
});
|
||
|
||
it("后面的值应覆盖前面的同名属性", () => {
|
||
expect(mergeClass({ foo: true }, { foo: false })).toEqual({ foo: false });
|
||
});
|
||
|
||
it("字符串形式的类名应覆盖前面的", () => {
|
||
// "foo" → { foo: true },后者覆盖前者
|
||
expect(mergeClass("foo", "foo")).toEqual({ foo: true });
|
||
});
|
||
|
||
it("单个参数应正常工作", () => {
|
||
expect(mergeClass("foo")).toEqual({ foo: true });
|
||
});
|
||
|
||
it("应处理空字符串参数", () => {
|
||
expect(mergeClass("")).toEqual({});
|
||
});
|
||
|
||
it("应处理空数组参数", () => {
|
||
expect(mergeClass([])).toEqual({});
|
||
});
|
||
|
||
it("应处理空对象参数", () => {
|
||
expect(mergeClass({})).toEqual({});
|
||
});
|
||
|
||
it("应合并多个对象类名", () => {
|
||
expect(
|
||
mergeClass({ color: true }, { size: true }, { weight: true }),
|
||
).toEqual({ color: true, size: true, weight: true });
|
||
});
|
||
|
||
it("实际使用场景:Vue 组件中合并 class", () => {
|
||
// 模拟组件内部 class + 传入 class
|
||
const internal = "btn primary";
|
||
const custom = { active: true, disabled: false };
|
||
expect(mergeClass(internal, custom)).toEqual({
|
||
btn: true,
|
||
primary: true,
|
||
active: true,
|
||
disabled: false,
|
||
});
|
||
});
|
||
});
|