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