mirror of
https://github.com/Belphemur/CBZOptimizer.git
synced 2025-10-14 04:28:51 +02:00
262 lines
6.4 KiB
Go
262 lines
6.4 KiB
Go
package webp
|
|
|
|
import (
|
|
"bytes"
|
|
"image"
|
|
"image/color"
|
|
"image/draw"
|
|
"image/png"
|
|
"sync"
|
|
"testing"
|
|
|
|
"github.com/belphemur/CBZOptimizer/v2/internal/manga"
|
|
"github.com/belphemur/CBZOptimizer/v2/pkg/converter/constant"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func createTestImage(width, height int) image.Image {
|
|
img := image.NewRGBA(image.Rect(0, 0, width, height))
|
|
draw.Draw(img, img.Bounds(), &image.Uniform{color.White}, image.Point{}, draw.Src)
|
|
return img
|
|
}
|
|
|
|
func createTestPage(t *testing.T, index int, width, height int) *manga.Page {
|
|
img := createTestImage(width, height)
|
|
var buf bytes.Buffer
|
|
err := png.Encode(&buf, img)
|
|
require.NoError(t, err)
|
|
|
|
return &manga.Page{
|
|
Index: uint16(index),
|
|
Contents: &buf,
|
|
Extension: ".png",
|
|
Size: uint64(buf.Len()),
|
|
}
|
|
}
|
|
|
|
// TestConverter_ConvertChapter tests the ConvertChapter method of the WebP converter.
|
|
// It verifies various scenarios including:
|
|
// - Converting single normal images
|
|
// - Converting multiple normal images
|
|
// - Converting tall images with split enabled
|
|
// - Handling tall images that exceed maximum height
|
|
//
|
|
// For each test case it validates:
|
|
// - Proper error handling
|
|
// - Expected number of output pages
|
|
// - Correct page ordering
|
|
// - Split page handling and indexing
|
|
// - Progress callback behavior
|
|
//
|
|
// The test uses different image dimensions and split settings to ensure
|
|
// the converter handles all cases correctly while maintaining proper
|
|
// progress reporting and page ordering.
|
|
func TestConverter_ConvertChapter(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
pages []*manga.Page
|
|
split bool
|
|
expectSplit bool
|
|
expectError bool
|
|
numExpected int
|
|
}{
|
|
{
|
|
name: "Single normal image",
|
|
pages: []*manga.Page{createTestPage(t, 1, 800, 1200)},
|
|
split: false,
|
|
expectSplit: false,
|
|
numExpected: 1,
|
|
},
|
|
{
|
|
name: "Multiple normal images",
|
|
pages: []*manga.Page{
|
|
createTestPage(t, 1, 800, 1200),
|
|
createTestPage(t, 2, 800, 1200),
|
|
},
|
|
split: false,
|
|
expectSplit: false,
|
|
numExpected: 2,
|
|
},
|
|
{
|
|
name: "Tall image with split enabled",
|
|
pages: []*manga.Page{createTestPage(t, 1, 800, 5000)},
|
|
split: true,
|
|
expectSplit: true,
|
|
numExpected: 3, // Based on cropHeight of 2000
|
|
},
|
|
{
|
|
name: "Tall image without split",
|
|
pages: []*manga.Page{createTestPage(t, 1, 800, webpMaxHeight+100)},
|
|
split: false,
|
|
expectError: true,
|
|
numExpected: 1,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
converter := New()
|
|
err := converter.PrepareConverter()
|
|
require.NoError(t, err)
|
|
|
|
chapter := &manga.Chapter{
|
|
Pages: tt.pages,
|
|
}
|
|
|
|
var progressMutex sync.Mutex
|
|
var lastProgress uint32
|
|
progress := func(message string, current uint32, total uint32) {
|
|
progressMutex.Lock()
|
|
defer progressMutex.Unlock()
|
|
assert.GreaterOrEqual(t, current, lastProgress, "Progress should never decrease")
|
|
lastProgress = current
|
|
assert.LessOrEqual(t, current, total, "Current progress should not exceed total")
|
|
}
|
|
|
|
convertedChapter, err := converter.ConvertChapter(chapter, 80, tt.split, progress)
|
|
|
|
if tt.expectError {
|
|
assert.Error(t, err)
|
|
if convertedChapter != nil {
|
|
assert.LessOrEqual(t, len(convertedChapter.Pages), tt.numExpected)
|
|
}
|
|
return
|
|
}
|
|
|
|
require.NoError(t, err)
|
|
require.NotNil(t, convertedChapter)
|
|
assert.Len(t, convertedChapter.Pages, tt.numExpected)
|
|
|
|
// Verify page order
|
|
for i := 1; i < len(convertedChapter.Pages); i++ {
|
|
prevPage := convertedChapter.Pages[i-1]
|
|
currPage := convertedChapter.Pages[i]
|
|
|
|
if prevPage.Index == currPage.Index {
|
|
assert.Less(t, prevPage.SplitPartIndex, currPage.SplitPartIndex,
|
|
"Split parts should be in ascending order for page %d", prevPage.Index)
|
|
} else {
|
|
assert.Less(t, prevPage.Index, currPage.Index,
|
|
"Pages should be in ascending order")
|
|
}
|
|
}
|
|
|
|
if tt.expectSplit {
|
|
splitFound := false
|
|
for _, page := range convertedChapter.Pages {
|
|
if page.IsSplitted {
|
|
splitFound = true
|
|
break
|
|
}
|
|
}
|
|
assert.True(t, splitFound, "Expected to find at least one split page")
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestConverter_convertPage(t *testing.T) {
|
|
converter := New()
|
|
err := converter.PrepareConverter()
|
|
require.NoError(t, err)
|
|
|
|
tests := []struct {
|
|
name string
|
|
format string
|
|
isToBeConverted bool
|
|
expectWebP bool
|
|
}{
|
|
{
|
|
name: "Convert PNG to WebP",
|
|
format: "png",
|
|
isToBeConverted: true,
|
|
expectWebP: true,
|
|
},
|
|
{
|
|
name: "Already WebP",
|
|
format: "webp",
|
|
isToBeConverted: true,
|
|
expectWebP: true,
|
|
},
|
|
{
|
|
name: "Skip conversion",
|
|
format: "png",
|
|
isToBeConverted: false,
|
|
expectWebP: false,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
page := createTestPage(t, 1, 100, 100)
|
|
container := manga.NewContainer(page, createTestImage(100, 100), tt.format, tt.isToBeConverted)
|
|
defer container.Close()
|
|
|
|
converted, err := converter.convertPage(container, 80)
|
|
require.NoError(t, err)
|
|
assert.NotNil(t, converted)
|
|
|
|
if tt.expectWebP {
|
|
assert.Equal(t, ".webp", converted.Page.Extension)
|
|
} else {
|
|
assert.NotEqual(t, ".webp", converted.Page.Extension)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestConverter_checkPageNeedsSplit(t *testing.T) {
|
|
converter := New()
|
|
|
|
tests := []struct {
|
|
name string
|
|
imageHeight int
|
|
split bool
|
|
expectSplit bool
|
|
expectError bool
|
|
}{
|
|
{
|
|
name: "Normal height",
|
|
imageHeight: 1000,
|
|
split: true,
|
|
expectSplit: false,
|
|
},
|
|
{
|
|
name: "Height exceeds max with split enabled",
|
|
imageHeight: 5000,
|
|
split: true,
|
|
expectSplit: true,
|
|
},
|
|
{
|
|
name: "Height exceeds webp max without split",
|
|
imageHeight: webpMaxHeight + 100,
|
|
split: false,
|
|
expectError: true,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
page := createTestPage(t, 1, 800, tt.imageHeight)
|
|
|
|
needsSplit, img, format, err := converter.checkPageNeedsSplit(page, tt.split)
|
|
|
|
if tt.expectError {
|
|
assert.Error(t, err)
|
|
return
|
|
}
|
|
|
|
require.NoError(t, err)
|
|
assert.NotNil(t, img)
|
|
assert.NotEmpty(t, format)
|
|
assert.Equal(t, tt.expectSplit, needsSplit)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestConverter_Format(t *testing.T) {
|
|
converter := New()
|
|
assert.Equal(t, constant.WebP, converter.Format())
|
|
}
|