diff --git a/cmd/muxt/generate.go b/cmd/muxt/generate.go index e30e89f..b44eab5 100644 --- a/cmd/muxt/generate.go +++ b/cmd/muxt/generate.go @@ -96,12 +96,12 @@ func generateCommand(args []string, workingDirectory string, getEnv func(string) if err != nil { return err } - patterns, err := muxt.TemplatePatterns(ts) + templateNames, err := muxt.TemplateNames(ts) if err != nil { return err } out := log.New(stdout, "", 0) - s, err := muxt.Generate(patterns, g.goPackage, g.templatesVariable, g.routesFunction, g.receiverIdent, g.Package.Fset, g.Package.Syntax, g.Package.Syntax, out) + s, err := muxt.Generate(templateNames, g.goPackage, g.templatesVariable, g.routesFunction, g.receiverIdent, g.Package.Fset, g.Package.Syntax, g.Package.Syntax, out) if err != nil { return err } diff --git a/generate.go b/generate.go index e89bc6c..913f947 100644 --- a/generate.go +++ b/generate.go @@ -43,7 +43,7 @@ const ( DefaultRoutesFunctionName = "Routes" ) -func Generate(patterns []Pattern, packageName, templatesVariableName, routesFunctionName, receiverTypeIdent string, _ *token.FileSet, receiverPackage, templatesPackage []*ast.File, log *log.Logger) (string, error) { +func Generate(templateNames []TemplateName, packageName, templatesVariableName, routesFunctionName, receiverTypeIdent string, _ *token.FileSet, receiverPackage, templatesPackage []*ast.File, log *log.Logger) (string, error) { packageName = cmp.Or(packageName, defaultPackageName) templatesVariableName = cmp.Or(templatesVariableName, DefaultTemplatesVariableName) routesFunctionName = cmp.Or(routesFunctionName, DefaultRoutesFunctionName) @@ -61,7 +61,7 @@ func Generate(patterns []Pattern, packageName, templatesVariableName, routesFunc imports := []*ast.ImportSpec{ importSpec("net/" + httpPackageIdent), } - for _, pattern := range patterns { + for _, pattern := range templateNames { var method *ast.FuncType if pattern.fun != nil { for _, funcDecl := range source.IterateFunctions(receiverPackage) { @@ -113,7 +113,7 @@ func Generate(patterns []Pattern, packageName, templatesVariableName, routesFunc return source.Format(file), nil } -func (def Pattern) callHandleFunc(handlerFuncLit *ast.FuncLit) *ast.ExprStmt { +func (def TemplateName) callHandleFunc(handlerFuncLit *ast.FuncLit) *ast.ExprStmt { return &ast.ExprStmt{X: &ast.CallExpr{ Fun: &ast.SelectorExpr{ X: ast.NewIdent(muxVarIdent), @@ -129,7 +129,7 @@ func (def Pattern) callHandleFunc(handlerFuncLit *ast.FuncLit) *ast.ExprStmt { }} } -func (def Pattern) funcLit(templatesVariableIdent string, method *ast.FuncType) (*ast.FuncLit, []*ast.ImportSpec, error) { +func (def TemplateName) funcLit(templatesVariableIdent string, method *ast.FuncType) (*ast.FuncLit, []*ast.ImportSpec, error) { if def.Handler == "" { return def.httpRequestReceiverTemplateHandlerFunc(templatesVariableIdent), nil, nil } @@ -152,12 +152,12 @@ func (def Pattern) funcLit(templatesVariableIdent string, method *ast.FuncType) for _, a := range def.call.Args { arg := a.(*ast.Ident) switch arg.Name { - case PatternScopeIdentifierHTTPRequest, PatternScopeIdentifierHTTPResponse: + case TemplateNameScopeIdentifierHTTPRequest, TemplateNameScopeIdentifierHTTPResponse: call.Args = append(call.Args, ast.NewIdent(arg.Name)) imports = append(imports, importSpec("net/http")) - case PatternScopeIdentifierContext: + case TemplateNameScopeIdentifierContext: lit.Body.List = append(lit.Body.List, contextAssignment()) - call.Args = append(call.Args, ast.NewIdent(PatternScopeIdentifierContext)) + call.Args = append(call.Args, ast.NewIdent(TemplateNameScopeIdentifierContext)) imports = append(imports, importSpec("context")) default: lit.Body.List = append(lit.Body.List, httpPathValueAssignment(arg)) @@ -204,7 +204,7 @@ func (def Pattern) funcLit(templatesVariableIdent string, method *ast.FuncType) return lit, imports, nil } -func (def Pattern) funcType() (*ast.FuncType, []*ast.ImportSpec) { +func (def TemplateName) funcType() (*ast.FuncType, []*ast.ImportSpec) { method := &ast.FuncType{ Params: &ast.FieldList{}, Results: &ast.FieldList{List: []*ast.Field{{Type: ast.NewIdent("any")}}}, @@ -213,13 +213,13 @@ func (def Pattern) funcType() (*ast.FuncType, []*ast.ImportSpec) { for _, a := range def.call.Args { arg := a.(*ast.Ident) switch arg.Name { - case PatternScopeIdentifierHTTPRequest: + case TemplateNameScopeIdentifierHTTPRequest: method.Params.List = append(method.Params.List, httpRequestField()) imports = append(imports, importSpec("net/"+httpPackageIdent)) - case PatternScopeIdentifierHTTPResponse: + case TemplateNameScopeIdentifierHTTPResponse: method.Params.List = append(method.Params.List, httpResponseField()) imports = append(imports, importSpec("net/"+httpPackageIdent)) - case PatternScopeIdentifierContext: + case TemplateNameScopeIdentifierContext: method.Params.List = append(method.Params.List, contextContextField()) imports = append(imports, importSpec(contextPackageIdent)) default: @@ -254,24 +254,24 @@ func fieldListTypes(fieldList *ast.FieldList) func(func(int, ast.Expr) bool) { } } -func errWrongNumberOfArguments(def Pattern, method *ast.FuncType) error { +func errWrongNumberOfArguments(def TemplateName, method *ast.FuncType) error { return fmt.Errorf("handler %s expects %d arguments but call %s has %d", source.Format(&ast.FuncDecl{Name: ast.NewIdent(def.fun.Name), Type: method}), method.Params.NumFields(), def.Handler, len(def.call.Args)) } func checkArgument(exp ast.Expr, tp ast.Expr) error { arg := exp.(*ast.Ident) switch arg.Name { - case PatternScopeIdentifierHTTPRequest: + case TemplateNameScopeIdentifierHTTPRequest: if !matchSelectorIdents(tp, httpPackageIdent, httpRequestIdent, true) { return fmt.Errorf("method expects type %s but %s is *%s.%s", source.Format(tp), arg.Name, httpPackageIdent, httpRequestIdent) } return nil - case PatternScopeIdentifierHTTPResponse: + case TemplateNameScopeIdentifierHTTPResponse: if !matchSelectorIdents(tp, httpPackageIdent, httpResponseWriterIdent, false) { return fmt.Errorf("method expects type %s but %s is %s.%s", source.Format(tp), arg.Name, httpPackageIdent, httpResponseWriterIdent) } return nil - case PatternScopeIdentifierContext: + case TemplateNameScopeIdentifierContext: if !matchSelectorIdents(tp, contextPackageIdent, contextContextTypeIdent, false) { return fmt.Errorf("method expects type %s but %s is %s.%s", source.Format(tp), arg.Name, contextPackageIdent, contextContextTypeIdent) } @@ -310,14 +310,14 @@ func pathValueField(name string) *ast.Field { func contextContextField() *ast.Field { return &ast.Field{ - Names: []*ast.Ident{ast.NewIdent(PatternScopeIdentifierContext)}, + Names: []*ast.Ident{ast.NewIdent(TemplateNameScopeIdentifierContext)}, Type: contextContextType(), } } func httpResponseField() *ast.Field { return &ast.Field{ - Names: []*ast.Ident{ast.NewIdent(PatternScopeIdentifierHTTPResponse)}, + Names: []*ast.Ident{ast.NewIdent(TemplateNameScopeIdentifierHTTPResponse)}, Type: &ast.SelectorExpr{X: ast.NewIdent(httpPackageIdent), Sel: ast.NewIdent(httpResponseWriterIdent)}, } } @@ -335,7 +335,7 @@ func routesFuncType(receiverType ast.Expr) *ast.FuncType { func httpRequestField() *ast.Field { return &ast.Field{ - Names: []*ast.Ident{ast.NewIdent(PatternScopeIdentifierHTTPRequest)}, + Names: []*ast.Ident{ast.NewIdent(TemplateNameScopeIdentifierHTTPRequest)}, Type: &ast.StarExpr{X: &ast.SelectorExpr{X: ast.NewIdent(httpPackageIdent), Sel: ast.NewIdent(httpRequestIdent)}}, } } @@ -369,10 +369,10 @@ func httpStatusCode(name string) *ast.SelectorExpr { func contextAssignment() *ast.AssignStmt { return &ast.AssignStmt{ Tok: token.DEFINE, - Lhs: []ast.Expr{ast.NewIdent(PatternScopeIdentifierContext)}, + Lhs: []ast.Expr{ast.NewIdent(TemplateNameScopeIdentifierContext)}, Rhs: []ast.Expr{&ast.CallExpr{ Fun: &ast.SelectorExpr{ - X: ast.NewIdent(PatternScopeIdentifierHTTPRequest), + X: ast.NewIdent(TemplateNameScopeIdentifierHTTPRequest), Sel: ast.NewIdent(httpRequestContextMethod), }, }}, @@ -385,7 +385,7 @@ func httpPathValueAssignment(arg *ast.Ident) *ast.AssignStmt { Lhs: []ast.Expr{ast.NewIdent(arg.Name)}, Rhs: []ast.Expr{&ast.CallExpr{ Fun: &ast.SelectorExpr{ - X: ast.NewIdent(PatternScopeIdentifierHTTPRequest), + X: ast.NewIdent(TemplateNameScopeIdentifierHTTPRequest), Sel: ast.NewIdent(requestPathValue), }, Args: []ast.Expr{ @@ -398,12 +398,12 @@ func httpPathValueAssignment(arg *ast.Ident) *ast.AssignStmt { } } -func (def Pattern) executeCall(templatesVariable *ast.Ident, status, data ast.Expr) *ast.ExprStmt { +func (def TemplateName) executeCall(templatesVariable *ast.Ident, status, data ast.Expr) *ast.ExprStmt { return &ast.ExprStmt{X: &ast.CallExpr{ Fun: ast.NewIdent(executeIdentName), Args: []ast.Expr{ - ast.NewIdent(PatternScopeIdentifierHTTPResponse), - ast.NewIdent(PatternScopeIdentifierHTTPRequest), + ast.NewIdent(TemplateNameScopeIdentifierHTTPResponse), + ast.NewIdent(TemplateNameScopeIdentifierHTTPRequest), &ast.CallExpr{ Fun: &ast.SelectorExpr{ X: ast.NewIdent(templatesVariable.Name), @@ -417,14 +417,14 @@ func (def Pattern) executeCall(templatesVariable *ast.Ident, status, data ast.Ex }} } -func (def Pattern) httpRequestReceiverTemplateHandlerFunc(templatesVariableName string) *ast.FuncLit { +func (def TemplateName) httpRequestReceiverTemplateHandlerFunc(templatesVariableName string) *ast.FuncLit { return &ast.FuncLit{ Type: httpHandlerFuncType(), - Body: &ast.BlockStmt{List: []ast.Stmt{def.executeCall(ast.NewIdent(templatesVariableName), httpStatusCode(httpStatusCode200Ident), ast.NewIdent(PatternScopeIdentifierHTTPRequest))}}, + Body: &ast.BlockStmt{List: []ast.Stmt{def.executeCall(ast.NewIdent(templatesVariableName), httpStatusCode(httpStatusCode200Ident), ast.NewIdent(TemplateNameScopeIdentifierHTTPRequest))}}, } } -func (def Pattern) matchReceiver(funcDecl *ast.FuncDecl, receiverTypeIdent string) bool { +func (def TemplateName) matchReceiver(funcDecl *ast.FuncDecl, receiverTypeIdent string) bool { if funcDecl == nil || funcDecl.Name == nil || funcDecl.Name.Name != def.fun.Name || funcDecl.Recv == nil || len(funcDecl.Recv.List) < 1 { return false diff --git a/generate_internal_test.go b/generate_internal_test.go index 36f8c81..579b3bb 100644 --- a/generate_internal_test.go +++ b/generate_internal_test.go @@ -10,7 +10,7 @@ import ( "github.com/crhntr/muxt/internal/source" ) -func TestPattern_funcLit(t *testing.T) { +func TestTemplateName_funcLit(t *testing.T) { for _, tt := range []struct { Name string In string @@ -102,7 +102,7 @@ func TestPattern_funcLit(t *testing.T) { }, } { t.Run(tt.Name, func(t *testing.T) { - pat, err, ok := NewPattern(tt.In) + pat, err, ok := NewTemplateName(tt.In) require.True(t, ok) require.NoError(t, err) tv := "templates" @@ -113,7 +113,7 @@ func TestPattern_funcLit(t *testing.T) { } } -func TestPattern_HandlerFuncLit_err(t *testing.T) { +func TestTemplateName_HandlerFuncLit_err(t *testing.T) { for _, tt := range []struct { Name string In string @@ -209,7 +209,7 @@ func TestPattern_HandlerFuncLit_err(t *testing.T) { }, } { t.Run(tt.Name, func(t *testing.T) { - pat, err, ok := NewPattern(tt.In) + pat, err, ok := NewTemplateName(tt.In) require.True(t, ok) require.NoError(t, err) tv := "templates" diff --git a/generate_test.go b/generate_test.go index caeaf00..599bace 100644 --- a/generate_test.go +++ b/generate_test.go @@ -369,12 +369,12 @@ func execute(response http.ResponseWriter, request *http.Request, t *template.Te } { t.Run(tt.Name, func(t *testing.T) { ts := template.Must(template.New(tt.Name).Parse(tt.Templates)) - patterns, err := muxt.TemplatePatterns(ts) + templateNames, err := muxt.TemplateNames(ts) require.NoError(t, err) logs := log.New(io.Discard, "", 0) set := token.NewFileSet() goFiles := methodFuncTypeLoader(t, set, tt.ReceiverPackage) - out, err := muxt.Generate(patterns, tt.PackageName, tt.TemplatesVar, tt.RoutesFunc, tt.Receiver, set, goFiles, goFiles, logs) + out, err := muxt.Generate(templateNames, tt.PackageName, tt.TemplatesVar, tt.RoutesFunc, tt.Receiver, set, goFiles, goFiles, logs) if tt.ExpectedError == "" { assert.NoError(t, err) assert.Equal(t, tt.ExpectedFile, out) diff --git a/internal/source/template.go b/internal/source/template.go index f491d63..1de0733 100644 --- a/internal/source/template.go +++ b/internal/source/template.go @@ -114,13 +114,13 @@ func parseTemplates(workingDirectory, templatesVariable, templatesPackageIdent s if err != nil { return nil, err } - patterns, err := parseStringLiterals(workingDirectory, fileSet, call.Args[1:]) + templateNames, err := parseStringLiterals(workingDirectory, fileSet, call.Args[1:]) if err != nil { return nil, err } filtered := matches[:0] for _, ef := range matches { - for j, pattern := range patterns { + for j, pattern := range templateNames { match, err := filepath.Match(pattern, ef) if err != nil { return nil, contextError(workingDirectory, fileSet, call.Args[j+1].Pos(), fmt.Errorf("bad pattern %q: %w", pattern, err)) @@ -164,11 +164,11 @@ func embedFSFilepaths(dir string, fileSet *token.FileSet, files []*ast.File, exp } var comment strings.Builder commentNode := readComments(&comment, decl.Doc, spec.Doc) - patterns, err := parsePatterns(comment.String()) + templateNames, err := parseTemplateNames(comment.String()) if err != nil { return nil, err } - absMat, err := embeddedFilesMatchingPatternList(dir, fileSet, commentNode, patterns, embeddedFiles) + absMat, err := embeddedFilesMatchingTemplateNameList(dir, fileSet, commentNode, templateNames, embeddedFiles) if err != nil { return nil, err } @@ -178,10 +178,10 @@ func embedFSFilepaths(dir string, fileSet *token.FileSet, files []*ast.File, exp return nil, fmt.Errorf("variable %s not found", fsIdent.Name) } -func embeddedFilesMatchingPatternList(dir string, set *token.FileSet, comment ast.Node, patterns, embeddedFiles []string) ([]string, error) { +func embeddedFilesMatchingTemplateNameList(dir string, set *token.FileSet, comment ast.Node, templateNames, embeddedFiles []string) ([]string, error) { var matches []string for _, fp := range embeddedFiles { - for _, pattern := range patterns { + for _, pattern := range templateNames { pat := filepath.FromSlash(pattern) if !strings.ContainsAny(pat, "*[]") { prefix := filepath.FromSlash(pat + "/") @@ -221,13 +221,13 @@ func readComments(s *strings.Builder, groups ...*ast.CommentGroup) ast.Node { return n } -func parsePatterns(input string) ([]string, error) { +func parseTemplateNames(input string) ([]string, error) { // todo: refactor to use strconv.QuotedPrefix var ( - patterns []string - currentPattern strings.Builder - inQuote = false - quoteChar rune + templateNames []string + currentTemplateName strings.Builder + inQuote = false + quoteChar rune ) for _, r := range input { @@ -239,32 +239,32 @@ func parsePatterns(input string) ([]string, error) { continue } if r != quoteChar { - currentPattern.WriteRune(r) + currentTemplateName.WriteRune(r) continue } - patterns = append(patterns, currentPattern.String()) - currentPattern.Reset() + templateNames = append(templateNames, currentTemplateName.String()) + currentTemplateName.Reset() inQuote = false case unicode.IsSpace(r): if inQuote { - currentPattern.WriteRune(r) + currentTemplateName.WriteRune(r) continue } - if currentPattern.Len() > 0 { - patterns = append(patterns, currentPattern.String()) - currentPattern.Reset() + if currentTemplateName.Len() > 0 { + templateNames = append(templateNames, currentTemplateName.String()) + currentTemplateName.Reset() } default: - currentPattern.WriteRune(r) + currentTemplateName.WriteRune(r) } } // Add any remaining pattern - if currentPattern.Len() > 0 { - patterns = append(patterns, currentPattern.String()) + if currentTemplateName.Len() > 0 { + templateNames = append(templateNames, currentTemplateName.String()) } - return patterns, nil + return templateNames, nil } func contextError(workingDirectory string, set *token.FileSet, pos token.Pos, err error) error { diff --git a/internal/source/template_internal_test.go b/internal/source/template_internal_test.go index 2783a01..78f2016 100644 --- a/internal/source/template_internal_test.go +++ b/internal/source/template_internal_test.go @@ -7,7 +7,7 @@ import ( "github.com/stretchr/testify/require" ) -func Test_parsePatterns(t *testing.T) { +func Test_parseTemplateNames(t *testing.T) { for _, tt := range []struct { name string input string @@ -40,7 +40,7 @@ func Test_parsePatterns(t *testing.T) { }, } { t.Run(tt.name, func(t *testing.T) { - result, err := parsePatterns(tt.input) + result, err := parseTemplateNames(tt.input) require.NoError(t, err) assert.EqualValues(t, tt.expected, result) }) diff --git a/pattern.go b/pattern.go index 466d457..f12f7ad 100644 --- a/pattern.go +++ b/pattern.go @@ -15,28 +15,28 @@ import ( "github.com/crhntr/muxt/internal/source" ) -func TemplatePatterns(ts *template.Template) ([]Pattern, error) { - var patterns []Pattern +func TemplateNames(ts *template.Template) ([]TemplateName, error) { + var templateNames []TemplateName routes := make(map[string]struct{}) for _, t := range ts.Templates() { - pat, err, ok := NewPattern(t.Name()) + pat, err, ok := NewTemplateName(t.Name()) if !ok { continue } if err != nil { - return patterns, err + return templateNames, err } if _, exists := routes[pat.Method+pat.Path]; exists { - return patterns, fmt.Errorf("duplicate route pattern: %s", pat.Route) + return templateNames, fmt.Errorf("duplicate route pattern: %s", pat.Route) } routes[pat.Method+pat.Path] = struct{}{} - patterns = append(patterns, pat) + templateNames = append(templateNames, pat) } - slices.SortFunc(patterns, Pattern.byPathThenMethod) - return patterns, nil + slices.SortFunc(templateNames, TemplateName.byPathThenMethod) + return templateNames, nil } -type Pattern struct { +type TemplateName struct { name string Method, Host, Path, Route string Handler string @@ -47,12 +47,12 @@ type Pattern struct { pathValueNames []string } -func NewPattern(in string) (Pattern, error, bool) { +func NewTemplateName(in string) (TemplateName, error, bool) { if !templateNameMux.MatchString(in) { - return Pattern{}, nil, false + return TemplateName{}, nil, false } matches := templateNameMux.FindStringSubmatch(in) - p := Pattern{ + p := TemplateName{ name: in, Method: matches[templateNameMux.SubexpIndex("Method")], Host: matches[templateNameMux.SubexpIndex("Host")], @@ -69,11 +69,11 @@ func NewPattern(in string) (Pattern, error, bool) { names, err := p.parsePathValueNames() if err != nil { - return Pattern{}, err, true + return TemplateName{}, err, true } p.pathValueNames = names if err := checkPathValueNames(p.pathValueNames); err != nil { - return Pattern{}, err, true + return TemplateName{}, err, true } return p, parseHandler(&p), true @@ -84,7 +84,7 @@ var ( templateNameMux = regexp.MustCompile(`^(?P(((?P[A-Z]+)\s+)?)(?P([^/])*)(?P(/(\S)*)))(?P.*)$`) ) -func (def Pattern) parsePathValueNames() ([]string, error) { +func (def TemplateName) parsePathValueNames() ([]string, error) { var result []string for _, match := range pathSegmentPattern.FindAllStringSubmatch(def.Path, strings.Count(def.Path, "/")) { n := match[1] @@ -112,13 +112,10 @@ func checkPathValueNames(in []string) error { return nil } -func (def Pattern) String() string { return def.name } -func (def Pattern) PathValueNames() []string { return def.pathValueNames } -func (def Pattern) CallExpr() *ast.CallExpr { return def.call } -func (def Pattern) FunIdent() *ast.Ident { return def.fun } -func (def Pattern) sameRoute(p Pattern) bool { return def.Route == p.Route } +func (def TemplateName) String() string { return def.name } +func (def TemplateName) sameRoute(p TemplateName) bool { return def.Route == p.Route } -func (def Pattern) byPathThenMethod(d Pattern) int { +func (def TemplateName) byPathThenMethod(d TemplateName) int { if n := cmp.Compare(def.Path, d.Path); n != 0 { return n } @@ -128,7 +125,7 @@ func (def Pattern) byPathThenMethod(d Pattern) int { return cmp.Compare(def.Handler, d.Handler) } -func parseHandler(def *Pattern) error { +func parseHandler(def *TemplateName) error { if def.Handler == "" { return nil } @@ -166,19 +163,19 @@ func parseHandler(def *Pattern) error { } const ( - PatternScopeIdentifierHTTPRequest = "request" - PatternScopeIdentifierHTTPResponse = "response" - PatternScopeIdentifierContext = "ctx" - PatternScopeIdentifierTemplate = "template" - PatternScopeIdentifierLogger = "logger" + TemplateNameScopeIdentifierHTTPRequest = "request" + TemplateNameScopeIdentifierHTTPResponse = "response" + TemplateNameScopeIdentifierContext = "ctx" + TemplateNameScopeIdentifierTemplate = "template" + TemplateNameScopeIdentifierLogger = "logger" ) func patternScope() []string { return []string{ - PatternScopeIdentifierHTTPRequest, - PatternScopeIdentifierHTTPResponse, - PatternScopeIdentifierContext, - PatternScopeIdentifierTemplate, - PatternScopeIdentifierLogger, + TemplateNameScopeIdentifierHTTPRequest, + TemplateNameScopeIdentifierHTTPResponse, + TemplateNameScopeIdentifierContext, + TemplateNameScopeIdentifierTemplate, + TemplateNameScopeIdentifierLogger, } } diff --git a/pattern_internal_test.go b/pattern_internal_test.go index f5a72c8..9605abf 100644 --- a/pattern_internal_test.go +++ b/pattern_internal_test.go @@ -10,7 +10,7 @@ import ( func TestTemplateName_ByPathThenMethod(t *testing.T) { for _, tt := range []struct { Name string - In, Exp []Pattern + In, Exp []TemplateName }{ { Name: "sort by path then method", @@ -85,16 +85,16 @@ func TestTemplateName_ByPathThenMethod(t *testing.T) { }, } { t.Run(tt.Name, func(t *testing.T) { - slices.SortFunc(tt.In, Pattern.byPathThenMethod) + slices.SortFunc(tt.In, TemplateName.byPathThenMethod) assert.Equal(t, tt.Exp, tt.In) }) } } -func mustNewTemplateName(in ...string) []Pattern { - var result []Pattern +func mustNewTemplateName(in ...string) []TemplateName { + var result []TemplateName for _, n := range in { - p, err, _ := NewPattern(n) + p, err, _ := NewTemplateName(n) if err != nil { panic(err) } diff --git a/pattern_test.go b/pattern_test.go index b57b43a..1b76578 100644 --- a/pattern_test.go +++ b/pattern_test.go @@ -11,33 +11,33 @@ import ( "github.com/crhntr/muxt" ) -func TestTemplatePatterns(t *testing.T) { +func TestTemplateNames(t *testing.T) { t.Run("when one of the template names is a malformed pattern", func(t *testing.T) { ts := template.Must(template.New("").Parse(`{{define "HEAD /"}}{{end}}`)) - _, err := muxt.TemplatePatterns(ts) + _, err := muxt.TemplateNames(ts) require.Error(t, err) }) t.Run("when the pattern is not unique", func(t *testing.T) { ts := template.Must(template.New("").Parse(`{{define "GET / F1()"}}a{{end}} {{define "GET / F2()"}}b{{end}}`)) - _, err := muxt.TemplatePatterns(ts) + _, err := muxt.TemplateNames(ts) require.Error(t, err) }) } -func TestNewPattern(t *testing.T) { +func TestNewTemplateName(t *testing.T) { for _, tt := range []struct { Name string - TemplateName string + In string ExpMatch bool - Pattern func(t *testing.T, pat muxt.Pattern) + TemplateName func(t *testing.T, pat muxt.TemplateName) Error func(t *testing.T, err error) }{ { - Name: "get root", - TemplateName: "GET /", - ExpMatch: true, - Pattern: func(t *testing.T, pat muxt.Pattern) { - assert.EqualExportedValues(t, muxt.Pattern{ + Name: "get root", + In: "GET /", + ExpMatch: true, + TemplateName: func(t *testing.T, pat muxt.TemplateName) { + assert.EqualExportedValues(t, muxt.TemplateName{ Method: http.MethodGet, Host: "", Path: "/", @@ -47,11 +47,11 @@ func TestNewPattern(t *testing.T) { }, }, { - Name: "multiple spaces after method", - TemplateName: "GET /", - ExpMatch: true, - Pattern: func(t *testing.T, pat muxt.Pattern) { - assert.EqualExportedValues(t, muxt.Pattern{ + Name: "multiple spaces after method", + In: "GET /", + ExpMatch: true, + TemplateName: func(t *testing.T, pat muxt.TemplateName) { + assert.EqualExportedValues(t, muxt.TemplateName{ Method: http.MethodGet, Host: "", Path: "/", @@ -61,11 +61,11 @@ func TestNewPattern(t *testing.T) { }, }, { - Name: "post root", - TemplateName: "POST /", - ExpMatch: true, - Pattern: func(t *testing.T, pat muxt.Pattern) { - assert.EqualExportedValues(t, muxt.Pattern{ + Name: "post root", + In: "POST /", + ExpMatch: true, + TemplateName: func(t *testing.T, pat muxt.TemplateName) { + assert.EqualExportedValues(t, muxt.TemplateName{ Method: http.MethodPost, Host: "", Path: "/", @@ -75,11 +75,11 @@ func TestNewPattern(t *testing.T) { }, }, { - Name: "patch root", - TemplateName: "PATCH /", - ExpMatch: true, - Pattern: func(t *testing.T, pat muxt.Pattern) { - assert.EqualExportedValues(t, muxt.Pattern{ + Name: "patch root", + In: "PATCH /", + ExpMatch: true, + TemplateName: func(t *testing.T, pat muxt.TemplateName) { + assert.EqualExportedValues(t, muxt.TemplateName{ Method: http.MethodPatch, Host: "", Path: "/", @@ -89,11 +89,11 @@ func TestNewPattern(t *testing.T) { }, }, { - Name: "delete root", - TemplateName: "DELETE /", - ExpMatch: true, - Pattern: func(t *testing.T, pat muxt.Pattern) { - assert.EqualExportedValues(t, muxt.Pattern{ + Name: "delete root", + In: "DELETE /", + ExpMatch: true, + TemplateName: func(t *testing.T, pat muxt.TemplateName) { + assert.EqualExportedValues(t, muxt.TemplateName{ Method: http.MethodDelete, Host: "", Path: "/", @@ -103,11 +103,11 @@ func TestNewPattern(t *testing.T) { }, }, { - Name: "put root", - TemplateName: "PUT /", - ExpMatch: true, - Pattern: func(t *testing.T, pat muxt.Pattern) { - assert.EqualExportedValues(t, muxt.Pattern{ + Name: "put root", + In: "PUT /", + ExpMatch: true, + TemplateName: func(t *testing.T, pat muxt.TemplateName) { + assert.EqualExportedValues(t, muxt.TemplateName{ Method: http.MethodPut, Host: "", Path: "/", @@ -117,11 +117,11 @@ func TestNewPattern(t *testing.T) { }, }, { - Name: "with end of path wildcard", - TemplateName: "PUT /ping/pong/{$}", - ExpMatch: true, - Pattern: func(t *testing.T, pat muxt.Pattern) { - assert.EqualExportedValues(t, muxt.Pattern{ + Name: "with end of path wildcard", + In: "PUT /ping/pong/{$}", + ExpMatch: true, + TemplateName: func(t *testing.T, pat muxt.TemplateName) { + assert.EqualExportedValues(t, muxt.TemplateName{ Method: http.MethodPut, Host: "", Path: "/ping/pong/{$}", @@ -131,52 +131,52 @@ func TestNewPattern(t *testing.T) { }, }, { - Name: "put root", - TemplateName: "OPTIONS /", - ExpMatch: true, + Name: "put root", + In: "OPTIONS /", + ExpMatch: true, Error: func(t *testing.T, err error) { assert.ErrorContains(t, err, "OPTIONS method not allowed") }, }, { - Name: "path parameter is not an identifier", - TemplateName: "GET /{123} F(123)", - ExpMatch: true, + Name: "path parameter is not an identifier", + In: "GET /{123} F(123)", + ExpMatch: true, Error: func(t *testing.T, err error) { assert.ErrorContains(t, err, `path parameter name not permitted: "123" is not a Go identifier`) }, }, { - Name: "path end sentential in the middle is not permitted", - TemplateName: "GET /x/{$}/y F()", - ExpMatch: true, + Name: "path end sentential in the middle is not permitted", + In: "GET /x/{$}/y F()", + ExpMatch: true, Error: func(t *testing.T, err error) { assert.ErrorContains(t, err, `path parameter name not permitted: "$" is not a Go identifier`) }, }, { Name: "path end sentential in the middle is not permitted", - TemplateName: "GET /x/{$} F()", + In: "GET /x/{$} F()", ExpMatch: true, - Pattern: func(t *testing.T, pat muxt.Pattern) {}, + TemplateName: func(t *testing.T, pat muxt.TemplateName) {}, }, { - Name: "duplicate path parameter name", - TemplateName: "GET /{name}/{name} F()", - ExpMatch: true, + Name: "duplicate path parameter name", + In: "GET /{name}/{name} F()", + ExpMatch: true, Error: func(t *testing.T, err error) { assert.ErrorContains(t, err, `forbidden repeated path parameter names: found at least 2 path parameters with name "name"`) }, }, } { t.Run(tt.Name, func(t *testing.T) { - pat, err, match := muxt.NewPattern(tt.TemplateName) + pat, err, match := muxt.NewTemplateName(tt.In) require.Equal(t, tt.ExpMatch, match) if tt.Error != nil { tt.Error(t, err) - } else if tt.Pattern != nil { + } else if tt.TemplateName != nil { assert.NoError(t, err) - tt.Pattern(t, pat) + tt.TemplateName(t, pat) } }) } @@ -218,7 +218,7 @@ func TestPattern_parseHandler(t *testing.T) { }, } { t.Run(tt.Name, func(t *testing.T) { - p, err, ok := muxt.NewPattern(tt.In) + p, err, ok := muxt.NewTemplateName(tt.In) require.True(t, ok) require.NotZero(t, p.Handler) if tt.ExpErr != "" {