분산 워커 관측 Part C — useNodeStatus 3초 폴링 훅 + statusVisual 색/라벨 매핑 + 2D 워커 카드 그리드 + raw three.js 파이프라인 시각화(정상=시안 파티클 흐름 / busy=가속 / paused=앰버 정지 / degraded=주황 / down=빨강 끊김, Redis 끊김=버스 빨강). GET /api/agent-office/nodes(Part B) 소비. r3f 대신 기설치 three 직접 사용. WebGL 미지원 시 카드 폴백 + 3D/그리드 토글. vitest 10 passed, build OK. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019LV86jBozkNhSFXJA412fq
43 lines
1.9 KiB
JavaScript
43 lines
1.9 KiB
JavaScript
import { describe, it, expect } from 'vitest';
|
|
import { linkColor, workerStateLabel, workerStatus, workerColor, workerTitle } from './statusVisual';
|
|
|
|
describe('statusVisual', () => {
|
|
it('maps link status to theme colors', () => {
|
|
expect(linkColor('healthy')).toBe('#00d4ff');
|
|
expect(linkColor('paused')).toBe('#fbbf24');
|
|
expect(linkColor('degraded')).toBe('#fb923c');
|
|
expect(linkColor('down')).toBe('#f43f5e');
|
|
expect(linkColor('???')).toBe('#4a5572');
|
|
});
|
|
|
|
it('labels a dead worker offline', () => {
|
|
expect(workerStateLabel({ alive: false })).toBe('오프라인');
|
|
expect(workerStateLabel(null)).toBe('오프라인');
|
|
});
|
|
|
|
it('labels alive workers by state', () => {
|
|
expect(workerStateLabel({ alive: true, state: 'idle' })).toBe('대기');
|
|
expect(workerStateLabel({ alive: true, state: 'busy' })).toBe('처리 중');
|
|
expect(workerStateLabel({ alive: true, state: 'paused' })).toBe('일시정지');
|
|
expect(workerStateLabel({ alive: true, state: 'market_open' })).toBe('장중');
|
|
});
|
|
|
|
it('derives worker status with dead-letter and paused precedence', () => {
|
|
expect(workerStatus({ alive: false })).toBe('down');
|
|
expect(workerStatus({ alive: true, state: 'paused' })).toBe('paused');
|
|
expect(workerStatus({ alive: true, state: 'idle', dead_letter: 3 })).toBe('degraded');
|
|
expect(workerStatus({ alive: true, state: 'idle', dead_letter: 0 })).toBe('healthy');
|
|
});
|
|
|
|
it('workerColor follows workerStatus', () => {
|
|
expect(workerColor({ alive: false })).toBe('#f43f5e');
|
|
expect(workerColor({ alive: true, state: 'idle' })).toBe('#00d4ff');
|
|
});
|
|
|
|
it('humanizes worker names', () => {
|
|
expect(workerTitle('insta-render')).toBe('Insta Render');
|
|
expect(workerTitle('ai_trade')).toBe('AI Trade');
|
|
expect(workerTitle('unknown-x')).toBe('unknown-x');
|
|
});
|
|
});
|