UNPKG

default-template

Version:

一个用于定义默认值和转换对象结构的实用工具

270 lines (269 loc) 14.9 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; Object.defineProperty(exports, "__esModule", { value: true }); /// <reference types="vitest" /> const vitest_1 = require("vitest"); const index_1 = __importStar(require("./index")); (0, vitest_1.describe)('defaultTemplate', () => { (0, vitest_1.it)('基本类型:undefined/null 返回默认值', () => { const result1 = (0, index_1.default)(10, undefined); console.log('基本类型:undefined/null 返回默认值', result1); (0, vitest_1.expect)(result1).toBe(10); const result2 = (0, index_1.default)(10, null); console.log('基本类型:undefined/null 返回默认值', result2); (0, vitest_1.expect)(result2).toBe(10); const result3 = (0, index_1.default)(false, undefined); console.log('基本类型:undefined/null 返回默认值', result3); (0, vitest_1.expect)(result3).toBe(false); const result4 = (0, index_1.default)('', undefined); console.log('基本类型:undefined/null 返回默认值', result4); (0, vitest_1.expect)(result4).toBe(''); }); (0, vitest_1.it)('基本类型:类型自动转换', () => { const result1 = (0, index_1.default)(10, '20'); console.log('基本类型:类型自动转换', result1); (0, vitest_1.expect)(result1).toBe(20); const result2 = (0, index_1.default)(false, 'true'); console.log('基本类型:类型自动转换', result2); (0, vitest_1.expect)(result2).toBe(true); const result3 = (0, index_1.default)(false, 'false'); console.log('基本类型:类型自动转换', result3); (0, vitest_1.expect)(result3).toBe(false); const result4 = (0, index_1.default)('', 123); console.log('基本类型:类型自动转换', result4); (0, vitest_1.expect)(result4).toBe('123'); const result5 = (0, index_1.default)(BigInt(1), '2'); console.log('基本类型:类型自动转换', result5); (0, vitest_1.expect)(result5).toBe('2'); // bigint 作为模板时,字符串原样返回 const result6 = (0, index_1.default)(Symbol('a'), Symbol('b')); console.log('基本类型:类型自动转换', typeof result6); (0, vitest_1.expect)(typeof result6).toBe('symbol'); }); (0, vitest_1.it)('基本类型:function 作为模板', () => { const fn = (x) => (typeof x === 'number' ? x * 2 : 0); let result = (0, index_1.default)(fn, 5); console.log('基本类型:function 作为模板', result); (0, vitest_1.expect)(result).toBe(10); result = (0, index_1.default)(fn, undefined); console.log('基本类型:function 作为模板', result); (0, vitest_1.expect)(result).toBe(0); }); (0, vitest_1.it)('基本类型:Date 作为模板', () => { const d = new Date('2020-01-01'); const d2 = new Date('2022-01-01'); let result = (0, index_1.default)(d, d2); console.log('基本类型:Date 作为模板', result); (0, vitest_1.expect)(result).toBe(d2); result = (0, index_1.default)(d, undefined); console.log('基本类型:Date 作为模板', result); (0, vitest_1.expect)(result).toBe(d); }); (0, vitest_1.it)('基本类型:原样返回', () => { let result = (0, index_1.default)(null, 10); console.log('基本类型:原样返回', result); (0, vitest_1.expect)(result).toBe(10); result = (0, index_1.default)(null, '10'); console.log('基本类型:原样返回', result); (0, vitest_1.expect)(result).toBe('10'); result = (0, index_1.default)(null, { a: 1 }); console.log('基本类型:原样返回', result); (0, vitest_1.expect)(result).toEqual({ a: 1 }); }); (0, vitest_1.it)('数组:元素模板', () => { const result1 = (0, index_1.default)([10], [null, '20', 20]); console.log('数组:元素模板', result1); (0, vitest_1.expect)(result1).toEqual([10, 20, 20]); const result2 = (0, index_1.default)([false], [1, 0, 'false']); console.log('数组:元素模板', result2); (0, vitest_1.expect)(result2).toEqual([true, false, false]); const result3 = (0, index_1.default)([{ a: 1 }], [{ a: 2, b: 3 }, { a: '3', b: 4 }]); console.log('数组:元素模板', result3); // 只保留模板字段 a (0, vitest_1.expect)(result3).toEqual([{ a: 2 }, { a: 3 }]); }); (0, vitest_1.it)('数组:嵌套数组', () => { const result = (0, index_1.default)([[0]], [[1, 2], [3, null]]); console.log('数组:嵌套数组', result); (0, vitest_1.expect)(result).toEqual([[1, 2], [3, 0]]); }); (0, vitest_1.it)('数组:空模板数组', () => { let result = (0, index_1.default)([], [1, 2, 3]); console.log('数组:空模板数组', result); (0, vitest_1.expect)(result).toEqual([1, 2, 3]); result = (0, index_1.default)([], undefined); console.log('数组:空模板数组', result); (0, vitest_1.expect)(result).toEqual([]); }); (0, vitest_1.it)('对象:基础对象模板', () => { const result = (0, index_1.default)({ a: 10, b: false, c: 20 }, { a: '20', b: null, d: 'test' }); console.log('对象:基础对象模板', result); (0, vitest_1.expect)(result).toEqual({ a: 20, b: false, c: 20 }); }); (0, vitest_1.it)('对象:深层嵌套对象', () => { const def = { a: { b: { c: 1 } } }; const src = { a: { b: { c: '2', d: 3 }, e: 4 } }; const result = (0, index_1.default)(def, src); console.log('对象:深层嵌套对象', result); (0, vitest_1.expect)(result).toEqual({ a: { b: { c: 2 } } }); }); (0, vitest_1.it)('对象:通配符模板', () => { const result1 = (0, index_1.default)({ '?': true }, { x: null, y: false }); console.log('对象:通配符模板', result1); (0, vitest_1.expect)(result1).toEqual({ x: true, y: false }); const result2 = (0, index_1.default)({ a: 1, '?': 0 }, { a: 2, b: '3', c: null }); console.log('对象:通配符模板', result2); (0, vitest_1.expect)(result2).toEqual({ a: 2, b: 3, c: 0 }); }); (0, vitest_1.it)('对象:通配符与显式key混用', () => { const result = (0, index_1.default)({ a: 1, '?': 2 }, { a: undefined, b: 3 }); console.log('对象:通配符与显式key混用', result); (0, vitest_1.expect)(result).toEqual({ a: 1, b: 3 }); }); (0, vitest_1.it)('对象:自定义通配符键名', () => { const result = (0, index_1.default)({ '*': 1 }, { a: null, b: 2 }, { allTemplateKey: '*' }); console.log('对象:自定义通配符键名', result); (0, vitest_1.expect)(result).toEqual({ a: 1, b: 2 }); }); (0, vitest_1.it)('对象:空对象模板', () => { let result = (0, index_1.default)({}, { a: 1 }); console.log('对象:空对象模板', result); (0, vitest_1.expect)(result).toEqual({}); result = (0, index_1.default)({}, {}); console.log('对象:空对象模板', result); (0, vitest_1.expect)(result).toEqual({}); }); (0, vitest_1.it)('对象:嵌套结构', () => { const def = { user: { name: '', age: 0, tags: [''] }, active: false }; const src = { user: { name: '张三', age: '18', tags: [null, 'vip'] }, active: 'true', extra: 123 }; const result = (0, index_1.default)(def, src); console.log('对象:嵌套结构', result); (0, vitest_1.expect)(result).toEqual({ user: { name: '张三', age: 18, tags: ['', 'vip'] }, active: true }); }); (0, vitest_1.it)('对象:键名映射', () => { const def = { id: 0, name: new index_1.TemplateRename('username', '') }; const src = { id: 1, name: '张三' }; const result = (0, index_1.default)(def, src); console.log('对象:键名映射', result); (0, vitest_1.expect)(result).toEqual({ id: 1, username: '张三' }); }); (0, vitest_1.it)('对象:键名映射为函数', () => { const def = { foo: new index_1.TemplateRename(k => 'bar_' + k, 1) }; const src = { foo: 2 }; const result = (0, index_1.default)(def, src); console.log('对象:键名映射为函数', result); (0, vitest_1.expect)(result).toEqual({ bar_foo: 2 }); }); (0, vitest_1.it)('对象:TemplateRename 嵌套', () => { const def = { a: new index_1.TemplateRename('b', new index_1.TemplateRename('c', 1)) }; const src = { a: 2 }; const result = (0, index_1.default)(def, src); console.log('对象:TemplateRename 嵌套', result); (0, vitest_1.expect)(result).toEqual({ c: 2 }); }); (0, vitest_1.it)('自定义处理函数', () => { const result1 = (0, index_1.default)((data) => Array.isArray(data) ? data.length : 0, [1, 2, 3]); console.log('自定义处理函数', result1); (0, vitest_1.expect)(result1).toBe(3); const result2 = (0, index_1.default)((data) => typeof data === 'string' ? data.toUpperCase() : '', 'abc'); console.log('自定义处理函数', result2); (0, vitest_1.expect)(result2).toBe('ABC'); // 测试 owner 参数 const result3 = (0, index_1.default)((data, owner) => owner && owner.flag ? 1 : 0, 5, undefined); console.log('自定义处理函数', result3); (0, vitest_1.expect)(result3).toBe(0); const result4 = (0, index_1.default)((data, owner) => owner && owner.flag ? 1 : 0, 5, undefined); console.log('自定义处理函数', result4); (0, vitest_1.expect)(result4).toBe(0); const result5 = (0, index_1.default)((data, owner) => owner && owner.flag ? 1 : 0, 5, undefined); console.log('自定义处理函数', result5); (0, vitest_1.expect)(result5).toBe(0); }); (0, vitest_1.it)('边界:模板为 null/undefined', () => { const result1 = (0, index_1.default)(null, 123); console.log('边界:模板为 null/undefined', result1); (0, vitest_1.expect)(result1).toBe(123); const result2 = (0, index_1.default)(undefined, 456); console.log('边界:模板为 null/undefined', result2); (0, vitest_1.expect)(result2).toBe(456); }); (0, vitest_1.it)('边界:src 为 null/undefined', () => { const result1 = (0, index_1.default)(1, null); console.log('边界:src 为 null/undefined', result1); (0, vitest_1.expect)(result1).toBe(1); const result2 = (0, index_1.default)({ a: 1 }, null); console.log('边界:src 为 null/undefined', result2); (0, vitest_1.expect)(result2).toEqual({ a: 1 }); const result3 = (0, index_1.default)([1], null); console.log('边界:src 为 null/undefined', result3); (0, vitest_1.expect)(result3).toEqual([]); }); (0, vitest_1.it)('边界:对象模板未声明的字段被删除', () => { const result = (0, index_1.default)({ a: 1 }, { a: 2, b: 3 }); console.log('边界:对象模板未声明的字段被删除', result); (0, vitest_1.expect)(result).toEqual({ a: 2 }); }); (0, vitest_1.it)('边界:数组模板长度为0', () => { let result = (0, index_1.default)([], [1, 2, 3]); console.log('边界:数组模板长度为0', result); (0, vitest_1.expect)(result).toEqual([1, 2, 3]); result = (0, index_1.default)([], undefined); console.log('边界:数组模板长度为0', result); (0, vitest_1.expect)(result).toEqual([]); }); (0, vitest_1.it)('极端情况:模板和数据都为 undefined/null/空', () => { const result1 = (0, index_1.default)(undefined, undefined); console.log('极端情况:模板和数据都为 undefined/null/空', result1); (0, vitest_1.expect)(result1).toBe(undefined); const result2 = (0, index_1.default)(null, null); console.log('极端情况:模板和数据都为 undefined/null/空', result2); (0, vitest_1.expect)(result2).toBe(null); const result3 = (0, index_1.default)({}, undefined); console.log('极端情况:模板和数据都为 undefined/null/空', result3); (0, vitest_1.expect)(result3).toEqual({}); const result4 = (0, index_1.default)([], undefined); console.log('极端情况:模板和数据都为 undefined/null/空', result4); (0, vitest_1.expect)(result4).toEqual([]); }); (0, vitest_1.it)('异常输入:模板为非对象/数组/基本类型/函数', () => { const result1 = (0, index_1.default)(new Set([1]), [1]); console.log('异常输入:模板为非对象/数组/基本类型/函数', result1); (0, vitest_1.expect)(result1).toEqual(new Set([1])); const result2 = (0, index_1.default)(new Map([[1, 2]]), { a: 1 }); console.log('异常输入:模板为非对象/数组/基本类型/函数', result2); (0, vitest_1.expect)(result2).toEqual(new Map([[1, 2]])); }); (0, vitest_1.it)('泛型推断:类型安全', () => { const def = { id: 0, name: '', active: false }; const user = (0, index_1.default)(def, { id: '1', name: '张三', active: 'true' }); console.log('泛型推断:类型安全', user); (0, vitest_1.expect)(user).toEqual({ id: 1, name: '张三', active: true }); }); (0, vitest_1.it)('数组模板:字段补全', () => { const result = (0, index_1.default)([{ min: 0 }], [{ val: -1 }, { val: 5 }]); console.log('数组模板:字段补全', result); // 只保留模板字段 min (0, vitest_1.expect)(result).toEqual([{ min: 0 }, { min: 0 }]); }); });