Files
go-zero/tools/goctl/api/gogen/gencomment_test.go

182 lines
6.1 KiB
Go

package gogen
import (
"os"
"path/filepath"
"strings"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/zeromicro/go-zero/tools/goctl/internal/version"
)
// TestGenerationComments verifies that all generated files have appropriate generation comments
func TestGenerationComments(t *testing.T) {
// Create a temporary directory for our test
tempDir, err := os.MkdirTemp("", "goctl_test_")
require.NoError(t, err)
defer os.RemoveAll(tempDir)
// Create a simple API spec for testing
apiContent := `
syntax = "v1"
type HelloRequest {
Name string ` + "`json:\"name\"`" + `
}
type HelloResponse {
Message string ` + "`json:\"message\"`" + `
}
service hello-api {
@handler helloHandler
post /hello (HelloRequest) returns (HelloResponse)
}`
// Write the API spec to a temporary file
apiFile := filepath.Join(tempDir, "test.api")
err = os.WriteFile(apiFile, []byte(apiContent), 0644)
require.NoError(t, err)
// Parse and generate the API files using the correct function signature
err = DoGenProject(apiFile, tempDir, "gozero", false)
require.NoError(t, err)
// Define expected files and their comment types
expectedFiles := map[string]string{
// Files that should have "DO NOT EDIT" comments (regenerated files)
"internal/types/types.go": "DO NOT EDIT",
// Files that should have "Safe to edit" comments (scaffolded files)
"internal/handler/hellohandler.go": "Safe to edit",
"internal/config/config.go": "Safe to edit",
"hello.go": "Safe to edit", // main file
"internal/svc/servicecontext.go": "Safe to edit",
"internal/logic/hellologic.go": "Safe to edit",
}
// Check each file for the correct generation comment
for filePath, expectedCommentType := range expectedFiles {
fullPath := filepath.Join(tempDir, filePath)
// Skip if file doesn't exist (some files might not be generated in all cases)
if _, err := os.Stat(fullPath); os.IsNotExist(err) {
t.Logf("File %s does not exist, skipping", filePath)
continue
}
content, err := os.ReadFile(fullPath)
require.NoError(t, err, "Failed to read file: %s", filePath)
contentStr := string(content)
lines := strings.Split(contentStr, "\n")
// Check that the file starts with proper generation comments
require.GreaterOrEqual(t, len(lines), 2, "File %s should have at least 2 lines", filePath)
if expectedCommentType == "DO NOT EDIT" {
assert.Contains(t, lines[0], "// Code generated by goctl. DO NOT EDIT.",
"File %s should have 'DO NOT EDIT' comment as first line", filePath)
} else if expectedCommentType == "Safe to edit" {
assert.Contains(t, lines[0], "// Code scaffolded by goctl. Safe to edit.",
"File %s should have 'Safe to edit' comment as first line", filePath)
}
// Check that the second line contains the version
assert.Contains(t, lines[1], "// goctl",
"File %s should have version comment as second line", filePath)
assert.Contains(t, lines[1], version.BuildVersion,
"File %s should contain version %s in second line", filePath, version.BuildVersion)
}
}
// TestRoutesGenerationComment verifies routes files have "DO NOT EDIT" comment
func TestRoutesGenerationComment(t *testing.T) {
// Create a temporary directory for our test
tempDir, err := os.MkdirTemp("", "goctl_routes_test_")
require.NoError(t, err)
defer os.RemoveAll(tempDir)
// Create an API spec with multiple handlers to ensure routes file is generated
apiContent := `
syntax = "v1"
type HelloRequest {
Name string ` + "`json:\"name\"`" + `
}
type HelloResponse {
Message string ` + "`json:\"message\"`" + `
}
service hello-api {
@handler helloHandler
post /hello (HelloRequest) returns (HelloResponse)
@handler worldHandler
get /world returns (HelloResponse)
}`
// Write the API spec to a temporary file
apiFile := filepath.Join(tempDir, "test.api")
err = os.WriteFile(apiFile, []byte(apiContent), 0644)
require.NoError(t, err)
// Generate the API files using the correct function signature
err = DoGenProject(apiFile, tempDir, "gozero", false)
require.NoError(t, err)
// Check the routes file specifically
routesFile := filepath.Join(tempDir, "internal/handler/routes.go")
if _, err := os.Stat(routesFile); os.IsNotExist(err) {
t.Skip("Routes file not generated, skipping test")
return
}
content, err := os.ReadFile(routesFile)
require.NoError(t, err, "Failed to read routes.go")
contentStr := string(content)
lines := strings.Split(contentStr, "\n")
// Check that routes.go has "DO NOT EDIT" comment
require.GreaterOrEqual(t, len(lines), 2, "Routes file should have at least 2 lines")
assert.Contains(t, lines[0], "// Code generated by goctl. DO NOT EDIT.",
"Routes file should have 'DO NOT EDIT' comment")
assert.Contains(t, lines[1], "// goctl",
"Routes file should have version comment")
assert.Contains(t, lines[1], version.BuildVersion,
"Routes file should contain version %s", version.BuildVersion)
}
// TestVersionInTemplateData verifies that version is correctly passed to templates
func TestVersionInTemplateData(t *testing.T) {
// Test that BuildVersion is available
assert.NotEmpty(t, version.BuildVersion, "BuildVersion should not be empty")
}
// TestCommentsFollowGoStandards verifies our comments follow Go community standards
func TestCommentsFollowGoStandards(t *testing.T) {
// Test the format of our generation comments
doNotEditComment := "// Code generated by goctl. DO NOT EDIT."
safeToEditComment := "// Code scaffolded by goctl. Safe to edit."
// Both should be valid Go comments
assert.True(t, strings.HasPrefix(doNotEditComment, "//"),
"DO NOT EDIT comment should start with //")
assert.True(t, strings.HasPrefix(safeToEditComment, "//"),
"Safe to edit comment should start with //")
// Should contain key information
assert.Contains(t, doNotEditComment, "goctl",
"DO NOT EDIT comment should mention goctl")
assert.Contains(t, safeToEditComment, "goctl",
"Safe to edit comment should mention goctl")
assert.Contains(t, doNotEditComment, "DO NOT EDIT",
"Should clearly state DO NOT EDIT")
assert.Contains(t, safeToEditComment, "Safe to edit",
"Should clearly state Safe to edit")
}