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 originalRequire = loaded.require.bind(loaded) loaded.require = (id) => id === './zodiac' ? load('zodiac') : originalRequire(id) loaded._compile(ts.transpileModule(fs.readFileSync(filename, 'utf8'), { compilerOptions: { module: ts.ModuleKind.CommonJS, target: ts.ScriptTarget.ES2017 } }).outputText, filename) return loaded.exports } const { getBeijingDate, getZodiacRelation, calculateWeeklyZodiacFortune: weekly } = load('zodiacWeekly') test('合冲表对称,12生肖均覆盖1六合、2三合、1六冲、1相害', () => { const branches = [...'子丑寅卯辰巳午未申酉戌亥'] for (const first of branches) { const counts = {} for (const second of branches) { const relation = getZodiacRelation(first, second) assert.equal(relation, getZodiacRelation(second, first)) counts[relation] = (counts[relation] || 0) + 1 } assert.deepEqual(counts, { 平常: 7, 六合: 1, 三合: 2, 六冲: 1, 相害: 1 }) assert.equal(getZodiacRelation(first, first), '平常') } assert.equal(getZodiacRelation('子', '丑'), '六合') assert.equal(getZodiacRelation('寅', '午'), '三合') assert.equal(getZodiacRelation('子', '午'), '六冲') assert.equal(getZodiacRelation('子', '未'), '相害') assert.throws(() => getZodiacRelation('鼠', '子')) }) test('北京时间零点边界、周一到周日及跨年周正确', () => { assert.equal(getBeijingDate(new Date('2026-10-18T15:59:59Z')), '2026-10-18') assert.equal(getBeijingDate(new Date('2026-10-18T16:00:00Z')), '2026-10-19') assert.equal(getBeijingDate(new Date('invalid')), '') const monday = weekly('1998-06-18', '2026-10-12') const sunday = weekly('1998-06-18', '2026-10-18') assert.deepEqual(monday, sunday) assert.equal(monday.weekStart, '2026-10-12') assert.equal(monday.weekEnd, '2026-10-18') assert.equal(weekly('1998-06-18', '2026-10-19').weekStart, '2026-10-19') const newYear = weekly('1998-06-18', '2027-01-01') assert.equal(newYear.weekStart, '2026-12-28') assert.equal(newYear.weekEnd, '2027-01-03') }) test('逐日分值与周状态可复算,日期不遗漏、不重复,状态有差异', () => { const statuses = new Set() const date = '2026-10-15' for (let year = 2008; year < 2020; year++) { const report = weekly(`${year}-06-15`, date) assert.equal(report.days.length, 7) assert.equal(new Set(report.days.map((day) => day.date)).size, 7) const weights = { 六合: 2, 三合: 1, 六冲: -2, 相害: -1, 平常: 0 } report.days.forEach((day) => { const [y, m, d] = day.date.split('-').map(Number) assert.equal(day.branch, Solar.fromYmd(y, m, d).getLunar().getDayZhi()) assert.equal(day.relation, getZodiacRelation(report.branch, day.branch)) assert.equal(day.score, weights[day.relation]) }) assert.equal(report.score, report.days.reduce((sum, day) => sum + day.score, 0)) assert.equal(report.status, report.score >= 2 ? '顺势' : report.score <= -2 ? '谨慎' : '平稳') assert.ok(report.supportiveDays.every((day) => day.score > 0)) assert.ok(report.cautiousDays.every((day) => day.score < 0)) statuses.add(report.status) } assert.deepEqual([...statuses].sort(), ['平稳', '谨慎', '顺势'].sort()) }) test('生日、周次驱动结果,同生肖同周稳定,跨周明细改变', () => { const first = weekly('1998-06-18', '2026-10-15') assert.deepEqual(first, weekly('1998-06-18', '2026-10-15')) assert.deepEqual(first, weekly('2010-06-18', '2026-10-15')) assert.notDeepEqual(first.days, weekly('1999-06-18', '2026-10-15').days) assert.notDeepEqual(first.days, weekly('1998-06-18', '2026-10-22').days) assert.equal(weekly('2024-02-09', '2026-10-15').zodiac, '兔') assert.equal(weekly('2024-02-10', '2026-10-15').zodiac, '龙') }) test('非法生日与非法参考日期不给出虚构周运', () => { assert.equal(weekly('', '2026-10-15'), null) assert.equal(weekly('2025-02-29', '2026-10-15'), null) for (const date of ['', 'invalid', '2026-02-30', '2026-13-01', '2026-00-01', '2026-10-00']) { assert.equal(weekly('1998-06-18', date), null) } })