package rdp import "testing" func TestNewPixelBuffer(t *testing.T) { pb := NewPixelBuffer(100, 50) if pb.Width != 100 { t.Errorf("Width = %d, want 100", pb.Width) } if pb.Height != 50 { t.Errorf("Height = %d, want 50", pb.Height) } expectedLen := 100 * 50 * 4 if len(pb.Data) != expectedLen { t.Errorf("Data length = %d, want %d", len(pb.Data), expectedLen) } // All pixels should be initialized to zero for i, b := range pb.Data { if b != 0 { t.Errorf("Data[%d] = %d, want 0", i, b) break } } } func TestNewPixelBufferSmall(t *testing.T) { pb := NewPixelBuffer(1, 1) if len(pb.Data) != 4 { t.Errorf("1x1 buffer Data length = %d, want 4", len(pb.Data)) } } func TestUpdateRegion(t *testing.T) { pb := NewPixelBuffer(10, 10) // 10x10 pixels // Create a 3x2 red patch patch := make([]byte, 3*2*4) // 3 wide, 2 tall for i := 0; i < 3*2; i++ { patch[i*4+0] = 255 // R patch[i*4+1] = 0 // G patch[i*4+2] = 0 // B patch[i*4+3] = 255 // A } // Apply at position (2, 3) pb.Update(2, 3, 3, 2, patch) // Check that pixel (2,3) is red offset := (3*10 + 2) * 4 if pb.Data[offset+0] != 255 || pb.Data[offset+1] != 0 || pb.Data[offset+2] != 0 || pb.Data[offset+3] != 255 { t.Errorf("pixel (2,3) = [%d,%d,%d,%d], want [255,0,0,255]", pb.Data[offset+0], pb.Data[offset+1], pb.Data[offset+2], pb.Data[offset+3]) } // Check that pixel (4,4) is red (last pixel of patch) offset = (4*10 + 4) * 4 if pb.Data[offset+0] != 255 || pb.Data[offset+1] != 0 || pb.Data[offset+2] != 0 || pb.Data[offset+3] != 255 { t.Errorf("pixel (4,4) = [%d,%d,%d,%d], want [255,0,0,255]", pb.Data[offset+0], pb.Data[offset+1], pb.Data[offset+2], pb.Data[offset+3]) } // Check that pixel (1,3) is still black (just outside patch) offset = (3*10 + 1) * 4 if pb.Data[offset+0] != 0 || pb.Data[offset+3] != 0 { t.Errorf("pixel (1,3) should be untouched, got [%d,%d,%d,%d]", pb.Data[offset+0], pb.Data[offset+1], pb.Data[offset+2], pb.Data[offset+3]) } // Check that pixel (5,3) is still black (just outside patch) offset = (3*10 + 5) * 4 if pb.Data[offset+0] != 0 || pb.Data[offset+3] != 0 { t.Errorf("pixel (5,3) should be untouched, got [%d,%d,%d,%d]", pb.Data[offset+0], pb.Data[offset+1], pb.Data[offset+2], pb.Data[offset+3]) } } func TestUpdateRegionClipping(t *testing.T) { pb := NewPixelBuffer(10, 10) // Create a 5x5 green patch and place it at (8, 8), so it overflows patch := make([]byte, 5*5*4) for i := 0; i < 5*5; i++ { patch[i*4+0] = 0 patch[i*4+1] = 255 patch[i*4+2] = 0 patch[i*4+3] = 255 } // Should not panic — overflowing regions are clipped pb.Update(8, 8, 5, 5, patch) // Pixel (8,8) should be green offset := (8*10 + 8) * 4 if pb.Data[offset+1] != 255 { t.Errorf("pixel (8,8) G = %d, want 255", pb.Data[offset+1]) } // Pixel (9,9) should also be green (last valid pixel) offset = (9*10 + 9) * 4 if pb.Data[offset+1] != 255 { t.Errorf("pixel (9,9) G = %d, want 255", pb.Data[offset+1]) } } func TestDirtyFlag(t *testing.T) { pb := NewPixelBuffer(10, 10) if pb.IsDirty() { t.Error("new buffer should not be dirty") } // Update a region patch := make([]byte, 4) // 1x1 pixel patch[0] = 255 patch[3] = 255 pb.Update(0, 0, 1, 1, patch) if !pb.IsDirty() { t.Error("buffer should be dirty after update") } pb.ClearDirty() if pb.IsDirty() { t.Error("buffer should not be dirty after ClearDirty") } } func TestGetFrameReturnsCopy(t *testing.T) { pb := NewPixelBuffer(2, 2) // Set first pixel to white patch := []byte{255, 255, 255, 255} pb.Update(0, 0, 1, 1, patch) frame1 := pb.GetFrame() // Modify the returned frame frame1[0] = 0 // Get another frame — it should still have the original value frame2 := pb.GetFrame() if frame2[0] != 255 { t.Errorf("GetFrame did not return an independent copy: got %d, want 255", frame2[0]) } } func TestFullFrameUpdate(t *testing.T) { pb := NewPixelBuffer(4, 4) // Create a full-frame update with all blue pixels fullFrame := make([]byte, 4*4*4) for i := 0; i < 4*4; i++ { fullFrame[i*4+0] = 0 fullFrame[i*4+1] = 0 fullFrame[i*4+2] = 255 fullFrame[i*4+3] = 255 } pb.Update(0, 0, 4, 4, fullFrame) frame := pb.GetFrame() for i := 0; i < 4*4; i++ { if frame[i*4+2] != 255 { t.Errorf("pixel %d blue channel = %d, want 255", i, frame[i*4+2]) break } } }