38 lines
3.2 KiB
JavaScript
38 lines
3.2 KiB
JavaScript
'use strict';
|
|
const assert = require('node:assert/strict');
|
|
const SS = require('../js/skin-score'), UI = require('../js/report-ui');
|
|
const keys = ['closed_comedones','acne','acne_pustule','acne_nodule','acne_mark'];
|
|
const node = counts => Object.fromEntries(keys.map((key,i)=>[key,counts[i]===null?{}:{count:counts[i]}]));
|
|
function run(front,left,right,score=100){
|
|
const r=structuredClone(SS.MOCK_RESULT);Object.assign(r,node(front));r.score_info.acne_score=score;
|
|
const sides={left:{left_acne_info:{...node(left),score:0}},right:{right_acne_info:{...node(right),score:0}}};
|
|
const before=JSON.stringify({r,sides});const vm=SS.buildViewModel(r,sides,{});
|
|
assert.equal(JSON.stringify({r,sides}),before,'raw inputs unchanged');
|
|
return {vm,cat:vm.cats.acne,view:UI.build(vm,r).views.find(v=>v.key==='acne')};
|
|
}
|
|
const result=run([2,0,0,0,3],[5,1,0,0,1],[3,1,0,0,4]);
|
|
assert.deepEqual(Object.values(result.cat.vars.acne_counts),[5,1,0,0,4]);
|
|
assert.equal(result.cat.vars.acne_scoring.deduction,13);assert.equal(result.cat.P,87);
|
|
assert.equal(result.cat.vars.acne_cnt,10);assert.equal(result.cat.vars.acne_detail,'闭口粉刺5处、丘疹1处、痘印4处');
|
|
assert.deepEqual(result.cat.vars.acne_scoring.types[1].sources,['left','right']);
|
|
assert.equal(result.vm.dims.stab.S,9.61);assert(result.view.text.includes('丘疹1处'));
|
|
assert.equal(run([2,0,0,0,3],[5,1,0,0,1],[3,1,0,0,4],80).cat.P,70,'front score mapping still limits score');
|
|
const heavy=run([0,0,0,0,0],[0,0,1,0,0],[0,0,0,1,0]);
|
|
assert.equal(heavy.cat.P,90);assert.equal(heavy.view.level,'优秀');
|
|
assert(heavy.view.text.includes('脓包1处')&&heavy.view.text.includes('结节1处'));
|
|
assert(heavy.view.text.includes('含脓包、结节'));
|
|
const empty=run([null,null,null,null,null],[null,null,null,null,null],[null,null,null,null,null]);
|
|
assert.equal(empty.cat.P,100);assert.equal(empty.cat.vars.acne_cnt,null);assert(empty.view.text.includes('未获取完整'));
|
|
assert.equal(empty.cat.vars.acne_scoring.deduction,null);
|
|
const partial=run([null,0,null,null,null],[null,null,null,null,null],[null,null,null,null,null]);
|
|
assert.equal(partial.cat.vars.acne_counts_complete,false);assert(partial.view.text.includes('部分类型数据缺失'));
|
|
assert.equal(run([null,null,null,null,null],[null,null,null,null,null],[null,null,null,null,null],null).cat.P,null);
|
|
const capped=run([100,100,100,100,100],[0,0,0,0,0],[0,0,0,0,0]);
|
|
assert.equal(capped.cat.P,50);assert.equal(capped.cat.vars.acne_scoring.raw_deduction,1450);assert.equal(capped.cat.vars.acne_scoring.deduction,50);
|
|
const r=structuredClone(SS.MOCK_RESULT);r.acne={rectangle:[{},{}]};
|
|
let vm=SS.buildViewModel(r,null,{});assert.equal(vm.cats.acne.vars.acne_counts.acne,2,'rectangle fallback');
|
|
for(const n of [-1,1.5,NaN,Infinity]){r.acne={count:n};vm=SS.buildViewModel(r,null,{});assert.equal(vm.cats.acne.vars.acne_counts.acne,null);}
|
|
const zero=run([0,0,0,0,0],[null,null,null,null,null],[null,null,null,null,null]);
|
|
assert.equal(zero.cat.P,100);assert.equal(zero.cat.vars.acne_counts_complete,true);assert(zero.view.text.includes('未检出明显皮损'));
|
|
console.log('PASS acne maxima per type, no sum/view selection, front-score mapping, heavy side lesions/copy, missing vs zero, cap50, source audit, invalid counts and unchanged inputs');
|