const test = require('node:test') const assert = require('node:assert/strict') const fs = require('node:fs') const path = require('node:path') const vm = require('node:vm') const ts = require('typescript') const root = path.resolve(__dirname, '..') const cache = new Map() function load(file) { if (cache.has(file)) return cache.get(file) const exports = {} cache.set(file, exports) const code = ts.transpileModule(fs.readFileSync(file, 'utf8'), { compilerOptions: { module: ts.ModuleKind.CommonJS, target: ts.ScriptTarget.ES2019, jsx: ts.JsxEmit.ReactJSX } }).outputText vm.runInNewContext(code, { exports, require: id => { if (id.endsWith('.scss')) return {} if (id === '@tarojs/components') return { View: 'view', Text: 'text' } if (id.startsWith('.')) return load(path.resolve(path.dirname(file), `${id}.ts`)) return require(id) } }) return exports } const { getDayMasterIcon } = load(path.join(root, 'src/utils/elementIcon.ts')) const { calculateFiveElements, analyzePillars } = load(path.join(root, 'src/utils/fiveElements.ts')) const { FiveElementIcon } = load(path.join(root, 'src/components/FiveElementIcon.tsx')) test('十天干的日主对应五种元素图标,不按最高占比或喜用选择', () => { const days = ['甲子', '乙丑', '丙寅', '丁卯', '戊辰', '己巳', '庚午', '辛未', '壬申', '癸酉'] const expected = ['wood', 'wood', 'fire', 'fire', 'earth', 'earth', 'metal', 'metal', 'water', 'water'] days.forEach((day, index) => { const report = analyzePillars(['甲寅', '乙卯', day, '壬子']) const icon = getDayMasterIcon(report) assert.equal(icon.kind, expected[index]) assert.equal(icon.label, report.masterElement) assert.match(icon.color, /^#[0-9a-f]{6}$/) const component = FiveElementIcon({ report }) assert.equal(component.props.className, `five-element-icon five-element-${expected[index]}`) assert.equal(component.props['aria-label'], `日主五行:${report.masterElement}`) }) const report = analyzePillars(['甲寅', '乙卯', '庚申', '甲寅']) assert.equal([...report.scores].sort((a, b) => b.value - a.value)[0].name, '木') assert.equal(getDayMasterIcon(report).kind, 'metal') }) test('真实生日变动同步切换日主图标,数据缺失或非法不默认显示水', () => { const kinds = new Set() for (let day = 10; day < 20; day++) { const report = calculateFiveElements(`1998-06-${day}`, '辰时') kinds.add(getDayMasterIcon(report).kind) } assert.equal(kinds.size, 5) const first = getDayMasterIcon(calculateFiveElements('1998-06-18', '辰时')) const changed = getDayMasterIcon(calculateFiveElements('1998-06-20', '辰时')) assert.notEqual(first.kind, changed.kind) for (const report of [null, undefined, { masterElement: '未知' }, calculateFiveElements('', '')]) { assert.equal(getDayMasterIcon(report).kind, 'unknown') } assert.equal(FiveElementIcon({ report: null }).props['aria-label'], '完善出生信息后显示日主五行') }) test('我的元素复用当前报告,个人头像保持独立,图标样式不污染水滴默认头像', () => { const page = fs.readFileSync(path.join(root, 'src/pages/my/index.tsx'), 'utf8') assert.match(page, //) assert.match(page, /calculateFiveElements\(profile.birthday, profile.birthHour\)/) assert.match(page, /\[profile\?\.birthday, profile\?\.birthHour\]/) assert.match(page, /]+fallback=\{\}/) assert.doesNotMatch(page, / rule.selectors.forEach(selector => assert.match(selector, /^\.five-element-/))) assert.doesNotMatch(css, /\.water-mascot/) })