| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210 |
- import test from 'node:test'
- import assert from 'node:assert/strict'
- import { readFile } from 'node:fs/promises'
- import vm from 'node:vm'
- import { computed, effectScope, nextTick, ref, watch } from 'vue'
- import { parse } from '@vue/compiler-sfc'
- const filename = new URL('../src/views/subSystem/alarm/common/remind.vue', import.meta.url)
- const { descriptor } = parse(await readFile(filename, 'utf8'))
- // 执行实际页面脚本,用可控请求和生命周期验证异步显示,不依赖真实接口或等待轮询。
- const script = descriptor.scriptSetup.content.replace(/^import .+$/gm, '')
- function mountReminder(t) {
- const requests = { reminders: [], statistics: [], options: [] }
- const lifecycle = {}, timers = new Map(), scope = ref({ rootTypeId: 2 })
- const request = name => params => new Promise((resolve, reject) => {
- requests[name].push({ params, resolve, reject })
- })
- const context = {
- computed, ref, watch,
- useAlarmScope: () => ({ scope, scopeKey: computed(() => JSON.stringify(scope.value)) }),
- getAlarmReminders: request('reminders'),
- getAlarmStatistics: request('statistics'),
- getAlarmOptions: request('options'),
- onMounted: callback => { lifecycle.mounted = callback },
- onActivated: callback => { lifecycle.activated = callback },
- onDeactivated: callback => { lifecycle.deactivated = callback },
- onBeforeUnmount: callback => { lifecycle.unmount = callback },
- setInterval: (callback, delay) => { timers.set(delay, callback); return delay },
- clearInterval: timer => timers.delete(timer)
- }
- const effects = effectScope()
- effects.run(() => vm.runInNewContext(`${script}
- globalThis.page = {
- visibleRows, received, loading, hasLoaded, stats, options, error, refreshError,
- manualPause, hoverPause, focusPause, detailPause, pending, level,
- load, restart, retry
- }
- `, context))
- t.after(() => { lifecycle.unmount(); effects.stop() })
- return { page: context.page, requests, lifecycle, timers, scope }
- }
- async function flush() {
- for (let i = 0; i < 5; i += 1) await Promise.resolve()
- await nextTick()
- }
- const rowsResponse = records => ({ data: { records } })
- const event = id => ({ id, latestOperationTime: '2026-09-24 10:00:00' })
- test('first response displays immediately without waiting for statistics, options or polling', async t => {
- const { page, requests, lifecycle, timers } = mountReminder(t)
- assert.equal(requests.reminders.length, 1)
- assert.equal(timers.size, 0)
- lifecycle.mounted()
- lifecycle.activated()
- assert.equal(requests.reminders.length, 1)
- assert.ok(timers.has(30000))
- const rows = [event(1)]
- requests.reminders[0].resolve(rowsResponse(rows))
- await flush()
- assert.deepEqual(page.visibleRows.value, rows)
- assert.equal(page.loading.value, false)
- assert.equal(page.hasLoaded.value, true)
- requests.statistics[0].resolve({ data: [{ level: 1, total: 3 }] })
- await flush()
- assert.equal(page.stats.value[0].total, 3)
- assert.deepEqual(page.visibleRows.value, rows)
- })
- for (const pause of ['hoverPause', 'focusPause', 'manualPause', 'detailPause']) {
- test(`first response still displays while ${pause} is active`, async t => {
- const { page, requests } = mountReminder(t)
- page[pause].value = true
- requests.reminders[0].resolve(rowsResponse([event(1)]))
- await flush()
- assert.equal(page.visibleRows.value[0]?.id, 1)
- assert.equal(page.pending.value, 0)
- assert.equal(page.loading.value, false)
- })
- }
- test('subsequent polling preserves paused reading and releases updates when unpaused', async t => {
- const { page, requests, lifecycle, timers } = mountReminder(t)
- lifecycle.mounted()
- requests.reminders[0].resolve(rowsResponse([event(1)]))
- await flush()
- page.hoverPause.value = true
- timers.get(30000)()
- assert.equal(page.loading.value, true)
- assert.equal(page.hasLoaded.value, true)
- assert.equal(page.visibleRows.value[0].id, 1)
- requests.reminders[1].resolve(rowsResponse([event(2)]))
- await flush()
- assert.equal(page.visibleRows.value[0].id, 1)
- assert.equal(page.received.value[0].id, 2)
- assert.equal(page.pending.value, 1)
- page.hoverPause.value = false
- await flush()
- assert.equal(page.visibleRows.value[0].id, 2)
- assert.equal(page.pending.value, 0)
- })
- test('an initially empty list shows newly received events even while paused', async t => {
- const { page, requests } = mountReminder(t)
- requests.reminders[0].resolve(rowsResponse([]))
- await flush()
- page.hoverPause.value = true
- page.load()
- requests.reminders[1].resolve(rowsResponse([event(1)]))
- await flush()
- assert.equal(page.visibleRows.value[0]?.id, 1)
- })
- test('statistics and options failures do not hide reminders and can be retried', async t => {
- const { page, requests } = mountReminder(t)
- requests.statistics[0].reject(new Error('statistics failed'))
- requests.options[0].reject(new Error('options failed'))
- requests.reminders[0].resolve(rowsResponse([event(1)]))
- await flush()
- assert.equal(page.loading.value, false)
- assert.equal(page.visibleRows.value.length, 1)
- assert.equal(page.refreshError.value, 'statistics failed')
- page.retry()
- assert.equal(requests.options.length, 2)
- requests.statistics[1].resolve({ data: [] })
- requests.options[1].resolve({ data: { alarmLevels: [] } })
- requests.reminders[1].resolve(rowsResponse([event(2)]))
- await flush()
- assert.equal(page.refreshError.value, '')
- assert.equal(page.visibleRows.value[0].id, 2)
- })
- test('a failed list request stops loading immediately and recovers while paused', async t => {
- const { page, requests } = mountReminder(t)
- requests.reminders[0].reject(new Error('reminders failed'))
- await flush()
- assert.equal(page.loading.value, false)
- assert.equal(page.error.value, 'reminders failed')
- requests.statistics[0].resolve({ data: [] })
- await flush()
- assert.equal(page.error.value, 'reminders failed')
- page.focusPause.value = true
- page.retry()
- requests.reminders[1].resolve(rowsResponse([event(1)]))
- await flush()
- assert.equal(page.error.value, '')
- assert.equal(page.visibleRows.value[0].id, 1)
- })
- test('changing scope rejects older responses and displays the new scope while paused', async t => {
- const { page, requests, scope } = mountReminder(t)
- page.hoverPause.value = true
- scope.value = { rootTypeId: 1 }
- await flush()
- assert.equal(requests.reminders[1].params.rootTypeId, 1)
- requests.reminders[1].resolve(rowsResponse([event(2)]))
- requests.statistics[1].resolve({ data: [{ level: 1, total: 2 }] })
- requests.options[1].resolve({ data: { name: 'current' } })
- await flush()
- requests.reminders[0].resolve(rowsResponse([event(1)]))
- requests.statistics[0].resolve({ data: [{ level: 1, total: 99 }] })
- requests.options[0].reject(new Error('old scope failed'))
- await flush()
- assert.equal(page.visibleRows.value[0].id, 2)
- assert.equal(page.stats.value[0].total, 2)
- assert.equal(page.options.value.name, 'current')
- assert.equal(page.refreshError.value, '')
- })
- test('filter changes show the new result immediately despite manual pause', async t => {
- const { page, requests } = mountReminder(t)
- requests.reminders[0].resolve(rowsResponse([event(1)]))
- await flush()
- page.manualPause.value = true
- page.level.value = 2
- page.restart()
- assert.equal(requests.reminders[1].params.alarmLevel, 2)
- requests.reminders[1].resolve(rowsResponse([event(2)]))
- await flush()
- assert.equal(page.visibleRows.value[0].id, 2)
- assert.equal(page.manualPause.value, true)
- })
- test('returning to a cached page refreshes immediately and ignores pre-deactivation requests', async t => {
- const { page, requests, lifecycle } = mountReminder(t)
- requests.reminders[0].resolve(rowsResponse([event(1)]))
- await flush()
- page.hoverPause.value = true
- page.focusPause.value = true
- page.manualPause.value = true
- page.load()
- lifecycle.deactivated()
- page.load()
- assert.equal(requests.reminders.length, 2)
- assert.equal(page.hoverPause.value, false)
- assert.equal(page.focusPause.value, false)
- lifecycle.activated()
- assert.equal(requests.reminders.length, 3)
- requests.reminders[1].resolve(rowsResponse([event(2)]))
- await flush()
- assert.equal(page.loading.value, true)
- assert.equal(page.visibleRows.value[0].id, 1)
- requests.reminders[2].resolve(rowsResponse([event(3)]))
- await flush()
- assert.equal(page.loading.value, false)
- assert.equal(page.visibleRows.value[0].id, 3)
- assert.equal(page.manualPause.value, true)
- })
|