58 lines
2.5 KiB
TypeScript
58 lines
2.5 KiB
TypeScript
import { describe, it, expect } from 'vitest'
|
||
import { computeYpt, buildTierClassifier, annotateYpt } from '../src/common/material-ranking'
|
||
|
||
const M = (methanal: number|null, tvoc: number|null, benzene: number|null, toluene: number|null, pxylene: number|null) => ({
|
||
methanal_be_area: methanal, tvoc_be_area: tvoc, benzene_be_area: benzene, toluene_be_area: toluene, p_xylene_be_area: pxylene
|
||
})
|
||
|
||
describe('computeYpt', () => {
|
||
it('按权重求和', () => {
|
||
// 1*1.8 + 2*0.25 + 3*1 + 4*0.45 + 5*0.38 = 1.8+0.5+3+1.8+1.9 = 9
|
||
expect(computeYpt(M(1, 2, 3, 4, 5))).toBeCloseTo(9, 6)
|
||
})
|
||
it('任一缺值返回 null', () => {
|
||
expect(computeYpt(M(1, null, 3, 4, 5))).toBeNull()
|
||
expect(computeYpt(M(1, 2, 3, 4, undefined as never))).toBeNull()
|
||
})
|
||
})
|
||
|
||
describe('buildTierClassifier', () => {
|
||
it('全库三分位: 6 个材料 -> 2A 2B 2C', () => {
|
||
// ypt 分别为 1..6(每个只用 methanal 权重 1.8,但相对顺序即 methanal 顺序)
|
||
const all = [1, 2, 3, 4, 5, 6].map(v => M(v, 0, 0, 0, 0))
|
||
const classify = buildTierClassifier(all)
|
||
const ypts = all.map(computeYpt)
|
||
expect(ypts.map(classify)).toEqual(['A', 'A', 'B', 'B', 'C', 'C'])
|
||
})
|
||
it('缺值材料不参与分位、classify(null)=null', () => {
|
||
const all = [M(1,0,0,0,0), M(2,0,0,0,0), M(3,0,0,0,0), M(1,null,0,0,0)]
|
||
const classify = buildTierClassifier(all)
|
||
expect(classify(null)).toBeNull()
|
||
})
|
||
it('相同 Ypt 落同档(并列不强拆)', () => {
|
||
const all = [M(1,0,0,0,0), M(1,0,0,0,0), M(1,0,0,0,0)]
|
||
const classify = buildTierClassifier(all)
|
||
const tiers = all.map(m => classify(computeYpt(m)))
|
||
expect(new Set(tiers).size).toBe(1) // 全相等 -> 同一档
|
||
})
|
||
it('小 n=1 -> 该材料为 A', () => {
|
||
const all = [M(5,0,0,0,0)]
|
||
const classify = buildTierClassifier(all)
|
||
expect(classify(computeYpt(all[0]))).toBe('A')
|
||
})
|
||
})
|
||
|
||
describe('annotateYpt', () => {
|
||
it('只挂上 ypt(健康档不再实时计算,已定格到 health_level)', () => {
|
||
const all = [M(1,0,0,0,0), M(2,0,0,0,0), M(3,0,0,0,0)]
|
||
const out = annotateYpt(all)
|
||
expect(out[0].ypt).toBeCloseTo(1.8, 6)
|
||
expect(out[2].ypt).toBeCloseTo(5.4, 6)
|
||
expect(out[0]).not.toHaveProperty('health_tier')
|
||
})
|
||
it('缺值材料 ypt=null', () => {
|
||
const out = annotateYpt([M(1, null, 0, 0, 0)])
|
||
expect(out[0].ypt).toBeNull()
|
||
})
|
||
})
|