74 lines
4.0 KiB
JavaScript
74 lines
4.0 KiB
JavaScript
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, /<FiveElementIcon report=\{elementReport\} \/>/)
|
||
|
|
assert.match(page, /calculateFiveElements\(profile.birthday, profile.birthHour\)/)
|
||
|
|
assert.match(page, /\[profile\?\.birthday, profile\?\.birthHour\]/)
|
||
|
|
assert.match(page, /<UserAvatar src=\{profile.avatarUrl\}[^>]+fallback=\{<WaterMascot \/>\}/)
|
||
|
|
assert.doesNotMatch(page, /<WaterMascot compact/)
|
||
|
|
const sass = require(require.resolve('sass', { paths: [require.resolve('@tarojs/webpack5-runner')] }))
|
||
|
|
const postcss = require(require.resolve('postcss', { paths: [require.resolve('@tarojs/webpack5-runner')] }))
|
||
|
|
const css = sass.renderSync({ file: path.join(root, 'src/components/FiveElementIcon.scss') }).css.toString()
|
||
|
|
postcss.parse(css).walkRules(rule => rule.selectors.forEach(selector => assert.match(selector, /^\.five-element-/)))
|
||
|
|
assert.doesNotMatch(css, /\.water-mascot/)
|
||
|
|
})
|