Merge pull request #783 from Codexiaoyi/parse-config

add annotator to parse doc
This commit is contained in:
Ming Deng 2021-05-24 21:14:36 +08:00 committed by GitHub
commit 102d5f8cc9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 177 additions and 0 deletions

1
go.mod
View File

@ -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

68
parser/annotator.go Normal file
View File

@ -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{})
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
}

108
parser/annotator_test.go Normal file
View File

@ -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)
}
}