yeg
2026-09-08 1a1d8986216a1d0fcdad1e334941de430ea80916
更新现有回归测试以验证正式图表与观测契约
4个文件已修改
82 ■■■■■ 已修改文件
tests/test-chart-display-units.test.mjs 61 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
tests/test-console-live-values.contract.test.mjs 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
tests/test-console-live.contract.test.mjs 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
tests/test-ticket23-console-step-regression.test.mjs 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
tests/test-chart-display-units.test.mjs
@@ -12,9 +12,10 @@
  return new Function(...Object.keys(bindings), 'toTestDisplayValue', script)(...Object.values(bindings), toTestDisplayValue)
}
async function printModule(name) {
async function measurementModule() {
  const name = 'reportMeasurementChart'
  const source = await readFile(new URL(`../src/utils/${name}.ts`, import.meta.url), 'utf8')
  const script = ts.transpileModule(`${source}\nexport { createChartSvg }`, { compilerOptions: { target: ts.ScriptTarget.ES2022, module: ts.ModuleKind.CommonJS } }).outputText
  const script = ts.transpileModule(source, { compilerOptions: { target: ts.ScriptTarget.ES2022, module: ts.ModuleKind.CommonJS } }).outputText
  const exports = {}
  new Function('exports', 'require', script)(exports, id => {
    assert.equal(id, './testDataUnits')
@@ -22,15 +23,14 @@
  })
  return exports
}
const compare = await printModule('compareReportPrint')
const formation = await printModule('formationReportPrint')
const { measurementChartOption } = await measurementModule()
test('工步图电流序列和纵轴同步为 mA,保留负数与零', async () => {
  const records = [-8.1651, 0, -8.1674].map((current, index) => ({ batteryNo: 'BAT-1', current, deviceTime: index * 60000, sourceType: 'SNAPSHOT' }))
  const { metricValue, chartOption } = await componentFunctions('components/ConsoleChartPanel.vue', ['metricValue', 'recordTime', 'chartOption'], {
    props: { cells: [{ no: 'BAT-1' }] }, selectedRecords: () => records, selectedCells: { value: [{ no: 'BAT-1' }] }, metricMatches: () => true, seriesColors: { value: ['#3978f6'] },
  })
  const option = chartOption(compare.compareMetricDefinitions.find(metric => metric.key === 'current'))
  const option = chartOption({ key: 'current', unit: 'mA' })
  assert.deepEqual(option.series[0].data, [-8165.1, 0, -8167.4])
  assert.equal(option.yAxis[0].name, 'mA')
  assert.ok(option.yAxis[0].min < -8167.4)
@@ -53,26 +53,31 @@
  assert.equal(funcs.dischargeCapacityPerFactor('BAT-1', 1), null)
})
test('三类演示报表曲线、偏移量、纵轴和打印统一换算', async () => {
  const common = { seriesColors: { value: ['#3978f6'] } }
  const compareChart = await componentFunctions('views/ReportCompareForm.vue', ['chartOption'], { ...common, chartSeries: { value: [{ name: '测试', batteryNo: 'BAT-1' }] } })
  const current = compare.compareMetricDefinitions.find(metric => metric.key === 'current')
  const option = compareChart.chartOption(current)
  assert.equal(option.yAxis[0].name, 'mA')
  assert.equal(option.series[0].data[0], 1100)
  assert.equal(option.yAxis[0].max, 1380)
  const svg = compare.createChartSvg(current, { detailTests: [{ name: '测试', batteryNo: 'BAT-1' }], seriesColors: [] })
  assert.match(svg, />mA</)
  assert.match(svg, />1380</)
  const formationChart = await componentFunctions('views/FormationReportForm.vue', ['chartOption'], { ...common, reportSamples: { value: ['BAT-1'] }, activeCycle: { value: 2 } })
  const formationCurrent = formation.formationMetricDefinitions.find(metric => metric.key === 'current')
  assert.equal(formationChart.chartOption(formationCurrent).series[0].data[0], 1212)
  const formationSvg = formation.createChartSvg(formationCurrent, { cycle: 2 }, { samples: ['BAT-1'], seriesColors: [] })
  assert.match(formationSvg, />mA</)
  assert.match(formationSvg, />1212</)
  const spliceChart = await componentFunctions('views/SpliceReportForm.vue', ['chartOption', 'formatMinutes'], { ...common, samples: { value: ['BAT-1'] }, selectedTests: { value: [{}, {}] }, timeline: { value: { segments: [], labels: [] } } })
  const spliceOption = spliceChart.chartOption(formationCurrent)
  assert.equal(spliceOption.series[0].data[0], 1200)
  assert.equal(spliceOption.series[0].data[7], 1215)
  assert.equal(spliceOption.yAxis[0].name, 'mA')
})
test('保存报表共用测量图按真实时间和单位绘制,显隐不改变完整数据范围', () => {
  const items = [
    { name: '测试甲 · 1号', zeroTime: 1000, records: [
      { deviceTime: 1000, collectorDeviceTime: 9000, current: -0.125, voltage: 3.2, temperature: 0 },
      { deviceTime: 18000, collectorDeviceTime: 22000, current: null, voltage: null, temperature: null },
      { deviceTime: 181000, collectorDeviceTime: 182000, current: 0, voltage: 0, temperature: -5 },
    ] },
    { name: '测试乙 · 1号', zeroTime: 3000, records: [{ deviceTime: 7203000, current: 0.25 }] },
  ]
  const before = structuredClone(items)
  const metric = { key: 'current', unit: 'mA' }
  const option = measurementChartOption(metric, items, ['#123456', '#abcdef'])
  assert.deepEqual(option.series[0].data, [[0, -125], [17, null], [180, 0]])
  assert.equal(option.series[0].connectNulls, false)
  assert.equal(option.xAxis.max, 7200)
  assert.equal(option.xAxis.axisLabel.formatter(1800), '0.5')
  assert.deepEqual(option.yAxis.map(axis => [axis.name, axis.min, axis.max]), [['mA', -143.75, 250], ['mA', -143.75, 250]])
  const hidden = measurementChartOption(metric, [{ ...items[0], hidden: true }, items[1]], ['#123456', '#abcdef'])
  assert.equal(hidden.series.length, 1)
  assert.equal(hidden.series[0].lineStyle.color, '#abcdef')
  assert.equal(hidden.xAxis.max, option.xAxis.max)
  assert.equal(hidden.yAxis[0].min, option.yAxis[0].min)
  assert.deepEqual(items, before)
  const voltage = measurementChartOption({ key: 'voltage', unit: 'V' }, [items[0]], ['#123456'])
  assert.deepEqual(voltage.series[0].data, [[0, 3.2], [17, null], [180, 0]])
  const temperature = measurementChartOption({ key: 'temperature', unit: '℃' }, [items[0]], ['#123456'])
  assert.deepEqual(temperature.series[0].data, [[8, 0], [21, null], [181, -5]])
})
tests/test-console-live-values.contract.test.mjs
@@ -2,7 +2,7 @@
import { readFile } from 'node:fs/promises'
const view = await readFile(new URL('../src/views/TestConsole.vue', import.meta.url), 'utf8')
const liveService = await readFile(new URL('../../BatteryDetection/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TTestLiveServiceImpl.java', import.meta.url), 'utf8')
const liveService = await readFile(new URL('../../BatteryDetection/battery-business/src/main/java/com/battery/business/service/impl/TTestLiveServiceImpl.java', import.meta.url), 'utf8')
assert.match(view, /metric\(\['VOLTAGE', 'voltage'\], cabinetSource, 'voltageV'\)/)
assert.match(view, /metric\(\['CURRENT', 'current'\], cabinetSource, 'currentA'\)/)
tests/test-console-live.contract.test.mjs
@@ -13,7 +13,7 @@
assert.match(view, /liveConnection/)
assert.match(view, /不纳入结果/)
assert.doesNotMatch(view, /localStorage\.(setItem|getItem)\([^)]*test/i)
assert.match(view, /item\.sourceType !== 'COLLECTOR' \|\| !item\.status \|\| item\.status === 'OPEN'/)
assert.match(view, /filter\(item => !item\.status \|\| item\.status === 'OPEN'\)/)
assert.doesNotMatch(view, /完整性检查/)
assert.doesNotMatch(view, /integrity-panel/)
assert.match(api, /COMPLETION_PENDING: '检测完成'/)
tests/test-ticket23-console-step-regression.test.mjs
@@ -3,7 +3,7 @@
const view = await readFile(new URL('../src/views/TestConsole.vue', import.meta.url), 'utf8')
const dataList = await readFile(new URL('../src/components/ConsoleDataListPanel.vue', import.meta.url), 'utf8')
const liveService = await readFile(new URL('../../BatteryDetection/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TTestLiveServiceImpl.java', import.meta.url), 'utf8')
const liveService = await readFile(new URL('../../BatteryDetection/battery-business/src/main/java/com/battery/business/service/impl/TTestLiveServiceImpl.java', import.meta.url), 'utf8')
assert.match(view, /<strong>项目参数<\/strong><span>STEP PARAMETERS<\/span>/)
assert.match(view, /testPlan\?\.rows/)
@@ -28,18 +28,21 @@
assert.doesNotMatch(dataList, /<th>逻辑工步<\/th>/)
assert.doesNotMatch(dataList, /<th>实际工步<\/th>/)
assert.match(dataList, /activeTab\.value === 'step' \? stepRows\.value/)
assert.doesNotMatch(view, /:logic-step-mappings=/)
assert.doesNotMatch(view, /:plan-steps=/)
assert.doesNotMatch(view.match(/<ConsoleDataListPanel\b[^]*?\/>/)[0], /:logic-step-mappings=/)
assert.doesNotMatch(view.match(/<ConsoleDataListPanel\b[^]*?\/>/)[0], /:plan-steps=/)
assert.doesNotMatch(dataList, /mappedStepRows/)
assert.doesNotMatch(dataList, /observedStepPositions/)
assert.doesNotMatch(dataList, /sumValue\('capacity'\)/)
assert.doesNotMatch(dataList, /logical-step:/)
assert.match(dataList, /const filteredRows = computed\(\(\) =>\n  sourceRows\.value\.filter/)
assert.match(dataList, /const filteredRows = computed\(\(\) =>\r?\n  sourceRows\.value\.filter/)
assert.match(dataList, /:total="filteredRows\.length"/)
assert.doesNotMatch(dataList, /receptionIntervals/)
assert.match(dataList, /physicalIds/)
assert.match(dataList, /props\.receptionStatus === 'NOT_STARTED'/)
assert.match(liveService, /simulator\.btsTest\(battery\.getBinding\(\)\.getDevid\(\), battery\.getBinding\(\)\.getChlid\(\), 1\)/)
assert.match(await readFile(new URL('../../BatteryDetection/battery-device-simulator/src/main/java/com/battery/device/simulator/BtsDevelopmentSimulator.java', import.meta.url), 'utf8'), /Integer cyclePosition/)
// 接收状态只触发同步,当前有效历史不因接收暂停或未开始而在前端清空。
assert.match(dataList, /if \(next !== previous\) void loadRecords\(\)/)
assert.match(liveService, /adapter\.testPlan\(new ChannelIdentity\(binding\.getAdapterCode\(\), binding\.getDevtype\(\)/)
assert.match(liveService, /source\.currentCycleNo\(\), source\.currentStepNo\(\)/)
assert.doesNotMatch(liveService, /simulator\.btsTest/)
assert.match(await readFile(new URL('../../BatteryDetection/battery-device-simulator/src/main/java/com/battery/device/simulator/BtsDevelopmentSimulator.java', import.meta.url), 'utf8'), /new PlanRow\("STEP", index \+ 1, index \+ 1,/)
console.log('Ticket23 实时工步方案与数据列表工步映射回归契约通过')