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>
145 lines
4.5 KiB
Go
145 lines
4.5 KiB
Go
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)
|
||
}
|
||
}
|