nebius/SWE-rebench-V2-PRs huggingface dataset:
Repository: redis/lettuce
Pull request #2906 (2024-07-01 16:18:12)

Handle NPE
Issues: #2596 
<!--
Thank you for proposing a pull request. This template will guide you through the essential steps necessary for a pull request.
-->
Make sure that:

- [x] You have read the [contribution guidelines](https://github.com/lettuce-io/lettuce-core/blob/main/.github/CONTRIBUTING.md).
- [x] You have created a feature request first to discuss your contribution intent. Please reference the feature request ticket number in the pull request.
- [x] You applied code formatting rules using the `mvn formatter:format` target. Don’t submit any formatting related changes.
- [ ] You submit test cases (unit or integration tests) that back your changes.

 <!--
Great! Live long and prosper.
-->


tishun: Could you also please provide some unit/integration tests that check for this condition?

Patch:
diff --git a/src/main/java/io/lettuce/core/codec/ByteArrayCodec.java b/src/main/java/io/lettuce/core/codec/ByteArrayCodec.java
index c8a9cffd0..bcecd3d28 100644
--- a/src/main/java/io/lettuce/core/codec/ByteArrayCodec.java
+++ b/src/main/java/io/lettuce/core/codec/ByteArrayCodec.java
@@ -90,9 +90,11 @@ public class ByteArrayCodec implements RedisCodec<byte[], byte[]>, ToByteBufEnco
     }
 
     private static byte[] getBytes(ByteBuffer buffer) {
+        if (buffer == null) {
+            return EMPTY;
+        }
 
         int remaining = buffer.remaining();
-
         if (remaining == 0) {
             return EMPTY;
         }


Test patch:
diff --git a/src/test/java/io/lettuce/core/codec/ByteArrayCodecUnitTests.java b/src/test/java/io/lettuce/core/codec/ByteArrayCodecUnitTests.java
new file mode 100644
index 000000000..c8f2394da
--- /dev/null
+++ b/src/test/java/io/lettuce/core/codec/ByteArrayCodecUnitTests.java
@@ -0,0 +1,35 @@
+package io.lettuce.core.codec;
+
+import org.junit.jupiter.api.Test;
+
+import java.nio.ByteBuffer;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+class ByteArrayCodecUnitTests {
+
+    @Test
+    void testDecodeValue_withNonEmptyByteBuffer() {
+        final ByteArrayCodec byteArrayCodec = ByteArrayCodec.INSTANCE;
+        final byte[] expectedBytes = { 1, 2, 3, 4, 5 };
+        final ByteBuffer buffer = ByteBuffer.wrap(expectedBytes);
+        final byte[] result = byteArrayCodec.decodeValue(buffer);
+        assertThat(result).isEqualTo(expectedBytes);
+    }
+
+    @Test
+    void testDecodeValue_withEmptyByteBuffer() {
+        final ByteArrayCodec byteArrayCodec = ByteArrayCodec.INSTANCE;
+        final ByteBuffer buffer = ByteBuffer.allocate(0);
+        final byte[] result = byteArrayCodec.decodeValue(buffer);
+        assertThat(result).isEmpty();
+    }
+
+    @Test
+    void testDecodeValue_withNullByteBuffer() {
+        final ByteArrayCodec byteArrayCodec = ByteArrayCodec.INSTANCE;
+        final byte[] result = byteArrayCodec.decodeValue(null);
+        assertThat(result).isEmpty();
+    }
+
+}
Repository: goadesign/goa
Pull request #2614 (2020-07-16 18:17:41)

Remove path wildcards in openapi v3
Remove wildcards in path for openapi v3 like we do in openapi v2

raphael: Thank you! could you back-port to v2 as well? thanks!

Patch:
diff --git a/http/codegen/openapi/v3/builder.go b/http/codegen/openapi/v3/builder.go
index 8f773cda..57335683 100644
--- a/http/codegen/openapi/v3/builder.go
+++ b/http/codegen/openapi/v3/builder.go
@@ -110,6 +110,9 @@ func buildPaths(h *expr.HTTPExpr, bodies map[string]map[string]*EndpointBodies,
 		for _, e := range svc.HTTPEndpoints {
 			for _, r := range e.Routes {
 				for _, key := range r.FullPaths() {
+					// Remove any wildcards that is defined in path as a workaround to
+					// https://github.com/OAI/OpenAPI-Specification/issues/291
+					key = expr.HTTPWildcardRegex.ReplaceAllString(key, "/{$1}")
 					operation := buildOperation(key, r, sbod[e.Name()], api.Random())
 					path, ok := paths[key]
 					if !ok {


Test patch:
diff --git a/http/codegen/openapi/v3/testdata/golden/path-with-wildcards_file0.golden b/http/codegen/openapi/v3/testdata/golden/path-with-wildcards_file0.golden
index c8425959..96c7787c 100644
--- a/http/codegen/openapi/v3/testdata/golden/path-with-wildcards_file0.golden
+++ b/http/codegen/openapi/v3/testdata/golden/path-with-wildcards_file0.golden
@@ -1,1 +1,1 @@
-{"openapi":"3.0.3","info":{"title":"Goa API","version":"1.0"},"servers":[{"url":"localhost:80","description":"Default server for test api"}],"paths":{"/{*int_map}":{"post":{"tags":["test service"],"summary":"test endpoint test service","operationId":"test service#test endpoint","parameters":[{"name":"int_map","in":"path","required":true,"schema":{"type":"integer","example":9176544974339886224,"format":"int64"},"example":1933576090881074823}],"responses":{"204":{"description":"","content":{"application/json":{"example":{}}}}}}}},"components":{}}
\ No newline at end of file
+{"openapi":"3.0.3","info":{"title":"Goa API","version":"1.0"},"servers":[{"url":"localhost:80","description":"Default server for test api"}],"paths":{"/{int_map}":{"post":{"tags":["test service"],"summary":"test endpoint test service","operationId":"test service#test endpoint","parameters":[{"name":"int_map","in":"path","required":true,"schema":{"type":"integer","example":9176544974339886224,"format":"int64"},"example":1933576090881074823}],"responses":{"204":{"description":"","content":{"application/json":{"example":{}}}}}}}},"components":{}}
\ No newline at end of file
diff --git a/http/codegen/openapi/v3/testdata/golden/path-with-wildcards_file1.golden b/http/codegen/openapi/v3/testdata/golden/path-with-wildcards_file1.golden
index 18352d20..13067662 100644
--- a/http/codegen/openapi/v3/testdata/golden/path-with-wildcards_file1.golden
+++ b/http/codegen/openapi/v3/testdata/golden/path-with-wildcards_file1.golden
@@ -6,7 +6,7 @@ servers:
 - url: localhost:80
   description: Default server for test api
 paths:
-  /{*int_map}:
+  /{int_map}:
     post:
       tags:
       - test service
Repository: goadesign/goa
Pull request #2669 (2020-08-24 17:55:48)

Remove $ from goa command comment


Patch:
diff --git a/codegen/funcs.go b/codegen/funcs.go
index fecb7c74..107f5210 100644
--- a/codegen/funcs.go
+++ b/codegen/funcs.go
@@ -41,7 +41,7 @@ func TemplateFuncs() map[string]interface{} {
 
 // CommandLine return the command used to run this process.
 func CommandLine() string {
-	cmdl := "$ goa"
+	cmdl := "goa"
 	for _, arg := range os.Args {
 		if strings.HasPrefix(arg, "--cmd=") {
 			cmdl = arg[6:]


Test patch:
diff --git a/codegen/sections_test.go b/codegen/sections_test.go
index ee12988a..883331f7 100644
--- a/codegen/sections_test.go
+++ b/codegen/sections_test.go
@@ -63,7 +63,7 @@ import (
 // test title
 //
 // Command:
-// $ goa
+// goa
 
 package testpackage
 
diff --git a/codegen/service/testdata/convert_functions.go b/codegen/service/testdata/convert_functions.go
index d9d623ee..f427d0ab 100644
--- a/codegen/service/testdata/convert_functions.go
+++ b/codegen/service/testdata/convert_functions.go
@@ -209,7 +209,7 @@ func transformObjectFieldToTestdataObjectFieldT(v *ObjectField) *testdata.Object
 var CreateExternalConvert = `// Service service type conversion functions
 //
 // Command:
-// $ goa
+// goa
 
 package service
 
diff --git a/codegen/service/testdata/create_functions.go b/codegen/service/testdata/create_functions.go
index 1aa5e005..5e5d2f72 100644
--- a/codegen/service/testdata/create_functions.go
+++ b/codegen/service/testdata/create_functions.go
@@ -133,7 +133,7 @@ func (t *ObjectType) CreateFromObjectExtraT(v *testdata.ObjectExtraT) {
 var CreateAliasConvert = `// Service service type conversion functions
 //
 // Command:
-// $ goa
+// goa
 
 package service
 
@@ -153,7 +153,7 @@ func (t *StringType) CreateFromConvertModel(v *aliasd.ConvertModel) {
 var MixedCaseConvert = `// Service service type conversion functions
 //
 // Command:
-// $ goa
+// goa
 
 package service
Repository: goadesign/goa
Pull request #3143 (2022-09-08 00:02:50)

Replace any with interface{} - supporting older go installs
Switching to interface{} to allow for older Go installs to still work.


Patch:
diff --git a/grpc/codegen/protobuf_transform.go b/grpc/codegen/protobuf_transform.go
index 9ee61c96..4445d23e 100644
--- a/grpc/codegen/protobuf_transform.go
+++ b/grpc/codegen/protobuf_transform.go
@@ -369,7 +369,7 @@ func transformObject(source, target *expr.AttributeExpr, sourceVar, targetVar st
 	return buffer.String(), nil
 }
 
-func isNonZero(v any) bool {
+func isNonZero(v interface{}) bool {
 	switch v := v.(type) {
 	case nil:
 		return false
diff --git a/http/codegen/openapi/v3/types.go b/http/codegen/openapi/v3/types.go
index dfdb1c98..fc17566c 100644
--- a/http/codegen/openapi/v3/types.go
+++ b/http/codegen/openapi/v3/types.go
@@ -137,6 +137,13 @@ func buildBodyTypes(api *expr.APIExpr) (map[string]map[string]*EndpointBodies, m
 		}
 		sf.schemafy(&expr.AttributeExpr{Type: t})
 	}
+	for _, t := range expr.Root.ResultTypes {
+		_, ok := t.Attribute().Meta["type:generate:force"]
+		if !ok {
+			continue
+		}
+		sf.schemafy(&expr.AttributeExpr{Type: t})
+	}
 	return bodies, sf.schemas
 }
 


Test patch:
diff --git a/http/codegen/openapi/v3/testdata/dsls/types.go b/http/codegen/openapi/v3/testdata/dsls/types.go
index ba9b387f..a4e793fd 100644
--- a/http/codegen/openapi/v3/testdata/dsls/types.go
+++ b/http/codegen/openapi/v3/testdata/dsls/types.go
@@ -166,3 +166,21 @@ func ForcedTypeDSL(svcName, metName string) func() {
 		})
 	}
 }
+
+func ForcedResultTypeDSL(svcName, metName string) func() {
+	return func() {
+		var _ = ResultType("Forced", func() {
+			Attributes(func() {
+				Attribute("foo")
+			})
+			Meta("type:generate:force")
+		})
+		var _ = Service(svcName, func() {
+			Method(metName, func() {
+				HTTP(func() {
+					POST("/")
+				})
+			})
+		})
+	}
+}
diff --git a/http/codegen/openapi/v3/types_test.go b/http/codegen/openapi/v3/types_test.go
index 8a0407ad..3607d533 100644
--- a/http/codegen/openapi/v3/types_test.go
+++ b/http/codegen/openapi/v3/types_test.go
@@ -147,6 +147,13 @@ func TestBuildBodyTypes(t *testing.T) {
 		Name: "forced_type",
 		DSL:  dsls.ForcedTypeDSL(svcName, "forced_type"),
 
+		ExpectedType:          tempty,
+		ExpectedResponseTypes: rt{204: tempty},
+		ExpectedExtraTypes:    map[string]typ{"Forced": tobj("foo", tstring)},
+	}, {
+		Name: "forced_result_type",
+		DSL:  dsls.ForcedResultTypeDSL(svcName, "forced_result_type"),
+
 		ExpectedType:          tempty,
 		ExpectedResponseTypes: rt{204: tempty},
 		ExpectedExtraTypes:    map[string]typ{"Forced": tobj("foo", tstring)},
Repository: goadesign/goa
Pull request #3144 (2022-09-08 08:28:57)

Generate OpenAPI spec for forced result types
Similar to https://github.com/goadesign/goa/pull/3142 but focused on forced result types.

Relates to #3129.

raphael: Good catch, thank you!

Patch:
diff --git a/http/codegen/openapi/v3/types.go b/http/codegen/openapi/v3/types.go
index dfdb1c98..fc17566c 100644
--- a/http/codegen/openapi/v3/types.go
+++ b/http/codegen/openapi/v3/types.go
@@ -137,6 +137,13 @@ func buildBodyTypes(api *expr.APIExpr) (map[string]map[string]*EndpointBodies, m
 		}
 		sf.schemafy(&expr.AttributeExpr{Type: t})
 	}
+	for _, t := range expr.Root.ResultTypes {
+		_, ok := t.Attribute().Meta["type:generate:force"]
+		if !ok {
+			continue
+		}
+		sf.schemafy(&expr.AttributeExpr{Type: t})
+	}
 	return bodies, sf.schemas
 }
 


Test patch:
diff --git a/http/codegen/openapi/v3/testdata/dsls/types.go b/http/codegen/openapi/v3/testdata/dsls/types.go
index ba9b387f..a4e793fd 100644
--- a/http/codegen/openapi/v3/testdata/dsls/types.go
+++ b/http/codegen/openapi/v3/testdata/dsls/types.go
@@ -166,3 +166,21 @@ func ForcedTypeDSL(svcName, metName string) func() {
 		})
 	}
 }
+
+func ForcedResultTypeDSL(svcName, metName string) func() {
+	return func() {
+		var _ = ResultType("Forced", func() {
+			Attributes(func() {
+				Attribute("foo")
+			})
+			Meta("type:generate:force")
+		})
+		var _ = Service(svcName, func() {
+			Method(metName, func() {
+				HTTP(func() {
+					POST("/")
+				})
+			})
+		})
+	}
+}
diff --git a/http/codegen/openapi/v3/types_test.go b/http/codegen/openapi/v3/types_test.go
index 8a0407ad..3607d533 100644
--- a/http/codegen/openapi/v3/types_test.go
+++ b/http/codegen/openapi/v3/types_test.go
@@ -147,6 +147,13 @@ func TestBuildBodyTypes(t *testing.T) {
 		Name: "forced_type",
 		DSL:  dsls.ForcedTypeDSL(svcName, "forced_type"),
 
+		ExpectedType:          tempty,
+		ExpectedResponseTypes: rt{204: tempty},
+		ExpectedExtraTypes:    map[string]typ{"Forced": tobj("foo", tstring)},
+	}, {
+		Name: "forced_result_type",
+		DSL:  dsls.ForcedResultTypeDSL(svcName, "forced_result_type"),
+
 		ExpectedType:          tempty,
 		ExpectedResponseTypes: rt{204: tempty},
 		ExpectedExtraTypes:    map[string]typ{"Forced": tobj("foo", tstring)},
Repository: goadesign/goa
Pull request #3272 (2023-04-04 06:47:17)

Generate empty array for required types in response
As mentioned in #3216. This code change makes sure that an empty array is initialized in the response if the field is required

raphael: This looks great, thank you
raphael: Thank you, this looks great.

Patch:
diff --git a/codegen/go_transform.go b/codegen/go_transform.go
index 0d5ada33..26220648 100644
--- a/codegen/go_transform.go
+++ b/codegen/go_transform.go
@@ -252,7 +252,12 @@ func transformObject(source, target *expr.AttributeExpr, sourceVar, targetVar st
 			checkNil = isRef || marshalNonPrimitive
 		}
 		if code != "" && checkNil {
-			code = fmt.Sprintf("if %s != nil {\n\t%s}\n", srcVar, code)
+			code = fmt.Sprintf("if %s != nil {\n\t%s}", srcVar, code)
+			if expr.IsArray(srcc.Type) && srcMatt.IsRequired(n) {
+				code += fmt.Sprintf("else {\n\t%s = []%s{}\n}\n", tgtVar, ta.TargetCtx.Scope.Ref(expr.AsArray(tgtc.Type).ElemType, ta.TargetCtx.Pkg(expr.AsArray(tgtc.Type).ElemType)))
+			} else {
+				code += "\n"
+			}
 		}
 
 		// Default value handling. We need to handle default values if the target


Test patch:
diff --git a/codegen/codegentest/codegentest.go b/codegen/codegentest/codegentest.go
index 997a328c..c955e855 100644
--- a/codegen/codegentest/codegentest.go
+++ b/codegen/codegentest/codegentest.go
@@ -1,5 +1,5 @@
 // Package codegentest provides utilities to assist writing unit test for
-// codegen pacakges.
+// codegen packages.
 package codegentest
 
 import (
diff --git a/codegen/go_transform_test.go b/codegen/go_transform_test.go
index 6bbd38bd..316bcb89 100644
--- a/codegen/go_transform_test.go
+++ b/codegen/go_transform_test.go
@@ -483,6 +483,8 @@ const (
 		for i, val := range source.StringArray {
 			target.StringArray[i] = val
 		}
+	} else {
+		target.StringArray = []string{}
 	}
 }
 `
@@ -519,6 +521,8 @@ const (
 		for i, val := range source.StringArray {
 			target.StringArray[i] = val
 		}
+	} else {
+		target.StringArray = []string{}
 	}
 }
 `
@@ -667,6 +671,8 @@ const (
 		for i, val := range source.MyArray {
 			target.Array[i] = val
 		}
+	} else {
+		target.Array = []string{}
 	}
 }
 `
@@ -784,6 +790,8 @@ const (
 		for i, val := range source.RequiredArray {
 			target.RequiredArray[i] = val
 		}
+	} else {
+		target.RequiredArray = []string{}
 	}
 	if source.Map != nil {
 		target.Map = make(map[int]string, len(source.Map))
diff --git a/http/codegen/client_body_types_test.go b/http/codegen/client_body_types_test.go
index ea464ba2..6c2bc64f 100644
--- a/http/codegen/client_body_types_test.go
+++ b/http/codegen/client_body_types_test.go
@@ -308,6 +308,8 @@ func NewMethodARequestBody(p *servicemixedpayloadinbody.APayload) *MethodAReques
 		for i, val := range p.Array {
 			body.Array[i] = val
 		}
+	} else {
+		body.Array = []float32{}
 	}
 	if p.Map != nil {
 		body.Map = make(map[uint]any, len(p.Map))
Repository: goadesign/goa
Pull request #3366 (2023-09-26 13:53:08)

Use RedirectSlashes middleware by default Goa mux 
https://github.com/goadesign/goa/pull/3364#issuecomment-1734770313

tchssk: DeepSource: Test coverage looks always timed out.
raphael: This is great, thank you! (I need to fix the build failing for PRs coming from forks)

Patch:
diff --git a/http/mux.go b/http/mux.go
index f918c877..11013ecb 100644
--- a/http/mux.go
+++ b/http/mux.go
@@ -8,6 +8,7 @@ import (
 	"regexp"
 
 	chi "github.com/go-chi/chi/v5"
+	"github.com/go-chi/chi/v5/middleware"
 )
 
 type (
@@ -79,6 +80,9 @@ type (
 // NewMuxer returns a Muxer implementation based on a Chi router.
 func NewMuxer() ResolverMuxer {
 	r := chi.NewRouter()
+	// RedirectSlashes must be mounted at the top level of the router.
+	// See. https://github.com/go-chi/chi/blob/1129e362d6cce6e3805e3bc8dfbaeb34b5129789/middleware/strip_test.go#L105-L107
+	r.Use(middleware.RedirectSlashes)
 	r.NotFound(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
 		ctx := context.WithValue(req.Context(), AcceptTypeKey, req.Header.Get("Accept"))
 		enc := ResponseEncoder(ctx, w)


Test patch:
diff --git a/http/mux_test.go b/http/mux_test.go
index f3eacc17..94f59781 100644
--- a/http/mux_test.go
+++ b/http/mux_test.go
@@ -227,6 +227,16 @@ func TestResolvePattern(t *testing.T) {
 			w := httptest.NewRecorder()
 			mux.ServeHTTP(w, req)
 			assert.True(t, called)
+			// Make sure the URL with a trailing slash is redirected.
+			called = false // Reset.
+			req, _ = http.NewRequest("GET", c.URL+"/", nil)
+			w = httptest.NewRecorder()
+			mux.ServeHTTP(w, req)
+			assert.Equal(t, http.StatusMovedPermanently, w.Code)
+			req, _ = http.NewRequest("GET", w.Header().Get("Location"), nil)
+			w = httptest.NewRecorder()
+			mux.ServeHTTP(w, req)
+			assert.True(t, called)
 		})
 	}
 }
Repository: goadesign/goa
Pull request #3536 (2024-06-17 15:15:46)

Add test for eval.InvalidArgError()

raphael: Nice catch, thank you!

Patch:
diff --git a/dsl/attribute.go b/dsl/attribute.go
index 6ee52ca6..f34e6624 100644
--- a/dsl/attribute.go
+++ b/dsl/attribute.go
@@ -316,7 +316,7 @@ func Example(args ...any) {
 		var ok bool
 		summary, ok = args[0].(string)
 		if !ok {
-			eval.InvalidArgError("summary (string)", summary)
+			eval.InvalidArgError("summary (string)", args[0])
 			return
 		}
 		arg = args[1]


Test patch:
diff --git a/eval/eval_test.go b/eval/eval_test.go
index c316f52a..4afb4d07 100644
--- a/eval/eval_test.go
+++ b/eval/eval_test.go
@@ -9,6 +9,32 @@ import (
 	"goa.design/goa/v3/expr"
 )
 
+func TestInvalidArgError(t *testing.T) {
+	dsls := map[string]struct {
+		dsl  func()
+		want string
+	}{
+		"Attribute":        {func() { Type("name", func() { Attribute("name", String, "description", 1) }) }, "cannot use 1 (type int) as type func()"},
+		"Body":             {func() { Service("s", func() { Method("m", func() { HTTP(func() { Body(1) }) }) }) }, "cannot use 1 (type int) as type attribute name, user type or DSL"},
+		"ErrorName (bool)": {func() { Type("name", func() { ErrorName(true) }) }, "cannot use true (type bool) as type name or position"},
+		"ErrorName (int)":  {func() { Type("name", func() { ErrorName(1, 2) }) }, "cannot use 2 (type int) as type name"},
+		"Example":          {func() { Example(1, 2) }, "cannot use 1 (type int) as type summary (string)"},
+		"Headers":          {func() { Headers(1) }, "cannot use 1 (type int) as type function"},
+		"Param":            {func() { API("name", func() { HTTP(func() { Params(1) }) }) }, "cannot use 1 (type int) as type function"},
+		"Response":         {func() { Service("s", func() { HTTP(func() { Response(1) }) }) }, "cannot use 1 (type int) as type name of error"},
+		"ResultType":       {func() { ResultType("identifier", 1) }, "cannot use 1 (type int) as type function or string"},
+		"Security":         {func() { Security(1) }, "cannot use 1 (type int) as type security scheme or security scheme name"},
+		"Type":             {func() { Type("name", 1) }, "cannot use 1 (type int) as type type or function"},
+	}
+	for name, tc := range dsls {
+		t.Run(name, func(t *testing.T) {
+			err := expr.RunInvalidDSL(t, tc.dsl)
+			assert.Len(t, strings.Split(err.Error(), "\n"), 1)
+			assert.Contains(t, err.Error(), tc.want)
+		})
+	}
+}
+
 func TestTooManyArgError(t *testing.T) {
 	dsls := map[string]func(){
 		"APIKey":           func() { Type("name", func() { APIKey("scheme", "name", 1, 2, 3) }) },
Repository: goadesign/goa
Pull request #3577 (2024-08-13 17:01:39)

Add TooFewArgError to dsl.OneOf
Related to https://github.com/goadesign/goa/pull/3557

raphael: This is great, thank you!

Patch:
diff --git a/dsl/attribute.go b/dsl/attribute.go
index d6a7d3fa..75f74087 100644
--- a/dsl/attribute.go
+++ b/dsl/attribute.go
@@ -219,6 +219,10 @@ func Field(tag any, name string, args ...any) {
 //	    })
 //	})
 func OneOf(name string, args ...any) {
+	if len(args) == 0 {
+		eval.TooFewArgError()
+		return
+	}
 	if len(args) > 2 {
 		eval.TooManyArgError()
 		return


Test patch:
diff --git a/eval/eval_test.go b/eval/eval_test.go
index 14f91d87..d74c0c33 100644
--- a/eval/eval_test.go
+++ b/eval/eval_test.go
@@ -42,6 +42,7 @@ func TestTooFewArgError(t *testing.T) {
 		"ErrorName":       func() { ErrorName() },
 		"ErrorName (int)": func() { Type("name", func() { ErrorName(1) }) },
 		"Example":         func() { Example() },
+		"OneOf":           func() { OneOf("name") },
 		"Response (grpc)": func() { Service("s", func() { GRPC(func() { Response("name") }) }) },
 		"Response (http)": func() { Service("s", func() { HTTP(func() { Response("name") }) }) },
 	}
Repository: goadesign/goa
Pull request #3624 (2024-12-20 11:37:03)

Use eval.InvalidArgError() to dsl.OneOf()
Related to https://github.com/goadesign/goa/pull/3536

raphael: Thank you!
tchssk: It's ready to merge!

Patch:
diff --git a/dsl/attribute.go b/dsl/attribute.go
index 75f74087..ba4adce7 100644
--- a/dsl/attribute.go
+++ b/dsl/attribute.go
@@ -229,13 +229,13 @@ func OneOf(name string, args ...any) {
 	}
 	fn, ok := args[len(args)-1].(func())
 	if !ok {
-		eval.ReportError("OneOf: last argument must be a function")
+		eval.InvalidArgError("function", args[len(args)-1])
 	}
 	var desc string
 	if len(args) > 1 {
 		desc, ok = args[0].(string)
 		if !ok {
-			eval.ReportError("OneOf: description must be a string")
+			eval.InvalidArgError("string", args[0])
 		}
 	}
 	Attribute(name, &expr.Union{TypeName: name}, desc, fn)


Test patch:
diff --git a/eval/eval_test.go b/eval/eval_test.go
index d74c0c33..bfda3764 100644
--- a/eval/eval_test.go
+++ b/eval/eval_test.go
@@ -20,6 +20,8 @@ func TestInvalidArgError(t *testing.T) {
 		"ErrorName (int)":      {func() { Type("name", func() { ErrorName(1, 2) }) }, "cannot use 2 (type int) as type name"},
 		"Example":              {func() { Example(1, 2) }, "cannot use 1 (type int) as type summary (string)"},
 		"Headers":              {func() { Headers(1) }, "cannot use 1 (type int) as type function"},
+		"OneOf (function)":     {func() { Type("name", func() { OneOf("name", "description", 1) }) }, "cannot use 1 (type int) as type function"},
+		"OneOf (string)":       {func() { Type("name", func() { OneOf("name", 1, func() {}) }) }, "cannot use 1 (type int) as type string"},
 		"Param":                {func() { API("name", func() { HTTP(func() { Params(1) }) }) }, "cannot use 1 (type int) as type function"},
 		"Response":             {func() { Service("s", func() { HTTP(func() { Response(1) }) }) }, "cannot use 1 (type int) as type name of error"},
 		"ResultType":           {func() { ResultType("identifier", 1) }, "cannot use 1 (type int) as type function or string"},