Files
juzi/h5/test/customer-feedback.js
T

101 lines
7.1 KiB
JavaScript

'use strict';
const assert = require('assert/strict');
const fs = require('fs');
const vm = require('vm');
const path = require('path');
const SkinScore = require('../js/skin-score');
const ReportUI = require('../js/report-ui');
const result = JSON.parse(fs.readFileSync(path.join(__dirname, '../../reference/facepp-skinanalyze/examples/ref_3view_raw.json'))).result;
const details = ReportUI.wrinkleDetails(result);
assert.equal(details.length, 12);
assert.equal(new Set(details.map(row => row.key)).size, 12);
assert.equal(details[0].name, '抬头纹(额头纹)');
assert.deepEqual(details[0].metrics, {
wrinkle_score: 13, wrinkle_severity_level: 1, wrinkle_deep_num: 22, wrinkle_shallow_num: 18,
wrinkle_norm_length: result.forehead_wrinkle_info.wrinkle_norm_length,
wrinkle_norm_depth: result.forehead_wrinkle_info.wrinkle_norm_depth,
wrinkle_pixel_density: result.forehead_wrinkle_info.wrinkle_pixel_density,
wrinkle_area_ratio: result.forehead_wrinkle_info.wrinkle_area_ratio,
wrinkle_deep_ratio: result.forehead_wrinkle_info.wrinkle_deep_ratio
});
assert.equal(details.find(row => row.key === 'left_eye').metrics.wrinkle_deep_num, 58);
assert.equal(details.find(row => row.key === 'right_eye').metrics.wrinkle_shallow_num, 46);
assert.equal(details.find(row => row.key === 'left_cheek').metrics.wrinkle_score, 0);
const alternate = ReportUI.wrinkleDetails({ right_nasolabial_fold_info: { wrinkle_score: { value: 31 }, wrinkle_severity_level: { value: 2 } },
wrinkle_count: { right_nasolabial_count: 5 }, fine_line: { right_nasolabial_count: 0 } });
assert.equal(alternate.find(row => row.key === 'right_nasolabial').metrics.wrinkle_score, 31);
assert.equal(alternate.find(row => row.key === 'right_nasolabial').metrics.wrinkle_deep_num, 5);
assert.equal(alternate.find(row => row.key === 'right_nasolabial').metrics.wrinkle_shallow_num, 0);
assert(Object.values(alternate[0].metrics).every(value => value === null));
const model = SkinScore.buildViewModel(result, SkinScore.MOCK_SIDE, { realAge: 30 });
const modelBefore = JSON.stringify(model), rawBefore = JSON.stringify(result);
const presentation = ReportUI.build(model, result);
const text = presentation.views.find(view => view.key === 'wrinkles').text;
assert.deepEqual(presentation.views.find(view => view.key === 'wrinkles').details, details);
assert(!text.includes('分区明细') && !text.includes('标准化长度'));
const approved = {
'预警': '全脸共检测到皱纹 12 条、细纹 34 条,面中、口周、眼周等区域已出现静态纹倾向,纹路已呈现固化趋势,并非临时性干纹。',
'改善': '全脸共检测到皱纹 12 条、细纹 34 条,面部整体平整,仅眼周或口周有细微的干纹,无明显静态深纹,纹路面积占比相对较低。',
'良好': '全脸共检测到皱纹 12 条、细纹 34 条;整体纹路状态较好,建议维持日常淡纹与保湿护理。'
};
for (const level of Object.keys(approved)) {
const fixture = JSON.parse(modelBefore);
fixture.cats.wrinkles.level = level;
fixture.cats.wrinkles.P = { '预警': 20, '改善': 50, '良好': 90 }[level];
fixture.cats.wrinkles.vars.wr_cnt = 12;
fixture.cats.wrinkles.vars.fl_cnt = 34;
assert.equal(ReportUI.build(fixture, result).views.find(view => view.key === 'wrinkles').text, approved[level]);
}
assert.equal(JSON.stringify(model), modelBefore);
assert.equal(JSON.stringify(result), rawBefore);
const excellent = JSON.parse(JSON.stringify(model));
excellent.cats.smooth.level = '良好'; // Legacy level name maps to new "优秀".
excellent.cats.smooth.P = 90;
excellent.cats.smooth.vars.pore_cnt = 7;
excellent.cats.smooth.vars.blackhead_cnt = 2;
let smooth = ReportUI.build(excellent, result).views.find(view => view.key === 'smooth');
assert(smooth.text.includes('粗大毛孔 7 颗、黑头 2 颗'));
assert(!smooth.text.includes('无明显粗大毛孔'));
assert.equal(smooth.level, '优秀');
excellent.cats.smooth.vars.pore_cnt = null;
smooth = ReportUI.build(excellent, result).views.find(view => view.key === 'smooth');
assert(smooth.text.includes('未完整获取'));
const source = fs.readFileSync(path.join(__dirname, '../js/app.js'), 'utf8');
const pure = source.match(/\/\* viz-pure-begin[\s\S]*?\*\/([\s\S]*?)\/\* viz-pure-end \*\//)[1];
const sandbox = {}; vm.runInNewContext(pure, sandbox);
vm.runInNewContext(source.slice(source.indexOf(' var VIZ_CAT ='),source.indexOf(' /* viz-pure-begin')),sandbox);
const acneDefs=sandbox.VIZ_CAT.acne.marks;
assert.equal(acneDefs.find(x=>x.key==='acne_mark').color,'#8750C8');
const acneRaw={acne_mark:{count:1,rectangle:[{left:10,top:20,width:30,height:40}],polygon:[[{x:10,y:20},{x:40,y:20},{x:20,y:60}]]}};
const acneBefore=JSON.stringify(acneRaw),acneMarks=sandbox.vizCollectMarks(acneDefs,acneRaw);
assert.equal(acneMarks.length,1);assert.equal(acneMarks[0].rects.length,1);assert.equal(acneMarks[0].polygons.length,1);
assert.equal(JSON.stringify(acneRaw),acneBefore,'overlay does not change detection or scoring data');
assert.equal(sandbox.vizCollectMarks(acneDefs,{acne_mark:{count:3}}).length,0,'counts alone never generate fake positions');
assert.equal(sandbox.vizCollectMarks(acneDefs,{acne_mark:{count:0,rectangle:[],polygon:[]}}).length,0);
const crop = sandbox.vizFaceCrop(4000, 3000, { left: 1479, top: 1133, width: 1116, height: 1116 });
assert(crop.focused);
assert(crop.width < 1600 && crop.height < 1800);
assert(crop.left <= 1479 && crop.top <= 1133);
assert(crop.left + crop.width >= 2595 && crop.top + crop.height >= 2249);
assert(Math.abs(crop.width / crop.height - 215 / 278) < 1e-8);
const moved = sandbox.vizShiftContentDown(crop,{left:1479,top:1133,width:1116,height:1116},.09);
assert(Math.abs(moved.top-(crop.top-crop.height*.09))<1e-8);
assert.equal(moved.width,crop.width);assert.equal(moved.height,crop.height);assert.equal(moved.left,crop.left);
assert(moved.top>=0&&moved.top+moved.height>=2249);
assert.equal(sandbox.vizShiftContentDown(crop,null,.09),crop);
const edgeCrop=sandbox.vizFaceCrop(1000,1000,{left:100,top:0,width:300,height:300});
assert.equal(sandbox.vizShiftContentDown(edgeCrop,{left:100,top:0,width:300,height:300},.09).top,0);
for (const rect of [null, { left: NaN }, { left: 0, top: 0, width: -1, height: 20 },
{ left: 3900, top: 0, width: 1000, height: 1000 }, { left: 0, top: 0, width: '100', height: 100 }]) {
const full = sandbox.vizFaceCrop(4000, 3000, rect);
assert.equal(full.focused, false); assert.equal(full.width, 4000);
}
for (const rect of [{ left: 0, top: 0, width: 300, height: 300 }, { left: 700, top: 700, width: 300, height: 300 }]) {
const edge = sandbox.vizFaceCrop(1000, 1000, rect);
assert(edge.focused); assert(edge.left >= 0 && edge.top >= 0);
assert(edge.left + edge.width <= 1000 && edge.top + edge.height <= 1000);
assert(edge.left <= rect.left && edge.top <= rect.top);
assert(edge.left + edge.width >= rect.left + rect.width && edge.top + edge.height >= rect.top + rect.height);
}
console.log('PASS: 12 unique wrinkle regions, all nine real metrics, aliases/count fallbacks, missing≠zero; positive pore counts vs excellent score; no raw/model/algorithm mutations; face crop/aspect/edge containment/invalid-box fallback');