From 3e3b0359c084bf4f6ad1cf413eecf308ec957211 Mon Sep 17 00:00:00 2001 From: LinXiaoYi <874183200@qq.com> Date: Sun, 23 May 2021 20:16:20 +0800 Subject: [PATCH 1/2] add annotator to parse doc --- go.mod | 1 + parser/annotator.go | 68 ++++++++++++++++++++++++ parser/annotator_test.go | 108 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 177 insertions(+) create mode 100644 parser/annotator.go create mode 100644 parser/annotator_test.go diff --git a/go.mod b/go.mod index f6df31f..e4418a5 100644 --- a/go.mod +++ b/go.mod @@ -14,6 +14,7 @@ require ( github.com/pelletier/go-toml v1.8.1 github.com/smartwalle/pongo2render v1.0.1 github.com/spf13/viper v1.7.0 + github.com/stretchr/testify v1.4.0 golang.org/x/mod v0.4.2 // indirect golang.org/x/sys v0.0.0-20210507014357-30e306a8bba5 // indirect golang.org/x/tools v0.1.0 diff --git a/parser/annotator.go b/parser/annotator.go new file mode 100644 index 0000000..d2aa2fe --- /dev/null +++ b/parser/annotator.go @@ -0,0 +1,68 @@ +package beeParser + +import ( + "encoding/json" + "strings" +) + +type Annotator interface { + Annotate(string) []map[string]interface{} + AnnotateToJson(string) (string, error) +} + +type Annotation struct { +} + +func isWhitespace(ch byte) bool { return ch == ' ' || ch == '\t' || ch == '\r' } + +func handleHeadWhitespace(s string) string { + i := 0 + for i < len(s) && isWhitespace(s[i]) { + i++ + } + return s[i:] +} + +func handleTailWhitespace(s string) string { + i := len(s) + for i > 0 && isWhitespace(s[i-1]) { + i-- + } + return s[0:i] +} + +//handle value to remove head and tail space. +func handleWhitespaceValues(values []string) []string { + res := make([]string, 0) + for _, v := range values { + v = handleHeadWhitespace(v) + v = handleTailWhitespace(v) + res = append(res, v) + } + return res +} + +//parse annotation to generate array with key and values +//start with "@" as a key-value pair,key and values are separated by a space,wrap to distinguish values. +func (a *Annotation) Annotate(comment string) []map[string]interface{} { + results := make([]map[string]interface{}, 0) + //split annotation with '@' + lines := strings.Split(comment, "@") + //skip first line whitespace + for _, line := range lines[1:] { + kvs := strings.Split(line, " ") + key := kvs[0] + values := strings.Split(strings.TrimSpace(line[len(kvs[0]):]), "\n") + annotation := make(map[string]interface{}, 0) + annotation[key] = handleWhitespaceValues(values) + results = append(results, annotation) + } + return results +} + +//parse annotation to json +func (a *Annotation) AnnotateToJson(comment string) (string, error) { + annotate := a.Annotate(comment) + result, err := json.MarshalIndent(annotate, "", " ") + return string(result), err +} diff --git a/parser/annotator_test.go b/parser/annotator_test.go new file mode 100644 index 0000000..9436403 --- /dev/null +++ b/parser/annotator_test.go @@ -0,0 +1,108 @@ +package beeParser + +import ( + "os" + "testing" + + "github.com/stretchr/testify/assert" +) + +var BeeAnnotator Annotator + +const ( + Annotation1 = ` + @Name Field1 + @Type string + @Path https://github.com/beego/bee + https://github.com/beego + ` + Annotation2 = ` + @Number 2 + @Projects https://github.com/beego/bee + +https://github.com/beego + ` +) + +func TestMain(m *testing.M) { + BeeAnnotator = &Annotation{} + retCode := m.Run() //run test + os.Exit(retCode) +} + +func TestAnnotate(t *testing.T) { + expect1 := []map[string]interface{}{ + {"Name": []string{"Field1"}}, + {"Type": []string{"string"}}, + {"Path": []string{"https://github.com/beego/bee", "https://github.com/beego"}}, + } + + expect2 := []map[string]interface{}{ + {"Number": []string{"2"}}, + {"Projects": []string{"https://github.com/beego/bee", "", "https://github.com/beego"}}, + } + + actual := BeeAnnotator.Annotate(Annotation1) + actual2 := BeeAnnotator.Annotate(Annotation2) + + assert.Equal(t, expect1, actual) + assert.Equal(t, expect2, actual2) +} + +func TestAnnotateToJson(t *testing.T) { + expect := `[ + { + "Name": [ + "Field1" + ] + }, + { + "Type": [ + "string" + ] + }, + { + "Path": [ + "https://github.com/beego/bee", + "https://github.com/beego" + ] + } +]` + + actual, _ := BeeAnnotator.AnnotateToJson(Annotation1) + + assert.Equal(t, expect, actual) +} + +func TestHandleWhitespaceValues(t *testing.T) { + src := []string{ + " beego", + "", + " bee ", + " bee beego ", + } + + expect := []string{ + "beego", + "", + "bee", + "bee beego", + } + + actual := handleWhitespaceValues(src) + + assert.Equal(t, expect, actual) +} + +//benchmark test +func BenchmarkAnnotate(b *testing.B) { + for i := 0; i < b.N; i++ { + BeeAnnotator.Annotate(Annotation1) + } +} + +func BenchmarkAnnotateToJson(b *testing.B) { + for i := 0; i < b.N; i++ { + BeeAnnotator.AnnotateToJson(Annotation1) + } +} From 965e4d88032586dffb146e424c2c67248e542c72 Mon Sep 17 00:00:00 2001 From: LinXiaoYi <874183200@qq.com> Date: Sun, 23 May 2021 22:11:48 +0800 Subject: [PATCH 2/2] fix map init --- parser/annotator.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/parser/annotator.go b/parser/annotator.go index d2aa2fe..4822e4b 100644 --- a/parser/annotator.go +++ b/parser/annotator.go @@ -53,7 +53,7 @@ func (a *Annotation) Annotate(comment string) []map[string]interface{} { kvs := strings.Split(line, " ") key := kvs[0] values := strings.Split(strings.TrimSpace(line[len(kvs[0]):]), "\n") - annotation := make(map[string]interface{}, 0) + annotation := make(map[string]interface{}) annotation[key] = handleWhitespaceValues(values) results = append(results, annotation) }