package game import ( "strings" "testing" "thirdcollapse/internal/world" ) func TestBuildTinyMap(t *testing.T) { g := &Game{ World: world.New("../../data"), } mg := mapGlyphsForPlayer(true) tests := []struct { name string roomID int want []string // expected lines, or nil to just check count }{ { name: "room 1 has east exit", roomID: 1, }, { name: "room 2 has west/north/east", roomID: 2, }, { name: "room 4 has west/north/east", roomID: 4, }, { name: "room 21 has west only", roomID: 21, }, { name: "room 22 west of town square", roomID: 22, }, { name: "room 25 east of south of west", roomID: 25, }, { name: "room 8 hacking lab", roomID: 8, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { lines := buildTinyMap(g, tt.roomID, mg) if len(lines) != 7 { t.Fatalf("expected 7 lines, got %d", len(lines)) } if lines[0] != "╔═════╗" { t.Errorf("line 0: want ╔═════╗, got %s", lines[0]) } if lines[6] != "╚═════╝" { t.Errorf("line 6: want ╚═════╝, got %s", lines[6]) } for i := 1; i <= 5; i++ { if !strings.HasPrefix(lines[i], "║") || !strings.HasSuffix(lines[i], "║") { t.Errorf("line %d: should have ║ borders, got %s", i, lines[i]) } if len([]rune(lines[i])) != 7 { t.Errorf("line %d: expected 7 runes, got %d in %q", i, len([]rune(lines[i])), lines[i]) } } t.Logf("Room %d map:\n%s", tt.roomID, strings.Join(lines, "\n")) }) } } func TestWrapText(t *testing.T) { tests := []struct { text string width int want int // expected number of lines }{ {"hello world", 70, 1}, {"hello world", 5, 2}, {"", 70, 0}, {"a b c d e f g h i j", 5, 4}, } for _, tt := range tests { result := wrapText(tt.text, tt.width) if len(result) != tt.want { t.Errorf("wrapText(%q, %d) = %d lines, want %d: %v", tt.text, tt.width, len(result), tt.want, result) } } } func TestBuildFullMap(t *testing.T) { g := &Game{ World: world.New("../../data"), } mg := mapGlyphsForPlayer(true) tests := []struct { name string roomID int width int height int }{ {"room 1 30x20", 1, 30, 20}, {"room 1 20x10", 1, 20, 10}, {"room 25 30x20", 25, 30, 20}, {"min size 5x5", 1, 5, 5}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { lines := buildFullMap(g, tt.roomID, tt.width, tt.height, mg) if len(lines) != tt.height { t.Errorf("expected %d lines, got %d", tt.height, len(lines)) } for i, line := range lines { if len([]rune(line)) != tt.width { t.Errorf("line %d: expected %d runes, got %d in %q", i, tt.width, len([]rune(line)), line) } } t.Logf("Room %d %dx%d map:\n%s", tt.roomID, tt.width, tt.height, strings.Join(lines, "\n")) }) } } func TestStripBlankRows(t *testing.T) { input := []string{" ", "hello", "", " world ", " "} want := []string{"hello", " world "} got := stripBlankRows(input) if len(got) != len(want) { t.Fatalf("expected %d lines, got %d", len(want), len(got)) } for i := range want { if got[i] != want[i] { t.Errorf("line %d: want %q, got %q", i, want[i], got[i]) } } } func TestLeftTrimCommon(t *testing.T) { input := []string{" hello", " world", " ", " foo"} got := leftTrimCommon(input) // min leading spaces across non-blank lines: " hello"=4, " world"=4, " foo"=2 → min=2 // trim 2 from all lines if got[0] != " hello" { t.Errorf("line 0: want %q, got %q", " hello", got[0]) } if got[1] != " world" { t.Errorf("line 1: want %q, got %q", " world", got[1]) } if got[2] != "" { t.Errorf("line 2: want %q, got %q", "", got[2]) } if got[3] != "foo" { t.Errorf("line 3: want %q, got %q", "foo", got[3]) } } func TestLeftTrimCommonEmpty(t *testing.T) { input := []string{" ", "", " "} got := leftTrimCommon(input) if len(got) != 3 { t.Fatalf("expected 3 lines, got %d", len(got)) } } func TestLeftTrimCommonZero(t *testing.T) { input := []string{"hello", "world"} got := leftTrimCommon(input) if got[0] != "hello" { t.Errorf("line 0: want %q, got %q", "hello", got[0]) } if got[1] != "world" { t.Errorf("line 1: want %q, got %q", "world", got[1]) } }