@@ -3303,6 +3303,163 @@ func TestDecoder_MultiTagRemain(t *testing.T) {
33033303 }
33043304}
33053305
3306+ func TestDecoder_MultiTagBasic (t * testing.T ) {
3307+ type Person struct {
3308+ Name string `yaml:"name"`
3309+ Age int `json:"age"`
3310+ Email string `config:"email_address"`
3311+ }
3312+
3313+ input := map [string ]any {
3314+ "name" : "Alice" ,
3315+ "age" : 30 ,
3316+ "email_address" : "alice@example.com" ,
3317+ }
3318+ var result Person
3319+
3320+ dec , err := NewDecoder (& DecoderConfig {
3321+ TagName : "yaml,json,config" ,
3322+ Result : & result ,
3323+ })
3324+ if err != nil {
3325+ t .Fatalf ("NewDecoder error: %v" , err )
3326+ }
3327+
3328+ if err := dec .Decode (input ); err != nil {
3329+ t .Fatalf ("Decode error: %v" , err )
3330+ }
3331+
3332+ if result .Name != "Alice" {
3333+ t .Fatalf ("expected Name=Alice, got %q" , result .Name )
3334+ }
3335+ if result .Age != 30 {
3336+ t .Fatalf ("expected Age=30, got %d" , result .Age )
3337+ }
3338+ if result .Email != "alice@example.com" {
3339+ t .Fatalf ("expected Email=alice@example.com, got %q" , result .Email )
3340+ }
3341+ }
3342+
3343+ func TestDecoder_MultiTagPriority (t * testing.T ) {
3344+ // When both tags exist, the first tag name in the list takes precedence
3345+ type Item struct {
3346+ Value string `yaml:"yaml_value" json:"json_value"`
3347+ }
3348+
3349+ input := map [string ]any {
3350+ "yaml_value" : "from_yaml" ,
3351+ "json_value" : "from_json" ,
3352+ }
3353+
3354+ // Test yaml,json order - should use yaml tag
3355+ var result1 Item
3356+ dec1 , err := NewDecoder (& DecoderConfig {
3357+ TagName : "yaml,json" ,
3358+ Result : & result1 ,
3359+ })
3360+ if err != nil {
3361+ t .Fatalf ("NewDecoder error: %v" , err )
3362+ }
3363+ if err := dec1 .Decode (input ); err != nil {
3364+ t .Fatalf ("Decode error: %v" , err )
3365+ }
3366+ if result1 .Value != "from_yaml" {
3367+ t .Fatalf ("with yaml,json expected Value=from_yaml, got %q" , result1 .Value )
3368+ }
3369+
3370+ // Test json,yaml order - should use json tag
3371+ var result2 Item
3372+ dec2 , err := NewDecoder (& DecoderConfig {
3373+ TagName : "json,yaml" ,
3374+ Result : & result2 ,
3375+ })
3376+ if err != nil {
3377+ t .Fatalf ("NewDecoder error: %v" , err )
3378+ }
3379+ if err := dec2 .Decode (input ); err != nil {
3380+ t .Fatalf ("Decode error: %v" , err )
3381+ }
3382+ if result2 .Value != "from_json" {
3383+ t .Fatalf ("with json,yaml expected Value=from_json, got %q" , result2 .Value )
3384+ }
3385+ }
3386+
3387+ func TestDecoder_MultiTagWhitespace (t * testing.T ) {
3388+ type Person struct {
3389+ Name string `yaml:"name"`
3390+ Age int `json:"age"`
3391+ }
3392+
3393+ input := map [string ]any {
3394+ "name" : "Bob" ,
3395+ "age" : 25 ,
3396+ }
3397+ var result Person
3398+
3399+ // Test with whitespace around tag names
3400+ dec , err := NewDecoder (& DecoderConfig {
3401+ TagName : " yaml , json " ,
3402+ Result : & result ,
3403+ })
3404+ if err != nil {
3405+ t .Fatalf ("NewDecoder error: %v" , err )
3406+ }
3407+
3408+ if err := dec .Decode (input ); err != nil {
3409+ t .Fatalf ("Decode error: %v" , err )
3410+ }
3411+
3412+ if result .Name != "Bob" {
3413+ t .Fatalf ("expected Name=Bob, got %q" , result .Name )
3414+ }
3415+ if result .Age != 25 {
3416+ t .Fatalf ("expected Age=25, got %d" , result .Age )
3417+ }
3418+ }
3419+
3420+ func TestDecoder_MultiTagEmptyNames (t * testing.T ) {
3421+ type Person struct {
3422+ Name string `mapstructure:"name"`
3423+ }
3424+
3425+ input := map [string ]any {
3426+ "name" : "Charlie" ,
3427+ }
3428+
3429+ tests := []struct {
3430+ name string
3431+ tagName string
3432+ }{
3433+ {"leading comma" , ",yaml" },
3434+ {"trailing comma" , "yaml," },
3435+ {"multiple commas" , ",,yaml,," },
3436+ {"only commas" , ",,," },
3437+ {"empty with spaces" , " , , " },
3438+ }
3439+
3440+ for _ , tc := range tests {
3441+ t .Run (tc .name , func (t * testing.T ) {
3442+ var result Person
3443+ dec , err := NewDecoder (& DecoderConfig {
3444+ TagName : tc .tagName ,
3445+ Result : & result ,
3446+ })
3447+ if err != nil {
3448+ t .Fatalf ("NewDecoder error: %v" , err )
3449+ }
3450+
3451+ if err := dec .Decode (input ); err != nil {
3452+ t .Fatalf ("Decode error: %v" , err )
3453+ }
3454+
3455+ // With invalid/empty tag names, should fall back to mapstructure
3456+ if result .Name != "Charlie" {
3457+ t .Fatalf ("expected Name=Charlie (fallback to mapstructure), got %q" , result .Name )
3458+ }
3459+ })
3460+ }
3461+ }
3462+
33063463func TestDecoder_DecodeNilOption (t * testing.T ) {
33073464 t .Parallel ()
33083465
0 commit comments