Repository: goadesign/goa
Pull request #2383 (2019-11-19 05:45:20)

v3: Add t.Helper() to test helper functions
How about adding t.Helper function to test helper functions?


Patch:
diff --git a/dsl/http_file_server.go b/dsl/http_file_server.go
index 765ef4cd..665f582f 100644
--- a/dsl/http_file_server.go
+++ b/dsl/http_file_server.go
@@ -55,16 +55,19 @@ func Files(path, filename string, fns ...func()) {
 	if !strings.HasPrefix(path, "/") {
 		path = "/" + path
 	}
-	if s, ok := eval.Current().(*expr.ServiceExpr); ok {
-		r := expr.Root.API.HTTP.ServiceFor(s)
-		server := &expr.HTTPFileServerExpr{
-			Service:      r,
-			RequestPaths: []string{path},
-			FilePath:     filename,
-		}
-		if len(fns) > 0 {
-			eval.Execute(fns[0], server)
-		}
-		r.FileServers = append(r.FileServers, server)
+	s, ok := eval.Current().(*expr.ServiceExpr)
+	if !ok {
+		eval.IncompatibleDSL()
+		return
+	}
+	r := expr.Root.API.HTTP.ServiceFor(s)
+	server := &expr.HTTPFileServerExpr{
+		Service:      r,
+		RequestPaths: []string{path},
+		FilePath:     filename,
+	}
+	if len(fns) > 0 {
+		eval.Execute(fns[0], server)
 	}
+	r.FileServers = append(r.FileServers, server)
 }


Test patch:
diff --git a/codegen/testing.go b/codegen/testing.go
index 9ff87fb5..f930382e 100644
--- a/codegen/testing.go
+++ b/codegen/testing.go
@@ -17,6 +17,7 @@ import (
 
 // RunDSL returns the DSL root resulting from running the given DSL.
 func RunDSL(t *testing.T, dsl func()) *expr.RootExpr {
+	t.Helper()
 	eval.Reset()
 	expr.Root = new(expr.RootExpr)
 	expr.Root.GeneratedTypes = &expr.GeneratedRoot{}
@@ -37,6 +38,7 @@ func RunDSL(t *testing.T, dsl func()) *expr.RootExpr {
 // It executes a function to add any top-level types to the design Root before
 // running the DSL.
 func RunDSLWithFunc(t *testing.T, dsl func(), fn func()) *expr.RootExpr {
+	t.Helper()
 	eval.Reset()
 	expr.Root = new(expr.RootExpr)
 	expr.Root.GeneratedTypes = &expr.GeneratedRoot{}
@@ -70,6 +72,7 @@ func SectionsCode(t *testing.T, sections []*SectionTemplate) string {
 
 // SectionCodeFromImportsAndMethods generates and formats the code for given import and method definition sections.
 func SectionCodeFromImportsAndMethods(t *testing.T, importSection *SectionTemplate, methodSection *SectionTemplate) string {
+	t.Helper()
 	var code bytes.Buffer
 	if err := importSection.Write(&code); err != nil {
 		t.Fatal(err)
@@ -96,6 +99,7 @@ func sectionCodeWithPrefix(t *testing.T, section *SectionTemplate, prefix string
 // FormatTestCode formats the given Go code. The code must correspond to the
 // content of a valid Go source file (i.e. start with "package")
 func FormatTestCode(t *testing.T, code string) string {
+	t.Helper()
 	tmp := CreateTempFile(t, code)
 	defer os.Remove(tmp)
 	if err := finalizeGoSource(tmp); err != nil {
@@ -130,6 +134,7 @@ func Diff(t *testing.T, s1, s2 string) string {
 // CreateTempFile creates a temporary file and writes the given content.
 // It is used only for testing.
 func CreateTempFile(t *testing.T, content string) string {
+	t.Helper()
 	f, err := ioutil.TempFile("", "")
 	if err != nil {
 		t.Fatal(err)
diff --git a/expr/http_file_server_test.go b/expr/http_file_server_test.go
new file mode 100644
index 00000000..fdee36c0
--- /dev/null
+++ b/expr/http_file_server_test.go
@@ -0,0 +1,32 @@
+package expr_test
+
+import (
+	"strings"
+	"testing"
+
+	"goa.design/goa/v3/expr"
+	"goa.design/goa/v3/expr/testdata"
+)
+
+func TestFilesDSL(t *testing.T) {
+	cases := []struct {
+		Name  string
+		DSL   func()
+		Error string
+	}{
+		{Name: "valid", DSL: testdata.FilesValidDSL},
+		{Name: "incompatible", DSL: testdata.FilesIncompatibleDSL, Error: "invalid use of Files in API files-incompatile"},
+	}
+	for _, c := range cases {
+		t.Run(c.Name, func(t *testing.T) {
+			if c.Error == "" {
+				expr.RunDSL(t, c.DSL)
+			} else {
+				err := expr.RunInvalidDSL(t, c.DSL)
+				if !strings.HasSuffix(err.Error(), c.Error) {
+					t.Errorf("got error %q, expected has suffix %q", err.Error(), c.Error)
+				}
+			}
+		})
+	}
+}
diff --git a/expr/testdata/http_file_server.go b/expr/testdata/http_file_server.go
new file mode 100644
index 00000000..1e3950d5
--- /dev/null
+++ b/expr/testdata/http_file_server.go
@@ -0,0 +1,17 @@
+package testdata
+
+import (
+	. "goa.design/goa/v3/dsl"
+)
+
+var FilesValidDSL = func() {
+	Service("files-dsl", func() {
+		Files("path", "filename")
+	})
+}
+
+var FilesIncompatibleDSL = func() {
+	API("files-incompatile", func() {
+		Files("path", "filename")
+	})
+}
diff --git a/expr/testing.go b/expr/testing.go
index e9fef3aa..79e537a6 100644
--- a/expr/testing.go
+++ b/expr/testing.go
@@ -14,6 +14,7 @@ import (
 // RunDSL returns the DSL root resulting from running the given DSL.
 // Used only in tests.
 func RunDSL(t *testing.T, dsl func()) *RootExpr {
+	t.Helper()
 	setupDSLRun()
 
 	// run DSL (first pass)
@@ -33,6 +34,7 @@ func RunDSL(t *testing.T, dsl func()) *RootExpr {
 // RunInvalidDSL returns the error resulting from running the given DSL.
 // It is used only in tests.
 func RunInvalidDSL(t *testing.T, dsl func()) error {
+	t.Helper()
 	setupDSLRun()
 
 	// run DSL (first pass)
@@ -73,6 +75,7 @@ func Diff(t *testing.T, s1, s2 string) string {
 // CreateTempFile creates a temporary file and writes the given content.
 // It is used only for testing.
 func CreateTempFile(t *testing.T, content string) string {
+	t.Helper()
 	f, err := ioutil.TempFile("", "")
 	if err != nil {
 		t.Fatal(err)
diff --git a/grpc/codegen/testing.go b/grpc/codegen/testing.go
index 213b8c47..5044a485 100644
--- a/grpc/codegen/testing.go
+++ b/grpc/codegen/testing.go
@@ -19,6 +19,7 @@ func RunGRPCDSL(t *testing.T, dsl func()) *expr.RootExpr {
 }
 
 func sectionCode(t *testing.T, section ...*codegen.SectionTemplate) string {
+	t.Helper()
 	var code bytes.Buffer
 	for _, s := range section {
 		if err := s.Write(&code); err != nil {
diff --git a/http/codegen/testing.go b/http/codegen/testing.go
index 68a77f42..b6d0a08e 100644
--- a/http/codegen/testing.go
+++ b/http/codegen/testing.go
@@ -20,6 +20,7 @@ func RunHTTPDSL(t *testing.T, dsl func()) *expr.RootExpr {
 // makeGolden returns nil then the test should not generate test
 // expectations.
 func makeGolden(t *testing.T, p string) *os.File {
+	t.Helper()
 	if os.Getenv("GOLDEN") == "" {
 		return nil
 	}
diff --git a/middleware/xray/xraytest/testing.go b/middleware/xray/xraytest/testing.go
index 46f28755..7d8e8d22 100644
--- a/middleware/xray/xraytest/testing.go
+++ b/middleware/xray/xraytest/testing.go
@@ -14,6 +14,7 @@ import (
 
 // ReadUDP verifies that exactly the expected number of messages are received.
 func ReadUDP(t *testing.T, udplisten string, expectedMessages int, sender func()) []string {
+	t.Helper()
 	var (
 		readChan = make(chan []string)
 		msg      = make([]byte, 1024*32)