/** * Field 装饰器兼容性测试 * * 目的:验证 @Field 系列装饰器与 @AuditField 的元数据兼容性 * * 测试点: * 1. 元数据键是否一致 * 2. 元数据结构是否兼容 * 3. 格式化函数是否正确存储 * 4. 敏感字段标记是否正确传递 */ import 'reflect-metadata'; import { StringField, NumberField, BooleanField, EnumField } from './dist/decorators/field.decorators'; // 模拟枚举 const OrderStatus = { PENDING: 'pending', PROCESSING: 'processing', SHIPPED: 'shipped', DELIVERED: 'delivered', CANCELLED: 'cancelled', }; /** * 测试实体 - 使用新的 @Field 装饰器 */ class TestOrderEntity { @StringField({ fieldLabel: { zh: '订单号', en: 'Order Number' }, }) orderNumber: string; @StringField({ fieldLabel: { zh: '客户邮箱', en: 'Customer Email' }, sensitive: true, displayFormatter: (value: string) => { if (!value) return ''; const [local, domain] = value.split('@'); if (!domain) return value; return `${local.substring(0, 3)}***@${domain}`; }, }) customerEmail: string; @NumberField({ fieldLabel: { zh: '总金额', en: 'Total Amount' }, sensitive: true, displayFormatter: (value: number) => `¥${parseFloat(value as any).toFixed(2)}`, }) totalAmount: number; @EnumField( () => OrderStatus, { fieldLabel: { zh: '订单状态', en: 'Order Status' }, valueLabels: { pending: { zh: '待处理', en: 'Pending' }, processing: { zh: '处理中', en: 'Processing' }, shipped: { zh: '已发货', en: 'Shipped' }, delivered: { zh: '已送达', en: 'Delivered' }, cancelled: { zh: '已取消', en: 'Cancelled' }, }, }, ) status: string; @BooleanField({ fieldLabel: { zh: '是否已支付', en: 'Is Paid' }, valueLabels: { true: { zh: '已支付', en: 'Paid' }, false: { zh: '未支付', en: 'Unpaid' }, }, }) isPaid: boolean; } /** * 测试函数 */ function testFieldDecoratorCompatibility() { console.log('=== @Field 装饰器兼容性测试 ===\n'); // 1. 测试元数据键 console.log('1. 测试元数据键'); const AUDIT_FIELD_OPTIONS_KEY = 'FIELD_AUDIT_OPTIONS'; const metadata = Reflect.getMetadata(AUDIT_FIELD_OPTIONS_KEY, TestOrderEntity); if (metadata) { console.log(' ✓ 元数据键正确: "FIELD_AUDIT_OPTIONS"'); console.log(` ✓ 找到 ${Object.keys(metadata).length} 个字段的元数据`); } else { console.log(' ✗ 未找到元数据'); return false; } // 2. 测试字段标签映射 console.log('\n2. 测试字段标签映射'); const orderNumberMeta = metadata['orderNumber']; if (orderNumberMeta && orderNumberMeta.label) { console.log(' ✓ orderNumber.label:', orderNumberMeta.label); } else { console.log(' ✗ orderNumber 元数据不完整'); return false; } // 3. 测试敏感字段标记 console.log('\n3. 测试敏感字段标记'); const emailMeta = metadata['customerEmail']; if (emailMeta && emailMeta.sensitive) { console.log(' ✓ customerEmail.sensitive:', emailMeta.sensitive); } else { console.log(' ✗ customerEmail sensitive 标记未找到'); return false; } // 4. 测试格式化函数 console.log('\n4. 测试格式化函数'); if (emailMeta && typeof emailMeta.formatter === 'function') { const testEmail = 'zhangsan@example.com'; const formatted = emailMeta.formatter(testEmail); console.log(' ✓ customerEmail.formatter:', formatted); console.log(' 原始值:', testEmail); } else { console.log(' ✗ customerEmail formatter 未找到'); return false; } const amountMeta = metadata['totalAmount']; if (amountMeta && typeof amountMeta.formatter === 'function') { const formatted = amountMeta.formatter(99.99); console.log(' ✓ totalAmount.formatter:', formatted); } else { console.log(' ✗ totalAmount formatter 未找到'); return false; } // 5. 测试值标签映射 console.log('\n5. 测试值标签映射'); const statusMeta = metadata['status']; if (statusMeta && statusMeta.valueLabels) { console.log(' ✓ status.valueLabels:', JSON.stringify(statusMeta.valueLabels, null, 2)); } else { console.log(' ✗ status valueLabels 未找到'); return false; } // 6. 测试布尔字段的值标签 console.log('\n6. 测试布尔字段值标签'); const isPaidMeta = metadata['isPaid']; if (isPaidMeta && isPaidMeta.valueLabels) { console.log(' ✓ isPaid.valueLabels:', JSON.stringify(isPaidMeta.valueLabels, null, 2)); } else { console.log(' ✗ isPaid valueLabels 未找到'); return false; } // 7. 完整元数据结构验证 console.log('\n7. 完整元数据结构验证'); console.log(' customerEmail 元数据结构:'); console.log(' ', JSON.stringify({ label: emailMeta.label, description: emailMeta.description, formatter: typeof emailMeta.formatter, sensitive: emailMeta.sensitive, }, null, 2)); console.log('\n=== 所有测试通过 ✓ ===\n'); return true; } // 运行测试 try { testFieldDecoratorCompatibility(); } catch (error) { console.error('测试失败:', error); process.exit(1); }