import assert from 'node:assert/strict' import { test } from 'node:test' import { getWindowChangeAlarm } from '../src/utils/thresholdAlarmWindow.ts' const second = (value) => value * 1000 test('最近 10 秒内相邻数据上涨幅度大于超限范围时告警', () => { const points = [ { ts: second(47), value: 800 }, { ts: second(48), value: 901 }, { ts: second(55), value: 901 } ] assert.deepEqual(getWindowChangeAlarm(points, second(55), 10, 100), { change: 101, direction: 'increase', fromValue: 800, fromTs: second(47), toTs: second(48), toValue: 901 }) }) test('最近 10 秒内相邻数据下降幅度大于超限范围时同样告警', () => { const points = [ { ts: second(47), value: 901 }, { ts: second(48), value: 800 }, { ts: second(55), value: 800 } ] assert.deepEqual(getWindowChangeAlarm(points, second(55), 10, 100), { change: 101, direction: 'decrease', fromValue: 901, fromTs: second(47), toTs: second(48), toValue: 800 }) }) test('相邻数据间隔不固定时仍按相邻变化量判断', () => { const points = [ { ts: second(46), value: 800 }, { ts: second(47), value: 850 }, { ts: second(49), value: 951 }, { ts: second(53), value: 970 }, { ts: second(55), value: 970 } ] assert.deepEqual(getWindowChangeAlarm(points, second(55), 10, 100), { change: 101, direction: 'increase', fromValue: 850, fromTs: second(47), toTs: second(49), toValue: 951 }) }) test('相邻数据未超限时,即使窗口累计变化超限也不告警', () => { const points = [ { ts: second(46), value: 850 }, { ts: second(47), value: 900 }, { ts: second(48), value: 950 }, { ts: second(55), value: 950 } ] assert.equal(getWindowChangeAlarm(points, second(55), 10, 100), undefined) }) test('窗口内有多次超限时返回最新一组相邻变化', () => { const points = [ { ts: second(47), value: 800 }, { ts: second(48), value: 901 }, { ts: second(50), value: 800 }, { ts: second(51), value: 650 }, { ts: second(55), value: 650 } ] assert.deepEqual(getWindowChangeAlarm(points, second(55), 10, 100), { change: 150, direction: 'decrease', fromValue: 800, fromTs: second(50), toTs: second(51), toValue: 650 }) }) test('窗口外的数据不参与幅度计算', () => { const points = [ { ts: second(45), value: 1000 }, { ts: second(46), value: 800 }, { ts: second(55), value: 800 } ] assert.equal(getWindowChangeAlarm(points, second(55), 10, 100), undefined) }) test('窗口随最新数据右移,窗口外的相邻超限退出后告警解除', () => { const points = [ { ts: second(46), value: 800 }, { ts: second(47), value: 901 }, { ts: second(56), value: 900 } ] assert.equal(getWindowChangeAlarm(points, second(56), 10, 100), undefined) }) test('范围边界相等时不触发', () => { const points = [ { ts: second(54), value: 800 }, { ts: second(55), value: 900 } ] assert.equal(getWindowChangeAlarm(points, second(55), 10, 100), undefined) }) test('乱序数据中晚于当前时间的点不参与检查', () => { const points = [ { ts: second(54), value: 800 }, { ts: second(55), value: 900 }, { ts: second(56), value: 1000 } ] assert.equal(getWindowChangeAlarm(points, second(55), 10, 100), undefined) }) test('窗口内只有一个数据点时不触发', () => { const points = [{ ts: second(55), value: 800 }] assert.equal(getWindowChangeAlarm(points, second(55), 10, 0), undefined) })