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

85 lines
4.1 KiB
JavaScript

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 filename = path.resolve(__dirname, '../src/utils/fiveElements.ts')
const compiled = ts.transpileModule(fs.readFileSync(filename, 'utf8'), {
compilerOptions: { module: ts.ModuleKind.CommonJS, target: ts.ScriptTarget.ES2017 }
}).outputText
const loaded = new Module(filename, module)
loaded.filename = filename
loaded.paths = Module._nodeModulePaths(path.dirname(filename))
loaded._compile(compiled, filename)
const { analyzePillars, calculateFiveElements } = loaded.exports
test('同一日主在强弱不同的四柱下,扶抑方向应反转', () => {
const strong = analyzePillars(['甲寅', '乙卯', '甲寅', '乙卯'])
const weak = analyzePillars(['丙午', '丁巳', '甲申', '戊戌'])
assert.equal(strong.dayMaster, weak.dayMaster)
assert.equal(strong.strength, '偏强')
assert.equal(weak.strength, '偏弱')
assert.equal(strong.favorable, '火土金')
assert.equal(weak.favorable, '水木')
assert.equal(strong.analysis.season.supported, true)
assert.equal(weak.analysis.roots.supported, false)
})
test('地支藏干中的同类根必须计入,得势不包含日干自身', () => {
const report = analyzePillars(['丙午', '丁巳', '甲辰', '戊戌'])
assert.equal(report.analysis.roots.supported, true) // 辰藏乙,不能只看辰土。
assert.ok(report.analysis.roots.score > 0)
const noSupport = analyzePillars(['丙午', '丁巳', '甲申', '戊戌'])
assert.ok(noSupport.analysis.support.score < 20)
})
test('有效日期和时辰改变后重新排盘,不受昵称或后端报告影响', () => {
const first = calculateFiveElements('1998-06-18', '辰时')
assert.deepEqual(first.pillars, ['戊寅', '戊午', '丙申', '壬辰'])
const changedDate = calculateFiveElements('1998-12-18', '辰时')
const changedHour = calculateFiveElements('1998-06-18', '戌时')
assert.notDeepEqual(first.scores, changedDate.scores)
assert.notDeepEqual(first.pillars, changedHour.pillars)
assert.notDeepEqual(first.scores, changedHour.scores)
assert.deepEqual(first, calculateFiveElements('1998-06-18', '7'))
})
test('百分比总和为100,强弱有界,喜忌互斥,平衡不强行指定喜忌', () => {
let balanced = false
for (let month = 1; month <= 12; month++) {
for (const hour of ['子时', '辰时', '午时', '酉时']) {
const report = calculateFiveElements(`2000-${String(month).padStart(2, '0')}-15`, hour)
assert.equal(report.scores.reduce((sum, score) => sum + score.value, 0), 100)
assert.ok(report.scores.every((score) => Number.isInteger(score.value) && score.value >= 0 && score.value <= 100))
assert.ok(report.strengthScore >= 0 && report.strengthScore <= 100)
assert.ok(![...report.favorable].some((element) => report.unfavorable.includes(element)))
if (report.strength === '相对平衡') {
balanced = true
assert.equal(report.favorable, '')
assert.equal(report.unfavorable, '')
}
}
}
assert.equal(balanced, true)
})
test('不把无效生日、缺失时辰或越界时辰转换成虚构报告', () => {
for (const [date, hour] of [
['', '辰时'], ['2025-02-29', '辰时'], ['2024-02-30', '辰时'],
['2024-13-01', '辰时'], ['2000-01-01', ''], ['2000-01-01', '24'],
['2000-01-01', '-1'], ['2000-01-01', '辰时xxx']
]) assert.equal(calculateFiveElements(date, hour), null)
assert.ok(calculateFiveElements('2024-02-29', '子时'))
assert.throws(() => analyzePillars(['甲子', '无效', '甲子', '甲子']))
})
test('节气前后切换月柱;子时换日采用历法库第二流派', () => {
const before = calculateFiveElements('2024-02-03', '午时')
const after = calculateFiveElements('2024-02-05', '午时')
assert.notEqual(before.pillars[1], after.pillars[1])
const early = calculateFiveElements('2024-06-18', '0')
const late = calculateFiveElements('2024-06-18', '23')
assert.equal(early.dayMaster, late.dayMaster)
})