@ -719,9 +719,10 @@ func TestNormalizeFlatmapContainers(t *testing.T) {
}
}
func Test CopyMissing Values( t * testing . T ) {
func Test NormalizeNull Values( t * testing . T ) {
for i , tc := range [ ] struct {
Src , Dst , Expect cty . Value
Plan bool
} {
{
// The known set value is copied over the null set value
@ -745,6 +746,28 @@ func TestCopyMissingValues(t *testing.T) {
} ) ,
} ) ,
} ,
{
// The known set value is copied over the null set value
Src : cty . ObjectVal ( map [ string ] cty . Value {
"set" : cty . SetVal ( [ ] cty . Value {
cty . ObjectVal ( map [ string ] cty . Value {
"foo" : cty . NullVal ( cty . String ) ,
} ) ,
} ) ,
} ) ,
Dst : cty . ObjectVal ( map [ string ] cty . Value {
"set" : cty . NullVal ( cty . Set ( cty . Object ( map [ string ] cty . Type {
"foo" : cty . String ,
} ) ) ) ,
} ) ,
// If we're only in a plan, we can't compare sets at all
Expect : cty . ObjectVal ( map [ string ] cty . Value {
"set" : cty . NullVal ( cty . Set ( cty . Object ( map [ string ] cty . Type {
"foo" : cty . String ,
} ) ) ) ,
} ) ,
Plan : true ,
} ,
{
// The empty map is copied over the null map
Src : cty . ObjectVal ( map [ string ] cty . Value {
@ -758,7 +781,7 @@ func TestCopyMissingValues(t *testing.T) {
} ) ,
} ,
{
// A zer p value primitive is copied over a null primitive
// A zer o value primitive is copied over a null primitive
Src : cty . ObjectVal ( map [ string ] cty . Value {
"string" : cty . StringVal ( "" ) ,
} ) ,
@ -769,6 +792,19 @@ func TestCopyMissingValues(t *testing.T) {
"string" : cty . StringVal ( "" ) ,
} ) ,
} ,
{
// Plan primitives are kept
Src : cty . ObjectVal ( map [ string ] cty . Value {
"string" : cty . StringVal ( "" ) ,
} ) ,
Dst : cty . ObjectVal ( map [ string ] cty . Value {
"string" : cty . NullVal ( cty . String ) ,
} ) ,
Expect : cty . ObjectVal ( map [ string ] cty . Value {
"string" : cty . NullVal ( cty . String ) ,
} ) ,
Plan : true ,
} ,
{
// The null map is retained, because the src was unknown
Src : cty . ObjectVal ( map [ string ] cty . Value {
@ -821,9 +857,128 @@ func TestCopyMissingValues(t *testing.T) {
} ) ,
} ) ,
} ,
{
// Retain don't re-add unexpected planned values in a map
Src : cty . ObjectVal ( map [ string ] cty . Value {
"map" : cty . MapVal ( map [ string ] cty . Value {
"a" : cty . StringVal ( "a" ) ,
"b" : cty . StringVal ( "" ) ,
} ) ,
} ) ,
Dst : cty . ObjectVal ( map [ string ] cty . Value {
"map" : cty . MapVal ( map [ string ] cty . Value {
"a" : cty . StringVal ( "a" ) ,
} ) ,
} ) ,
Expect : cty . ObjectVal ( map [ string ] cty . Value {
"map" : cty . MapVal ( map [ string ] cty . Value {
"a" : cty . StringVal ( "a" ) ,
} ) ,
} ) ,
Plan : true ,
} ,
// a list in an object in a list, going from null to empty
{
Src : cty . ObjectVal ( map [ string ] cty . Value {
"network_interface" : cty . ListVal ( [ ] cty . Value {
cty . ObjectVal ( map [ string ] cty . Value {
"network_ip" : cty . UnknownVal ( cty . String ) ,
"access_config" : cty . NullVal ( cty . List ( cty . Object ( map [ string ] cty . Type { "public_ptr_domain_name" : cty . String , "nat_ip" : cty . String } ) ) ) ,
"address" : cty . NullVal ( cty . String ) ,
"name" : cty . StringVal ( "nic0" ) ,
} ) } ) ,
} ) ,
Dst : cty . ObjectVal ( map [ string ] cty . Value {
"network_interface" : cty . ListVal ( [ ] cty . Value {
cty . ObjectVal ( map [ string ] cty . Value {
"network_ip" : cty . StringVal ( "10.128.0.64" ) ,
"access_config" : cty . ListValEmpty ( cty . Object ( map [ string ] cty . Type { "public_ptr_domain_name" : cty . String , "nat_ip" : cty . String } ) ) ,
"address" : cty . StringVal ( "address" ) ,
"name" : cty . StringVal ( "nic0" ) ,
} ) ,
} ) ,
} ) ,
Expect : cty . ObjectVal ( map [ string ] cty . Value {
"network_interface" : cty . ListVal ( [ ] cty . Value {
cty . ObjectVal ( map [ string ] cty . Value {
"network_ip" : cty . StringVal ( "10.128.0.64" ) ,
"access_config" : cty . NullVal ( cty . List ( cty . Object ( map [ string ] cty . Type { "public_ptr_domain_name" : cty . String , "nat_ip" : cty . String } ) ) ) ,
"address" : cty . StringVal ( "address" ) ,
"name" : cty . StringVal ( "nic0" ) ,
} ) ,
} ) ,
} ) ,
} ,
// a list in an object in a list, going from empty to null
{
Src : cty . ObjectVal ( map [ string ] cty . Value {
"network_interface" : cty . ListVal ( [ ] cty . Value {
cty . ObjectVal ( map [ string ] cty . Value {
"network_ip" : cty . UnknownVal ( cty . String ) ,
"access_config" : cty . ListValEmpty ( cty . Object ( map [ string ] cty . Type { "public_ptr_domain_name" : cty . String , "nat_ip" : cty . String } ) ) ,
"address" : cty . NullVal ( cty . String ) ,
"name" : cty . StringVal ( "nic0" ) ,
} ) } ) ,
} ) ,
Dst : cty . ObjectVal ( map [ string ] cty . Value {
"network_interface" : cty . ListVal ( [ ] cty . Value {
cty . ObjectVal ( map [ string ] cty . Value {
"network_ip" : cty . StringVal ( "10.128.0.64" ) ,
"access_config" : cty . NullVal ( cty . List ( cty . Object ( map [ string ] cty . Type { "public_ptr_domain_name" : cty . String , "nat_ip" : cty . String } ) ) ) ,
"address" : cty . StringVal ( "address" ) ,
"name" : cty . StringVal ( "nic0" ) ,
} ) ,
} ) ,
} ) ,
Expect : cty . ObjectVal ( map [ string ] cty . Value {
"network_interface" : cty . ListVal ( [ ] cty . Value {
cty . ObjectVal ( map [ string ] cty . Value {
"network_ip" : cty . StringVal ( "10.128.0.64" ) ,
"access_config" : cty . ListValEmpty ( cty . Object ( map [ string ] cty . Type { "public_ptr_domain_name" : cty . String , "nat_ip" : cty . String } ) ) ,
"address" : cty . StringVal ( "address" ) ,
"name" : cty . StringVal ( "nic0" ) ,
} ) ,
} ) ,
} ) ,
} ,
// the empty list should be transferred, but the new unknown show not be overridden
{
Src : cty . ObjectVal ( map [ string ] cty . Value {
"network_interface" : cty . ListVal ( [ ] cty . Value {
cty . ObjectVal ( map [ string ] cty . Value {
"network_ip" : cty . StringVal ( "10.128.0.64" ) ,
"access_config" : cty . ListValEmpty ( cty . Object ( map [ string ] cty . Type { "public_ptr_domain_name" : cty . String , "nat_ip" : cty . String } ) ) ,
"address" : cty . NullVal ( cty . String ) ,
"name" : cty . StringVal ( "nic0" ) ,
} ) } ) ,
} ) ,
Dst : cty . ObjectVal ( map [ string ] cty . Value {
"network_interface" : cty . ListVal ( [ ] cty . Value {
cty . ObjectVal ( map [ string ] cty . Value {
"network_ip" : cty . UnknownVal ( cty . String ) ,
"access_config" : cty . NullVal ( cty . List ( cty . Object ( map [ string ] cty . Type { "public_ptr_domain_name" : cty . String , "nat_ip" : cty . String } ) ) ) ,
"address" : cty . StringVal ( "address" ) ,
"name" : cty . StringVal ( "nic0" ) ,
} ) ,
} ) ,
} ) ,
Expect : cty . ObjectVal ( map [ string ] cty . Value {
"network_interface" : cty . ListVal ( [ ] cty . Value {
cty . ObjectVal ( map [ string ] cty . Value {
"network_ip" : cty . UnknownVal ( cty . String ) ,
"access_config" : cty . ListValEmpty ( cty . Object ( map [ string ] cty . Type { "public_ptr_domain_name" : cty . String , "nat_ip" : cty . String } ) ) ,
"address" : cty . StringVal ( "address" ) ,
"name" : cty . StringVal ( "nic0" ) ,
} ) ,
} ) ,
} ) ,
Plan : true ,
} ,
} {
t . Run ( fmt . Sprintf ( "%d" , i ) , func ( t * testing . T ) {
got := copyMissingValues ( tc . Dst , tc . Src )
got := normalizeNull Values( tc . Dst , tc . Src , tc . Plan )
if ! got . RawEquals ( tc . Expect ) {
t . Fatalf ( "\nexpected: %#v\ngot: %#v\n" , tc . Expect , got )
}