This commit is contained in:
@@ -0,0 +1,122 @@
|
||||
package imageext
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"git.blackforestbytes.com/BlackForestBytes/goext/tst"
|
||||
)
|
||||
|
||||
func TestImageFit_Valid(t *testing.T) {
|
||||
tst.AssertTrue(t, ImageFitStretch.Valid())
|
||||
tst.AssertTrue(t, ImageFitCover.Valid())
|
||||
tst.AssertTrue(t, ImageFitContainCenter.Valid())
|
||||
tst.AssertTrue(t, ImageFitContainTopLeft.Valid())
|
||||
tst.AssertTrue(t, ImageFitContainTopRight.Valid())
|
||||
tst.AssertTrue(t, ImageFitContainBottomLeft.Valid())
|
||||
tst.AssertTrue(t, ImageFitContainBottomRight.Valid())
|
||||
|
||||
tst.AssertFalse(t, ImageFit("UNKNOWN").Valid())
|
||||
tst.AssertFalse(t, ImageFit("").Valid())
|
||||
}
|
||||
|
||||
func TestImageFit_String(t *testing.T) {
|
||||
tst.AssertEqual(t, ImageFitStretch.String(), "STRETCH")
|
||||
tst.AssertEqual(t, ImageFitCover.String(), "COVER")
|
||||
tst.AssertEqual(t, ImageFitContainCenter.String(), "CONTAIN_CENTER")
|
||||
}
|
||||
|
||||
func TestImageFit_VarName(t *testing.T) {
|
||||
tst.AssertEqual(t, ImageFitStretch.VarName(), "ImageFitStretch")
|
||||
tst.AssertEqual(t, ImageFitContainBottomRight.VarName(), "ImageFitContainBottomRight")
|
||||
tst.AssertEqual(t, ImageFit("UNKNOWN").VarName(), "")
|
||||
}
|
||||
|
||||
func TestImageFit_TypeName(t *testing.T) {
|
||||
tst.AssertEqual(t, ImageFitStretch.TypeName(), "ImageFit")
|
||||
}
|
||||
|
||||
func TestImageFit_Values(t *testing.T) {
|
||||
values := ImageFitValues()
|
||||
tst.AssertEqual(t, len(values), 7)
|
||||
tst.AssertEqual(t, values[0], ImageFitStretch)
|
||||
}
|
||||
|
||||
func TestImageFit_ValuesAny(t *testing.T) {
|
||||
tst.AssertEqual(t, len(ImageFitStretch.ValuesAny()), 7)
|
||||
}
|
||||
|
||||
func TestImageFit_ValuesMeta(t *testing.T) {
|
||||
meta := ImageFitValuesMeta()
|
||||
tst.AssertEqual(t, len(meta), 7)
|
||||
tst.AssertEqual(t, meta[0].VarName, "ImageFitStretch")
|
||||
}
|
||||
|
||||
func TestParseImageFit(t *testing.T) {
|
||||
v, ok := ParseImageFit("COVER")
|
||||
tst.AssertTrue(t, ok)
|
||||
tst.AssertEqual(t, v, ImageFitCover)
|
||||
|
||||
v, ok = ParseImageFit("CONTAIN_TOPLEFT")
|
||||
tst.AssertTrue(t, ok)
|
||||
tst.AssertEqual(t, v, ImageFitContainTopLeft)
|
||||
|
||||
_, ok = ParseImageFit("BOGUS")
|
||||
tst.AssertFalse(t, ok)
|
||||
}
|
||||
|
||||
func TestImageCompresson_Valid(t *testing.T) {
|
||||
tst.AssertTrue(t, CompressionPNGNone.Valid())
|
||||
tst.AssertTrue(t, CompressionPNGSpeed.Valid())
|
||||
tst.AssertTrue(t, CompressionPNGBest.Valid())
|
||||
tst.AssertTrue(t, CompressionJPEG100.Valid())
|
||||
tst.AssertTrue(t, CompressionJPEG1.Valid())
|
||||
|
||||
tst.AssertFalse(t, ImageCompresson("UNKNOWN").Valid())
|
||||
tst.AssertFalse(t, ImageCompresson("").Valid())
|
||||
}
|
||||
|
||||
func TestImageCompresson_String(t *testing.T) {
|
||||
tst.AssertEqual(t, CompressionPNGNone.String(), "PNG_NONE")
|
||||
tst.AssertEqual(t, CompressionJPEG90.String(), "JPEG_090")
|
||||
}
|
||||
|
||||
func TestImageCompresson_VarName(t *testing.T) {
|
||||
tst.AssertEqual(t, CompressionJPEG50.VarName(), "CompressionJPEG50")
|
||||
tst.AssertEqual(t, ImageCompresson("UNKNOWN").VarName(), "")
|
||||
}
|
||||
|
||||
func TestImageCompresson_TypeName(t *testing.T) {
|
||||
tst.AssertEqual(t, CompressionJPEG50.TypeName(), "ImageCompresson")
|
||||
}
|
||||
|
||||
func TestImageCompresson_Values(t *testing.T) {
|
||||
values := ImageCompressonValues()
|
||||
tst.AssertEqual(t, len(values), 12)
|
||||
}
|
||||
|
||||
func TestImageCompresson_ValuesAny(t *testing.T) {
|
||||
tst.AssertEqual(t, len(CompressionPNGBest.ValuesAny()), 12)
|
||||
}
|
||||
|
||||
func TestImageCompresson_ValuesMeta(t *testing.T) {
|
||||
meta := ImageCompressonValuesMeta()
|
||||
tst.AssertEqual(t, len(meta), 12)
|
||||
}
|
||||
|
||||
func TestParseImageCompresson(t *testing.T) {
|
||||
v, ok := ParseImageCompresson("PNG_BEST")
|
||||
tst.AssertTrue(t, ok)
|
||||
tst.AssertEqual(t, v, CompressionPNGBest)
|
||||
|
||||
v, ok = ParseImageCompresson("JPEG_080")
|
||||
tst.AssertTrue(t, ok)
|
||||
tst.AssertEqual(t, v, CompressionJPEG80)
|
||||
|
||||
_, ok = ParseImageCompresson("BOGUS")
|
||||
tst.AssertFalse(t, ok)
|
||||
}
|
||||
|
||||
func TestAllPackageEnums(t *testing.T) {
|
||||
enums := AllPackageEnums()
|
||||
tst.AssertEqual(t, len(enums), 2)
|
||||
}
|
||||
@@ -0,0 +1,302 @@
|
||||
package imageext
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"image"
|
||||
"image/color"
|
||||
"image/jpeg"
|
||||
"image/png"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"git.blackforestbytes.com/BlackForestBytes/goext/tst"
|
||||
)
|
||||
|
||||
// makeRGBA creates a solid-color RGBA image of the given size.
|
||||
func makeRGBA(w, h int, c color.Color) *image.RGBA {
|
||||
img := image.NewRGBA(image.Rect(0, 0, w, h))
|
||||
for y := 0; y < h; y++ {
|
||||
for x := 0; x < w; x++ {
|
||||
img.Set(x, y, c)
|
||||
}
|
||||
}
|
||||
return img
|
||||
}
|
||||
|
||||
// makeGradient creates an RGBA image with a gradient pattern.
|
||||
// Useful for codecs that may behave oddly with uniform colors.
|
||||
func makeGradient(w, h int) *image.RGBA {
|
||||
img := image.NewRGBA(image.Rect(0, 0, w, h))
|
||||
for y := 0; y < h; y++ {
|
||||
for x := 0; x < w; x++ {
|
||||
img.Set(x, y, color.RGBA{
|
||||
R: uint8((x * 255) / max1(w-1)),
|
||||
G: uint8((y * 255) / max1(h-1)),
|
||||
B: uint8(((x + y) * 255) / max1(w+h-2)),
|
||||
A: 255,
|
||||
})
|
||||
}
|
||||
}
|
||||
return img
|
||||
}
|
||||
|
||||
func max1(v int) int {
|
||||
if v <= 0 {
|
||||
return 1
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
func TestCropImage_HalfRegion(t *testing.T) {
|
||||
src := makeGradient(100, 80)
|
||||
|
||||
out, err := CropImage(src, 0.0, 0.0, 0.5, 0.5)
|
||||
tst.AssertNoErr(t, err)
|
||||
|
||||
tst.AssertEqual(t, out.Bounds().Dx(), 50)
|
||||
tst.AssertEqual(t, out.Bounds().Dy(), 40)
|
||||
}
|
||||
|
||||
func TestCropImage_Offset(t *testing.T) {
|
||||
src := makeGradient(200, 100)
|
||||
|
||||
out, err := CropImage(src, 0.25, 0.5, 0.5, 0.5)
|
||||
tst.AssertNoErr(t, err)
|
||||
|
||||
// SubImage preserves coordinates of the parent image.
|
||||
tst.AssertEqual(t, out.Bounds().Min.X, 50)
|
||||
tst.AssertEqual(t, out.Bounds().Min.Y, 50)
|
||||
tst.AssertEqual(t, out.Bounds().Dx(), 100)
|
||||
tst.AssertEqual(t, out.Bounds().Dy(), 50)
|
||||
}
|
||||
|
||||
func TestCropImage_Full(t *testing.T) {
|
||||
src := makeGradient(40, 40)
|
||||
|
||||
out, err := CropImage(src, 0.0, 0.0, 1.0, 1.0)
|
||||
tst.AssertNoErr(t, err)
|
||||
|
||||
tst.AssertEqual(t, out.Bounds().Dx(), 40)
|
||||
tst.AssertEqual(t, out.Bounds().Dy(), 40)
|
||||
}
|
||||
|
||||
func TestEncodeImage_AllCompressions(t *testing.T) {
|
||||
src := makeGradient(20, 16)
|
||||
|
||||
cases := []struct {
|
||||
comp ImageCompresson
|
||||
mime string
|
||||
signature []byte
|
||||
}{
|
||||
{CompressionPNGNone, "image/png", []byte{0x89, 'P', 'N', 'G'}},
|
||||
{CompressionPNGSpeed, "image/png", []byte{0x89, 'P', 'N', 'G'}},
|
||||
{CompressionPNGBest, "image/png", []byte{0x89, 'P', 'N', 'G'}},
|
||||
{CompressionJPEG100, "image/jpeg", []byte{0xFF, 0xD8, 0xFF}},
|
||||
{CompressionJPEG90, "image/jpeg", []byte{0xFF, 0xD8, 0xFF}},
|
||||
{CompressionJPEG80, "image/jpeg", []byte{0xFF, 0xD8, 0xFF}},
|
||||
{CompressionJPEG70, "image/jpeg", []byte{0xFF, 0xD8, 0xFF}},
|
||||
{CompressionJPEG60, "image/jpeg", []byte{0xFF, 0xD8, 0xFF}},
|
||||
{CompressionJPEG50, "image/jpeg", []byte{0xFF, 0xD8, 0xFF}},
|
||||
{CompressionJPEG25, "image/jpeg", []byte{0xFF, 0xD8, 0xFF}},
|
||||
{CompressionJPEG10, "image/jpeg", []byte{0xFF, 0xD8, 0xFF}},
|
||||
{CompressionJPEG1, "image/jpeg", []byte{0xFF, 0xD8, 0xFF}},
|
||||
}
|
||||
|
||||
for _, c := range cases {
|
||||
t.Run(string(c.comp), func(t *testing.T) {
|
||||
buf, mime, err := EncodeImage(src, c.comp)
|
||||
tst.AssertNoErr(t, err)
|
||||
tst.AssertEqual(t, mime, c.mime)
|
||||
tst.AssertTrue(t, buf.Len() > 0)
|
||||
|
||||
data := buf.Bytes()
|
||||
tst.AssertTrue(t, len(data) >= len(c.signature))
|
||||
tst.AssertTrue(t, bytes.Equal(data[:len(c.signature)], c.signature))
|
||||
|
||||
// Round-trip decode to confirm the bytes form a valid image.
|
||||
var dec image.Image
|
||||
var derr error
|
||||
if c.mime == "image/png" {
|
||||
dec, derr = png.Decode(bytes.NewReader(data))
|
||||
} else {
|
||||
dec, derr = jpeg.Decode(bytes.NewReader(data))
|
||||
}
|
||||
tst.AssertNoErr(t, derr)
|
||||
tst.AssertEqual(t, dec.Bounds().Dx(), 20)
|
||||
tst.AssertEqual(t, dec.Bounds().Dy(), 16)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestEncodeImage_UnknownCompression(t *testing.T) {
|
||||
src := makeRGBA(4, 4, color.White)
|
||||
|
||||
buf, mime, err := EncodeImage(src, ImageCompresson("UNKNOWN"))
|
||||
tst.AssertTrue(t, err != nil)
|
||||
tst.AssertEqual(t, mime, "")
|
||||
tst.AssertEqual(t, buf.Len(), 0)
|
||||
}
|
||||
|
||||
func TestObjectFitImage_Cover_SmallerThanBB(t *testing.T) {
|
||||
// Image (100x100) is smaller than the BB (200x100), so the output is
|
||||
// scaled down to the smaller-axis factor of 0.5: 100x50.
|
||||
src := makeGradient(100, 100)
|
||||
|
||||
out, rect, err := ObjectFitImage(src, 200, 100, ImageFitCover, color.Transparent)
|
||||
tst.AssertNoErr(t, err)
|
||||
|
||||
tst.AssertEqual(t, out.Bounds().Dx(), 100)
|
||||
tst.AssertEqual(t, out.Bounds().Dy(), 50)
|
||||
tst.AssertDeepEqual(t, rect, PercentageRectangle{0, 0, 1, 1})
|
||||
}
|
||||
|
||||
func TestObjectFitImage_Cover_LargerThanBB(t *testing.T) {
|
||||
// Image (400x200) is larger than the BB (200x100); fac is capped at 1, so
|
||||
// the output is exactly the BB size.
|
||||
src := makeGradient(400, 200)
|
||||
|
||||
out, _, err := ObjectFitImage(src, 200, 100, ImageFitCover, color.Transparent)
|
||||
tst.AssertNoErr(t, err)
|
||||
|
||||
tst.AssertEqual(t, out.Bounds().Dx(), 200)
|
||||
tst.AssertEqual(t, out.Bounds().Dy(), 100)
|
||||
}
|
||||
|
||||
func TestObjectFitImage_ContainCenter(t *testing.T) {
|
||||
// Image 100x100 in a BB of 200x100 -> output 200x100, drawn rect 100x100 centered.
|
||||
src := makeGradient(100, 100)
|
||||
|
||||
out, rect, err := ObjectFitImage(src, 200, 100, ImageFitContainCenter, color.Black)
|
||||
tst.AssertNoErr(t, err)
|
||||
|
||||
tst.AssertEqual(t, out.Bounds().Dx(), 200)
|
||||
tst.AssertEqual(t, out.Bounds().Dy(), 100)
|
||||
|
||||
// (200-100)/2 = 50 -> X=50/200 = 0.25, W=100/200=0.5, Y=0, H=1
|
||||
tst.AssertDeepEqual(t, rect, PercentageRectangle{X: 0.25, Y: 0, W: 0.5, H: 1})
|
||||
}
|
||||
|
||||
func TestObjectFitImage_ContainTopLeft(t *testing.T) {
|
||||
src := makeGradient(100, 100)
|
||||
|
||||
out, rect, err := ObjectFitImage(src, 200, 100, ImageFitContainTopLeft, color.Black)
|
||||
tst.AssertNoErr(t, err)
|
||||
|
||||
tst.AssertEqual(t, out.Bounds().Dx(), 200)
|
||||
tst.AssertEqual(t, out.Bounds().Dy(), 100)
|
||||
tst.AssertDeepEqual(t, rect, PercentageRectangle{X: 0, Y: 0, W: 0.5, H: 1})
|
||||
}
|
||||
|
||||
func TestObjectFitImage_ContainTopRight(t *testing.T) {
|
||||
src := makeGradient(100, 100)
|
||||
|
||||
out, rect, err := ObjectFitImage(src, 200, 100, ImageFitContainTopRight, color.Black)
|
||||
tst.AssertNoErr(t, err)
|
||||
|
||||
tst.AssertEqual(t, out.Bounds().Dx(), 200)
|
||||
tst.AssertEqual(t, out.Bounds().Dy(), 100)
|
||||
tst.AssertDeepEqual(t, rect, PercentageRectangle{X: 0.5, Y: 0, W: 0.5, H: 1})
|
||||
}
|
||||
|
||||
func TestObjectFitImage_ContainBottomLeft(t *testing.T) {
|
||||
// Image 200x100 in a BB of 100x100 (image is bigger so facOut is capped at 1)
|
||||
src := makeGradient(200, 100)
|
||||
|
||||
out, rect, err := ObjectFitImage(src, 100, 100, ImageFitContainBottomLeft, color.Black)
|
||||
tst.AssertNoErr(t, err)
|
||||
|
||||
tst.AssertEqual(t, out.Bounds().Dx(), 100)
|
||||
tst.AssertEqual(t, out.Bounds().Dy(), 100)
|
||||
// dw=100, dh=50 -> bottom-left rect: (0, 50, 100, 100) -> Y=0.5, H=0.5
|
||||
tst.AssertDeepEqual(t, rect, PercentageRectangle{X: 0, Y: 0.5, W: 1, H: 0.5})
|
||||
}
|
||||
|
||||
func TestObjectFitImage_ContainBottomRight(t *testing.T) {
|
||||
src := makeGradient(200, 100)
|
||||
|
||||
out, rect, err := ObjectFitImage(src, 100, 100, ImageFitContainBottomRight, color.Black)
|
||||
tst.AssertNoErr(t, err)
|
||||
|
||||
tst.AssertEqual(t, out.Bounds().Dx(), 100)
|
||||
tst.AssertEqual(t, out.Bounds().Dy(), 100)
|
||||
tst.AssertDeepEqual(t, rect, PercentageRectangle{X: 0, Y: 0.5, W: 1, H: 0.5})
|
||||
}
|
||||
|
||||
func TestObjectFitImage_Stretch(t *testing.T) {
|
||||
// Image 100x100 in BB 200x100 -> uses max(facW=0.5, facH=1.0) capped at 1, so result is 200x100.
|
||||
src := makeGradient(100, 100)
|
||||
|
||||
out, rect, err := ObjectFitImage(src, 200, 100, ImageFitStretch, color.Black)
|
||||
tst.AssertNoErr(t, err)
|
||||
|
||||
tst.AssertEqual(t, out.Bounds().Dx(), 200)
|
||||
tst.AssertEqual(t, out.Bounds().Dy(), 100)
|
||||
tst.AssertDeepEqual(t, rect, PercentageRectangle{0, 0, 1, 1})
|
||||
}
|
||||
|
||||
func TestObjectFitImage_Stretch_SmallImage(t *testing.T) {
|
||||
// Image 50x25 in BB 200x100 -> max(0.25, 0.25) = 0.25, output 50x25.
|
||||
src := makeGradient(50, 25)
|
||||
|
||||
out, _, err := ObjectFitImage(src, 200, 100, ImageFitStretch, color.Black)
|
||||
tst.AssertNoErr(t, err)
|
||||
|
||||
tst.AssertEqual(t, out.Bounds().Dx(), 50)
|
||||
tst.AssertEqual(t, out.Bounds().Dy(), 25)
|
||||
}
|
||||
|
||||
func TestObjectFitImage_UnknownFit(t *testing.T) {
|
||||
src := makeGradient(20, 20)
|
||||
|
||||
out, _, err := ObjectFitImage(src, 100, 100, ImageFit("BOGUS"), color.Black)
|
||||
tst.AssertTrue(t, err != nil)
|
||||
if out != nil {
|
||||
t.Errorf("expected nil image on error, got %v", out)
|
||||
}
|
||||
}
|
||||
|
||||
func TestVerifyAndDecodeImage_PNG(t *testing.T) {
|
||||
src := makeGradient(12, 8)
|
||||
buf := bytes.Buffer{}
|
||||
tst.AssertNoErr(t, png.Encode(&buf, src))
|
||||
|
||||
out, err := VerifyAndDecodeImage(&buf, "image/png")
|
||||
tst.AssertNoErr(t, err)
|
||||
tst.AssertEqual(t, out.Bounds().Dx(), 12)
|
||||
tst.AssertEqual(t, out.Bounds().Dy(), 8)
|
||||
}
|
||||
|
||||
func TestVerifyAndDecodeImage_JPEG(t *testing.T) {
|
||||
src := makeGradient(16, 16)
|
||||
buf := bytes.Buffer{}
|
||||
tst.AssertNoErr(t, jpeg.Encode(&buf, src, &jpeg.Options{Quality: 90}))
|
||||
|
||||
out, err := VerifyAndDecodeImage(&buf, "image/jpeg")
|
||||
tst.AssertNoErr(t, err)
|
||||
tst.AssertEqual(t, out.Bounds().Dx(), 16)
|
||||
tst.AssertEqual(t, out.Bounds().Dy(), 16)
|
||||
}
|
||||
|
||||
func TestVerifyAndDecodeImage_UnknownMime(t *testing.T) {
|
||||
out, err := VerifyAndDecodeImage(strings.NewReader("whatever"), "image/gif")
|
||||
tst.AssertTrue(t, err != nil)
|
||||
if out != nil {
|
||||
t.Errorf("expected nil image on error, got %v", out)
|
||||
}
|
||||
}
|
||||
|
||||
func TestVerifyAndDecodeImage_BadPNG(t *testing.T) {
|
||||
out, err := VerifyAndDecodeImage(strings.NewReader("not a png"), "image/png")
|
||||
tst.AssertTrue(t, err != nil)
|
||||
if out != nil {
|
||||
t.Errorf("expected nil image on error, got %v", out)
|
||||
}
|
||||
}
|
||||
|
||||
func TestVerifyAndDecodeImage_BadJPEG(t *testing.T) {
|
||||
out, err := VerifyAndDecodeImage(strings.NewReader("not a jpeg"), "image/jpeg")
|
||||
tst.AssertTrue(t, err != nil)
|
||||
if out != nil {
|
||||
t.Errorf("expected nil image on error, got %v", out)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
package imageext
|
||||
|
||||
import (
|
||||
"image"
|
||||
"testing"
|
||||
|
||||
"git.blackforestbytes.com/BlackForestBytes/goext/tst"
|
||||
)
|
||||
|
||||
func TestPercentageRectangle_Of_FullRef(t *testing.T) {
|
||||
r := PercentageRectangle{X: 0.25, Y: 0.5, W: 0.5, H: 0.25}
|
||||
ref := Rectangle{X: 0, Y: 0, W: 100, H: 200}
|
||||
|
||||
got := r.Of(ref)
|
||||
tst.AssertDeepEqual(t, got, Rectangle{X: 25, Y: 100, W: 50, H: 50})
|
||||
}
|
||||
|
||||
func TestPercentageRectangle_Of_OffsetRef(t *testing.T) {
|
||||
r := PercentageRectangle{X: 0.5, Y: 0.5, W: 0.5, H: 0.5}
|
||||
ref := Rectangle{X: 10, Y: 20, W: 100, H: 100}
|
||||
|
||||
got := r.Of(ref)
|
||||
tst.AssertDeepEqual(t, got, Rectangle{X: 60, Y: 70, W: 50, H: 50})
|
||||
}
|
||||
|
||||
func TestPercentageRectangle_Of_Identity(t *testing.T) {
|
||||
r := PercentageRectangle{X: 0, Y: 0, W: 1, H: 1}
|
||||
ref := Rectangle{X: 5, Y: 6, W: 7, H: 8}
|
||||
|
||||
got := r.Of(ref)
|
||||
tst.AssertDeepEqual(t, got, ref)
|
||||
}
|
||||
|
||||
func TestCalcRelativeRect_FullInner(t *testing.T) {
|
||||
inner := image.Rect(0, 0, 100, 100)
|
||||
outer := image.Rect(0, 0, 100, 100)
|
||||
|
||||
got := calcRelativeRect(inner, outer)
|
||||
tst.AssertDeepEqual(t, got, PercentageRectangle{X: 0, Y: 0, W: 1, H: 1})
|
||||
}
|
||||
|
||||
func TestCalcRelativeRect_Centered(t *testing.T) {
|
||||
inner := image.Rect(50, 25, 150, 75)
|
||||
outer := image.Rect(0, 0, 200, 100)
|
||||
|
||||
got := calcRelativeRect(inner, outer)
|
||||
tst.AssertDeepEqual(t, got, PercentageRectangle{X: 0.25, Y: 0.25, W: 0.5, H: 0.5})
|
||||
}
|
||||
|
||||
func TestCalcRelativeRect_OffsetOuter(t *testing.T) {
|
||||
inner := image.Rect(120, 60, 220, 110)
|
||||
outer := image.Rect(100, 50, 300, 150)
|
||||
|
||||
got := calcRelativeRect(inner, outer)
|
||||
tst.AssertDeepEqual(t, got, PercentageRectangle{X: 0.1, Y: 0.1, W: 0.5, H: 0.5})
|
||||
}
|
||||
Reference in New Issue
Block a user