package ai import ( "bytes" "image/jpeg" "testing" ) func TestEncodeScreenshot(t *testing.T) { width, height := 100, 80 // Create a test RGBA buffer (red pixels) rgba := make([]byte, width*height*4) for i := 0; i < len(rgba); i += 4 { rgba[i+0] = 255 // R rgba[i+1] = 0 // G rgba[i+2] = 0 // B rgba[i+3] = 255 // A } jpegData, err := EncodeScreenshot(rgba, width, height, 200, 200, 80) if err != nil { t.Fatalf("unexpected error: %v", err) } // Check JPEG magic bytes (FF D8) if len(jpegData) < 2 { t.Fatal("JPEG data too small") } if jpegData[0] != 0xFF || jpegData[1] != 0xD8 { t.Errorf("expected JPEG magic bytes FF D8, got %02X %02X", jpegData[0], jpegData[1]) } // Decode and verify dimensions (no downscale needed in this case) img, err := jpeg.Decode(bytes.NewReader(jpegData)) if err != nil { t.Fatalf("decode JPEG: %v", err) } bounds := img.Bounds() if bounds.Dx() != width || bounds.Dy() != height { t.Errorf("expected %dx%d, got %dx%d", width, height, bounds.Dx(), bounds.Dy()) } } func TestEncodeScreenshotDownscale(t *testing.T) { srcWidth, srcHeight := 1920, 1080 maxWidth, maxHeight := 1280, 720 // Create a test RGBA buffer (gradient) rgba := make([]byte, srcWidth*srcHeight*4) for y := 0; y < srcHeight; y++ { for x := 0; x < srcWidth; x++ { idx := (y*srcWidth + x) * 4 rgba[idx+0] = byte(x % 256) // R rgba[idx+1] = byte(y % 256) // G rgba[idx+2] = byte((x + y) % 256) // B rgba[idx+3] = 255 // A } } jpegData, err := EncodeScreenshot(rgba, srcWidth, srcHeight, maxWidth, maxHeight, 75) if err != nil { t.Fatalf("unexpected error: %v", err) } // Check JPEG magic bytes if jpegData[0] != 0xFF || jpegData[1] != 0xD8 { t.Errorf("expected JPEG magic bytes FF D8, got %02X %02X", jpegData[0], jpegData[1]) } // Decode and verify dimensions are within max bounds img, err := jpeg.Decode(bytes.NewReader(jpegData)) if err != nil { t.Fatalf("decode JPEG: %v", err) } bounds := img.Bounds() if bounds.Dx() > maxWidth { t.Errorf("output width %d exceeds max %d", bounds.Dx(), maxWidth) } if bounds.Dy() > maxHeight { t.Errorf("output height %d exceeds max %d", bounds.Dy(), maxHeight) } // Should maintain 16:9 ratio approximately expectedWidth := 1280 expectedHeight := 720 if bounds.Dx() != expectedWidth || bounds.Dy() != expectedHeight { t.Errorf("expected %dx%d, got %dx%d", expectedWidth, expectedHeight, bounds.Dx(), bounds.Dy()) } } func TestEncodeScreenshotBufferTooSmall(t *testing.T) { _, err := EncodeScreenshot([]byte{0, 0, 0, 0}, 100, 100, 200, 200, 75) if err == nil { t.Error("expected error for buffer too small") } } func TestFitDimensions(t *testing.T) { tests := []struct { srcW, srcH, maxW, maxH int wantW, wantH int }{ {1920, 1080, 1280, 720, 1280, 720}, // 16:9 fits exactly {1920, 1080, 800, 600, 800, 450}, // width-constrained {1080, 1920, 800, 600, 337, 600}, // height-constrained (portrait) {100, 100, 200, 200, 200, 200}, // smaller than max (but func called with > check) } for _, tt := range tests { w, h := fitDimensions(tt.srcW, tt.srcH, tt.maxW, tt.maxH) if w != tt.wantW || h != tt.wantH { t.Errorf("fitDimensions(%d,%d,%d,%d) = %d,%d, want %d,%d", tt.srcW, tt.srcH, tt.maxW, tt.maxH, w, h, tt.wantW, tt.wantH) } } }