package generator import ( "strings" "testing" ) func TestNewCPUGeneratorValidation(t *testing.T) { sampler := func(_, _, _, _, _ int) YCbCr10 { return YCbCr10{} } tests := []struct { name string width uint height uint sampler PixelSampler wantErrSub string }{ {name: "zero width", height: 1, sampler: sampler, wantErrSub: "greater than 0"}, {name: "zero height", width: 6, sampler: sampler, wantErrSub: "greater than 0"}, {name: "unaligned width", width: 7, height: 1, sampler: sampler, wantErrSub: "divisible by 6"}, {name: "nil sampler", width: 6, height: 1, wantErrSub: "sampler is nil"}, } for _, tc := range tests { t.Run(tc.name, func(t *testing.T) { _, err := NewCPUGenerator(tc.width, tc.height, tc.sampler) if err == nil || !strings.Contains(err.Error(), tc.wantErrSub) { t.Fatalf("error = %v, want substring %q", err, tc.wantErrSub) } }) } } func TestCPUGeneratorGenerateFrame(t *testing.T) { const width, height = 12, 2 const frameIndex = 7 g, err := NewCPUGenerator(width, height, func(x, y, _, _ int, tick int) YCbCr10 { return YCbCr10{ Y: uint32(100 + x + 10*y + tick), Cb: uint32(200 + x + 10*y + tick), Cr: uint32(300 + x + 10*y + tick), } }) if err != nil { t.Fatalf("NewCPUGenerator: %v", err) } frame := make([]byte, width*height*8/3) if err := g.GenerateFrame(frame, frameIndex); err != nil { t.Fatalf("GenerateFrame: %v", err) } for y := 0; y < height; y++ { for x := 0; x < width; x++ { gotY, gotCb, gotCr := sampleV210(frame, width, x, y) chromaX := x - x%2 wantY := uint32(100 + x + 10*y + frameIndex) wantCb := uint32(200 + chromaX + 10*y + frameIndex) wantCr := uint32(300 + chromaX + 10*y + frameIndex) if gotY != wantY || gotCb != wantCb || gotCr != wantCr { t.Fatalf("pixel (%d,%d): got %d/%d/%d, want %d/%d/%d", x, y, gotY, gotCb, gotCr, wantY, wantCb, wantCr) } } } } func TestCPUGeneratorMasksComponentsToTenBits(t *testing.T) { g, err := NewCPUGenerator(6, 1, func(_, _, _, _, _ int) YCbCr10 { return YCbCr10{Y: 0xC01, Cb: 0xC02, Cr: 0xC03} }) if err != nil { t.Fatalf("NewCPUGenerator: %v", err) } frame := make([]byte, 16) if err := g.GenerateFrame(frame, 0); err != nil { t.Fatalf("GenerateFrame: %v", err) } y, cb, cr := sampleV210(frame, 6, 0, 0) if y != 1 || cb != 2 || cr != 3 { t.Fatalf("masked components = %d/%d/%d, want 1/2/3", y, cb, cr) } } func TestCPUGeneratorRejectsSmallDestination(t *testing.T) { g, err := NewCPUGenerator(6, 1, func(_, _, _, _, _ int) YCbCr10 { return YCbCr10{} }) if err != nil { t.Fatalf("NewCPUGenerator: %v", err) } if err := g.GenerateFrame(make([]byte, 15), 0); err == nil || !strings.Contains(err.Error(), "too small") { t.Fatalf("error = %v, want destination size error", err) } }