Files
massive-cloud/server/measurementCompatibility.test.ts

135 lines
5.4 KiB
TypeScript

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 });
});
});