Files
sow-tools/internal/assets/convert_test.go
T
archvillainette 5ebef57160
build-binaries / build-binaries (push) Successful in 2m5s
test / test (push) Successful in 1m23s
assets builder tools (#39)
Reviewed-on: #39
Reviewed-by: xtul <mpiasecki720@protonmail.com>
2026-07-12 12:51:17 +00:00

109 lines
2.9 KiB
Go

package assets
import (
"bytes"
"image"
"image/color"
"image/png"
"os"
"os/exec"
"path/filepath"
"testing"
)
// writeTestPNG writes a 16x16 image: top half red, bottom half blue. The size
// and the half-way split keep every 4x4 DXT block a single flat color, so the
// DXT1 round trip stays lossless and only the flip is under test. (A 4x4 image
// is one mixed DXT block that magick's encoder collapses to a single color.)
func writeTestPNG(t *testing.T, path string) {
t.Helper()
const n = 16
img := image.NewRGBA(image.Rect(0, 0, n, n))
for y := 0; y < n; y++ {
c := color.RGBA{255, 0, 0, 255} // red
if y >= n/2 {
c = color.RGBA{0, 0, 255, 255} // blue
}
for x := 0; x < n; x++ {
img.Set(x, y, c)
}
}
f, err := os.Create(path)
if err != nil {
t.Fatal(err)
}
defer f.Close()
if err := png.Encode(f, img); err != nil {
t.Fatal(err)
}
}
func topRowIsBlue(t *testing.T, pngPath string) bool {
t.Helper()
f, err := os.Open(pngPath)
if err != nil {
t.Fatal(err)
}
defer f.Close()
img, err := png.Decode(f)
if err != nil {
t.Fatal(err)
}
r, _, b, _ := img.At(0, 0).RGBA()
return b > r // blue dominates the top-left after a flip
}
func TestConvertFlipsOnceAndRoundTrips(t *testing.T) {
magick := look("magick")
if magick == "" {
t.Skip("magick not on PATH")
}
dir := t.TempDir()
src := filepath.Join(dir, "tex.png")
writeTestPNG(t, src)
// Convert PNG -> DDS (in place: tex.png becomes tex.dds, original removed).
var out, errw bytes.Buffer
if code := runConvert([]string{"--to", "dds", dir}, &out, &errw); code != exitOK {
t.Fatalf("to-dds exit = %d\n%s", code, errw.String())
}
dds := filepath.Join(dir, "tex.dds")
if _, err := os.Stat(dds); err != nil {
t.Fatalf("dds not produced: %v", err)
}
if _, err := os.Stat(src); !os.IsNotExist(err) {
t.Fatal("source png was not replaced")
}
// Decode the DDS RAW (no extra flip) and confirm a single flip happened:
// the source top row was red, so the DDS top row must now be blue.
raw := filepath.Join(dir, "raw.png")
if err := exec.Command(magick, dds, raw).Run(); err != nil {
t.Fatalf("raw decode: %v", err)
}
if !topRowIsBlue(t, raw) {
t.Fatal("expected the DDS to be vertically flipped vs the source")
}
// Convert DDS -> PNG (another flip). Result should match the original.
out.Reset()
errw.Reset()
if code := runConvert([]string{"--to", "png", dir}, &out, &errw); code != exitOK {
t.Fatalf("to-png exit = %d\n%s", code, errw.String())
}
restored := filepath.Join(dir, "tex.png")
if topRowIsBlue(t, restored) {
t.Fatal("round trip did not restore the original orientation")
}
}
func TestConvertMissingBackendFailsClosed(t *testing.T) {
dir := t.TempDir()
writeTestPNG(t, filepath.Join(dir, "tex.png"))
var out, errw bytes.Buffer
code := runConvert([]string{"--backend", "/nonexistent/magick", dir}, &out, &errw)
if code != exitTool {
t.Fatalf("missing backend exit = %d, want %d", code, exitTool)
}
}