Files
hera-web/scripts/homeOverview.test.cjs

111 lines
5.8 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
const test = require('node:test')
const assert = require('node:assert/strict')
const fs = require('node:fs')
const path = require('node:path')
const Module = require('node:module')
const ts = require('typescript')
const { Solar } = require('lunar-typescript')
const cache = {}
function load(name) {
if (cache[name]) return cache[name].exports
const filename = path.resolve(__dirname, `../src/utils/${name}.ts`)
const loaded = new Module(filename, module)
cache[name] = loaded
loaded.filename = filename
loaded.paths = Module._nodeModulePaths(path.dirname(filename))
const original = loaded.require.bind(loaded)
loaded.require = (id) => id.startsWith('./') ? load(id.slice(2)) : original(id)
loaded._compile(ts.transpileModule(fs.readFileSync(filename, 'utf8'), { compilerOptions: { module: ts.ModuleKind.CommonJS, target: ts.ScriptTarget.ES2017 } }).outputText, filename)
return loaded.exports
}
const { generateHomeOverview: generate, normalizeDimensionOrder, HOME_DIMENSION_IDS } = load('homeOverview')
const profile = { birthday: '1998-06-18', birthHour: '辰时' }
test('昨日今日明日整体切换,公历星期农历均来自实际所选日期', () => {
const reports = [-1, 0, 1].map((offset) => generate(profile, '2026-10-15', offset))
assert.deepEqual(reports.map((item) => item.activeDay), ['昨日', '今日', '明日'])
assert.deepEqual(reports.map((item) => item.date), ['2026-10-14', '2026-10-15', '2026-10-16'])
reports.forEach((report) => {
const [y, m, d] = report.date.split('-').map(Number)
const solar = Solar.fromYmd(y, m, d)
const lunar = solar.getLunar()
assert.equal(report.weekName, `星期${'日一二三四五六'[solar.getWeek()]}`)
assert.equal(report.lunarDate, `农历${lunar.getYearInGanZhi()}年 ${lunar.getMonthInChinese()}月${lunar.getDayInChinese()}`)
assert.equal(report.luckyDirection, lunar.getDayPositionXiDesc())
assert.equal(report.days.find((day) => day.label === report.activeDay).status, report.status)
})
assert.notDeepEqual(reports[0].dimensions, reports[1].dimensions)
assert.notDeepEqual(reports[1].dimensions, reports[2].dimensions)
})
test('八维评分有界,宜忌与评分一致,综合指数可复算', () => {
for (let day = 1; day <= 31; day++) {
const report = generate(profile, `2026-10-${String(day).padStart(2, '0')}`)
assert.equal(report.dimensions.length, 8)
assert.equal(new Set(report.dimensions.map((item) => item.id)).size, 8)
report.dimensions.forEach((item) => {
assert.ok(item.score >= 15 && item.score <= 90)
assert.equal(item.suitable, item.score >= 50)
assert.ok(item.headline && item.detail)
})
assert.equal(report.overallIndex, Math.round(report.dimensions.reduce((sum, item) => sum + item.score, 0) / 8))
assert.equal(report.status, report.overallIndex >= 80 ? '大吉' : report.overallIndex >= 65 ? '小吉' : report.overallIndex >= 50 ? '平日' : report.overallIndex >= 35 ? '小逆' : '谨慎')
assert.equal(report.luckyColors.length, 2)
assert.equal(new Set(report.luckyNumbers).size, 2)
}
})
test('吉时仅取所选当日的吉时片段,不越过日期边界且时支不重复', () => {
for (let day = 1; day <= 31; day++) {
const report = generate(profile, `2026-10-${String(day).padStart(2, '0')}`)
const times = Solar.fromYmd(2026, 10, day).getLunar().getTimes()
assert.ok(report.luckyHours.length > 0 && report.luckyHours.length <= 2)
assert.equal(new Set(report.luckyHours.map((hour) => hour.branch)).size, report.luckyHours.length)
report.luckyHours.forEach(({ branch, time }) => {
const [start, end] = time.split('–')
const match = times.find((hour) => hour.getZhi() === branch && hour.getMinHm() === start)
assert.ok(match)
assert.equal(match.getTianShenLuck(), '吉')
assert.ok(end <= '24:00')
assert.ok(start < end)
})
}
})
test('日期、生日、时辰影响报告;相同输入稳定且不读取后端报告', () => {
const first = generate(profile, '2026-10-15')
assert.deepEqual(first, generate({ ...profile, elementReport: { invalid: true } }, '2026-10-15'))
assert.notDeepEqual(first, generate({ birthday: '1999-11-06', birthHour: '辰时' }, '2026-10-15'))
let changedHour = false
for (const hour of ['子时', '卯时', '午时', '戌时']) {
if (JSON.stringify(generate({ ...profile, birthHour: hour }, '2026-10-15')) !== JSON.stringify(first)) changedHour = true
}
assert.equal(changedHour, true)
})
test('跨月、跨年与非法日期安全处理,不回退为固定42分报告', () => {
assert.equal(generate(profile, '2026-01-01', -1).date, '2025-12-31')
assert.equal(generate(profile, '2026-12-31', 1).date, '2027-01-01')
assert.equal(generate(profile, '2024-03-01', -1).date, '2024-02-29')
for (const date of ['', '2026-02-30', '2026-13-01']) assert.equal(generate(profile, date), null)
assert.equal(generate({ birthday: '', birthHour: '' }, '2026-10-15'), null)
assert.equal(generate(profile, '2026-10-15', 2), null)
})
test('排序兼容缺失、重复、旧字段和损坏存储,保留八个维度', () => {
assert.deepEqual(normalizeDimensionOrder(null), HOME_DIMENSION_IDS)
assert.deepEqual(normalizeDimensionOrder('bad'), HOME_DIMENSION_IDS)
const order = normalizeDimensionOrder(['travel', 'travel', 'removed', 'wealth', null])
assert.deepEqual(order.slice(0, 2), ['travel', 'wealth'])
assert.equal(order.length, 8)
assert.equal(new Set(order).size, 8)
})
test('首页八个维度、头像与天宫图标资产存在', () => {
for (const icon of ['heart', 'gourd', 'vase', 'coin', 'fan', 'scroll', 'bamboo', 'horse', 'water', 'spirit']) {
const data = fs.readFileSync(path.resolve(__dirname, `../src/assets/home/${icon}.png`))
assert.equal(data.subarray(1, 4).toString(), 'PNG')
assert.equal(data.readUInt32BE(16), 256)
}
})