Files
image_table/image_table_test.go
Vladimir V Maksimov a4c5fc94b7 add test for TableBlockStyle column width calculation
Verifies that columns with styled rows don't get inflated widths
from struct string representation.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 05:26:40 +03:00

145 lines
4.5 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package image_table
import (
"image/color"
"image/png"
"log"
"os"
"testing"
)
func TestDrawTable(t *testing.T) {
header := []string{"Имя", "Возраст", "Город"}
rows := []any{
[]string{"Алиса", "23", "Москва"},
[]string{"Боб", "31", "Казань"},
struct {
Name string
Age int
City string
}{"Елена", 27, "Минск"},
[]string{"Олег", "44", "Сочи"},
}
img := DrawTableWarm(header, rows)
file, err := os.Create("./test-data/warm_table.png")
if err != nil {
log.Fatal("не могу создать файл:", err)
}
defer file.Close()
if err := png.Encode(file, img); err != nil {
log.Fatal("ошибка сохранения PNG:", err)
}
log.Println("Готово! Файл warm_table.png создан.")
}
func TestTableBlockStyleColumnWidths(t *testing.T) {
// Тест воспроизводит баг: когда все строки — *TableBlockStyle,
// ширина первого столбца не должна раздуваться из-за строкового
// представления всей структуры.
header := []string{"Час", "Заявка", "Ерид", "Тип отклонения", "Показы", "Клики"}
colorUp := color.RGBA{R: 200, G: 255, B: 200, A: 255}
colorDown := color.RGBA{R: 255, G: 200, B: 200, A: 255}
rows := []any{
&TableBlockStyle{
Cells: []any{"10", "test", "eridRanyko", "переполнение", "41% (сегодня 100 - вчера 71)", "18% (сегодня 50 - вчера 42)"},
BackgroundColor: colorUp,
},
&TableBlockStyle{
Cells: []any{"11", "test", "eridRanyko", "недостаток", "39% (сегодня 60 - вчера 99)", "22% (сегодня 30 - вчера 39)"},
BackgroundColor: colorDown,
},
&TableBlockStyle{
Cells: []any{"12", "test", "eridRanyko", "переполнение", "24% (сегодня 80 - вчера 65)", "10% (сегодня 44 - вчера 40)"},
BackgroundColor: colorUp,
},
}
img := DrawTableWarm(header, rows)
// Ширина столбца "Час" (с коротким содержимым "10","11","12") не должна
// быть больше 30% от общей ширины. До фикса она занимала ~70%.
imgWidth := img.Bounds().Dx()
maxFirstColWidth := imgWidth * 30 / 100
// Проверяем через пиксели: ищем первый вертикальный разделитель в заголовке
firstDividerX := 0
for x := 1; x < imgWidth; x++ {
r, g, b, _ := img.At(x, 16).RGBA()
if r>>8 == uint32(borderCol.R) && g>>8 == uint32(borderCol.G) && b>>8 == uint32(borderCol.B) {
firstDividerX = x
break
}
}
if firstDividerX == 0 {
t.Fatal("не нашёл вертикальный разделитель первого столбца")
}
t.Logf("ширина первого столбца: %d, общая ширина: %d, лимит: %d", firstDividerX, imgWidth, maxFirstColWidth)
if firstDividerX > maxFirstColWidth {
t.Errorf("первый столбец слишком широкий: %d > %d (%.0f%% от общей ширины)", firstDividerX, maxFirstColWidth, float64(firstDividerX)*100/float64(imgWidth))
}
// Сохраняем для визуальной проверки
file, err := os.Create("./test-data/styled_table.png")
if err != nil {
t.Fatal(err)
}
defer file.Close()
if err := png.Encode(file, img); err != nil {
t.Fatal(err)
}
t.Log("Файл test-data/styled_table.png создан")
}
func TestDocument(t *testing.T) {
doc := Document{
Blocks: []TableBlock{
{
Title: "Пользователи",
Header: []string{"ID", "Name", "Age"},
Rows: []any{
[]any{1, "Иван", 30},
&TableBlockStyle{
Cells: []any{2, "Пётр", 25},
BackgroundColor: color.RGBA{R: 225, G: 255, B: 225, A: 255},
},
},
},
{
Title: "Статистика",
Header: []string{"Метрика", "Значение"},
Rows: []any{
[]any{"Requests", 12000},
&TableBlockStyle{
Cells: []any{"Errors", 37},
BackgroundColor: color.RGBA{R: 255, G: 225, B: 225, A: 255},
},
},
},
},
}
img := RenderDocument(doc)
file, err := os.Create("./test-data/document.png")
if err != nil {
log.Fatal("не могу создать файл:", err)
}
defer file.Close()
if err := png.Encode(file, img); err != nil {
log.Fatal("ошибка сохранения PNG:", err)
}
}