diff --git a/site/src/types/preview.ts b/site/src/types/preview.ts index f423a4e..945c7e1 100644 --- a/site/src/types/preview.ts +++ b/site/src/types/preview.ts @@ -89,6 +89,9 @@ export interface SessionInputs { readonly User: WorkspaceOwner; } +// From types/value.go +export const UnknownStringValue = "??"; + // From types/parameter.go export const ValidationMonotonicDecreasing = "decreasing"; diff --git a/types/value.go b/types/value.go index ab8b2a4..4cc269b 100644 --- a/types/value.go +++ b/types/value.go @@ -9,6 +9,10 @@ import ( "github.com/zclconf/go-cty/cty" ) +const ( + UnknownStringValue = "??" +) + type NullHCLString struct { Value string `json:"value"` Valid bool `json:"valid"` @@ -94,7 +98,7 @@ func (s HCLString) AsString() string { return *s.Source } - return "??" + return UnknownStringValue } func (s HCLString) IsKnown() bool { diff --git a/types/value_test.go b/types/value_test.go new file mode 100644 index 0000000..099b0bd --- /dev/null +++ b/types/value_test.go @@ -0,0 +1,93 @@ +package types_test + +import ( + "encoding/json" + "testing" + + "github.com/stretchr/testify/require" + "github.com/zclconf/go-cty/cty" + + "github.com/coder/preview/types" +) + +func TestSafeHCLString(t *testing.T) { + t.Parallel() + + cases := []struct { + name string + input types.HCLString + + asString string + known bool + valid bool + }{ + { + name: "empty", + asString: types.UnknownStringValue, + }, + { + name: "string_literal", + input: types.StringLiteral("hello world"), + asString: "hello world", + known: true, + valid: true, + }, + { + name: "number", + input: types.HCLString{ + Value: cty.NumberIntVal(1), + }, + asString: "1", + known: true, + valid: true, + }, + { + name: "bool", + input: types.HCLString{ + Value: cty.BoolVal(true), + }, + asString: "true", + known: true, + valid: true, + }, + // Crazy ideas + { + name: "null", + input: types.HCLString{ + Value: cty.NullVal(cty.NilType), + }, + asString: types.UnknownStringValue, + known: false, + valid: false, + }, + { + name: "empty_string_list", + input: types.HCLString{ + Value: cty.ListValEmpty(cty.String), + }, + asString: types.UnknownStringValue, + known: false, + valid: false, + }, + { + name: "dynamic", + input: types.HCLString{ + Value: cty.DynamicVal, + }, + asString: types.UnknownStringValue, + known: false, + valid: false, + }, + } + + for _, tc := range cases { + t.Run(tc.name, func(t *testing.T) { + require.Equal(t, tc.asString, tc.input.AsString()) + require.Equal(t, tc.known, tc.input.IsKnown(), "known") + require.Equal(t, tc.valid, tc.input.Valid(), "valid") + + _, err := json.Marshal(tc.input) + require.NoError(t, err) + }) + } +}