101 lines
2.8 KiB
Go
101 lines
2.8 KiB
Go
|
|
package pdfassets
|
||
|
|
|
||
|
|
import (
|
||
|
|
"bytes"
|
||
|
|
"image"
|
||
|
|
"image/color"
|
||
|
|
"image/jpeg"
|
||
|
|
"os"
|
||
|
|
"path/filepath"
|
||
|
|
"testing"
|
||
|
|
)
|
||
|
|
|
||
|
|
func TestFitWithin(t *testing.T) {
|
||
|
|
w, h := fitWithin(400, 200, 100, 100)
|
||
|
|
if w != 100 || h != 50 {
|
||
|
|
t.Fatalf("fitWithin landscape = %dx%d, want 100x50", w, h)
|
||
|
|
}
|
||
|
|
|
||
|
|
w, h = fitWithin(200, 400, 100, 100)
|
||
|
|
if w != 50 || h != 100 {
|
||
|
|
t.Fatalf("fitWithin portrait = %dx%d, want 50x100", w, h)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestApplyOrientationRightTop(t *testing.T) {
|
||
|
|
img := image.NewRGBA(image.Rect(0, 0, 2, 3))
|
||
|
|
for y := 0; y < 3; y++ {
|
||
|
|
for x := 0; x < 2; x++ {
|
||
|
|
img.Set(x, y, color.RGBA{R: uint8(x), G: uint8(y), A: 0xff})
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
got := applyOrientation(img, 6)
|
||
|
|
if got.Bounds().Dx() != 3 || got.Bounds().Dy() != 2 {
|
||
|
|
t.Fatalf("oriented bounds = %v, want 3x2", got.Bounds())
|
||
|
|
}
|
||
|
|
assertRGBA(t, got.At(0, 0), color.RGBA{R: 0, G: 2, A: 0xff})
|
||
|
|
assertRGBA(t, got.At(2, 1), color.RGBA{R: 1, G: 0, A: 0xff})
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestPrepareTreeOptimizesImagesAndSkipsPDFs(t *testing.T) {
|
||
|
|
root := t.TempDir()
|
||
|
|
if err := os.MkdirAll(filepath.Join(root, "assets", "img"), 0o755); err != nil {
|
||
|
|
t.Fatal(err)
|
||
|
|
}
|
||
|
|
if err := os.WriteFile(filepath.Join(root, "index.html"), []byte(`<img src="assets/img/photo.jpg">`), 0o644); err != nil {
|
||
|
|
t.Fatal(err)
|
||
|
|
}
|
||
|
|
if err := os.WriteFile(filepath.Join(root, "old.pdf"), []byte("old pdf"), 0o644); err != nil {
|
||
|
|
t.Fatal(err)
|
||
|
|
}
|
||
|
|
|
||
|
|
var src bytes.Buffer
|
||
|
|
img := image.NewRGBA(image.Rect(0, 0, 400, 200))
|
||
|
|
for y := 0; y < 200; y++ {
|
||
|
|
for x := 0; x < 400; x++ {
|
||
|
|
img.Set(x, y, color.RGBA{R: uint8(x), G: uint8(y), B: 120, A: 0xff})
|
||
|
|
}
|
||
|
|
}
|
||
|
|
if err := jpeg.Encode(&src, img, &jpeg.Options{Quality: 95}); err != nil {
|
||
|
|
t.Fatal(err)
|
||
|
|
}
|
||
|
|
if err := os.WriteFile(filepath.Join(root, "assets", "img", "photo.jpg"), src.Bytes(), 0o644); err != nil {
|
||
|
|
t.Fatal(err)
|
||
|
|
}
|
||
|
|
|
||
|
|
prepared, err := PrepareTree(root, Options{MaxWidth: 100, MaxHeight: 100, JPEGQuality: 70})
|
||
|
|
if err != nil {
|
||
|
|
t.Fatal(err)
|
||
|
|
}
|
||
|
|
defer prepared.Cleanup()
|
||
|
|
|
||
|
|
if prepared.Stats.ImageFiles != 1 || prepared.Stats.OptimizedImages != 1 {
|
||
|
|
t.Fatalf("stats = %+v, want one optimized image", prepared.Stats)
|
||
|
|
}
|
||
|
|
if _, err := os.Stat(filepath.Join(prepared.Root, "old.pdf")); !os.IsNotExist(err) {
|
||
|
|
t.Fatalf("old PDF copied into prepared tree; err=%v", err)
|
||
|
|
}
|
||
|
|
|
||
|
|
out, err := os.Open(filepath.Join(prepared.Root, "assets", "img", "photo.jpg"))
|
||
|
|
if err != nil {
|
||
|
|
t.Fatal(err)
|
||
|
|
}
|
||
|
|
defer out.Close()
|
||
|
|
cfg, err := jpeg.DecodeConfig(out)
|
||
|
|
if err != nil {
|
||
|
|
t.Fatal(err)
|
||
|
|
}
|
||
|
|
if cfg.Width > 100 || cfg.Height > 100 {
|
||
|
|
t.Fatalf("optimized dimensions = %dx%d, want within 100x100", cfg.Width, cfg.Height)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func assertRGBA(t *testing.T, got color.Color, want color.RGBA) {
|
||
|
|
t.Helper()
|
||
|
|
r, g, b, a := got.RGBA()
|
||
|
|
if uint8(r>>8) != want.R || uint8(g>>8) != want.G || uint8(b>>8) != want.B || uint8(a>>8) != want.A {
|
||
|
|
t.Fatalf("color = rgba(%d,%d,%d,%d), want %+v", uint8(r>>8), uint8(g>>8), uint8(b>>8), uint8(a>>8), want)
|
||
|
|
}
|
||
|
|
}
|