Skip to content

Commit 570828e

Browse files
authored
tftypes: Adjust (tftypes.Value).Equal function to support dynamic value comparisons (#383)
* add as dynamic * add safe equal * remove save equal * add changelog * added tests for equal
1 parent 01b86e9 commit 570828e

File tree

3 files changed

+121
-1
lines changed

3 files changed

+121
-1
lines changed
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
kind: BUG FIXES
2+
body: 'tftypes: Fixed an edge-case where `(Value).Equal` would panic when comparing
3+
two values with underlying `DynamicPseudoType` types and different concrete values.'
4+
time: 2024-02-28T17:11:04.381759-05:00
5+
custom:
6+
Issue: "383"

tftypes/value.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,7 @@ func (val Value) Equal(o Value) bool {
223223
}
224224
deepEqual, err := val.deepEqual(o)
225225
if err != nil {
226-
panic(err)
226+
return false
227227
}
228228
return deepEqual
229229
}

tftypes/value_test.go

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -743,6 +743,11 @@ func TestValueEqual(t *testing.T) {
743743
val2: NewValue(String, "world"),
744744
equal: false,
745745
},
746+
"stringDiff-wrong-type": {
747+
val1: NewValue(String, "true"),
748+
val2: NewValue(Bool, true),
749+
equal: false,
750+
},
746751
"boolEqual": {
747752
val1: NewValue(Bool, true),
748753
val2: NewValue(Bool, true),
@@ -753,6 +758,11 @@ func TestValueEqual(t *testing.T) {
753758
val2: NewValue(Bool, true),
754759
equal: false,
755760
},
761+
"boolDiff-wrong-type": {
762+
val1: NewValue(Bool, true),
763+
val2: NewValue(String, "true"),
764+
equal: false,
765+
},
756766
"numberEqual": {
757767
val1: NewValue(Number, big.NewFloat(123)),
758768
val2: NewValue(Number, big.NewFloat(0).SetInt64(123)),
@@ -763,6 +773,11 @@ func TestValueEqual(t *testing.T) {
763773
val2: NewValue(Number, big.NewFloat(2)),
764774
equal: false,
765775
},
776+
"numberDiff-wrong-type": {
777+
val1: NewValue(Number, big.NewFloat(1)),
778+
val2: NewValue(String, "1"),
779+
equal: false,
780+
},
766781
"unknownEqual": {
767782
val1: NewValue(String, UnknownValue),
768783
val2: NewValue(String, UnknownValue),
@@ -811,6 +826,19 @@ func TestValueEqual(t *testing.T) {
811826
}),
812827
equal: false,
813828
},
829+
"listDiff-wrong-type": {
830+
val1: NewValue(List{ElementType: String}, []Value{
831+
NewValue(String, "hello"),
832+
NewValue(String, "world"),
833+
NewValue(String, "abc"),
834+
}),
835+
val2: NewValue(Set{ElementType: String}, []Value{
836+
NewValue(String, "hello"),
837+
NewValue(String, "world"),
838+
NewValue(String, "abc"),
839+
}),
840+
equal: false,
841+
},
814842
"setEqual": {
815843
val1: NewValue(Set{ElementType: String}, []Value{
816844
NewValue(String, "hello"),
@@ -849,6 +877,19 @@ func TestValueEqual(t *testing.T) {
849877
}),
850878
equal: false,
851879
},
880+
"setDiff-wrong-type": {
881+
val1: NewValue(Set{ElementType: String}, []Value{
882+
NewValue(String, "hello"),
883+
NewValue(String, "world"),
884+
NewValue(String, "abc"),
885+
}),
886+
val2: NewValue(List{ElementType: String}, []Value{
887+
NewValue(String, "hello"),
888+
NewValue(String, "world"),
889+
NewValue(String, "abc"),
890+
}),
891+
equal: false,
892+
},
852893
"tupleEqual": {
853894
val1: NewValue(Tuple{ElementTypes: []Type{
854895
String, Bool, Number, List{ElementType: String},
@@ -981,6 +1022,17 @@ func TestValueEqual(t *testing.T) {
9811022
}),
9821023
equal: false,
9831024
},
1025+
"mapDiff-wrong-types": {
1026+
val1: NewValue(Map{ElementType: String}, map[string]Value{
1027+
"one": NewValue(String, "true"),
1028+
"two": NewValue(String, "false"),
1029+
}),
1030+
val2: NewValue(Map{ElementType: Bool}, map[string]Value{
1031+
"one": NewValue(Bool, true),
1032+
"two": NewValue(Bool, false),
1033+
}),
1034+
equal: false,
1035+
},
9841036
"objectEqual": {
9851037
val1: NewValue(Object{AttributeTypes: map[string]Type{
9861038
"one": Number,
@@ -1068,6 +1120,68 @@ func TestValueEqual(t *testing.T) {
10681120
}),
10691121
equal: false,
10701122
},
1123+
"DynamicPseudoType-tupleEqual": {
1124+
val1: NewValue(Tuple{ElementTypes: []Type{
1125+
DynamicPseudoType, DynamicPseudoType,
1126+
}}, []Value{
1127+
NewValue(Bool, true),
1128+
NewValue(List{ElementType: String}, []Value{
1129+
NewValue(String, "a"),
1130+
NewValue(String, "b"),
1131+
NewValue(String, "c"),
1132+
}),
1133+
}),
1134+
val2: NewValue(Tuple{ElementTypes: []Type{
1135+
DynamicPseudoType, DynamicPseudoType,
1136+
}}, []Value{
1137+
NewValue(Bool, true),
1138+
NewValue(List{ElementType: String}, []Value{
1139+
NewValue(String, "a"),
1140+
NewValue(String, "b"),
1141+
NewValue(String, "c"),
1142+
}),
1143+
}),
1144+
equal: true,
1145+
},
1146+
// Previously, different value types with a DynamicPseudoType would cause a panic
1147+
// https://github.com/hashicorp/terraform-plugin-go/pull/383
1148+
"DynamicPseudoType-tupleDiff-different-value-types": {
1149+
val1: NewValue(Tuple{ElementTypes: []Type{DynamicPseudoType}}, []Value{
1150+
NewValue(String, "false"),
1151+
}),
1152+
val2: NewValue(Tuple{ElementTypes: []Type{DynamicPseudoType}}, []Value{
1153+
NewValue(Bool, false), // This value type is different than val1
1154+
}),
1155+
equal: false,
1156+
},
1157+
"DynamicPseudoType-objectEqual": {
1158+
val1: NewValue(Object{AttributeTypes: map[string]Type{
1159+
"dyn_val": DynamicPseudoType,
1160+
}}, map[string]Value{
1161+
"dyn_val": NewValue(String, "hello"),
1162+
}),
1163+
val2: NewValue(Object{AttributeTypes: map[string]Type{
1164+
"dyn_val": DynamicPseudoType,
1165+
}}, map[string]Value{
1166+
"dyn_val": NewValue(String, "hello"),
1167+
}),
1168+
equal: true,
1169+
},
1170+
// Previously, different value types with a DynamicPseudoType would cause a panic
1171+
// https://github.com/hashicorp/terraform-plugin-go/pull/383
1172+
"DynamicPseudoType-objectDiff-different-value-types": {
1173+
val1: NewValue(Object{AttributeTypes: map[string]Type{
1174+
"dyn_val": DynamicPseudoType,
1175+
}}, map[string]Value{
1176+
"dyn_val": NewValue(String, "1"),
1177+
}),
1178+
val2: NewValue(Object{AttributeTypes: map[string]Type{
1179+
"dyn_val": DynamicPseudoType,
1180+
}}, map[string]Value{
1181+
"dyn_val": NewValue(Number, big.NewFloat(1)), // This value type is different than val1
1182+
}),
1183+
equal: false,
1184+
},
10711185
"nullEqual": {
10721186
val1: NewValue(String, nil),
10731187
val2: NewValue(String, nil),

0 commit comments

Comments
 (0)