const fs = require('fs'); const path = require('path'); let passed = 0; let failed = 0; function assert(condition, testName, detail = '') { if (condition) { console.log(` [PASS] ${testName}`); passed++; } else { console.error(` [FAIL] ${testName} - ${detail}`); failed++; } } console.log("========================================================"); console.log(" 马豆实时动态汇率、首单步进对齐与精度自适应自动化测试"); console.log("========================================================\n"); // 1. RateService 实时汇率与缓存解耦验证 const rateServicePath = path.resolve(__dirname, '../addons/shopro/service/partner/RateService.php'); assert(fs.existsSync(rateServicePath), 'RateService.php 文件存在'); const rateServiceContent = fs.readFileSync(rateServicePath, 'utf-8'); assert( !rateServiceContent.includes("RateLog::order('id', 'desc')->find()"), 'currentRate() 已移除日结历史快照死锁逻辑,不再永久返回旧汇率' ); assert( rateServiceContent.includes('currentRate($forceRefresh = false)'), 'currentRate() 支持 $forceRefresh 参数穿透短缓存实时重算' ); assert( rateServiceContent.includes('public static function clearCache()'), 'RateService 包含 clearCache() 静态方法支持外部主动刷新' ); assert( rateServiceContent.includes('$multiple = max(1, floor($n / $step))'), 'calcRate() 算法严谨保留起步下限保底与线性步进' ); // 2. 订单支付监听器联动验证 const listenerPath = path.resolve(__dirname, '../addons/shopro/listener/Partner.php'); assert(fs.existsSync(listenerPath), 'Partner.php 监听器存在'); const listenerContent = fs.readFileSync(listenerPath, 'utf-8'); assert( listenerContent.includes('RateService::clearCache()'), '合格订单支付成功后自动调用 RateService::clearCache() 触发实时汇率联动' ); // 3. IdentityService 马豆格式化与精度优化验证 const identityPath = path.resolve(__dirname, '../addons/shopro/service/partner/IdentityService.php'); assert(fs.existsSync(identityPath), 'IdentityService.php 存在'); const identityContent = fs.readFileSync(identityPath, 'utf-8'); assert( identityContent.includes("number_format((float) $value, 0, '.', '')"), 'formatMadow() 保持历史纯整数输出契约' ); assert( identityContent.includes('$floatVal > 0 && $floatVal < 1'), 'formatMadow() 具备小于 1 豆的小数自适应保留能力,杜绝分润到账显示为 0 豆' ); // 4. 用户端 madow.vue 界面精度与兜底验证 const madowVuePath = path.resolve(__dirname, '../uniapp/pages/commission/madow.vue'); assert(fs.existsSync(madowVuePath), 'madow.vue 存在'); const madowVueContent = fs.readFileSync(madowVuePath, 'utf-8'); assert( madowVueContent.includes('formatInt') && madowVueContent.includes('num > 0 && num < 1'), 'madow.vue 中的 formatInt 支持微量小数自适应显示' ); assert( madowVueContent.includes('<0.01'), 'madow.vue 对微小市值(<0.01元)具备友好的 <0.01 优雅兜底展示' ); // 5. 纯算法逻辑与数值模拟测试 function calcRateSim(n, base = 0.00000075, step = 1) { const multiple = Math.max(1, Math.floor(n / step)); return Number((base * multiple).toFixed(10)); } assert(calcRateSim(0) === 0.00000075, '模拟测试:N=0 单时保底输出基准汇率 0.00000075'); assert(calcRateSim(1) === 0.00000075, '模拟测试:N=1 单时等于 0.00000075'); assert(calcRateSim(2) === 0.0000015, '模拟测试:N=2 单时递增至 0.00000150'); assert(calcRateSim(10000) === 0.0075, '模拟测试:N=10,000 单时精确达到 0.0075 元/豆'); function formatMadowSim(val) { const num = parseFloat(val) || 0; if (num > 0 && num < 1) { return parseFloat(num.toFixed(4)).toString(); } return String(Math.floor(num)); } assert(formatMadowSim(0.85) === '0.85', '模拟测试:0.85 豆自适应显示为 0.85'); assert(formatMadowSim(0.005) === '0.005', '模拟测试:0.005 豆自适应显示为 0.005'); assert(formatMadowSim(100) === '100', '模拟测试:100 豆整洁显示为 100'); assert(formatMadowSim(0) === '0', '模拟测试:0 豆整洁显示为 0'); console.log("\n--------------------------------------------------------"); console.log(`测试执行结果: 通过 ${passed} 项, 失败 ${failed} 项`); console.log("========================================================\n"); if (failed > 0) { process.exit(1); }