terraform/internal/repl/format_test.go
Sarah French b2fc2caf72
Some checks are pending
build / Determine intended Terraform version (push) Waiting to run
build / Determine Go toolchain version (push) Waiting to run
build / Generate release metadata (push) Blocked by required conditions
build / Build for freebsd_386 (push) Blocked by required conditions
build / Build for linux_386 (push) Blocked by required conditions
build / Build for openbsd_386 (push) Blocked by required conditions
build / Build for windows_386 (push) Blocked by required conditions
build / Build for darwin_amd64 (push) Blocked by required conditions
build / Build for freebsd_amd64 (push) Blocked by required conditions
build / Build for linux_amd64 (push) Blocked by required conditions
build / Build for openbsd_amd64 (push) Blocked by required conditions
build / Build for solaris_amd64 (push) Blocked by required conditions
build / Build for windows_amd64 (push) Blocked by required conditions
build / Build for freebsd_arm (push) Blocked by required conditions
build / Build for linux_arm (push) Blocked by required conditions
build / Build for darwin_arm64 (push) Blocked by required conditions
build / Build for linux_arm64 (push) Blocked by required conditions
build / Build for windows_arm64 (push) Blocked by required conditions
build / Build for linux_s390x (push) Blocked by required conditions
build / Build Docker image for linux_386 (push) Blocked by required conditions
build / Build Docker image for linux_amd64 (push) Blocked by required conditions
build / Build Docker image for linux_arm (push) Blocked by required conditions
build / Build Docker image for linux_arm64 (push) Blocked by required conditions
build / Build Docker image for linux_s390x (push) Blocked by required conditions
build / Build e2etest for linux_386 (push) Blocked by required conditions
build / Build e2etest for windows_386 (push) Blocked by required conditions
build / Build e2etest for darwin_amd64 (push) Blocked by required conditions
build / Build e2etest for linux_amd64 (push) Blocked by required conditions
build / Build e2etest for windows_amd64 (push) Blocked by required conditions
build / Build e2etest for linux_arm (push) Blocked by required conditions
build / Build e2etest for darwin_arm64 (push) Blocked by required conditions
build / Build e2etest for linux_arm64 (push) Blocked by required conditions
build / Run e2e test for linux_386 (push) Blocked by required conditions
build / Run e2e test for windows_386 (push) Blocked by required conditions
build / Run e2e test for darwin_amd64 (push) Blocked by required conditions
build / Run e2e test for linux_amd64 (push) Blocked by required conditions
build / Run e2e test for windows_amd64 (push) Blocked by required conditions
build / Run e2e test for linux_arm (push) Blocked by required conditions
build / Run e2e test for linux_arm64 (push) Blocked by required conditions
build / Run terraform-exec test for linux amd64 (push) Blocked by required conditions
Quick Checks / Unit Tests (push) Waiting to run
Quick Checks / Race Tests (push) Waiting to run
Quick Checks / End-to-end Tests (push) Waiting to run
Quick Checks / Code Consistency Checks (push) Waiting to run
Quick Checks / Automated defect checks (push) Waiting to run
fix: Remove deprecation marks when formatting output for the console command. (#38676)
This change introduces handling of deprecation marks to resolve the linked issue, where the `console` command would panic when displaying a deprecated field, either directly, as part of a whole resource, or when referenced within a resource/local/etc.

Deprecation marks aren't used to change how values are rendered, but they need to be removed before we use the cty library to get string representations of values.

I decided to only remove marks in the context of a deprecation mark being present; if a different type of mark is added in future then the engineer implementing it will need to make an explicit decision about how it should be handled in the context of `console`. If that isn't done then the panic from the cty library will re-appear.
2026-06-04 15:56:00 +01:00

198 lines
3.1 KiB
Go

// Copyright IBM Corp. 2014, 2026
// SPDX-License-Identifier: BUSL-1.1
package repl
import (
"fmt"
"testing"
"github.com/hashicorp/terraform/internal/lang/marks"
"github.com/zclconf/go-cty/cty"
)
func TestFormatValue(t *testing.T) {
tests := []struct {
Val cty.Value
Want string
}{
{
cty.NullVal(cty.DynamicPseudoType),
`null`,
},
{
cty.NullVal(cty.String),
`tostring(null)`,
},
{
cty.NullVal(cty.Number),
`tonumber(null)`,
},
{
cty.NullVal(cty.Bool),
`tobool(null)`,
},
{
cty.NullVal(cty.List(cty.String)),
`tolist(null) /* of string */`,
},
{
cty.NullVal(cty.Set(cty.Number)),
`toset(null) /* of number */`,
},
{
cty.NullVal(cty.Map(cty.Bool)),
`tomap(null) /* of bool */`,
},
{
cty.NullVal(cty.Object(map[string]cty.Type{"a": cty.Bool})),
`null /* object */`, // Ideally this would display the full object type, including its attributes
},
{
cty.UnknownVal(cty.DynamicPseudoType),
`(known after apply)`,
},
{
cty.StringVal(""),
`""`,
},
{
cty.StringVal("hello"),
`"hello"`,
},
{
cty.StringVal("hello\nworld"),
`<<EOT
hello
world
EOT`,
},
{
cty.StringVal("EOR\nEOS\nEOT\nEOU"),
`<<EOT_
EOR
EOS
EOT
EOU
EOT_`,
},
{
cty.ObjectVal(map[string]cty.Value{"foo": cty.StringVal("boop\nbeep")}),
`{
"foo" = <<-EOT
boop
beep
EOT
}`,
},
{
cty.Zero,
`0`,
},
{
cty.NumberIntVal(5),
`5`,
},
{
cty.NumberIntVal(1234567890),
`1234567890`,
},
{
cty.NumberFloatVal(5.2),
`5.2`,
},
{
cty.NumberFloatVal(123456789.0),
`123456789`,
},
{
cty.NumberFloatVal(123456789.01),
`123456789.01`,
},
{
cty.False,
`false`,
},
{
cty.True,
`true`,
},
{
cty.EmptyObjectVal,
`{}`,
},
{
cty.ObjectVal(map[string]cty.Value{
"a": cty.StringVal("b"),
}),
`{
"a" = "b"
}`,
},
{
cty.ObjectVal(map[string]cty.Value{
"a": cty.StringVal("b"),
"c": cty.StringVal("d"),
}),
`{
"a" = "b"
"c" = "d"
}`,
},
{
cty.MapValEmpty(cty.String),
`tomap({})`,
},
{
cty.EmptyTupleVal,
`[]`,
},
{
cty.TupleVal([]cty.Value{
cty.StringVal("b"),
}),
`[
"b",
]`,
},
{
cty.TupleVal([]cty.Value{
cty.StringVal("b"),
cty.StringVal("d"),
}),
`[
"b",
"d",
]`,
},
{
cty.ListValEmpty(cty.String),
`tolist([])`,
},
{
cty.SetValEmpty(cty.String),
`toset([])`,
},
{
cty.StringVal("a sensitive value").Mark(marks.Sensitive),
"(sensitive value)",
},
{
cty.StringVal("an ephemeral value").Mark(marks.Ephemeral),
"(ephemeral value)",
},
{
cty.StringVal("I'm a deprecated string value").Mark(marks.Deprecation),
`"I'm a deprecated string value"`, // We don't render deprecated values differently, but we need to ensure the deprecation mark doesn't interfere with formatting
},
}
for _, test := range tests {
t.Run(fmt.Sprintf("%#v", test.Val), func(t *testing.T) {
got := FormatValue(test.Val, 0)
if got != test.Want {
t.Errorf("wrong result\nvalue: %#v\ngot: %s\nwant: %s", test.Val, got, test.Want)
}
})
}
}