@@ -22,7 +22,7 @@ func testValue(t *testing.T, input interface{}, want url.Values) {
2222 t .Errorf ("Values(%q) returned error: %v" , input , err )
2323 }
2424 if diff := cmp .Diff (want , v ); diff != "" {
25- t .Errorf ("Values(%q ) mismatch:\n %s" , input , diff )
25+ t .Errorf ("Values(%#v ) mismatch:\n %s" , input , diff )
2626 }
2727}
2828
@@ -413,7 +413,7 @@ func (m customEncodedStrings) EncodeValues(key string, v *url.Values) error {
413413 return nil
414414}
415415
416- func TestValues_CustomEncoding (t * testing.T ) {
416+ func TestValues_CustomEncodingSlice (t * testing.T ) {
417417 tests := []struct {
418418 input interface {}
419419 want url.Values
@@ -478,6 +478,155 @@ func TestValues_CustomEncoding_Error(t *testing.T) {
478478 }
479479}
480480
481+ // customEncodedInt is an int with a custom URL encoding
482+ type customEncodedInt int
483+
484+ // EncodeValues encodes values with leading underscores
485+ func (m customEncodedInt ) EncodeValues (key string , v * url.Values ) error {
486+ v .Set (key , fmt .Sprintf ("_%d" , m ))
487+ return nil
488+ }
489+
490+ func TestValues_CustomEncodingInt (t * testing.T ) {
491+ var zero customEncodedInt = 0
492+ var one customEncodedInt = 1
493+ tests := []struct {
494+ input interface {}
495+ want url.Values
496+ }{
497+ {
498+ struct {
499+ V customEncodedInt `url:"v"`
500+ }{},
501+ url.Values {"v" : {"_0" }},
502+ },
503+ {
504+ struct {
505+ V customEncodedInt `url:"v,omitempty"`
506+ }{zero },
507+ url.Values {},
508+ },
509+ {
510+ struct {
511+ V customEncodedInt `url:"v"`
512+ }{one },
513+ url.Values {"v" : {"_1" }},
514+ },
515+
516+ // pointers to custom encoded types
517+ {
518+ struct {
519+ V * customEncodedInt `url:"v"`
520+ }{},
521+ url.Values {"v" : {"_0" }},
522+ },
523+ {
524+ struct {
525+ V * customEncodedInt `url:"v,omitempty"`
526+ }{},
527+ url.Values {},
528+ },
529+ {
530+ struct {
531+ V * customEncodedInt `url:"v,omitempty"`
532+ }{& zero },
533+ url.Values {"v" : {"_0" }},
534+ },
535+ {
536+ struct {
537+ V * customEncodedInt `url:"v"`
538+ }{& one },
539+ url.Values {"v" : {"_1" }},
540+ },
541+ }
542+
543+ for _ , tt := range tests {
544+ testValue (t , tt .input , tt .want )
545+ }
546+ }
547+
548+ // customEncodedInt is an int with a custom URL encoding defined on its pointer
549+ // value.
550+ type customEncodedIntPtr int
551+
552+ // EncodeValues encodes a 0 as false, 1 as true, and nil as unknown. All other
553+ // values cause an error.
554+ func (m * customEncodedIntPtr ) EncodeValues (key string , v * url.Values ) error {
555+ if m == nil {
556+ return nil
557+ }
558+ v .Set (key , fmt .Sprintf ("_%d" , * m ))
559+ return nil
560+ }
561+
562+ // Test behavior when encoding is defined for a pointer of a custom type.
563+ // Custom type should be able to encode values for nil pointers.
564+ func TestValues_CustomEncodingPointer (t * testing.T ) {
565+ var zero customEncodedIntPtr = 0
566+ var one customEncodedIntPtr = 1
567+ tests := []struct {
568+ input interface {}
569+ want url.Values
570+ }{
571+ // non-pointer values do not get the custom encoding because
572+ // they don't implement the encoder interface.
573+ {
574+ struct {
575+ V customEncodedIntPtr `url:"v"`
576+ }{},
577+ url.Values {"v" : {"0" }},
578+ },
579+ {
580+ struct {
581+ V customEncodedIntPtr `url:"v,omitempty"`
582+ }{},
583+ url.Values {},
584+ },
585+ {
586+ struct {
587+ V customEncodedIntPtr `url:"v"`
588+ }{one },
589+ url.Values {"v" : {"1" }},
590+ },
591+
592+ // pointers to custom encoded types. (Values below are not necessarily desirable)
593+ {
594+ struct {
595+ V * customEncodedIntPtr `url:"v"`
596+ }{},
597+ url.Values {"v" : {"_0" }},
598+ },
599+ {
600+ struct {
601+ V * customEncodedIntPtr `url:"v,omitempty"`
602+ }{},
603+ url.Values {},
604+ },
605+ {
606+ struct {
607+ V * customEncodedIntPtr `url:"v"`
608+ }{& zero },
609+ url.Values {"v" : {"0" }},
610+ },
611+ {
612+ struct {
613+ V * customEncodedIntPtr `url:"v,omitempty"`
614+ }{& zero },
615+ url.Values {"v" : {"0" }},
616+ },
617+ {
618+ struct {
619+ V * customEncodedIntPtr `url:"v"`
620+ }{& one },
621+ url.Values {"v" : {"1" }},
622+ },
623+ }
624+
625+ for _ , tt := range tests {
626+ testValue (t , tt .input , tt .want )
627+ }
628+ }
629+
481630func TestIsEmptyValue (t * testing.T ) {
482631 str := "string"
483632 tests := []struct {
0 commit comments