test: Phase 3 comprehensive test coverage — 105 tests, zero race conditions
- Add test/crypto/ (19 tests): AES-256-GCM encrypt/decrypt, PBKDF2, IsEncrypted, HashPassword - Add test/knownhosts/ (14 tests): TOFU verify, MITM detection, CRUD, persistence - Add test/storage/ (20 tests): KeyPair/Snippet CRUD, encryption, MergeStrategy - Add test/config/ (9 tests): config lifecycle, path getters - Add test/tui/ (10 tests): WrapFooter, ClampWidth, TruncateStr - Fix knownhosts deadlock: Add/Remove use saveInternal() - Export responsive.go functions for testing - Add docs/TEST_PLAN.md with full scenario documentation Coverage: crypto 0%→100%, knownhosts 0%→100%, storage 40%→90%, config 22%→80%, tui 40%→70%
This commit is contained in:
@@ -0,0 +1,92 @@
|
||||
package tui_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"git.tukangketik.id/swanadiva/hostkeeper/pkg/tui"
|
||||
)
|
||||
|
||||
// 5.1 WrapFooter short — single line
|
||||
func TestWrapFooterShort(t *testing.T) {
|
||||
result := tui.WrapFooter("short footer", 80)
|
||||
if result != "short footer" {
|
||||
t.Errorf("WrapFooter short = %q, want %q", result, "short footer")
|
||||
}
|
||||
}
|
||||
|
||||
// 5.2 WrapFooter long — multi-line
|
||||
func TestWrapFooterLong(t *testing.T) {
|
||||
// Footer longer than 30 chars should wrap
|
||||
footer := "key1 key2 key3 key4 key5 key6 key7 key8 key9 key10"
|
||||
result := tui.WrapFooter(footer, 30)
|
||||
if result == footer {
|
||||
t.Error("WrapFooter should wrap long footer")
|
||||
}
|
||||
}
|
||||
|
||||
// 5.3 WrapFooter empty
|
||||
func TestWrapFooterEmpty(t *testing.T) {
|
||||
result := tui.WrapFooter("", 80)
|
||||
if result != "" {
|
||||
t.Errorf("WrapFooter empty = %q, want %q", result, "")
|
||||
}
|
||||
}
|
||||
|
||||
// 5.4 ClampWidth over max
|
||||
func TestClampWidthOver(t *testing.T) {
|
||||
result := tui.ClampWidth(200, 80)
|
||||
if result > 74 { // 80 - 6 (boxOverhead)
|
||||
t.Errorf("ClampWidth(200, 80) = %d, should be <= 74", result)
|
||||
}
|
||||
}
|
||||
|
||||
// 5.5 ClampWidth under min
|
||||
func TestClampWidthUnder(t *testing.T) {
|
||||
result := tui.ClampWidth(5, 80)
|
||||
if result < 20 {
|
||||
t.Errorf("ClampWidth(5, 80) = %d, should be >= 20", result)
|
||||
}
|
||||
}
|
||||
|
||||
// 5.6 ClampWidth in range
|
||||
func TestClampWidthInRange(t *testing.T) {
|
||||
result := tui.ClampWidth(50, 80)
|
||||
if result != 50 {
|
||||
t.Errorf("ClampWidth(50, 80) = %d, want 50", result)
|
||||
}
|
||||
}
|
||||
|
||||
// 5.7 TruncateStr short
|
||||
func TestTruncateStrShort(t *testing.T) {
|
||||
result := tui.TruncateStr("hello", 20)
|
||||
if result != "hello" {
|
||||
t.Errorf("TruncateStr short = %q, want %q", result, "hello")
|
||||
}
|
||||
}
|
||||
|
||||
// 5.8 TruncateStr long
|
||||
func TestTruncateStrLong(t *testing.T) {
|
||||
result := tui.TruncateStr("this is a very long string that should be truncated", 10)
|
||||
if result == "this is a very long string that should be truncated" {
|
||||
t.Error("TruncateStr should truncate long string")
|
||||
}
|
||||
if len(result) > 12 { // 11 content + 1 ellipsis
|
||||
t.Errorf("TruncateStr result too long: %d chars", len(result))
|
||||
}
|
||||
}
|
||||
|
||||
// 5.9 TruncateStr empty
|
||||
func TestTruncateStrEmpty(t *testing.T) {
|
||||
result := tui.TruncateStr("", 20)
|
||||
if result != "" {
|
||||
t.Errorf("TruncateStr empty = %q, want %q", result, "")
|
||||
}
|
||||
}
|
||||
|
||||
// 5.10 TruncateStr unicode
|
||||
func TestTruncateStrUnicode(t *testing.T) {
|
||||
result := tui.TruncateStr("こんにちは世界", 5)
|
||||
if result == "こんにちは世界" {
|
||||
t.Error("TruncateStr should truncate unicode string")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user