@@ -5,14 +5,23 @@ package tftypes
55
66import (
77 "encoding/hex"
8+ "errors"
89 "math"
910 "math/big"
11+ "strings"
1012 "testing"
1113
1214 "github.com/google/go-cmp/cmp"
1315 "github.com/hashicorp/terraform-plugin-go/tftypes/refinement"
1416)
1517
18+ // Hex encoding of the long prefix refinements used in this test
19+ var longPrefixRefinement = "c801050c8201c202d9ff7072656669783a2f2f303132333435363738392d303132333435363738392d303132333435363738392d30313" +
20+ "2333435363738392d303132333435363738392d303132333435363738392d303132333435363738392d303132333435363738392d303132333435363738392d30313" +
21+ "2333435363738392d303132333435363738392d303132333435363738392d303132333435363738392d303132333435363738392d303132333435363738392d30313" +
22+ "2333435363738392d303132333435363738392d303132333435363738392d303132333435363738392d303132333435363738392d303132333435363738392d30313" +
23+ "2333435363738392d30313233"
24+
1625func TestValueFromMsgPack (t * testing.T ) {
1726 t .Parallel ()
1827 type testCase struct {
@@ -533,17 +542,91 @@ func TestValueFromMsgPack(t *testing.T) {
533542 }),
534543 typ : List {ElementType : DynamicPseudoType },
535544 },
536- "unknown-string-with-refinements" : {
537- // TODO: How to actually visualize this? So hard to read these tests...
545+ "unknown-dynamic-refinements-ignored" : {
546+ hex : "d40000" ,
547+ value : NewValue (DynamicPseudoType , UnknownValue ).Refine (refinement.Refinements {
548+ refinement .KeyNullness : refinement .NewNullness (false ),
549+ }),
550+ typ : DynamicPseudoType ,
551+ },
552+ "unknown-bool-with-nullness-refinement" : {
553+ hex : "c7030c8101c2" ,
554+ value : NewValue (Bool , UnknownValue ).Refine (refinement.Refinements {
555+ refinement .KeyNullness : refinement .NewNullness (false ),
556+ }),
557+ typ : Bool ,
558+ },
559+ "unknown-number-with-nullness-refinement" : {
560+ hex : "c7030c8101c2" ,
561+ value : NewValue (Number , UnknownValue ).Refine (refinement.Refinements {
562+ refinement .KeyNullness : refinement .NewNullness (false ),
563+ }),
564+ typ : Number ,
565+ },
566+ "unknown-string-with-nullness-refinement" : {
567+ hex : "c7030c8101c2" ,
568+ value : NewValue (String , UnknownValue ).Refine (refinement.Refinements {
569+ refinement .KeyNullness : refinement .NewNullness (false ),
570+ }),
571+ typ : String ,
572+ },
573+ "unknown-list-with-nullness-refinement" : {
574+ hex : "c7030c8101c2" ,
575+ value : NewValue (List {ElementType : String }, UnknownValue ).Refine (refinement.Refinements {
576+ refinement .KeyNullness : refinement .NewNullness (false ),
577+ }),
578+ typ : List {ElementType : String },
579+ },
580+ "unknown-object-with-nullness-refinement" : {
581+ hex : "c7030c8101c2" ,
582+ value : NewValue (Object {AttributeTypes : map [string ]Type {"attr" : String }}, UnknownValue ).Refine (refinement.Refinements {
583+ refinement .KeyNullness : refinement .NewNullness (false ),
584+ }),
585+ typ : Object {AttributeTypes : map [string ]Type {"attr" : String }},
586+ },
587+ "unknown-string-with-empty-prefix-refinement" : {
588+ hex : "c7030c8101c2" ,
589+ value : NewValue (String , UnknownValue ).Refine (refinement.Refinements {
590+ refinement .KeyNullness : refinement .NewNullness (false ),
591+ refinement .KeyStringPrefix : refinement .NewStringPrefix ("" ),
592+ }),
593+ typ : String ,
594+ },
595+ "unknown-string-with-prefix-refinement" : {
538596 hex : "c70e0c8201c202a97072656669783a2f2f" ,
539597 value : NewValue (String , UnknownValue ).Refine (refinement.Refinements {
540598 refinement .KeyNullness : refinement .NewNullness (false ),
541599 refinement .KeyStringPrefix : refinement .NewStringPrefix ("prefix://" ),
542600 }),
543601 typ : String ,
544602 },
545- "unknown-number-with-refinements" : {
546- // TODO: How to actually visualize this? So hard to read these tests...
603+ "unknown-string-with-long-prefix-refinement-one" : {
604+ // This prefix will be cutoff at 256 bytes, so it will be equal to the other long prefix test.
605+ hex : longPrefixRefinement ,
606+ value : NewValue (String , UnknownValue ).Refine (refinement.Refinements {
607+ refinement .KeyNullness : refinement .NewNullness (false ),
608+ refinement .KeyStringPrefix : refinement .NewStringPrefix (
609+ "prefix://0123456789-0123456789-0123456789-0123456789-0123456789-0123456789-0123456789-" +
610+ "0123456789-0123456789-0123456789-0123456789-0123456789-0123456789-0123456789-0123456789-" +
611+ "0123456789-0123456789-0123456789-0123456789-0123456789-0123456789-0123456789-0123456789-thiswillbecutoff1" ,
612+ ),
613+ }),
614+ typ : String ,
615+ },
616+ "unknown-string-with-long-prefix-refinement-two" : {
617+ // This prefix will be cutoff at 256 bytes, so it will be equal to the other long prefix test.
618+ hex : longPrefixRefinement ,
619+ value : NewValue (String , UnknownValue ).Refine (refinement.Refinements {
620+ refinement .KeyNullness : refinement .NewNullness (false ),
621+ refinement .KeyStringPrefix : refinement .NewStringPrefix (
622+ "prefix://0123456789-0123456789-0123456789-0123456789-0123456789-0123456789-0123456789-" +
623+ "0123456789-0123456789-0123456789-0123456789-0123456789-0123456789-0123456789-0123456789-" +
624+ "0123456789-0123456789-0123456789-0123456789-0123456789-0123456789-0123456789-0123456789-0123456789-thiswillbecutoff2" ,
625+ ),
626+ }),
627+ typ : String ,
628+ },
629+ "unknown-number-with-bound-refinements-integers-inclusive" : {
547630 hex : "c70b0c8301c2039201c3049205c3" ,
548631 value : NewValue (Number , UnknownValue ).Refine (refinement.Refinements {
549632 refinement .KeyNullness : refinement .NewNullness (false ),
@@ -552,8 +635,34 @@ func TestValueFromMsgPack(t *testing.T) {
552635 }),
553636 typ : Number ,
554637 },
555- "unknown-list-with-refinements" : {
556- // TODO: How to actually visualize this? So hard to read these tests...
638+ "unknown-number-with-bound-refinements-integers-exclusive" : {
639+ hex : "c70b0c8301c2039201c2049205c2" ,
640+ value : NewValue (Number , UnknownValue ).Refine (refinement.Refinements {
641+ refinement .KeyNullness : refinement .NewNullness (false ),
642+ refinement .KeyNumberLowerBound : refinement .NewNumberLowerBound (big .NewFloat (1 ), false ),
643+ refinement .KeyNumberUpperBound : refinement .NewNumberUpperBound (big .NewFloat (5 ), false ),
644+ }),
645+ typ : Number ,
646+ },
647+ "unknown-number-with-bound-refinements-float-inclusive" : {
648+ hex : "c71b0c8301c20392cb3ff3ae147ae147aec30492cb4016ae147ae147aec3" ,
649+ value : NewValue (Number , UnknownValue ).Refine (refinement.Refinements {
650+ refinement .KeyNullness : refinement .NewNullness (false ),
651+ refinement .KeyNumberLowerBound : refinement .NewNumberLowerBound (big .NewFloat (1.23 ), true ),
652+ refinement .KeyNumberUpperBound : refinement .NewNumberUpperBound (big .NewFloat (5.67 ), true ),
653+ }),
654+ typ : Number ,
655+ },
656+ "unknown-number-with-bound-refinements-float-exclusive" : {
657+ hex : "c71b0c8301c20392cb3ff3ae147ae147aec20492cb4016ae147ae147aec2" ,
658+ value : NewValue (Number , UnknownValue ).Refine (refinement.Refinements {
659+ refinement .KeyNullness : refinement .NewNullness (false ),
660+ refinement .KeyNumberLowerBound : refinement .NewNumberLowerBound (big .NewFloat (1.23 ), false ),
661+ refinement .KeyNumberUpperBound : refinement .NewNumberUpperBound (big .NewFloat (5.67 ), false ),
662+ }),
663+ typ : Number ,
664+ },
665+ "unknown-list-with-bound-refinements" : {
557666 hex : "c7070c8301c205010605" ,
558667 value : NewValue (List {ElementType : String }, UnknownValue ).Refine (refinement.Refinements {
559668 refinement .KeyNullness : refinement .NewNullness (false ),
@@ -562,37 +671,46 @@ func TestValueFromMsgPack(t *testing.T) {
562671 }),
563672 typ : List {ElementType : String },
564673 },
565- "unknown-map-with-refinements" : {
566- // TODO: How to actually visualize this? So hard to read these tests...
567- hex : "c7070c8301c205010605" ,
568- value : NewValue (Map {ElementType : String }, UnknownValue ).Refine (refinement.Refinements {
674+ "unknown-map-with-bound-refinements" : {
675+ hex : "c7070c8301c205000604" ,
676+ value : NewValue (Map {ElementType : Number }, UnknownValue ).Refine (refinement.Refinements {
569677 refinement .KeyNullness : refinement .NewNullness (false ),
570- refinement .KeyCollectionLengthLowerBound : refinement .NewCollectionLengthLowerBound (1 ),
571- refinement .KeyCollectionLengthUpperBound : refinement .NewCollectionLengthUpperBound (5 ),
678+ refinement .KeyCollectionLengthLowerBound : refinement .NewCollectionLengthLowerBound (0 ),
679+ refinement .KeyCollectionLengthUpperBound : refinement .NewCollectionLengthUpperBound (4 ),
572680 }),
573- typ : Map {ElementType : String },
681+ typ : Map {ElementType : Number },
574682 },
575- "unknown-set-with-refinements" : {
576- // TODO: How to actually visualize this? So hard to read these tests...
577- hex : "c7070c8301c205010605" ,
578- value : NewValue (Set {ElementType : String }, UnknownValue ).Refine (refinement.Refinements {
683+ "unknown-set-with-bound-refinements" : {
684+ hex : "c7070c8301c205020606" ,
685+ value : NewValue (Set {ElementType : Bool }, UnknownValue ).Refine (refinement.Refinements {
579686 refinement .KeyNullness : refinement .NewNullness (false ),
580- refinement .KeyCollectionLengthLowerBound : refinement .NewCollectionLengthLowerBound (1 ),
581- refinement .KeyCollectionLengthUpperBound : refinement .NewCollectionLengthUpperBound (5 ),
687+ refinement .KeyCollectionLengthLowerBound : refinement .NewCollectionLengthLowerBound (2 ),
688+ refinement .KeyCollectionLengthUpperBound : refinement .NewCollectionLengthUpperBound (6 ),
582689 }),
583- typ : Set {ElementType : String },
690+ typ : Set {ElementType : Bool },
691+ },
692+ "unknown-with-invalid-refinement-type" : {
693+ hex : "d40000" ,
694+ value : NewValue (Bool , UnknownValue ).Refine (refinement.Refinements {
695+ // This refinement will be ignored since only strings will attempt to encode this
696+ refinement .KeyStringPrefix : refinement .NewStringPrefix ("ignored" ),
697+ }),
698+ typ : Bool ,
699+ },
700+ "unknown-with-invalid-refinement-data" : {
701+ hex : "d40000" ,
702+ value : NewValue (Bool , UnknownValue ).Refine (refinement.Refinements {
703+ // This refinement will be ignored since we don't know how to encode it
704+ refinement .Key (100 ): refinement .NewStringPrefix ("ignored" ),
705+ }),
706+ typ : Bool ,
584707 },
585- // TODO: Test putting refinements with too long of data (string prefix over 256)
586- // TODO: Test putting refinements with incorrect data (string prefix on nullness key)
587- // TODO: Test putting refinements on incorrect types (prefix on number or boolean)
588- // TODO: Test refinement number that doesn't exist? Should just be unknown value
589- // TODO: Test DynamicPseudoType?
590708 }
591709 for name , test := range tests {
592710 name , test := name , test
593711 t .Run (name , func (t * testing.T ) {
594712 t .Parallel ()
595- got , err := test .value .MarshalMsgPack (test .typ ) //nolint:staticcheck
713+ got , err := test .value .MarshalMsgPack (test .typ )
596714 if err != nil {
597715 t .Fatalf ("unexpected error marshaling: %s" , err )
598716 }
@@ -617,3 +735,75 @@ func TestValueFromMsgPack(t *testing.T) {
617735 })
618736 }
619737}
738+
739+ func TestMarshalMsgPack_error (t * testing.T ) {
740+ t .Parallel ()
741+ tests := map [string ]struct {
742+ value Value
743+ typ Type
744+ expectedError error
745+ }{
746+ "unknown-with-invalid-nullness-refinement" : {
747+ value : NewValue (String , UnknownValue ).Refine (refinement.Refinements {
748+ // String prefix is invalid on KeyNullness
749+ refinement .KeyNullness : refinement .NewStringPrefix ("invalid" ),
750+ }),
751+ typ : String ,
752+ expectedError : errors .New ("error encoding Nullness value refinement: unexpected refinement data of type refinement.StringPrefix" ),
753+ },
754+ "unknown-with-invalid-prefix-refinement" : {
755+ value : NewValue (String , UnknownValue ).Refine (refinement.Refinements {
756+ // Nullness is invalid on KeyStringPrefix
757+ refinement .KeyStringPrefix : refinement .NewNullness (false ),
758+ }),
759+ typ : String ,
760+ expectedError : errors .New ("error encoding StringPrefix value refinement: unexpected refinement data of type refinement.Nullness" ),
761+ },
762+ "unknown-with-invalid-number-lowerbound-refinement" : {
763+ value : NewValue (Number , UnknownValue ).Refine (refinement.Refinements {
764+ // NumberUpperBound is invalid on KeyNumberLowerBound
765+ refinement .KeyNumberLowerBound : refinement .NewNumberUpperBound (big .NewFloat (1 ), true ),
766+ }),
767+ typ : Number ,
768+ expectedError : errors .New ("error encoding NumberLowerBound value refinement: unexpected refinement data of type refinement.NumberUpperBound" ),
769+ },
770+ "unknown-with-invalid-number-upperbound-refinement" : {
771+ value : NewValue (Number , UnknownValue ).Refine (refinement.Refinements {
772+ // NumberLowerBound is invalid on KeyNumberUpperBound
773+ refinement .KeyNumberUpperBound : refinement .NewNumberLowerBound (big .NewFloat (1 ), true ),
774+ }),
775+ typ : Number ,
776+ expectedError : errors .New ("error encoding NumberUpperBound value refinement: unexpected refinement data of type refinement.NumberLowerBound" ),
777+ },
778+ "unknown-with-invalid-collection-lowerbound-refinement" : {
779+ value : NewValue (List {ElementType : String }, UnknownValue ).Refine (refinement.Refinements {
780+ // CollectionLengthUpperBound is invalid on KeyCollectionLengthLowerBound
781+ refinement .KeyCollectionLengthLowerBound : refinement .NewCollectionLengthUpperBound (1 ),
782+ }),
783+ typ : List {ElementType : String },
784+ expectedError : errors .New ("error encoding CollectionLengthLowerBound value refinement: unexpected refinement data of type refinement.CollectionLengthUpperBound" ),
785+ },
786+ "unknown-with-invalid-collection-upperbound-refinement" : {
787+ value : NewValue (Map {ElementType : String }, UnknownValue ).Refine (refinement.Refinements {
788+ // CollectionLengthLowerBound is invalid on KeyCollectionLengthUpperBound
789+ refinement .KeyCollectionLengthUpperBound : refinement .NewCollectionLengthLowerBound (1 ),
790+ }),
791+ typ : Map {ElementType : String },
792+ expectedError : errors .New ("error encoding CollectionLengthUpperBound value refinement: unexpected refinement data of type refinement.CollectionLengthLowerBound" ),
793+ },
794+ }
795+ for name , test := range tests {
796+ name , test := name , test
797+ t .Run (name , func (t * testing.T ) {
798+ t .Parallel ()
799+ _ , err := test .value .MarshalMsgPack (test .typ )
800+ if err == nil {
801+ t .Fatalf ("got no error, wanted err: %s" , test .expectedError )
802+ }
803+
804+ if ! strings .Contains (err .Error (), test .expectedError .Error ()) {
805+ t .Fatalf ("wanted error %q, got error: %s" , test .expectedError .Error (), err .Error ())
806+ }
807+ })
808+ }
809+ }
0 commit comments