Files
everything-is-suitable/scripts/test-daily-push-algorithm.mjs
zhangxiang 17ada52928 chore: 更新依赖配置与测试工具
- 添加 uni-cloud 等云开发依赖
- 更新 vitest 测试配置,支持云函数 mock
- 扩展 uni-app mock 支持云函数调用
- 添加每日推送算法测试脚本
2026-08-13 08:06:28 +08:00

160 lines
5.2 KiB
JavaScript

#!/usr/bin/env node
/**
* _algorithm.js 功能测试
* 验证 dailyPush 云函数中运势算法的正确性
* 用法: node scripts/test-daily-push-algorithm.mjs
*/
import { createRequire } from 'module'
import { strict as assert } from 'assert'
const require = createRequire(import.meta.url)
const algo = require('../everything-is-suitable-uniapp/cloudfunctions/dailyPush/_algorithm.js')
let passed = 0
let failed = 0
function test(name, fn) {
try {
fn()
passed++
console.log(` ✅ ${name}`)
} catch (e) {
failed++
console.log(` ❌ ${name}: ${e.message}`)
}
}
console.log('🧪 _algorithm.js 功能测试\n')
// ===== 测试数据 =====
const birthInfo = {
birthDate: '1990-06-15',
birthHour: 8,
birthMinute: 30,
birthPlace: '北京',
longitude: 116.4,
latitude: 39.9,
gender: 'male',
}
const testDate = new Date('2026-08-13T07:00:00')
// ===== 测试用例 =====
console.log('--- generatePushContent ---')
const content = algo.generatePushContent(birthInfo, testDate)
test('应返回包含 overallScore 且 0-100 之间', () => {
assert.ok(content.overallScore >= 0 && content.overallScore <= 100, `Score ${content.overallScore} out of range`)
})
test('应返回 overallLuck 字符串', () => {
assert.ok(typeof content.overallLuck === 'string' && content.overallLuck.length > 0)
})
test('应返回四个维度的建议', () => {
assert.ok(content.careerAdvice.includes('事业'))
assert.ok(content.wealthAdvice.includes('财运'))
assert.ok(content.relationshipAdvice.includes('感情'))
assert.ok(content.healthAdvice.includes('健康'))
})
test('应返回 luckyColor', () => {
const colors = ['红色', '黄色', '蓝色', '绿色', '紫色', '金色', '白色', '黑色']
assert.ok(colors.includes(content.luckyColor), `Unexpected color: ${content.luckyColor}`)
})
test('应返回 luckyNumber (1-9)', () => {
const num = parseInt(content.luckyNumber)
assert.ok(num >= 1 && num <= 9, `Lucky number ${num} out of range`)
})
console.log('\n--- determineLuckLevel ---')
test('90分以上应返回大吉', () => {
assert.equal(algo.determineLuckLevel(95), '大吉')
})
test('80-89分应返回吉', () => {
assert.equal(algo.determineLuckLevel(85), '吉')
})
test('70-79分应返回中吉', () => {
assert.equal(algo.determineLuckLevel(75), '中吉')
})
test('60-69分应返回平', () => {
assert.equal(algo.determineLuckLevel(65), '平')
})
test('50-59分应返回中平', () => {
assert.equal(algo.determineLuckLevel(55), '中平')
})
test('40-49分应返回小凶', () => {
assert.equal(algo.determineLuckLevel(45), '小凶')
})
test('40分以下应返回凶', () => {
assert.equal(algo.determineLuckLevel(30), '凶')
})
console.log('\n--- calculateLuckyColor ---')
test('幸运色应在颜色列表中', () => {
const colors = ['红色', '黄色', '蓝色', '绿色', '紫色', '金色', '白色', '黑色']
const color = algo.calculateLuckyColor(birthInfo, testDate)
assert.ok(colors.includes(color), `Unexpected color: ${color}`)
})
test('同生日的不同日期幸运色可能不同', () => {
const color1 = algo.calculateLuckyColor(birthInfo, new Date('2026-08-13'))
const color2 = algo.calculateLuckyColor(birthInfo, new Date('2026-08-14'))
// 不同日期可能不同,但不强制,仅用于验证不报错
assert.ok(typeof color1 === 'string')
assert.ok(typeof color2 === 'string')
})
console.log('\n--- calculateLuckyNumber ---')
test('幸运数字应为1-9之间的字符串', () => {
const num = algo.calculateLuckyNumber(birthInfo, testDate)
assert.ok(/^[1-9]$/.test(num), `Invalid lucky number: ${num}`)
})
console.log('\n--- 边界测试 ---')
test('birthHour 为 0 时也应正常工作', () => {
const info = { ...birthInfo, birthHour: 0 }
const result = algo.generatePushContent(info, testDate)
assert.ok(result.overallScore >= 0 && result.overallScore <= 100)
})
test('birthDate 不含日期的也应工作', () => {
const info = { ...birthInfo, birthDate: '1990-06' }
const result = algo.generatePushContent(info, testDate)
assert.ok(result.overallScore >= 0 && result.overallScore <= 100)
})
test('不同生辰应产生不同运势结果', () => {
const info1 = { birthDate: '1990-01-01', birthHour: 0, gender: 'male' }
const info2 = { birthDate: '2000-12-31', birthHour: 23, gender: 'female' }
const r1 = algo.generatePushContent(info1, testDate)
const r2 = algo.generatePushContent(info2, testDate)
// 不同生辰的结果可能相同(算法确定),但应正常返回
assert.ok(r1.overallScore >= 0 && r1.overallScore <= 100)
assert.ok(r2.overallScore >= 0 && r2.overallScore <= 100)
})
console.log('\n--- 整体结果示例 ---')
console.log(` 综合评分: ${content.overallScore}`)
console.log(` 运势等级: ${content.overallLuck}`)
console.log(` 事业: ${content.careerAdvice}`)
console.log(` 财运: ${content.wealthAdvice}`)
console.log(` 感情: ${content.relationshipAdvice}`)
console.log(` 健康: ${content.healthAdvice}`)
console.log(` 幸运色: ${content.luckyColor}`)
console.log(` 幸运数字: ${content.luckyNumber}`)
// ===== 结果汇总 =====
console.log(`\n${'='.repeat(40)}`)
console.log(`总测试: ${passed + failed} | 通过: ${passed} | 失败: ${failed}`)
console.log(`${'='.repeat(40)}`)
process.exit(failed > 0 ? 1 : 0)