From 65ef1fb08b07c68245e5a3a5cb9f7e80ea502ceb Mon Sep 17 00:00:00 2001 From: ericlugo Date: Fri, 3 May 2024 15:23:14 -0400 Subject: [PATCH] Add sortable ServiceMethods for template use with requisite unit tests --- renderer.go | 6 ++++-- template.go | 16 ++++++++++++++++ template_test.go | 16 ++++++++++++++++ 3 files changed, 36 insertions(+), 2 deletions(-) diff --git a/renderer.go b/renderer.go index eba74c5f..e440d7dc 100644 --- a/renderer.go +++ b/renderer.go @@ -90,10 +90,10 @@ type Processor interface { // supplying a non-empty string as the last parameter. // // Example: generating an HTML template (assuming you've got a Template object) -// data, err := RenderTemplate(RenderTypeHTML, &template, "") +// data, err := RenderTemplate(RenderTypeHTML, &template, "") // // Example: generating a custom template (assuming you've got a Template object) -// data, err := RenderTemplate(RenderTypeHTML, &template, "{{range .Files}}{{.Name}}{{end}}") +// data, err := RenderTemplate(RenderTypeHTML, &template, "{{range .Files}}{{.Name}}{{end}}") func RenderTemplate(kind RenderType, template *Template, inputTemplate string) ([]byte, error) { if inputTemplate != "" { processor := &textRenderer{inputTemplate} @@ -113,6 +113,7 @@ type textRenderer struct { } func (mr *textRenderer) Apply(template *Template) ([]byte, error) { + funcMap["SortServiceMethods"] = SortServiceMethods tmpl, err := text_template.New("Text Template").Funcs(funcMap).Funcs(sprig.TxtFuncMap()).Parse(mr.inputTemplate) if err != nil { return nil, err @@ -131,6 +132,7 @@ type htmlRenderer struct { } func (mr *htmlRenderer) Apply(template *Template) ([]byte, error) { + funcMap["SortServiceMethods"] = SortServiceMethods tmpl, err := html_template.New("Text Template").Funcs(funcMap).Funcs(sprig.HtmlFuncMap()).Parse(mr.inputTemplate) if err != nil { return nil, err diff --git a/template.go b/template.go index 9edaac72..287ede5f 100644 --- a/template.go +++ b/template.go @@ -18,6 +18,7 @@ type Template struct { Files []*File `json:"files"` // Details about the scalar values and their respective types in supported languages. Scalars []*ScalarValue `json:"scalarValueTypes"` + // Function Map usable within Templates } // NewTemplate creates a Template object from a set of descriptors. @@ -534,6 +535,15 @@ func parseServiceMethod(pm *protokit.MethodDescriptor) *ServiceMethod { } } +func SortServiceMethods(methods []*ServiceMethod) orderedMethods { + sortedMethods := make(orderedMethods, 0, len(methods)) + for _, method := range methods { + sortedMethods = append(sortedMethods, method) + } + sort.Sort(sortedMethods) + return sortedMethods +} + func baseName(name string) string { parts := strings.Split(name, ".") return parts[len(parts)-1] @@ -597,3 +607,9 @@ type orderedServices []*Service func (os orderedServices) Len() int { return len(os) } func (os orderedServices) Swap(i, j int) { os[i], os[j] = os[j], os[i] } func (os orderedServices) Less(i, j int) bool { return os[i].LongName < os[j].LongName } + +type orderedMethods []*ServiceMethod + +func (om orderedMethods) Len() int { return len(om) } +func (om orderedMethods) Swap(i, j int) { om[i], om[j] = om[j], om[i] } +func (om orderedMethods) Less(i, j int) bool { return om[i].Name < om[j].Name } diff --git a/template_test.go b/template_test.go index 717919b2..758df655 100644 --- a/template_test.go +++ b/template_test.go @@ -426,6 +426,22 @@ func TestServiceMethodProperties(t *testing.T) { require.True(t, *method.Option(E_ExtendMethod.Name).(*bool)) } +func TestServiceMethodSorting(t *testing.T) { + service := findService("VehicleService", vehicleFile) + + // verify 'by file' order by default + unsortedMethods := service.Methods + require.Equal(t, "GetModels", unsortedMethods[0].Name) + require.Equal(t, "AddModels", unsortedMethods[1].Name) + require.Equal(t, "GetVehicle", unsortedMethods[2].Name) + + // verify 'a-z' order when sorted + sortedMethods := SortServiceMethods(service.Methods) + require.Equal(t, "AddModels", sortedMethods[0].Name) + require.Equal(t, "GetModels", sortedMethods[1].Name) + require.Equal(t, "GetVehicle", sortedMethods[2].Name) +} + func TestExcludedComments(t *testing.T) { message := findMessage("ExcludedMessage", vehicleFile) require.Empty(t, message.Description)