feat: standardize algorithm measurement results
This commit is contained in:
134
server/measurementCompatibility.test.ts
Normal file
134
server/measurementCompatibility.test.ts
Normal file
@@ -0,0 +1,134 @@
|
||||
import { afterEach, describe, expect, it } from 'vitest';
|
||||
|
||||
import {
|
||||
inspectionObjectContextFromName,
|
||||
normalizeMeasurements,
|
||||
sortNormalizedMeasurements,
|
||||
} from './measurementCompatibility.js';
|
||||
|
||||
const valueFields = {
|
||||
value: 1.25,
|
||||
unit: 'mm',
|
||||
tolerance: 0.8,
|
||||
toleranceLabel: '+0.8/-0.2',
|
||||
baseline: 375,
|
||||
status: 'pass' as const,
|
||||
passLabel: '通过',
|
||||
};
|
||||
|
||||
afterEach(() => {
|
||||
delete process.env.MEASUREMENT_COMPAT_ENABLED;
|
||||
});
|
||||
|
||||
describe('normalizeMeasurements', () => {
|
||||
it.each([
|
||||
['任务46_车体横断面对角线差值', '46', '车体横断面对角线差值'],
|
||||
['任务11 · 车钩面板的平整度', '11', '车钩面板的平整度'],
|
||||
])('拆分通用旧任务名 %s', (originalName, taskNo, name) => {
|
||||
const output = normalizeMeasurements({
|
||||
pluginId: 'train-measurement',
|
||||
measurements: [{ name: originalName, ...valueFields }],
|
||||
});
|
||||
expect(output.measurements[0]).toMatchObject({
|
||||
taskNo,
|
||||
metricCode: `legacy.train_measurement.task_${taskNo}`,
|
||||
name,
|
||||
legacyOriginalName: originalName,
|
||||
...valueFields,
|
||||
});
|
||||
});
|
||||
|
||||
it('新协议结果原样保留且重复调用一致', () => {
|
||||
const measurement = { taskNo: '8', metricCode: 'coupler.reference-offset', name: '参考面右偏转', ...valueFields, customConclusion: '合格' };
|
||||
const first = normalizeMeasurements({ pluginId: 'coupler-panel', measurements: [measurement], extra: { marker: true } });
|
||||
const second = normalizeMeasurements({ pluginId: 'coupler-panel', measurements: first.measurements, extra: first.extra });
|
||||
expect(first.measurements).toEqual([measurement]);
|
||||
expect(second).toEqual(first);
|
||||
});
|
||||
|
||||
it('任务 5 保留左右梁两行和位置顺序', () => {
|
||||
const output = normalizeMeasurements({
|
||||
pluginId: 'underframe-deflection',
|
||||
measurements: [
|
||||
{ name: '右梁 · 纵向梁到直线的垂直偏差(挠度)', value: 2 },
|
||||
{ name: '左梁 · 纵向梁到直线的垂直偏差(挠度)', value: 1 },
|
||||
],
|
||||
});
|
||||
expect(output.measurements).toMatchObject([
|
||||
{ taskNo: '5', name: '挠度', position: '左梁', value: 1 },
|
||||
{ taskNo: '5', name: '挠度', position: '右梁', value: 2 },
|
||||
]);
|
||||
});
|
||||
|
||||
it.each([
|
||||
['头车', '8', '10'],
|
||||
['中车', '9', '12'],
|
||||
['中间车', '9', '12'],
|
||||
])('%s 车钩精确映射为正确任务号', (objectName, referenceTaskNo, longitudinalTaskNo) => {
|
||||
const output = normalizeMeasurements({
|
||||
pluginId: 'coupler-panel',
|
||||
context: inspectionObjectContextFromName(objectName),
|
||||
measurements: [
|
||||
{ name: '车钩面板距纵向中心的右偏转角', value: 2 },
|
||||
{ name: '车钩面板距参考面的右偏转角', value: 1 },
|
||||
],
|
||||
});
|
||||
expect(output.measurements).toMatchObject([
|
||||
{ taskNo: referenceTaskNo, name: '参考面右偏转', value: 1 },
|
||||
{ taskNo: longitudinalTaskNo, name: '纵向中心右偏转', value: 2 },
|
||||
]);
|
||||
});
|
||||
|
||||
it('未知检测对象不默认成头车', () => {
|
||||
const output = normalizeMeasurements({
|
||||
pluginId: 'coupler-panel',
|
||||
context: inspectionObjectContextFromName('拖车'),
|
||||
measurements: [{ name: '车钩面板距参考面的右偏转角', value: 1 }],
|
||||
});
|
||||
expect(output.measurements[0]).toMatchObject({ legacyUnmapped: true });
|
||||
expect(output.measurements[0].taskNo).toBeUndefined();
|
||||
expect(output.warnings).toHaveLength(1);
|
||||
});
|
||||
|
||||
it('车钩中间量移入 extra.intermediateMetrics 并保留字段', () => {
|
||||
const intermediate = ['最大 x 偏差 dx_y', '最大 x 偏差 dx_z', '面板 y 向最大偏差 D_y', '面板 z 向最大偏差 D_z']
|
||||
.map((name, index) => ({ name, value: index, unit: 'mm', status: 'info' }));
|
||||
const output = normalizeMeasurements({
|
||||
pluginId: 'coupler-panel',
|
||||
context: inspectionObjectContextFromName('头车'),
|
||||
measurements: [{ name: '车钩面板距参考面的右偏转角', value: 1 }, ...intermediate],
|
||||
extra: { marker: 'kept' },
|
||||
});
|
||||
expect(output.measurements).toHaveLength(1);
|
||||
expect(output.extra).toEqual({ marker: 'kept', intermediateMetrics: intermediate });
|
||||
});
|
||||
|
||||
it('未知名称不模糊猜测并生成稳定编码', () => {
|
||||
const source = { name: '类似车钩面板距参考面的右偏转角但不是', ...valueFields, customConclusion: '人工通过' };
|
||||
const output = normalizeMeasurements({ pluginId: 'coupler-panel', measurements: [source] });
|
||||
expect(output.measurements[0]).toMatchObject({
|
||||
...source,
|
||||
legacyUnmapped: true,
|
||||
legacyOriginalName: source.name,
|
||||
});
|
||||
expect(output.measurements[0].metricCode).toMatch(/^legacy\.coupler_panel\.unmapped\.[0-9a-f]{8}$/);
|
||||
});
|
||||
|
||||
it('按数字任务号排序且未映射项最后', () => {
|
||||
const sorted = sortNormalizedMeasurements([
|
||||
{ taskNo: '46', name: '46' },
|
||||
{ name: 'unknown' },
|
||||
{ taskNo: '5', position: '右梁', name: '5R' },
|
||||
{ taskNo: '11', name: '11' },
|
||||
{ taskNo: '5', position: '左梁', name: '5L' },
|
||||
]);
|
||||
expect(sorted.map((item) => item.name)).toEqual(['5L', '5R', '11', '46', 'unknown']);
|
||||
});
|
||||
|
||||
it('环境开关关闭时原样返回', () => {
|
||||
process.env.MEASUREMENT_COMPAT_ENABLED = '0';
|
||||
const measurements = [{ name: '任务46_原始', value: 1 }];
|
||||
const output = normalizeMeasurements({ pluginId: 'train-measurement', measurements, extra: { raw: true } });
|
||||
expect(output).toEqual({ measurements, extra: { raw: true }, warnings: [], converted: false });
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user