json: Eval json null values as cty.Null (#90)
Evaluate json null values as cty.Null, rather than as unknown value. Using DynamicPseudoType as the null type as a placeholder for the null type. Callers may convert the type against schema to get the concrete type.
This commit is contained in:
parent
7e26f2f346
commit
fdf8e232b6
@ -499,6 +499,8 @@ func (e *expression) Value(ctx *hcl.EvalContext) (cty.Value, hcl.Diagnostics) {
|
|||||||
return cty.DynamicVal, diags
|
return cty.DynamicVal, diags
|
||||||
}
|
}
|
||||||
return cty.ObjectVal(attrs), diags
|
return cty.ObjectVal(attrs), diags
|
||||||
|
case *nullVal:
|
||||||
|
return cty.NullVal(cty.DynamicPseudoType), nil
|
||||||
default:
|
default:
|
||||||
// Default to DynamicVal so that ASTs containing invalid nodes can
|
// Default to DynamicVal so that ASTs containing invalid nodes can
|
||||||
// still be partially-evaluated.
|
// still be partially-evaluated.
|
||||||
|
@ -8,6 +8,7 @@ import (
|
|||||||
"github.com/davecgh/go-spew/spew"
|
"github.com/davecgh/go-spew/spew"
|
||||||
"github.com/go-test/deep"
|
"github.com/go-test/deep"
|
||||||
"github.com/hashicorp/hcl2/hcl"
|
"github.com/hashicorp/hcl2/hcl"
|
||||||
|
"github.com/zclconf/go-cty/cty"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestBodyPartialContent(t *testing.T) {
|
func TestBodyPartialContent(t *testing.T) {
|
||||||
@ -1351,3 +1352,62 @@ func TestStaticExpressionList(t *testing.T) {
|
|||||||
t.Fatalf("wrong first expression node")
|
t.Fatalf("wrong first expression node")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestExpression_Value(t *testing.T) {
|
||||||
|
src := `{
|
||||||
|
"string": "string_val",
|
||||||
|
"number": 5,
|
||||||
|
"bool_true": true,
|
||||||
|
"bool_false": false,
|
||||||
|
"array": ["a"],
|
||||||
|
"object": {"key": "value"},
|
||||||
|
"null": null
|
||||||
|
}`
|
||||||
|
expected := map[string]cty.Value{
|
||||||
|
"string": cty.StringVal("string_val"),
|
||||||
|
"number": cty.NumberIntVal(5),
|
||||||
|
"bool_true": cty.BoolVal(true),
|
||||||
|
"bool_false": cty.BoolVal(false),
|
||||||
|
"array": cty.TupleVal([]cty.Value{cty.StringVal("a")}),
|
||||||
|
"object": cty.ObjectVal(map[string]cty.Value{
|
||||||
|
"key": cty.StringVal("value"),
|
||||||
|
}),
|
||||||
|
"null": cty.NullVal(cty.DynamicPseudoType),
|
||||||
|
}
|
||||||
|
|
||||||
|
file, diags := Parse([]byte(src), "")
|
||||||
|
if len(diags) != 0 {
|
||||||
|
t.Errorf("got %d diagnostics on parse; want 0", len(diags))
|
||||||
|
for _, diag := range diags {
|
||||||
|
t.Logf("- %s", diag.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if file == nil {
|
||||||
|
t.Errorf("got nil File; want actual file")
|
||||||
|
}
|
||||||
|
if file.Body == nil {
|
||||||
|
t.Fatalf("got nil Body; want actual body")
|
||||||
|
}
|
||||||
|
attrs, diags := file.Body.JustAttributes()
|
||||||
|
if len(diags) != 0 {
|
||||||
|
t.Errorf("got %d diagnostics on decode; want 0", len(diags))
|
||||||
|
for _, diag := range diags {
|
||||||
|
t.Logf("- %s", diag.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for ek, ev := range expected {
|
||||||
|
val, diags := attrs[ek].Expr.Value(&hcl.EvalContext{})
|
||||||
|
if len(diags) != 0 {
|
||||||
|
t.Errorf("got %d diagnostics on eval; want 0", len(diags))
|
||||||
|
for _, diag := range diags {
|
||||||
|
t.Logf("- %s", diag.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !val.RawEquals(ev) {
|
||||||
|
t.Errorf("wrong result %#v; want %#v", val, ev)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user