check / check (push) Canceled after 0s
magic.DetectFormat returns an imagerequest.Format. ValidateMagicBytes returns the format it checked against the upstream Content-Type. The cache reads a cached source's format from its file's first bytes, as it reads a variant's. The proxy hands the format to Process. Process refuses a format that is not a source format, and input libvips would load with another loader, such as an SVG passing as AVIF. Format.MIMEType declares each MIME string once, and the fetcher, the cache's variant read and the Accept matching use it. magic.MIMEType, magic.ImageFormat, MIMEToImageFormat, magic's SVG detection, detectFormat, formatFromString, FormatToMIME and Result.InputFormat are gone. Model: opus-5-5
126 lines
3.7 KiB
Go
126 lines
3.7 KiB
Go
package imageprocessor
|
|
|
|
import (
|
|
"bytes"
|
|
"errors"
|
|
"testing"
|
|
|
|
"sneak.berlin/go/pixa/internal/imagerequest"
|
|
)
|
|
|
|
// TestImageProcessor_RefusesFitOutsideAboveMaximum verifies that FitOutside,
|
|
// which scales the input to cover the requested size and so past it on one
|
|
// side, is refused with ErrOutputTooLarge when that side would come out above
|
|
// MaxOutputDimension, and otherwise makes the scaled size. A 1024x256 or
|
|
// 256x1024 input scaled by 8 has 8192 for its long side.
|
|
func TestImageProcessor_RefusesFitOutsideAboveMaximum(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
tests := []struct {
|
|
name string
|
|
inputWidth, inputHeight int
|
|
size imagerequest.Size
|
|
// wantWidth and wantHeight are the output's, 0 for a refusal
|
|
wantWidth, wantHeight int
|
|
}{
|
|
{"width above the maximum", 3000, 600,
|
|
imagerequest.Size{Width: 1, Height: 8192}, 0, 0},
|
|
{"height above the maximum", 600, 3000,
|
|
imagerequest.Size{Width: 8192, Height: 1}, 0, 0},
|
|
{"width at the maximum", 1024, 256,
|
|
imagerequest.Size{Width: 1, Height: 2048}, 8192, 2048},
|
|
{"height at the maximum", 256, 1024,
|
|
imagerequest.Size{Width: 2048, Height: 1}, 2048, 8192},
|
|
{"within the maximum", 3000, 600,
|
|
imagerequest.Size{Width: 1, Height: 1200}, 6000, 1200},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
input := createTestJPEG(t, tt.inputWidth, tt.inputHeight)
|
|
|
|
result, err := New(Params{
|
|
MaxInputBytes: 50 << 20,
|
|
MaxConcurrentProcessing: 1,
|
|
}).Process(t.Context(),
|
|
bytes.NewReader(input), imagerequest.FormatJPEG,
|
|
&imagerequest.Transform{
|
|
Size: tt.size,
|
|
Format: imagerequest.FormatJPEG,
|
|
FitMode: imagerequest.FitOutside,
|
|
})
|
|
if result != nil {
|
|
t.Logf("Process() made %dx%d", result.Width, result.Height)
|
|
}
|
|
|
|
if tt.wantWidth == 0 {
|
|
if !errors.Is(err, ErrOutputTooLarge) {
|
|
t.Errorf("Process() error = %v, want %v", err, ErrOutputTooLarge)
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
if err != nil {
|
|
t.Fatalf("Process() error = %v", err)
|
|
}
|
|
|
|
if result.Width != tt.wantWidth || result.Height != tt.wantHeight {
|
|
t.Errorf("Process() made %dx%d, want %dx%d",
|
|
result.Width, result.Height, tt.wantWidth, tt.wantHeight)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
// TestImageProcessor_FitOutsideSideIsAtLeastOne verifies that FitOutside
|
|
// keeps each side at 1 or more when it works both sides out again from the
|
|
// larger scale. A side of 49 scaled to 1 is 49 times 1/49, which in floating
|
|
// point is just under 1 and so rounded down to 0, a width libvips refuses.
|
|
func TestImageProcessor_FitOutsideSideIsAtLeastOne(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
tests := []struct {
|
|
name string
|
|
inputWidth, inputHeight int
|
|
size imagerequest.Size
|
|
wantWidth, wantHeight int
|
|
}{
|
|
{"49x8192 at 0x100", 49, 8192, imagerequest.Size{Height: 100}, 1, 167},
|
|
{"49x49 at 1x1", 49, 49, imagerequest.Size{Width: 1, Height: 1}, 1, 1},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
input := createTestJPEG(t, tt.inputWidth, tt.inputHeight)
|
|
|
|
result, err := New(Params{
|
|
MaxInputBytes: 50 << 20,
|
|
MaxConcurrentProcessing: 1,
|
|
}).Process(t.Context(),
|
|
bytes.NewReader(input), imagerequest.FormatJPEG,
|
|
&imagerequest.Transform{
|
|
Size: tt.size,
|
|
Format: imagerequest.FormatJPEG,
|
|
FitMode: imagerequest.FitOutside,
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("Process() error = %v", err)
|
|
}
|
|
|
|
defer func() { _ = result.Content.Close() }()
|
|
|
|
t.Logf("Process() made %dx%d", result.Width, result.Height)
|
|
|
|
if result.Width != tt.wantWidth || result.Height != tt.wantHeight {
|
|
t.Errorf("Process() made %dx%d, want %dx%d",
|
|
result.Width, result.Height, tt.wantWidth, tt.wantHeight)
|
|
}
|
|
})
|
|
}
|
|
}
|