|
|
@@ -0,0 +1,128 @@
|
|
|
+import assert from 'node:assert/strict'
|
|
|
+import { test } from 'node:test'
|
|
|
+import { planMarker } from '../src/modules/cockpit/domain/markerPlan.js'
|
|
|
+import { mountMarkerOverlay, syncMarkerOverlay, unmountMarkerOverlay } from '../src/modules/cockpit/services/markerOverlay.js'
|
|
|
+import { markerTestDocument } from './helpers/marker-dom.mjs'
|
|
|
+
|
|
|
+const tones = { lv1: '#ff3b52', lv2: '#ffb020', lv3: '#01abea', lv4: '#27d17a', neutral: '#5680b0' }
|
|
|
+const facility = (status, id = '1') => ({
|
|
|
+ key: `facility-point|WATER_PLANT|${id}`, kind: 'facility-point', code: 'WP001',
|
|
|
+ name: '水厂', type: 'WATER_PLANT', entityId: id, detailCategory: 'WATER_PLANT', clickable: true,
|
|
|
+ status, longitude: 110.38, latitude: 28.43,
|
|
|
+})
|
|
|
+const planOf = (row) => planMarker({ kind: row.kind, status: row.status, facilityType: row.type, industry: row.industry, tone: row.tone })
|
|
|
+
|
|
|
+function mount(t) {
|
|
|
+ const previous = globalThis.document
|
|
|
+ const document = markerTestDocument()
|
|
|
+ globalThis.document = document
|
|
|
+ assert.equal(mountMarkerOverlay(document.host), true)
|
|
|
+ t.after(() => {
|
|
|
+ unmountMarkerOverlay()
|
|
|
+ if (previous === undefined) delete globalThis.document
|
|
|
+ else globalThis.document = previous
|
|
|
+ })
|
|
|
+ return {
|
|
|
+ document,
|
|
|
+ sync: (rows, effectOf, extra = {}) => syncMarkerOverlay({
|
|
|
+ facilities: rows, facilityPlanOf: planOf, planOf, tones,
|
|
|
+ facilityEffectOf: effectOf, projectToWindow: () => ({ x: 100, y: 200 }), ...extra,
|
|
|
+ }),
|
|
|
+ node: (row) => document.host.nodes().find((node) => node.dataset.markerOverlayKey === row.key),
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+test('正常设施不能被错误或过期的门控键挂上报警环', (t) => {
|
|
|
+ const scene = mount(t)
|
|
|
+ const row = { ...facility('0'), tone: 'lv1' }
|
|
|
+ scene.sync([row], () => 'pulse')
|
|
|
+ assert.equal(scene.node(row).dataset.markerRing, 'no')
|
|
|
+ assert.equal(scene.node(row).dataset.markerEffect, undefined)
|
|
|
+})
|
|
|
+
|
|
|
+test('同一设施在超限降级与恢复时更新已有环的大小和透明度', (t) => {
|
|
|
+ const scene = mount(t)
|
|
|
+ const row = facility('2')
|
|
|
+ scene.sync([row], () => 'pulse')
|
|
|
+ assert.equal(scene.node(row).dataset.markerEffectConverged, 'no')
|
|
|
+ scene.sync([row], () => 'pulse', { converge: { peak: 0.6, alpha: 0.5 } })
|
|
|
+ const degraded = scene.node(row)
|
|
|
+ assert.equal(degraded.dataset.markerEffectConverged, 'yes')
|
|
|
+ assert.equal(degraded.dataset.markerEffectAlpha, '0.5')
|
|
|
+ const ringHost = degraded.children.find((node) => node.className.includes('marker-overlay-fx--'))
|
|
|
+ assert.equal(ringHost.style.opacity, '0.5')
|
|
|
+ assert.equal(ringHost.style.transform, 'scale(0.6)')
|
|
|
+ scene.sync([row], () => 'pulse', { converge: null })
|
|
|
+ assert.equal(scene.node(row).dataset.markerEffectConverged, 'no')
|
|
|
+ assert.equal(scene.node(row).dataset.markerEffectAlpha, '1')
|
|
|
+})
|
|
|
+
|
|
|
+test('设施报警、预警、维修与同态设备的实际环节点和动画配置一致', (t) => {
|
|
|
+ const scene = mount(t)
|
|
|
+ for (const [status, deviceStatus, effect, layers, period, color, glow] of [
|
|
|
+ ['1', 'WORK_ORDER', 'spin', 1, '18000ms', '#01abea', 0],
|
|
|
+ ['2', 'ALARM', 'pulse', 4, '1800ms', '#ff3b52', 1],
|
|
|
+ ['WARNING', 'WARNING', 'blink', 3, '1400ms', '#ffb020', 0],
|
|
|
+ ]) {
|
|
|
+ const row = facility(status)
|
|
|
+ scene.sync([row], () => effect, {
|
|
|
+ devices: [{ code: 'd1', status: deviceStatus, industry: 'WATER_SUPPLY', x: 100, y: 200 }],
|
|
|
+ deviceEffectOf: () => effect,
|
|
|
+ })
|
|
|
+ const node = scene.node(row)
|
|
|
+ const device = scene.document.host.nodes().find((item) => item.dataset.markerOverlayKey === 'device|d1')
|
|
|
+ assert.equal(node.dataset.markerTone, color)
|
|
|
+ for (const key of ['markerEffect', 'markerEffectLayers', 'markerEffectAlpha', 'markerEffectConverged', 'markerDrawWidth']) {
|
|
|
+ assert.equal(node.dataset[key], device.dataset[key])
|
|
|
+ }
|
|
|
+ const rings = node.children[0].children.filter((item) => item.className === 'marker-overlay-fx-ring')
|
|
|
+ assert.equal(rings.length, layers)
|
|
|
+ assert.equal(rings[0].style.animationDuration, period)
|
|
|
+ assert.equal(rings[0].style.animationName, effect === 'spin' ? 'markerFxSpin' : `markerFxRing--${effect}--0`)
|
|
|
+ assert.equal(node.children[0].children.filter((item) => item.className === 'marker-overlay-fx-glow').length, glow)
|
|
|
+ }
|
|
|
+})
|
|
|
+
|
|
|
+test('特效开关与设施状态切换不遗留旧环,编码重复的设施按主键独立更新', (t) => {
|
|
|
+ const scene = mount(t)
|
|
|
+ const left = facility('1', 'A')
|
|
|
+ const right = facility('2', 'B')
|
|
|
+ const effects = (row) => row.key === left.key ? 'spin' : 'pulse'
|
|
|
+ scene.sync([left, right], effects)
|
|
|
+ assert.equal(scene.node(left).dataset.markerEffect, 'spin')
|
|
|
+ assert.equal(scene.node(right).dataset.markerEffect, 'pulse')
|
|
|
+ scene.sync([left, right], () => '')
|
|
|
+ assert.equal(scene.node(left).dataset.markerRing, 'no')
|
|
|
+ assert.equal(scene.node(right).dataset.markerEffect, undefined)
|
|
|
+ scene.sync([left, right], effects)
|
|
|
+ assert.equal(scene.node(left).dataset.markerEffect, 'spin')
|
|
|
+ scene.sync([{ ...left, status: '0' }, right], effects)
|
|
|
+ assert.equal(scene.node(left).dataset.markerRing, 'no')
|
|
|
+ assert.equal(scene.node(right).dataset.markerRing, 'yes')
|
|
|
+ scene.sync([], effects)
|
|
|
+ assert.equal(scene.node(left).style.display, 'none')
|
|
|
+ assert.equal(scene.node(right).style.display, 'none')
|
|
|
+})
|
|
|
+
|
|
|
+test('跨图层降级与恢复同时更新设备和监测点已有节点', (t) => {
|
|
|
+ const scene = mount(t)
|
|
|
+ const extra = {
|
|
|
+ devices: [{ code: 'd2', status: 'ALARM', x: 100, y: 200 }],
|
|
|
+ deviceEffectOf: () => 'pulse',
|
|
|
+ markers: [{ kind: 'monitoring-point', code: 'MP1', status: 'ALARM', tone: 'lv1', longitude: 110.38, latitude: 28.43 }],
|
|
|
+ effectOf: () => 'pulse',
|
|
|
+ }
|
|
|
+ scene.sync([], () => '', extra)
|
|
|
+ scene.sync([], () => '', { ...extra, converge: { peak: 0.6, alpha: 0.5 } })
|
|
|
+ for (const key of ['device|d2', 'monitoring-point|MP1']) {
|
|
|
+ const node = scene.document.host.nodes().find((item) => item.dataset.markerOverlayKey === key)
|
|
|
+ assert.equal(node.dataset.markerEffectConverged, 'yes')
|
|
|
+ assert.equal(node.dataset.markerEffectAlpha, '0.5')
|
|
|
+ }
|
|
|
+ scene.sync([], () => '', extra)
|
|
|
+ for (const key of ['device|d2', 'monitoring-point|MP1']) {
|
|
|
+ const node = scene.document.host.nodes().find((item) => item.dataset.markerOverlayKey === key)
|
|
|
+ assert.equal(node.dataset.markerEffectConverged, 'no')
|
|
|
+ assert.equal(node.dataset.markerEffectAlpha, '1')
|
|
|
+ }
|
|
|
+})
|