alarmListStatistics.test.mjs 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. import test from 'node:test'
  2. import assert from 'node:assert/strict'
  3. import { readFile } from 'node:fs/promises'
  4. import vm from 'node:vm'
  5. import { computed, effectScope, nextTick, reactive, ref, watch } from 'vue'
  6. import { parse } from '@vue/compiler-sfc'
  7. import { rangeParams } from '../src/views/subSystem/alarm/common/utils/alarmOperationsModel.js'
  8. const { descriptor } = parse(await readFile(new URL('../src/views/subSystem/alarm/common/list.vue', import.meta.url), 'utf8'))
  9. const script = descriptor.scriptSetup.content.replace(/^import .+$/gm, '')
  10. async function flush() {
  11. for (let i = 0; i < 8; i++) await Promise.resolve()
  12. await nextTick()
  13. }
  14. function mount(t) {
  15. const requests = { list: [], statistics: [] }, scope = ref({ rootTypeId: 2 }), lifecycle = {}
  16. const request = key => params => new Promise((resolve, reject) => requests[key].push({ params, resolve, reject }))
  17. const context = {
  18. ref, reactive, watch, rangeParams, Document: {}, Warning: {}, CircleCheck: {},
  19. useAlarmScope: () => ({ scope, scopeKey: computed(() => JSON.stringify(scope.value)), route: { query: {} } }),
  20. getAlarms: request('list'), getAlarmStatistics: request('statistics'),
  21. getAlarmOptions: async () => ({ data: {} }),
  22. onBeforeUnmount: callback => { lifecycle.unmount = callback }
  23. }
  24. const effects = effectScope()
  25. effects.run(() => vm.runInNewContext(`${script}
  26. globalThis.page = { statistics, statisticsLoading, statisticsError, rows, total, loading, error, filters, dates, pageNum, pageSize, search, reset, load }
  27. `, context))
  28. t.after(() => { lifecycle.unmount(); effects.stop() })
  29. return { page: context.page, requests, scope }
  30. }
  31. const stats = (total, abnormal, recovered) => ({ data: [{ level: 1, total, abnormal, recovered }] })
  32. const snapshot = value => JSON.parse(JSON.stringify(value))
  33. test('statistics use the full filtered result and do not delay table rendering', async t => {
  34. const { page, requests } = mount(t)
  35. await flush()
  36. requests.list[0].resolve({ data: { records: [{ id: 'one' }], total: 120 } })
  37. await flush()
  38. assert.equal(page.rows.value.length, 1)
  39. assert.equal(page.loading.value, false)
  40. assert.equal(page.statisticsLoading.value, true)
  41. requests.statistics[0].resolve({ data: [
  42. { level: 1, total: '30', abnormal: '10', recovered: '20' },
  43. { level: null, total: '90', abnormal: '40', recovered: '48' }
  44. ] })
  45. await flush()
  46. assert.deepEqual(snapshot(page.statistics.value), { total: 120, abnormal: 50, recovered: 68 })
  47. Object.assign(page.filters, { alarmNo: 'BJ', keyword: '设备', alarmLevel: 2, alarmStatus: 1 })
  48. page.dates.value = ['2026-09-01', '2026-09-24']
  49. page.pageNum.value = 3
  50. page.load()
  51. const params = requests.statistics[1].params
  52. assert.equal(params.rootTypeId, 2)
  53. assert.equal(params.keyword, '设备')
  54. assert.equal(params.alarmNo, 'BJ')
  55. assert.equal(params.alarmLevel, 2)
  56. assert.equal(params.alarmStatus, 1)
  57. assert.equal(params.startTime, '2026-09-01 00:00:00')
  58. assert.equal(params.endTime, '2026-09-24 23:59:59.999999')
  59. assert.equal(params.pageNum, undefined)
  60. assert.equal(params.pageSize, undefined)
  61. assert.equal(requests.list[1].params.pageNum, 3)
  62. })
  63. test('late statistics from an old search or subsystem cannot overwrite current cards', async t => {
  64. const { page, requests, scope } = mount(t)
  65. await flush()
  66. page.filters.keyword = '新查询'
  67. page.search()
  68. requests.statistics[1].resolve(stats(4, 3, 1))
  69. await flush()
  70. requests.statistics[0].resolve(stats(120, 50, 70))
  71. await flush()
  72. assert.equal(page.statistics.value.total, 4)
  73. page.search()
  74. scope.value = { rootTypeId: 1 }
  75. await flush()
  76. assert.equal(page.statistics.value, null)
  77. assert.equal(requests.statistics[3].params.rootTypeId, 1)
  78. requests.statistics[3].resolve(stats(2, 1, 1))
  79. requests.statistics[2].resolve(stats(10, 8, 2))
  80. await flush()
  81. assert.equal(page.statistics.value.total, 2)
  82. })
  83. test('statistics failure remains distinct from zero and leaves the list usable', async t => {
  84. const { page, requests } = mount(t)
  85. await flush()
  86. requests.statistics[0].reject(new Error('统计请求失败'))
  87. requests.list[0].resolve({ data: { records: [{ id: 'one' }], total: 1 } })
  88. await flush()
  89. assert.equal(page.statistics.value, null)
  90. assert.equal(page.statisticsError.value, '统计请求失败')
  91. assert.equal(page.statisticsLoading.value, false)
  92. assert.equal(page.rows.value.length, 1)
  93. assert.equal(page.error.value, '')
  94. page.reset()
  95. requests.statistics[1].resolve({ data: [] })
  96. await flush()
  97. assert.deepEqual(snapshot(page.statistics.value), { total: 0, abnormal: 0, recovered: 0 })
  98. assert.equal(page.statisticsError.value, '')
  99. })