clone

fifteen puzzle games for the terminal, with daily puzzles, weekly ladders and xp, built on bubble tea

chore/app-model-decomp
puzzletea / games / nonogram / print_adapter_test.go
print_adapter_test.go 3.4K
1package nonogram23import (4 "math"5 "testing"67 "github.com/FelineStateMachine/puzzletea/export/pdf"8)910func TestNormalizeNonogramHintsForRender(t *testing.T) {11 tests := []struct {12 name string13 hints [][]int14 size int15 want [][]int16 }{17 {18 name: "empty source defaults to zeros",19 hints: nil,20 size: 3,21 want: [][]int{{0}, {0}, {0}},22 },23 {24 name: "preserves provided hint rows",25 hints: [][]int{{3, 1}, {}, {2}},26 size: 3,27 want: [][]int{{3, 1}, {0}, {2}},28 },29 {30 name: "pads beyond provided rows",31 hints: [][]int{{1}},32 size: 3,33 want: [][]int{{1}, {0}, {0}},34 },35 {36 name: "non-positive size returns nil",37 hints: [][]int{{1}},38 size: 0,39 want: nil,40 },41 }4243 for _, tt := range tests {44 t.Run(tt.name, func(t *testing.T) {45 got := normalizeNonogramHintsForRender(tt.hints, tt.size)46 if len(got) != len(tt.want) {47 t.Fatalf("rows = %d, want %d", len(got), len(tt.want))48 }49 for row := range len(tt.want) {50 if len(got[row]) != len(tt.want[row]) {51 t.Fatalf("row %d len = %d, want %d", row, len(got[row]), len(tt.want[row]))52 }53 for col := range len(tt.want[row]) {54 if got[row][col] != tt.want[row][col] {55 t.Fatalf("row %d col %d = %d, want %d", row, col, got[row][col], tt.want[row][col])56 }57 }58 }59 })60 }61}6263func TestNormalizeNonogramHintsForRenderCopiesRows(t *testing.T) {64 src := [][]int{{2, 1}}6566 got := normalizeNonogramHintsForRender(src, 1)67 if got == nil || len(got) != 1 {68 t.Fatalf("unexpected normalized hints: %#v", got)69 }7071 src[0][0] = 972 if got[0][0] != 2 {73 t.Fatalf("normalized hint should be copied, got %d want 2", got[0][0])74 }75}7677func TestLayoutNonogramCentersGrid(t *testing.T) {78 tests := []struct {79 name string80 rowHintCol int81 colHintRow int82 }{83 {name: "shallow hints", rowHintCol: 1, colHintRow: 1},84 {name: "deep hints", rowHintCol: 5, colHintRow: 4},85 }8687 const (88 pageNo = 389 pageW = 139.790 pageH = 215.991 )9293 boardArea := pdfexport.PuzzleBoardRect(pageW, pageH, pageNo, 1)94 for _, tt := range tests {95 t.Run(tt.name, func(t *testing.T) {96 layout := layoutNonogram(97 pageW,98 pageH,99 pageNo,100 1,101 10,102 10,103 tt.rowHintCol,104 tt.colHintRow,105 )106 if layout.cellSize <= 0 {107 t.Fatal("expected non-zero cell size")108 }109110 gridW := 10.0 * layout.cellSize111 gridH := 10.0 * layout.cellSize112 centerX := layout.gridX + gridW/2113 centerY := layout.gridY + gridH/2114 wantX := boardArea.X + boardArea.W/2115 wantY := boardArea.Y + boardArea.H/2116117 if diff := math.Abs(centerX - wantX); diff > 0.8 {118 t.Fatalf("grid centerX diff = %.3f, want <= 0.8", diff)119 }120 if diff := math.Abs(centerY - wantY); diff > 0.8 {121 t.Fatalf("grid centerY diff = %.3f, want <= 0.8", diff)122 }123124 fullW := float64(tt.rowHintCol+10) * layout.cellSize125 fullH := float64(tt.colHintRow+10) * layout.cellSize126 if layout.hintStartX < boardArea.X-0.01 {127 t.Fatalf("hintStartX = %.3f, want >= %.3f", layout.hintStartX, boardArea.X)128 }129 if layout.hintStartY < boardArea.Y-0.01 {130 t.Fatalf("hintStartY = %.3f, want >= %.3f", layout.hintStartY, boardArea.Y)131 }132 if right := layout.hintStartX + fullW; right > boardArea.X+boardArea.W+0.01 {133 t.Fatalf("hint block right = %.3f, want <= %.3f", right, boardArea.X+boardArea.W)134 }135 if bottom := layout.hintStartY + fullH; bottom > boardArea.Y+boardArea.H+0.01 {136 t.Fatalf("hint block bottom = %.3f, want <= %.3f", bottom, boardArea.Y+boardArea.H)137 }138 })139 }140}