@@ -650,3 +650,313 @@ func TestGeneratorOutputParameters(t *testing.T) {
650650 t .Log ("Missing: av_fifo_write_from_cb, av_fifo_read_to_cb, av_fifo_peek_to_cb" )
651651 })
652652}
653+
654+ // TestGeneratorFieldAccessors validates that struct field getters work as expected
655+ // This tests the getter generation pattern for various field types
656+ func TestGeneratorFieldAccessors (t * testing.T ) {
657+ t .Run ("primitive_fields" , func (t * testing.T ) {
658+ frame := AVFrameAlloc ()
659+ if frame == nil {
660+ t .Fatal ("AVFrameAlloc returned nil" )
661+ }
662+ defer AVFrameFree (& frame )
663+
664+ // Test that getters return expected types and compile
665+ _ = frame .Width () // int
666+ _ = frame .Height () // int
667+ _ = frame .Format () // int (pix_fmt)
668+ _ = frame .Pts () // int64
669+ _ = frame .PktDts () // int64
670+ _ = frame .Data () // [8]unsafe.Pointer (const array)
671+ _ = frame .Linesize () // [8]int (const array)
672+
673+ t .Log ("Primitive field accessors compile and work correctly" )
674+ })
675+
676+ t .Run ("byvalue_struct_fields" , func (t * testing.T ) {
677+ frame := AVFrameAlloc ()
678+ if frame == nil {
679+ t .Fatal ("AVFrameAlloc returned nil" )
680+ }
681+ defer AVFrameFree (& frame )
682+
683+ // Test ByValue struct field returns proper type
684+ timebase := frame .TimeBase ()
685+ _ = timebase .Num ()
686+ _ = timebase .Den ()
687+
688+ sampleAspectRatio := frame .SampleAspectRatio ()
689+ _ = sampleAspectRatio .Num ()
690+ _ = sampleAspectRatio .Den ()
691+
692+ t .Log ("ByValue struct field accessors work correctly" )
693+ })
694+
695+ t .Run ("pointer_struct_fields" , func (t * testing.T ) {
696+ codecCtx := AVCodecAllocContext3 (nil )
697+ if codecCtx == nil {
698+ t .Fatal ("AVCodecAllocContext3 returned nil" )
699+ }
700+ defer AVCodecFreeContext (& codecCtx )
701+
702+ // Test pointer field accessors
703+ _ = codecCtx .Extradata () // unsafe.Pointer
704+ _ = codecCtx .ExtradataSize () // int
705+ _ = codecCtx .Codec () // *AVCodec
706+
707+ t .Log ("Pointer struct field accessors work correctly" )
708+ })
709+ }
710+
711+ // TestGeneratorEnumArrayHelpers validates that enum array helpers work correctly
712+ // This tests the AllocXArray generation pattern for enums
713+ func TestGeneratorEnumArrayHelpers (t * testing.T ) {
714+ t .Run ("codec_id_array" , func (t * testing.T ) {
715+ // Allocate an enum array using generated helper
716+ arr := AllocAVCodecIDArray (3 )
717+ if arr == nil {
718+ t .Fatal ("AllocAVCodecIDArray returned nil" )
719+ }
720+ defer AVFree (arr .RawPtr ())
721+
722+ // Set and get enum values
723+ arr .Set (0 , AVCodecIdH264 )
724+ arr .Set (1 , AVCodecIdHevc )
725+ arr .Set (2 , AVCodecIdAV1 )
726+
727+ if arr .Get (0 ) != AVCodecIdH264 {
728+ t .Errorf ("Array Get(0) failed: got %v, want AVCodecIdH264" , arr .Get (0 ))
729+ }
730+ if arr .Get (1 ) != AVCodecIdHevc {
731+ t .Errorf ("Array Get(1) failed: got %v, want AVCodecIdHEVC" , arr .Get (1 ))
732+ }
733+ if arr .Get (2 ) != AVCodecIdAV1 {
734+ t .Errorf ("Array Get(2) failed: got %v, want AVCodecIdAV1" , arr .Get (2 ))
735+ }
736+
737+ t .Log ("Enum array helpers work correctly" )
738+ })
739+
740+ t .Run ("pixel_format_array" , func (t * testing.T ) {
741+ // Test that pixel format arrays compile and work
742+ arr := AllocAVPixelFormatArray (2 )
743+ if arr == nil {
744+ t .Fatal ("AllocAVPixelFormatArray returned nil" )
745+ }
746+ defer AVFree (arr .RawPtr ())
747+
748+ arr .Set (0 , AVPixFmtRgb24 )
749+ arr .Set (1 , AVPixFmtYuv420P )
750+
751+ if arr .Get (0 ) != AVPixFmtRgb24 {
752+ t .Errorf ("Pixel format array failed: got %v, want AVPixFmtRgb24" , arr .Get (0 ))
753+ }
754+
755+ t .Log ("Pixel format array helpers work correctly" )
756+ })
757+
758+ t .Run ("sample_format_array" , func (t * testing.T ) {
759+ // Test sample format array generation
760+ arr := AllocAVSampleFormatArray (3 )
761+ if arr == nil {
762+ t .Fatal ("AllocAVSampleFormatArray returned nil" )
763+ }
764+ defer AVFree (arr .RawPtr ())
765+
766+ arr .Set (0 , AVSampleFmtS16 )
767+ arr .Set (1 , AVSampleFmtFlt )
768+ arr .Set (2 , AVSampleFmtNone )
769+
770+ if arr .Get (0 ) != AVSampleFmtS16 {
771+ t .Errorf ("Sample format array failed: got %v, want AVSampleFmtS16" , arr .Get (0 ))
772+ }
773+
774+ t .Log ("Sample format array helpers work correctly" )
775+ })
776+ }
777+
778+ // TestGeneratorCStrHandling validates CStr wrapper generation and usage
779+ // This tests the char* pointer handling pattern
780+ func TestGeneratorCStrHandling (t * testing.T ) {
781+ t .Run ("cstr_creation" , func (t * testing.T ) {
782+ str := ToCStr ("Hello, FFmpeg!" )
783+ if str == nil {
784+ t .Fatal ("ToCStr returned nil" )
785+ }
786+ defer str .Free ()
787+
788+ result := str .String ()
789+ if result != "Hello, FFmpeg!" {
790+ t .Errorf ("CStr roundtrip failed: got %q, want %q" , result , "Hello, FFmpeg!" )
791+ }
792+
793+ t .Log ("CStr creation and conversion work correctly" )
794+ })
795+
796+ t .Run ("cstr_as_parameter" , func (t * testing.T ) {
797+ // Test that CStr works as function parameter
798+ codecName := ToCStr ("libx264" )
799+ defer codecName .Free ()
800+
801+ codec := AVCodecFindEncoderByName (codecName )
802+ if codec == nil {
803+ t .Error ("AVCodecFindEncoderByName should find libx264 codec" )
804+ } else {
805+ name := codec .Name ()
806+ t .Logf ("Found codec: %s" , name )
807+ }
808+
809+ t .Log ("CStr parameters work correctly" )
810+ })
811+
812+ t .Run ("nil_cstr_handling" , func (t * testing.T ) {
813+ // Test that nil returns are properly detected with CStr parameters
814+ nonexistent := ToCStr ("nonexistent_codec_xyz_12345" )
815+ defer nonexistent .Free ()
816+
817+ codec := AVCodecFindEncoderByName (nonexistent )
818+ if codec != nil {
819+ t .Error ("Should return nil for nonexistent codec" )
820+ }
821+
822+ t .Log ("Nil CStr handling works correctly" )
823+ })
824+ }
825+
826+ // TestGeneratorNilSafety validates that nil pointer checks work correctly
827+ // This tests the nil-safety code generation pattern
828+ func TestGeneratorNilSafety (t * testing.T ) {
829+ t .Run ("nil_struct_pointer_parameter" , func (t * testing.T ) {
830+ // Test that functions accepting nil struct pointers work
831+ // AVCodecIsEncoder accepts nil and returns (0, nil) error gracefully
832+ result , err := AVCodecIsEncoder (nil )
833+ if err != nil {
834+ t .Errorf ("AVCodecIsEncoder(nil) should not error: %v" , err )
835+ }
836+ if result != 0 {
837+ t .Error ("AVCodecIsEncoder(nil) should return 0" )
838+ }
839+
840+ t .Log ("Nil struct pointer parameters handled correctly" )
841+ })
842+
843+ t .Run ("nil_double_pointer_parameter" , func (t * testing.T ) {
844+ // Test that nil double pointers are handled
845+ var frame * AVFrame = nil
846+ AVFrameFree (& frame ) // Should not crash with nil pointer
847+
848+ t .Log ("Nil double pointer parameters handled correctly" )
849+ })
850+
851+ t .Run ("nil_return_value" , func (t * testing.T ) {
852+ // Test that nil returns are properly detected
853+ codec := AVCodecFindDecoder (AVCodecIdNone )
854+ if codec != nil {
855+ t .Error ("Should return nil for CODEC_ID_NONE" )
856+ }
857+
858+ t .Log ("Nil return values detected correctly" )
859+ })
860+ }
861+
862+ // TestGeneratorMultipleReturnValues validates int+error return pattern
863+ // This tests the error wrapping generation pattern
864+ func TestGeneratorMultipleReturnValues (t * testing.T ) {
865+ t .Run ("success_case" , func (t * testing.T ) {
866+ // Test successful operation returns (0, nil)
867+ var dict * AVDictionary = nil
868+ key := ToCStr ("key" )
869+ value := ToCStr ("value" )
870+ defer key .Free ()
871+ defer value .Free ()
872+
873+ ret , err := AVDictSet (& dict , key , value , 0 )
874+ if err != nil {
875+ t .Errorf ("AVDictSet should succeed: %v" , err )
876+ }
877+ if ret != 0 {
878+ t .Errorf ("AVDictSet should return 0 on success, got %d" , ret )
879+ }
880+ AVDictFree (& dict )
881+
882+ t .Log ("Success case returns (0, nil) correctly" )
883+ })
884+
885+ t .Run ("error_case" , func (t * testing.T ) {
886+ // Test error operation returns (negative, error)
887+ frame := AVFrameAlloc ()
888+ if frame == nil {
889+ t .Fatal ("AVFrameAlloc returned nil" )
890+ }
891+ defer AVFrameFree (& frame )
892+
893+ // Try to get buffer without allocating it first - should fail
894+ ret , err := AVFrameGetBuffer (frame , 0 )
895+ if ret >= 0 {
896+ t .Error ("AVFrameGetBuffer should fail without proper setup" )
897+ }
898+ if err == nil {
899+ t .Error ("Error should not be nil when ret < 0" )
900+ }
901+
902+ t .Logf ("Error case returns (negative=%d, error=%v) correctly" , ret , err )
903+ })
904+ }
905+
906+ // TestGeneratorCallbackTypes validates callback type alias generation
907+ // This tests that callback function pointer typedefs are properly aliased to unsafe.Pointer
908+ func TestGeneratorCallbackTypes (t * testing.T ) {
909+ t .Run ("callback_type_exists" , func (t * testing.T ) {
910+ // Test that callback type aliases are generated
911+ var txFn AVTxFn
912+ var sadFn AVPixelutilsSadFn
913+
914+ // These should compile as type aliases to unsafe.Pointer
915+ _ = txFn
916+ _ = sadFn
917+
918+ t .Log ("Callback type aliases generated correctly" )
919+ })
920+
921+ t .Run ("callback_pointer_parameters" , func (t * testing.T ) {
922+ // Test that functions accepting pointers to callbacks compile
923+ var txFn AVTxFn
924+ // AVTxInit should accept *AVTxFn
925+ _ = & txFn
926+
927+ t .Log ("Callback pointer parameters handled correctly" )
928+ })
929+ }
930+
931+ // TestGeneratorSkipPatterns documents which patterns are intentionally skipped
932+ // This serves as a regression test to ensure skip logic remains consistent
933+ func TestGeneratorSkipPatterns (t * testing.T ) {
934+ t .Run ("documented_skips" , func (t * testing.T ) {
935+ // Document all intentional skip patterns for future reference
936+ skips := map [string ]string {
937+ "variadic_functions" : "Cannot represent ... in Go (e.g., av_log)" ,
938+ "function_pointer_params" : "CGO callback limitations (e.g., av_fifo_write_from_cb)" ,
939+ "FILE_star_types" : "C standard library not exposed (e.g., av_fopen_utf8)" ,
940+ "va_list_types" : "C standard library variadic (e.g., av_log_format_line)" ,
941+ "tm_types" : "C standard library time struct" ,
942+ "bitfield_struct_fields" : "No Go equivalent for bitfields" ,
943+ "union_struct_fields" : "CGO doesn't expose union fields directly" ,
944+ "callback_struct_fields" : "Function pointers in structs are opaque" ,
945+ "pointer_to_pointer_returns" : "Complex array returns need special handling" ,
946+ "callback_by_value_parameters" : "CGO cannot convert function pointer to value" ,
947+ }
948+
949+ for pattern , reason := range skips {
950+ t .Logf ("Skip pattern: %s - %s" , pattern , reason )
951+ }
952+
953+ t .Logf ("Documented %d skip patterns" , len (skips ))
954+ })
955+
956+ t .Run ("skip_patterns_are_logged" , func (t * testing.T ) {
957+ // The generator logs all skips with reasons
958+ // This test just documents that behavior
959+ t .Log ("All skipped items are logged with reasons during generation" )
960+ t .Log ("Check generator output for: 'skipped due to' messages" )
961+ })
962+ }
0 commit comments