Написал недостающие юнит тесты.
This commit is contained in:
parent
676d7e2bd9
commit
e87099550a
57
previewer/application/query_test.go
Normal file
57
previewer/application/query_test.go
Normal file
@ -0,0 +1,57 @@
|
||||
package application
|
||||
|
||||
import (
|
||||
"github.com/stretchr/testify/require"
|
||||
"net/url"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestBuildQuery(t *testing.T) {
|
||||
|
||||
urlParcer := func(u string) *url.URL {
|
||||
res, _ := url.Parse(u)
|
||||
return res
|
||||
}
|
||||
|
||||
table := []struct {
|
||||
url *url.URL
|
||||
expWidth int
|
||||
expHeight int
|
||||
expURL *url.URL
|
||||
err bool
|
||||
msg string
|
||||
}{
|
||||
{
|
||||
url: urlParcer("/fill/10/10/domain.me/some/pic.jpg"), expWidth: 10, expHeight: 10, expURL: urlParcer("http://domain.me/some/pic.jpg"), err: false, msg: "Normal request",
|
||||
},
|
||||
{
|
||||
url: urlParcer("/fill/10/10/pic.jpg"), expWidth: 10, expHeight: 10, expURL: urlParcer("http://pic.jpg"), err: false, msg: "Short URL",
|
||||
},
|
||||
{
|
||||
url: urlParcer("/fill/10"), expWidth: 0, expHeight: 0, expURL: nil, err: true, msg: "Only width",
|
||||
},
|
||||
{
|
||||
url: urlParcer("/fill/10/10"), expWidth: 0, expHeight: 0, expURL: nil, err: true, msg: "Only dimensions",
|
||||
},
|
||||
{
|
||||
url: urlParcer("/fill/qwew/qwew/domain.me/some/pic.jpg"), expWidth: 0, expHeight: 0, expURL: nil, err: true, msg: "Strings in dimensions",
|
||||
},
|
||||
{
|
||||
url: urlParcer("/fill/domain.me/some/pic.jpg"), expWidth: 0, expHeight: 0, expURL: nil, err: true, msg: "No dimensions",
|
||||
},
|
||||
}
|
||||
|
||||
for _, dat := range table {
|
||||
t.Run(dat.msg, func(t *testing.T) {
|
||||
i := false
|
||||
query, err := buildQuery(dat.url)
|
||||
if err != nil {
|
||||
i = true
|
||||
}
|
||||
require.Equal(t, dat.err, i, dat.msg)
|
||||
require.Equal(t, dat.expWidth, query.Width, dat.msg)
|
||||
require.Equal(t, dat.expHeight, query.Height, dat.msg)
|
||||
require.Equal(t, dat.expURL, query.URL, dat.msg)
|
||||
})
|
||||
}
|
||||
}
|
@ -9,12 +9,14 @@ import (
|
||||
"image/jpeg"
|
||||
"image/png"
|
||||
"net/http"
|
||||
"sync"
|
||||
|
||||
"github.com/nfnt/resize"
|
||||
)
|
||||
|
||||
type Image struct {
|
||||
image.Image
|
||||
mx sync.Mutex
|
||||
}
|
||||
|
||||
func SelectType(width int, height int, b []byte) ([]byte, error) {
|
||||
@ -64,13 +66,17 @@ func SelectType(width int, height int, b []byte) ([]byte, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
m := Image{i}
|
||||
m := NewImage(i)
|
||||
if err = m.convert(width, height); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return encode(m.Image)
|
||||
}
|
||||
|
||||
func NewImage(img image.Image) Image {
|
||||
return Image{img, sync.Mutex{}}
|
||||
}
|
||||
|
||||
func (img *Image) convert(width int, height int) error {
|
||||
widthOrig := img.Bounds().Max.X
|
||||
heightOrig := img.Bounds().Max.Y
|
||||
@ -79,19 +85,22 @@ func (img *Image) convert(width int, height int) error {
|
||||
|
||||
switch {
|
||||
case sfOriginal > sfNew:
|
||||
// Ресайз по одной высоте и кроп по ширине следом
|
||||
// Определение ширины кропа.
|
||||
calcWidth := int(float64(height) * sfOriginal)
|
||||
img.resize(calcWidth, height)
|
||||
if err := img.resize(calcWidth, height); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := img.crop(image.Point{X: (calcWidth - width) / 2, Y: 0}, image.Point{X: (calcWidth-width)/2 + width, Y: height}); err != nil {
|
||||
return err
|
||||
}
|
||||
case sfOriginal == sfNew:
|
||||
img.resize(width, height)
|
||||
if err := img.resize(width, height); err != nil {
|
||||
return err
|
||||
}
|
||||
case sfOriginal < sfNew:
|
||||
// Ресайз по одной ширине и кроп по высоте следом
|
||||
calcHeight := int(float64(width) / sfOriginal)
|
||||
img.resize(width, calcHeight)
|
||||
if err := img.resize(width, calcHeight); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := img.crop(image.Point{X: 0, Y: (calcHeight - height) / 2}, image.Point{X: width, Y: (calcHeight-height)/2 + height}); err != nil {
|
||||
return err
|
||||
}
|
||||
@ -99,15 +108,24 @@ func (img *Image) convert(width int, height int) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (img *Image) resize(width, height int) {
|
||||
img.Image = resize.Resize(uint(width), uint(height), img, resize.Bicubic)
|
||||
func (img *Image) resize(width, height int) error {
|
||||
img.mx.Lock()
|
||||
defer img.mx.Unlock()
|
||||
if width <= 0 || height <= 0 {
|
||||
return errors.New("can't resize to zero or negative value")
|
||||
}
|
||||
tmpImg := resize.Resize(uint(width), uint(height), img, resize.Bicubic)
|
||||
img.Image = tmpImg
|
||||
return nil
|
||||
}
|
||||
|
||||
func (img *Image) crop(p1 image.Point, p2 image.Point) error {
|
||||
if img == nil {
|
||||
img.mx.Lock()
|
||||
defer img.mx.Unlock()
|
||||
if img.Image == nil {
|
||||
return errors.New("corrupted image")
|
||||
}
|
||||
if p1.X < 0 || p1.Y < 0 || p2.X < 0 || p2.Y < 0 {
|
||||
if p1.X < 0 || p1.Y < 0 || p2.X > img.Image.Bounds().Max.X || p2.Y > img.Image.Bounds().Max.Y {
|
||||
return errors.New("not valid corner points")
|
||||
}
|
||||
b := image.Rect(0, 0, p2.X-p1.X, p2.Y-p1.Y)
|
||||
|
159
previewer/converter/converter_test.go
Normal file
159
previewer/converter/converter_test.go
Normal file
@ -0,0 +1,159 @@
|
||||
package converter
|
||||
|
||||
import (
|
||||
"github.com/stretchr/testify/require"
|
||||
"image"
|
||||
"image/color"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestResize(t *testing.T) {
|
||||
table := []struct {
|
||||
width int
|
||||
height int
|
||||
expectedX int
|
||||
expectedY int
|
||||
err bool
|
||||
msg string
|
||||
}{
|
||||
{
|
||||
width: 300, height: 200, expectedX: 300, expectedY: 200, err: false, msg: "Reducing the image size",
|
||||
},
|
||||
{
|
||||
width: 1600, height: 1200, expectedX: 1600, expectedY: 1200, err: false, msg: "Increasing the image size",
|
||||
},
|
||||
{
|
||||
width: 0, height: 0, expectedX: 800, expectedY: 600, err: true, msg: "Resize to zero",
|
||||
},
|
||||
{
|
||||
width: -1000, height: -1200, expectedX: 800, expectedY: 600, err: true, msg: "Use negative values",
|
||||
},
|
||||
}
|
||||
|
||||
for _, dat := range table {
|
||||
t.Run(dat.msg, func(t *testing.T) {
|
||||
img := Image{Image: createImage(800, 600)}
|
||||
i := false
|
||||
err := img.resize(dat.width, dat.height)
|
||||
if err != nil {
|
||||
i = true
|
||||
}
|
||||
require.Equal(t, dat.err, i, dat.msg)
|
||||
require.Equal(t, dat.expectedX, img.Bounds().Max.X, dat.msg)
|
||||
require.Equal(t, dat.expectedY, img.Bounds().Max.Y, dat.msg)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestCrop(t *testing.T) {
|
||||
table := []struct {
|
||||
topLeft image.Point
|
||||
bottomRight image.Point
|
||||
expectedX int
|
||||
expectedY int
|
||||
err bool
|
||||
msg string
|
||||
}{
|
||||
{
|
||||
topLeft: image.Point{X: 400, Y: 0}, bottomRight: image.Point{X: 600, Y: 1000}, expectedX: 200, expectedY: 1000, err: false, msg: "Vertical crop",
|
||||
},
|
||||
{
|
||||
topLeft: image.Point{X: 0, Y: 400}, bottomRight: image.Point{X: 1000, Y: 600}, expectedX: 1000, expectedY: 200, err: false, msg: "Horizontal crop",
|
||||
},
|
||||
{
|
||||
topLeft: image.Point{X: 100, Y: 100}, bottomRight: image.Point{X: 900, Y: 900}, expectedX: 800, expectedY: 800, err: false, msg: "Square crop",
|
||||
},
|
||||
{
|
||||
topLeft: image.Point{X: -100, Y: 0}, bottomRight: image.Point{X: 2000, Y: 1000}, expectedX: 1000, expectedY: 1000, err: true, msg: "Too wide crop with negative offset",
|
||||
},
|
||||
{
|
||||
topLeft: image.Point{X: 0, Y: -100}, bottomRight: image.Point{X: 1000, Y: 2000}, expectedX: 1000, expectedY: 1000, err: true, msg: "Too tall crop with negative offset",
|
||||
},
|
||||
{
|
||||
topLeft: image.Point{X: 100, Y: 0}, bottomRight: image.Point{X: 2000, Y: 1000}, expectedX: 1000, expectedY: 1000, err: true, msg: "Too wide crop with positive offset",
|
||||
},
|
||||
{
|
||||
topLeft: image.Point{X: 0, Y: 100}, bottomRight: image.Point{X: 1000, Y: 2000}, expectedX: 1000, expectedY: 1000, err: true, msg: "Too tall crop with positive offset",
|
||||
},
|
||||
}
|
||||
|
||||
for _, dat := range table {
|
||||
t.Run(dat.msg, func(t *testing.T) {
|
||||
img := Image{Image: createImage(1000, 1000)}
|
||||
i := false
|
||||
err := img.crop(dat.topLeft, dat.bottomRight)
|
||||
if err != nil {
|
||||
i = true
|
||||
}
|
||||
require.Equal(t, dat.err, i, dat.msg)
|
||||
require.Equal(t, dat.expectedX, img.Image.Bounds().Max.X, dat.msg)
|
||||
require.Equal(t, dat.expectedY, img.Image.Bounds().Max.Y, dat.msg)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
func TestConvert(t *testing.T) {
|
||||
originalAspect := 800.0 / 600.0
|
||||
releasedValue := 3000
|
||||
table := []struct {
|
||||
width int
|
||||
height int
|
||||
expectedX int
|
||||
expectedY int
|
||||
err bool
|
||||
msg string
|
||||
}{
|
||||
{
|
||||
width: 400, height: 600, expectedX: 400, expectedY: int(400 / originalAspect), err: false, msg: "Reducing the image size by horizontal",
|
||||
},
|
||||
{
|
||||
width: 800, height: 400, expectedX: int(400 * originalAspect), expectedY: 400, err: false, msg: "Reducing the image size by vertical",
|
||||
},
|
||||
{
|
||||
width: 400, height: int(400 / originalAspect), expectedX: 400, expectedY: int(400 / originalAspect), err: false, msg: "Resize to original aspect ratio",
|
||||
},
|
||||
{
|
||||
width: 1000, height: releasedValue, expectedX: 1000, expectedY: int(1000 / originalAspect), err: false, msg: "Increasing the image size by horizontal",
|
||||
},
|
||||
{
|
||||
width: releasedValue, height: 1000, expectedX: int(1000 * originalAspect), expectedY: 1000, err: false, msg: "Increasing the image size by vertical",
|
||||
},
|
||||
{
|
||||
width: 0, height: 0, expectedX: 800, expectedY: 600, err: true, msg: "Resize to zero",
|
||||
},
|
||||
{
|
||||
width: -1000, height: -1200, expectedX: 800, expectedY: 600, err: true, msg: "Use negative values",
|
||||
},
|
||||
}
|
||||
|
||||
for _, dat := range table {
|
||||
t.Run(dat.msg, func(t *testing.T) {
|
||||
img := Image{Image: createImage(800, 600)}
|
||||
i := false
|
||||
err := img.convert(dat.width, dat.height)
|
||||
if err != nil {
|
||||
i = true
|
||||
}
|
||||
require.Equal(t, dat.err, i, dat.msg)
|
||||
require.Equal(t, dat.expectedX, img.Image.Bounds().Max.X, dat.msg)
|
||||
require.Equal(t, dat.expectedY, img.Image.Bounds().Max.Y, dat.msg)
|
||||
})
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
func createImage(w, h int) image.Image {
|
||||
res := image.NewRGBA(image.Rectangle{Min: image.Point{X: 0, Y: 0}, Max: image.Point{X: w, Y: h}})
|
||||
for x := 0; x < w; x++ {
|
||||
for y := 0; y < h; y++ {
|
||||
switch {
|
||||
case x%10 == 0 || y%10 == 00: // upper left quadrant
|
||||
res.Set(x, y, color.Black)
|
||||
default:
|
||||
res.Set(x, y, color.White)
|
||||
}
|
||||
}
|
||||
}
|
||||
return res
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user