From bc2aac07dd7a31bb29d5d17d56499c74f542850d Mon Sep 17 00:00:00 2001 From: Taichi Sasaki Date: Sat, 13 Jul 2024 05:38:31 +0900 Subject: [PATCH] Add eval.TooFewArgError() (#3557) * Add eval.TooFewArgError() * Fix a condition in dsl.ErrorName * Fix a test case in expr.TestExample * Remove an unnecessary block --------- Co-authored-by: Raphael Simon --- dsl/attribute.go | 42 ++++++++++++++++++++---------------------- dsl/error.go | 6 +++--- dsl/http.go | 2 +- dsl/response.go | 4 ++-- eval/eval.go | 6 ++++++ eval/eval_test.go | 18 ++++++++++++++++++ expr/example_test.go | 2 +- 7 files changed, 51 insertions(+), 29 deletions(-) diff --git a/dsl/attribute.go b/dsl/attribute.go index f34e6624fe..d6a7d3faf3 100644 --- a/dsl/attribute.go +++ b/dsl/attribute.go @@ -112,29 +112,27 @@ import ( // }) func Attribute(name string, args ...any) { var parent *expr.AttributeExpr - { - switch def := eval.Current().(type) { - case *expr.AttributeExpr: - parent = def - case expr.CompositeExpr: - parent = def.Attribute() - default: - eval.IncompatibleDSL() - return - } - if parent == nil { - eval.ReportError("invalid syntax, attribute %#v has no parent", name) + switch def := eval.Current().(type) { + case *expr.AttributeExpr: + parent = def + case expr.CompositeExpr: + parent = def.Attribute() + default: + eval.IncompatibleDSL() + return + } + if parent == nil { + eval.ReportError("invalid syntax, attribute %#v has no parent", name) + return + } + if parent.Type == nil { + parent.Type = &expr.Object{} + } + if _, ok := parent.Type.(*expr.Object); !ok { + if _, ok := parent.Type.(*expr.Union); !ok { + eval.ReportError("can't define child attribute %#v on attribute of type %s %T", name, parent.Type.Name(), parent.Type) return } - if parent.Type == nil { - parent.Type = &expr.Object{} - } - if _, ok := parent.Type.(*expr.Object); !ok { - if _, ok := parent.Type.(*expr.Union); !ok { - eval.ReportError("can't define child attribute %#v on attribute of type %s %T", name, parent.Type.Name(), parent.Type) - return - } - } } var attr *expr.AttributeExpr @@ -298,7 +296,7 @@ func Default(def any) { // }) func Example(args ...any) { if len(args) == 0 { - eval.ReportError("not enough arguments") + eval.TooFewArgError() return } if len(args) > 2 { diff --git a/dsl/error.go b/dsl/error.go index a7816b2d51..9093f36b16 100644 --- a/dsl/error.go +++ b/dsl/error.go @@ -173,7 +173,7 @@ func Error(name string, args ...any) { // } func ErrorName(args ...any) { if len(args) == 0 { - eval.IncompatibleDSL() + eval.TooFewArgError() return } dsl, ok := args[len(args)-1].(func()) @@ -191,8 +191,8 @@ func ErrorName(args ...any) { case string: Attribute(actual, args[1:]...) case int: - if len(args) == 1 { - eval.IncompatibleDSL() + if len(args) == 2 { + eval.TooFewArgError() return } name, ok := args[1].(string) diff --git a/dsl/http.go b/dsl/http.go index b653bb9f94..5a2ef937ff 100644 --- a/dsl/http.go +++ b/dsl/http.go @@ -895,7 +895,7 @@ func SkipResponseBodyEncodeDecode() { // }) func Body(args ...any) { if len(args) == 0 { - eval.ReportError("not enough arguments, use Body(name), Body(type), Body(func()) or Body(type, func())") + eval.TooFewArgError() return } diff --git a/dsl/response.go b/dsl/response.go index 615270558d..438ac7c490 100644 --- a/dsl/response.go +++ b/dsl/response.go @@ -202,7 +202,7 @@ func Code(code int) { func grpcError(n string, p eval.Expression, args ...any) *expr.GRPCErrorExpr { if len(args) == 0 { - eval.ReportError("not enough arguments, use Response(name, status), Response(name, status, func()) or Response(name, func())") + eval.TooFewArgError() return nil } var ( @@ -260,7 +260,7 @@ func parseResponseArgs(val any, args ...any) (code int, fn func()) { func httpError(n string, p eval.Expression, args ...any) *expr.HTTPErrorExpr { if len(args) == 0 { - eval.ReportError("not enough arguments, use Response(name, status), Response(name, status, func()) or Response(name, func())") + eval.TooFewArgError() return nil } var ( diff --git a/eval/eval.go b/eval/eval.go index 81e6e03af4..5a41acfb69 100644 --- a/eval/eval.go +++ b/eval/eval.go @@ -126,6 +126,12 @@ func InvalidArgError(expected string, actual any) { ReportError("cannot use %#v (type %s) as type %s", actual, reflect.TypeOf(actual), expected) } +// TooFewArgError records a too few arguments error. It is used by DSL +// functions that take dynamic arguments. +func TooFewArgError() { + ReportError("too few arguments given to %s", caller()) +} + // TooManyArgError records a too many arguments error. It is used by DSL // functions that take dynamic arguments. func TooManyArgError() { diff --git a/eval/eval_test.go b/eval/eval_test.go index 4afb4d07aa..2660f1312c 100644 --- a/eval/eval_test.go +++ b/eval/eval_test.go @@ -35,6 +35,24 @@ func TestInvalidArgError(t *testing.T) { } } +func TestTooFewArgError(t *testing.T) { + dsls := map[string]func(){ + "Body": func() { Body() }, + "ErrorName": func() { ErrorName() }, + "ErrorName (int)": func() { Type("name", func() { ErrorName(1) }) }, + "Example": func() { Example() }, + "Response (grpc)": func() { Service("s", func() { GRPC(func() { Response("name") }) }) }, + "Response (http)": func() { Service("s", func() { HTTP(func() { Response("name") }) }) }, + } + for name, dsl := range dsls { + t.Run(name, func(t *testing.T) { + err := expr.RunInvalidDSL(t, dsl) + assert.Len(t, strings.Split(err.Error(), "\n"), 1) + assert.Contains(t, err.Error(), "too few arguments given to "+strings.Split(name, " ")[0]) + }) + } +} + func TestTooManyArgError(t *testing.T) { dsls := map[string]func(){ "APIKey": func() { Type("name", func() { APIKey("scheme", "name", 1, 2, 3) }) }, diff --git a/expr/example_test.go b/expr/example_test.go index 872e74be3b..09edc55bfe 100644 --- a/expr/example_test.go +++ b/expr/example_test.go @@ -63,7 +63,7 @@ func TestExample(t *testing.T) { {"overriding-example", testdata.OverridingExampleDSL, map[string]any{"name": "overridden"}, ""}, {"with-extend", testdata.WithExtendExampleDSL, map[string]any{"name": "example"}, ""}, {"invalid-example-type", testdata.InvalidExampleTypeDSL, nil, "example value map[int]int{1:1} is incompatible with attribute of type map in attribute"}, - {"empty-example", testdata.EmptyExampleDSL, nil, "not enough arguments in attribute"}, + {"empty-example", testdata.EmptyExampleDSL, nil, "too few arguments given to Example in attribute"}, {"hiding-example", testdata.HidingExampleDSL, nil, ""}, {"overriding-hidden-examples", testdata.OverridingHiddenExamplesDSL, "example", ""}, }