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) } }