zclsyntax: start of testing expression evaluation
This commit is contained in:
parent
3765519c52
commit
085dff2472
@ -9,6 +9,61 @@ import (
|
||||
"github.com/zclconf/go-zcl/zcl"
|
||||
)
|
||||
|
||||
func TestExpressionParseAndValue(t *testing.T) {
|
||||
// This is a combo test that exercises both the parser and the Value
|
||||
// method, with the focus on the latter but indirectly testing the former.
|
||||
tests := []struct {
|
||||
input string
|
||||
ctx *zcl.EvalContext
|
||||
want cty.Value
|
||||
diagCount int
|
||||
}{
|
||||
{
|
||||
`1`,
|
||||
nil,
|
||||
cty.NumberIntVal(1),
|
||||
0,
|
||||
},
|
||||
{
|
||||
`(1)`,
|
||||
nil,
|
||||
cty.NumberIntVal(1),
|
||||
0,
|
||||
},
|
||||
{
|
||||
`(1`,
|
||||
nil,
|
||||
cty.NumberIntVal(1),
|
||||
1, // Unbalanced parentheses
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.input, func(t *testing.T) {
|
||||
expr, parseDiags := ParseExpression([]byte(test.input), "", zcl.Pos{Line: 1, Column: 1, Byte: 0})
|
||||
|
||||
got, valDiags := expr.Value(test.ctx)
|
||||
|
||||
diagCount := len(parseDiags) + len(valDiags)
|
||||
|
||||
if diagCount != test.diagCount {
|
||||
t.Errorf("wrong number of diagnostics %d; want %d", diagCount, test.diagCount)
|
||||
for _, diag := range parseDiags {
|
||||
t.Logf(" - %s", diag.Error())
|
||||
}
|
||||
for _, diag := range valDiags {
|
||||
t.Logf(" - %s", diag.Error())
|
||||
}
|
||||
}
|
||||
|
||||
if !got.RawEquals(test.want) {
|
||||
t.Errorf("wrong result\ngot: %#v\nwant: %#v", got, test.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestFunctionCallExprValue(t *testing.T) {
|
||||
funcs := map[string]function.Function{
|
||||
"length": stdlib.StrlenFunc,
|
||||
|
@ -7,6 +7,7 @@ import (
|
||||
|
||||
"github.com/apparentlymart/go-textseg/textseg"
|
||||
"github.com/zclconf/go-cty/cty"
|
||||
"github.com/zclconf/go-cty/cty/convert"
|
||||
"github.com/zclconf/go-zcl/zcl"
|
||||
)
|
||||
|
||||
@ -418,8 +419,40 @@ func (p *parser) parseExpressionTerm() (Expression, zcl.Diagnostics) {
|
||||
p.setRecovery()
|
||||
}
|
||||
|
||||
p.Read() // eat closing paren
|
||||
|
||||
return expr, diags
|
||||
|
||||
case TokenNumberLit:
|
||||
tok := p.Read() // eat number token
|
||||
|
||||
// We'll lean on the cty converter to do the conversion, to ensure that
|
||||
// the behavior is the same as what would happen if converting a
|
||||
// non-literal string to a number.
|
||||
numStrVal := cty.StringVal(string(tok.Bytes))
|
||||
numVal, err := convert.Convert(numStrVal, cty.Number)
|
||||
if err != nil {
|
||||
ret := &LiteralValueExpr{
|
||||
Val: cty.UnknownVal(cty.Number),
|
||||
SrcRange: tok.Range,
|
||||
}
|
||||
return ret, zcl.Diagnostics{
|
||||
{
|
||||
Severity: zcl.DiagError,
|
||||
Summary: "Invalid number literal",
|
||||
// FIXME: not a very good error message, but convert only
|
||||
// gives us "a number is required", so not much help either.
|
||||
Detail: "Failed to recognize the value of this number literal.",
|
||||
Subject: &ret.SrcRange,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
return &LiteralValueExpr{
|
||||
Val: numVal,
|
||||
SrcRange: tok.Range,
|
||||
}, nil
|
||||
|
||||
default:
|
||||
var diags zcl.Diagnostics
|
||||
if !p.recovery {
|
||||
|
@ -27,8 +27,23 @@ func ParseConfig(src []byte, filename string, start zcl.Pos) (*zcl.File, zcl.Dia
|
||||
|
||||
// ParseExpression parses the given buffer as a standalone zcl expression,
|
||||
// returning it as an instance of Expression.
|
||||
func ParseExpression(src []byte, filename string, start zcl.Pos) (*Expression, zcl.Diagnostics) {
|
||||
panic("ParseExpression is not yet implemented")
|
||||
func ParseExpression(src []byte, filename string, start zcl.Pos) (Expression, zcl.Diagnostics) {
|
||||
tokens := LexExpression(src, filename, start)
|
||||
peeker := newPeeker(tokens, false)
|
||||
parser := &parser{peeker: peeker}
|
||||
expr, diags := parser.ParseExpression()
|
||||
|
||||
next := parser.Peek()
|
||||
if next.Type != TokenEOF {
|
||||
diags = append(diags, &zcl.Diagnostic{
|
||||
Severity: zcl.DiagError,
|
||||
Summary: "Extra characters after expression",
|
||||
Detail: "An expression was successfully parsed, but extra characters were found after it.",
|
||||
Subject: &next.Range,
|
||||
})
|
||||
}
|
||||
|
||||
return expr, diags
|
||||
}
|
||||
|
||||
// ParseTemplate parses the given buffer as a standalone zcl template,
|
||||
|
Loading…
Reference in New Issue
Block a user