go-blockchain/tui/status_model_test.go
Claude df6d4c82c0
feat(tui): add StatusModel for chain sync header
Implements StatusModel as a cli.FrameModel that renders a single-line
chain status bar showing height, sync percentage, difficulty, peer
count and tip age. Includes formatAge and formatDifficulty helpers
with SI suffixes. Adds core/cli as a direct dependency.

Co-Authored-By: Charon <charon@lethean.io>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-22 23:55:22 +00:00

87 lines
1.9 KiB
Go

// Copyright (c) 2017-2026 Lethean (https://lt.hn)
//
// Licensed under the European Union Public Licence (EUPL) version 1.2.
// SPDX-License-Identifier: EUPL-1.2
package tui
import (
"strings"
"testing"
"time"
)
func TestStatusModel_View_Good_Initial(t *testing.T) {
c := seedChain(t, 0)
n := NewNode(c)
m := NewStatusModel(n)
got := m.View(80, 1)
if !strings.Contains(got, "syncing") && !strings.Contains(got, "0") {
t.Errorf("initial View should contain \"syncing\" or \"0\", got %q", got)
}
}
func TestStatusModel_Update_Good_StatusMsg(t *testing.T) {
c := seedChain(t, 5)
n := NewNode(c)
n.interval = 10 * time.Millisecond // keep test fast
m := NewStatusModel(n)
msg := NodeStatusMsg{
Height: 100,
Difficulty: 1500000,
PeerCount: 4,
SyncPct: 75.5,
TipTime: time.Now().Add(-30 * time.Second),
}
updated, cmd := m.Update(msg)
if cmd == nil {
t.Fatal("Update(NodeStatusMsg) should return a non-nil cmd")
}
if updated == nil {
t.Fatal("Update(NodeStatusMsg) should return a non-nil model")
}
sm, ok := updated.(*StatusModel)
if !ok {
t.Fatalf("Update returned %T, want *StatusModel", updated)
}
got := sm.View(120, 1)
if !strings.Contains(got, "100") {
t.Errorf("View after status update should contain height \"100\", got %q", got)
}
if !strings.Contains(got, "75.5") {
t.Errorf("View after status update should contain sync pct \"75.5\", got %q", got)
}
}
func TestStatusModel_View_Good_FullSync(t *testing.T) {
c := seedChain(t, 1)
n := NewNode(c)
m := NewStatusModel(n)
msg := NodeStatusMsg{
Height: 6312,
SyncPct: 100.0,
}
m.Update(msg)
got := m.View(120, 1)
if !strings.Contains(got, "6312") {
t.Errorf("View should contain height \"6312\", got %q", got)
}
}
func TestStatusModel_Init_Good(t *testing.T) {
c := seedChain(t, 3)
n := NewNode(c)
m := NewStatusModel(n)
cmd := m.Init()
if cmd == nil {
t.Fatal("Init() should return a non-nil cmd")
}
}