采集从仪表盘组件挪进模块级单例(web/telemetry.ts),流量曲线和每路 吞吐的历史跨页面留存——跟着组件走的话切一次页面就清零一次。每路吞吐 从 /connections 快照按连接逐条求差再按 inboundName 聚合:先求和再求差 会在连接关闭时算出负数。 图表换 ECharts(按需注册):手写 SVG 折线做不出平滑曲线和时间轴, 颜色在运行时从 CSS 变量取,跟随主题切换重取。 路由列表每行带走势、速率和可选的公网 IP 检测,点击跳路由页并选中 那一路(外壳传 focus 给 RouterPage 消费)。
51 lines
1.5 KiB
TypeScript
51 lines
1.5 KiB
TypeScript
import { describe, expect, it } from 'bun:test'
|
|
import { firstPort, kernelPorts, modeLabel } from './dashboard.ts'
|
|
|
|
describe('运行模式', () => {
|
|
it('三个已知模式有中文名', () => {
|
|
expect(modeLabel('rule')).toBe('规则')
|
|
expect(modeLabel('global')).toBe('全局')
|
|
expect(modeLabel('direct')).toBe('直连')
|
|
})
|
|
|
|
it('没见过的值原样显示,缺省是破折号', () => {
|
|
expect(modeLabel('script')).toBe('script')
|
|
expect(modeLabel(undefined)).toBe('—')
|
|
expect(modeLabel('')).toBe('—')
|
|
})
|
|
})
|
|
|
|
describe('代理端口', () => {
|
|
it('挑出大于 0 的端口,按固定顺序', () => {
|
|
expect(kernelPorts({ 'mixed-port': 7890, port: 7891, 'socks-port': 0 })).toEqual([
|
|
{ name: 'port', port: 7891 },
|
|
{ name: 'mixed-port', port: 7890 },
|
|
])
|
|
})
|
|
|
|
it('0、缺省和非数字都不算启用', () => {
|
|
expect(kernelPorts({ port: 0, 'socks-port': 'abc' })).toEqual([])
|
|
})
|
|
|
|
it('字符串端口号也认得', () => {
|
|
expect(kernelPorts({ port: '7890' })).toEqual([{ name: 'port', port: 7890 }])
|
|
})
|
|
})
|
|
|
|
describe('探测端口', () => {
|
|
it('单个端口直接用', () => {
|
|
expect(firstPort('7890')).toBe(7890)
|
|
})
|
|
|
|
it('多端口和区间取第一个数', () => {
|
|
expect(firstPort('200,302')).toBe(200)
|
|
expect(firstPort('401-429')).toBe(401)
|
|
})
|
|
|
|
it('解析不出或越界返回 null', () => {
|
|
expect(firstPort('')).toBeNull()
|
|
expect(firstPort('abc')).toBeNull()
|
|
expect(firstPort('70000')).toBeNull()
|
|
})
|
|
})
|