2020-05-01 11:53:41 +02:00
|
|
|
package thumb
|
|
|
|
|
|
|
|
import (
|
|
|
|
"os"
|
|
|
|
"testing"
|
|
|
|
|
|
|
|
"github.com/disintegration/imaging"
|
|
|
|
"github.com/photoprism/photoprism/pkg/fs"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
|
|
)
|
|
|
|
|
|
|
|
func TestResampleOptions(t *testing.T) {
|
2020-05-14 17:28:55 +02:00
|
|
|
t.Run("ResamplePng, FillCenter", func(t *testing.T) {
|
|
|
|
method, filter, format := ResampleOptions(ResamplePng, ResampleFillCenter, ResampleDefault)
|
2020-05-01 11:53:41 +02:00
|
|
|
|
2020-05-14 17:28:55 +02:00
|
|
|
assert.Equal(t, ResampleFillCenter, method)
|
|
|
|
assert.Equal(t, imaging.Lanczos.Support, filter.Support)
|
2020-12-12 17:20:31 +01:00
|
|
|
assert.Equal(t, fs.FormatPng, format)
|
2020-05-14 17:28:55 +02:00
|
|
|
})
|
|
|
|
t.Run("ResampleNearestNeighbor, FillTopLeft", func(t *testing.T) {
|
|
|
|
method, filter, format := ResampleOptions(ResampleNearestNeighbor, ResampleFillTopLeft)
|
|
|
|
|
|
|
|
assert.Equal(t, ResampleFillTopLeft, method)
|
|
|
|
assert.Equal(t, imaging.NearestNeighbor.Support, filter.Support)
|
2020-12-12 17:20:31 +01:00
|
|
|
assert.Equal(t, fs.FormatJpeg, format)
|
2020-05-14 17:28:55 +02:00
|
|
|
})
|
|
|
|
t.Run("ResampleNearestNeighbor, FillBottomRight", func(t *testing.T) {
|
|
|
|
method, filter, format := ResampleOptions(ResampleNearestNeighbor, ResampleFillBottomRight)
|
|
|
|
|
|
|
|
assert.Equal(t, ResampleFillBottomRight, method)
|
|
|
|
assert.Equal(t, imaging.NearestNeighbor.Support, filter.Support)
|
2020-12-12 17:20:31 +01:00
|
|
|
assert.Equal(t, fs.FormatJpeg, format)
|
2020-05-14 17:28:55 +02:00
|
|
|
})
|
2020-05-01 11:53:41 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestResample(t *testing.T) {
|
2020-05-14 17:28:55 +02:00
|
|
|
t.Run("tile50 options", func(t *testing.T) {
|
|
|
|
tile50 := Types["tile_50"]
|
|
|
|
|
|
|
|
src := "testdata/example.jpg"
|
|
|
|
|
|
|
|
assert.FileExists(t, src)
|
|
|
|
|
|
|
|
img, err := imaging.Open(src, imaging.AutoOrientation(true))
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
bounds := img.Bounds()
|
|
|
|
|
|
|
|
assert.Equal(t, 750, bounds.Max.X)
|
|
|
|
assert.Equal(t, 500, bounds.Max.Y)
|
|
|
|
|
2020-05-29 18:04:30 +02:00
|
|
|
result := Resample(img, tile50.Width, tile50.Height, tile50.Options...)
|
2020-05-14 17:28:55 +02:00
|
|
|
|
|
|
|
boundsNew := result.Bounds()
|
|
|
|
|
|
|
|
assert.Equal(t, 50, boundsNew.Max.X)
|
|
|
|
assert.Equal(t, 50, boundsNew.Max.Y)
|
|
|
|
})
|
|
|
|
t.Run("left_224 options", func(t *testing.T) {
|
2020-06-07 10:09:35 +02:00
|
|
|
left224 := Types["left_224"]
|
2020-05-14 17:28:55 +02:00
|
|
|
|
|
|
|
src := "testdata/example.jpg"
|
|
|
|
|
|
|
|
assert.FileExists(t, src)
|
|
|
|
|
|
|
|
img, err := imaging.Open(src, imaging.AutoOrientation(true))
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
bounds := img.Bounds()
|
2020-05-01 11:53:41 +02:00
|
|
|
|
2020-05-14 17:28:55 +02:00
|
|
|
assert.Equal(t, 750, bounds.Max.X)
|
|
|
|
assert.Equal(t, 500, bounds.Max.Y)
|
2020-05-01 11:53:41 +02:00
|
|
|
|
2020-06-07 10:09:35 +02:00
|
|
|
result := Resample(img, left224.Width, left224.Height, left224.Options...)
|
2020-05-01 11:53:41 +02:00
|
|
|
|
2020-05-14 17:28:55 +02:00
|
|
|
boundsNew := result.Bounds()
|
2020-05-01 11:53:41 +02:00
|
|
|
|
2020-05-14 17:28:55 +02:00
|
|
|
assert.Equal(t, 224, boundsNew.Max.X)
|
|
|
|
assert.Equal(t, 224, boundsNew.Max.Y)
|
|
|
|
})
|
|
|
|
t.Run("right_224 options", func(t *testing.T) {
|
2020-06-07 10:09:35 +02:00
|
|
|
right224 := Types["right_224"]
|
2020-05-01 11:53:41 +02:00
|
|
|
|
2020-05-14 17:28:55 +02:00
|
|
|
src := "testdata/example.jpg"
|
2020-05-01 11:53:41 +02:00
|
|
|
|
2020-05-14 17:28:55 +02:00
|
|
|
assert.FileExists(t, src)
|
2020-05-01 11:53:41 +02:00
|
|
|
|
2020-05-14 17:28:55 +02:00
|
|
|
img, err := imaging.Open(src, imaging.AutoOrientation(true))
|
2020-05-01 11:53:41 +02:00
|
|
|
|
2020-05-14 17:28:55 +02:00
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
bounds := img.Bounds()
|
|
|
|
|
|
|
|
assert.Equal(t, 750, bounds.Max.X)
|
|
|
|
assert.Equal(t, 500, bounds.Max.Y)
|
|
|
|
|
2020-06-07 10:09:35 +02:00
|
|
|
result := Resample(img, right224.Width, right224.Height, right224.Options...)
|
2020-05-14 17:28:55 +02:00
|
|
|
|
|
|
|
boundsNew := result.Bounds()
|
|
|
|
|
|
|
|
assert.Equal(t, 224, boundsNew.Max.X)
|
|
|
|
assert.Equal(t, 224, boundsNew.Max.Y)
|
|
|
|
})
|
|
|
|
t.Run("fit_1280 options", func(t *testing.T) {
|
2020-06-07 10:09:35 +02:00
|
|
|
fit1280 := Types["fit_1280"]
|
2020-05-01 11:53:41 +02:00
|
|
|
|
2020-05-14 17:28:55 +02:00
|
|
|
src := "testdata/example.jpg"
|
|
|
|
|
|
|
|
assert.FileExists(t, src)
|
|
|
|
|
|
|
|
img, err := imaging.Open(src, imaging.AutoOrientation(true))
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
bounds := img.Bounds()
|
|
|
|
|
|
|
|
assert.Equal(t, 750, bounds.Max.X)
|
|
|
|
assert.Equal(t, 500, bounds.Max.Y)
|
|
|
|
|
2020-06-07 10:09:35 +02:00
|
|
|
result := Resample(img, fit1280.Width, fit1280.Height, fit1280.Options...)
|
2020-05-14 17:28:55 +02:00
|
|
|
|
|
|
|
boundsNew := result.Bounds()
|
|
|
|
|
|
|
|
assert.Equal(t, 750, boundsNew.Max.X)
|
|
|
|
assert.Equal(t, 500, boundsNew.Max.Y)
|
|
|
|
})
|
2020-05-01 11:53:41 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestPostfix(t *testing.T) {
|
|
|
|
tile50 := Types["tile_50"]
|
|
|
|
|
|
|
|
result := Postfix(tile50.Width, tile50.Height, tile50.Options...)
|
|
|
|
|
|
|
|
assert.Equal(t, "50x50_center.jpg", result)
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestFilename(t *testing.T) {
|
|
|
|
t.Run("colors", func(t *testing.T) {
|
|
|
|
colorThumb := Types["colors"]
|
|
|
|
|
|
|
|
result, err := Filename("123456789098765432", "testdata", colorThumb.Width, colorThumb.Height, colorThumb.Options...)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
assert.Equal(t, "testdata/1/2/3/123456789098765432_3x3_resize.png", result)
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("fit_720", func(t *testing.T) {
|
|
|
|
fit720 := Types["fit_720"]
|
|
|
|
|
|
|
|
result, err := Filename("123456789098765432", "testdata", fit720.Width, fit720.Height, fit720.Options...)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
assert.Equal(t, "testdata/1/2/3/123456789098765432_720x720_fit.jpg", result)
|
|
|
|
})
|
2020-05-14 17:28:55 +02:00
|
|
|
t.Run("invalid width", func(t *testing.T) {
|
|
|
|
colorThumb := Types["colors"]
|
|
|
|
|
|
|
|
result, err := Filename("123456789098765432", "testdata", -2, colorThumb.Height, colorThumb.Options...)
|
|
|
|
|
2020-05-29 18:04:30 +02:00
|
|
|
if err == nil {
|
|
|
|
t.Fatal("error expected")
|
|
|
|
}
|
2020-05-14 17:28:55 +02:00
|
|
|
assert.Equal(t, "resample: width exceeds limit (-2)", err.Error())
|
|
|
|
assert.Empty(t, result)
|
|
|
|
})
|
|
|
|
t.Run("invalid height", func(t *testing.T) {
|
|
|
|
colorThumb := Types["colors"]
|
|
|
|
|
|
|
|
result, err := Filename("123456789098765432", "testdata", colorThumb.Width, -3, colorThumb.Options...)
|
|
|
|
|
2020-05-29 18:04:30 +02:00
|
|
|
if err == nil {
|
|
|
|
t.Fatal("error expected")
|
|
|
|
}
|
2020-05-14 17:28:55 +02:00
|
|
|
assert.Equal(t, "resample: height exceeds limit (-3)", err.Error())
|
|
|
|
assert.Empty(t, result)
|
|
|
|
})
|
|
|
|
t.Run("invalid hash", func(t *testing.T) {
|
|
|
|
colorThumb := Types["colors"]
|
|
|
|
|
|
|
|
result, err := Filename("12", "testdata", colorThumb.Width, colorThumb.Height, colorThumb.Options...)
|
|
|
|
|
2020-05-29 18:04:30 +02:00
|
|
|
if err == nil {
|
|
|
|
t.Fatal("error expected")
|
|
|
|
}
|
2020-05-14 17:28:55 +02:00
|
|
|
assert.Equal(t, "resample: file hash is empty or too short (12)", err.Error())
|
|
|
|
assert.Empty(t, result)
|
|
|
|
})
|
|
|
|
t.Run("invalid thumb path", func(t *testing.T) {
|
|
|
|
colorThumb := Types["colors"]
|
|
|
|
|
|
|
|
result, err := Filename("123456789098765432", "", colorThumb.Width, colorThumb.Height, colorThumb.Options...)
|
|
|
|
|
2020-05-29 18:04:30 +02:00
|
|
|
if err == nil {
|
|
|
|
t.Fatal("error expected")
|
|
|
|
}
|
2020-05-14 17:28:55 +02:00
|
|
|
assert.Equal(t, "resample: folder is empty", err.Error())
|
|
|
|
assert.Empty(t, result)
|
|
|
|
})
|
2020-05-01 11:53:41 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestFromFile(t *testing.T) {
|
|
|
|
t.Run("colors", func(t *testing.T) {
|
|
|
|
colorThumb := Types["colors"]
|
|
|
|
src := "testdata/example.gif"
|
|
|
|
dst := "testdata/1/2/3/123456789098765432_3x3_resize.png"
|
|
|
|
|
|
|
|
assert.FileExists(t, src)
|
|
|
|
|
2021-02-21 22:53:25 +01:00
|
|
|
fileName, err := FromFile(src, "123456789098765432", "testdata", colorThumb.Width, colorThumb.Height, OrientationNormal, colorThumb.Options...)
|
2020-05-01 11:53:41 +02:00
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
assert.Equal(t, dst, fileName)
|
|
|
|
|
|
|
|
assert.FileExists(t, dst)
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("missing file", func(t *testing.T) {
|
|
|
|
colorThumb := Types["colors"]
|
|
|
|
src := "testdata/example.xxx"
|
|
|
|
|
|
|
|
assert.NoFileExists(t, src)
|
|
|
|
|
2021-02-21 22:53:25 +01:00
|
|
|
fileName, err := FromFile(src, "193456789098765432", "testdata", colorThumb.Width, colorThumb.Height, OrientationNormal, colorThumb.Options...)
|
2020-05-01 11:53:41 +02:00
|
|
|
|
|
|
|
assert.Equal(t, "", fileName)
|
|
|
|
assert.Error(t, err)
|
|
|
|
})
|
2020-05-14 17:28:55 +02:00
|
|
|
t.Run("empty filename", func(t *testing.T) {
|
|
|
|
colorThumb := Types["colors"]
|
|
|
|
|
2021-02-21 22:53:25 +01:00
|
|
|
fileName, err := FromFile("", "193456789098765432", "testdata", colorThumb.Width, colorThumb.Height, OrientationNormal, colorThumb.Options...)
|
2020-05-14 17:28:55 +02:00
|
|
|
|
2020-05-29 18:04:30 +02:00
|
|
|
if err == nil {
|
|
|
|
t.Fatal("error expected")
|
|
|
|
}
|
2020-05-14 17:28:55 +02:00
|
|
|
assert.Equal(t, "", fileName)
|
|
|
|
assert.Equal(t, "resample: image filename is empty or too short ()", err.Error())
|
|
|
|
})
|
2020-05-01 11:53:41 +02:00
|
|
|
}
|
|
|
|
|
2020-05-05 15:42:54 +02:00
|
|
|
func TestFromCache(t *testing.T) {
|
|
|
|
t.Run("missing thumb", func(t *testing.T) {
|
|
|
|
tile50 := Types["tile_50"]
|
|
|
|
src := "testdata/example.jpg"
|
|
|
|
|
|
|
|
assert.FileExists(t, src)
|
|
|
|
|
|
|
|
fileName, err := FromCache(src, "193456789098765432", "testdata", tile50.Width, tile50.Height, tile50.Options...)
|
|
|
|
|
|
|
|
assert.Equal(t, "", fileName)
|
|
|
|
|
|
|
|
if err != ErrThumbNotCached {
|
|
|
|
t.Fatal("ErrThumbNotCached expected")
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("missing file", func(t *testing.T) {
|
|
|
|
tile50 := Types["tile_50"]
|
|
|
|
src := "testdata/example.xxx"
|
|
|
|
|
|
|
|
assert.NoFileExists(t, src)
|
|
|
|
|
|
|
|
fileName, err := FromCache(src, "193456789098765432", "testdata", tile50.Width, tile50.Height, tile50.Options...)
|
|
|
|
|
|
|
|
assert.Equal(t, "", fileName)
|
|
|
|
assert.Error(t, err)
|
|
|
|
})
|
2020-05-14 17:28:55 +02:00
|
|
|
t.Run("invalid hash", func(t *testing.T) {
|
|
|
|
tile50 := Types["tile_50"]
|
|
|
|
src := "testdata/example.jpg"
|
|
|
|
|
|
|
|
assert.FileExists(t, src)
|
|
|
|
|
|
|
|
fileName, err := FromCache(src, "12", "testdata", tile50.Width, tile50.Height, tile50.Options...)
|
|
|
|
|
2020-05-29 18:04:30 +02:00
|
|
|
if err == nil {
|
|
|
|
t.Fatal("error expected")
|
|
|
|
}
|
2020-05-14 17:28:55 +02:00
|
|
|
assert.Equal(t, "resample: file hash is empty or too short (12)", err.Error())
|
|
|
|
assert.Empty(t, fileName)
|
|
|
|
})
|
|
|
|
t.Run("empty filename", func(t *testing.T) {
|
|
|
|
tile50 := Types["tile_50"]
|
|
|
|
|
|
|
|
fileName, err := FromCache("", "193456789098765432", "testdata", tile50.Width, tile50.Height, tile50.Options...)
|
|
|
|
|
2020-05-29 18:04:30 +02:00
|
|
|
if err == nil {
|
|
|
|
t.Fatal("error expected")
|
|
|
|
}
|
2020-05-14 17:28:55 +02:00
|
|
|
assert.Equal(t, "resample: image filename is empty or too short ()", err.Error())
|
|
|
|
assert.Empty(t, fileName)
|
|
|
|
})
|
2020-05-05 15:42:54 +02:00
|
|
|
}
|
|
|
|
|
2020-05-01 11:53:41 +02:00
|
|
|
func TestCreate(t *testing.T) {
|
|
|
|
t.Run("tile_500", func(t *testing.T) {
|
|
|
|
tile500 := Types["tile_500"]
|
|
|
|
src := "testdata/example.jpg"
|
|
|
|
dst := "testdata/example.tile_500.jpg"
|
|
|
|
|
|
|
|
assert.FileExists(t, src)
|
|
|
|
assert.NoFileExists(t, dst)
|
|
|
|
|
|
|
|
img, err := imaging.Open(src, imaging.AutoOrientation(true))
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
bounds := img.Bounds()
|
|
|
|
|
|
|
|
assert.Equal(t, 750, bounds.Max.X)
|
|
|
|
assert.Equal(t, 500, bounds.Max.Y)
|
|
|
|
|
2020-05-29 18:04:30 +02:00
|
|
|
resized, err := Create(img, dst, tile500.Width, tile500.Height, tile500.Options...)
|
2020-05-01 11:53:41 +02:00
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
assert.FileExists(t, dst)
|
|
|
|
|
|
|
|
if err := os.Remove(dst); err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
2020-05-29 18:04:30 +02:00
|
|
|
imgNew := resized
|
2020-05-01 11:53:41 +02:00
|
|
|
boundsNew := imgNew.Bounds()
|
|
|
|
|
|
|
|
assert.Equal(t, 500, boundsNew.Max.X)
|
|
|
|
assert.Equal(t, 500, boundsNew.Max.Y)
|
|
|
|
})
|
2020-05-14 17:28:55 +02:00
|
|
|
t.Run("invalid width", func(t *testing.T) {
|
|
|
|
tile500 := Types["tile_500"]
|
|
|
|
src := "testdata/example.jpg"
|
|
|
|
dst := "testdata/example.tile_500.jpg"
|
|
|
|
|
|
|
|
assert.FileExists(t, src)
|
|
|
|
assert.NoFileExists(t, dst)
|
|
|
|
|
|
|
|
img, err := imaging.Open(src, imaging.AutoOrientation(true))
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
bounds := img.Bounds()
|
|
|
|
|
|
|
|
assert.Equal(t, 750, bounds.Max.X)
|
|
|
|
assert.Equal(t, 500, bounds.Max.Y)
|
|
|
|
|
2020-05-29 18:04:30 +02:00
|
|
|
resized, err := Create(img, dst, -5, tile500.Height, tile500.Options...)
|
|
|
|
|
|
|
|
if err == nil {
|
|
|
|
t.Fatal("error expected")
|
|
|
|
}
|
2020-05-14 17:28:55 +02:00
|
|
|
|
|
|
|
assert.Equal(t, "resample: width has an invalid value (-5)", err.Error())
|
|
|
|
t.Log(resized)
|
|
|
|
})
|
|
|
|
t.Run("invalid height", func(t *testing.T) {
|
|
|
|
tile500 := Types["tile_500"]
|
|
|
|
src := "testdata/example.jpg"
|
|
|
|
dst := "testdata/example.tile_500.jpg"
|
|
|
|
|
|
|
|
assert.FileExists(t, src)
|
|
|
|
assert.NoFileExists(t, dst)
|
|
|
|
|
|
|
|
img, err := imaging.Open(src, imaging.AutoOrientation(true))
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
bounds := img.Bounds()
|
|
|
|
|
|
|
|
assert.Equal(t, 750, bounds.Max.X)
|
|
|
|
assert.Equal(t, 500, bounds.Max.Y)
|
|
|
|
|
2020-05-29 18:04:30 +02:00
|
|
|
resized, err := Create(img, dst, tile500.Width, -3, tile500.Options...)
|
|
|
|
|
|
|
|
if err == nil {
|
|
|
|
t.Fatal("error expected")
|
|
|
|
}
|
2020-05-14 17:28:55 +02:00
|
|
|
|
|
|
|
assert.Equal(t, "resample: height has an invalid value (-3)", err.Error())
|
|
|
|
t.Log(resized)
|
|
|
|
})
|
2020-05-01 11:53:41 +02:00
|
|
|
}
|