123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369 |
- package test
- import (
- "fmt"
- "io/ioutil"
- "os"
- "path/filepath"
- "testing"
- "github.com/stretchr/testify/assert"
- "github.com/tal-tech/go-zero/tools/goctl/api/parser/g4/ast"
- )
- var (
- normalAPI = `
- syntax="v1"
-
- info (
- foo: bar
- )
- type Foo {
- Bar int
- }
- @server(
- foo: bar
- )
- service foo-api{
- @doc("foo")
- @handler foo
- post /foo (Foo) returns ([]int)
- }
- `
- missDeclarationAPI = `
- @server(
- foo: bar
- )
- service foo-api{
- @doc("foo")
- @handler foo
- post /foo (Foo) returns (Foo)
- }
- `
- missDeclarationInArrayAPI = `
- @server(
- foo: bar
- )
- service foo-api{
- @doc("foo")
- @handler foo
- post /foo returns ([]Foo)
- }
- `
- missDeclarationInArrayAPI2 = `
- @server(
- foo: bar
- )
- service foo-api{
- @doc("foo")
- @handler foo
- post /foo returns ([]*Foo)
- }
- `
- nestedAPIImport = `
- import "foo.api"
- `
- ambiguousSyntax = `
- syntax = "v2"
- `
- ambiguousService = `
- service bar-api{
- @handler foo
- post /foo
- }
- `
- duplicateHandler = `
- service bar-api{
- @handler foo
- post /foo
- }
- `
- duplicateRoute = `
- service bar-api{
- @handler bar
- post /foo
- }
- `
- duplicateType = `
- type Foo int
- `
- )
- func TestApiParser(t *testing.T) {
- t.Run("missDeclarationAPI", func(t *testing.T) {
- _, err := parser.ParseContent(missDeclarationAPI)
- assert.Error(t, err)
- fmt.Printf("%+v\n", err)
- })
- t.Run("missDeclarationAPI", func(t *testing.T) {
- _, err := parser.ParseContent(missDeclarationInArrayAPI)
- assert.Error(t, err)
- fmt.Printf("%+v\n", err)
- })
- t.Run("missDeclarationAPI", func(t *testing.T) {
- _, err := parser.ParseContent(missDeclarationInArrayAPI2)
- assert.Error(t, err)
- fmt.Printf("%+v\n", err)
- })
- t.Run("nestedImport", func(t *testing.T) {
- file := filepath.Join(t.TempDir(), "foo.api")
- err := ioutil.WriteFile(file, []byte(nestedAPIImport), os.ModePerm)
- if err != nil {
- return
- }
- _, err = parser.ParseContent(fmt.Sprintf(`import "%s"`, file))
- assert.Error(t, err)
- fmt.Printf("%+v\n", err)
- })
- t.Run("duplicateImport", func(t *testing.T) {
- _, err := parser.ParseContent(`
- import "foo.api"
- import "foo.api"
- `)
- assert.Error(t, err)
- })
- t.Run("duplicateKey", func(t *testing.T) {
- _, err := parser.ParseContent(`
- info (
- foo: bar
- foo: bar
- )
- `)
- assert.Error(t, err)
- })
- t.Run("ambiguousSyntax", func(t *testing.T) {
- file := filepath.Join(t.TempDir(), "foo.api")
- err := ioutil.WriteFile(file, []byte(ambiguousSyntax), os.ModePerm)
- if err != nil {
- return
- }
- _, err = parser.ParseContent(fmt.Sprintf(`
- syntax = "v1"
- import "%s"`, file))
- assert.Error(t, err)
- fmt.Printf("%+v\n", err)
- })
- t.Run("ambiguousSyntax", func(t *testing.T) {
- file := filepath.Join(t.TempDir(), "foo.api")
- err := ioutil.WriteFile(file, []byte(ambiguousSyntax), os.ModePerm)
- if err != nil {
- return
- }
- _, err = parser.ParseContent(fmt.Sprintf(`
- syntax = "v1"
- import "%s"`, file))
- assert.Error(t, err)
- fmt.Printf("%+v\n", err)
- })
- t.Run("ambiguousService", func(t *testing.T) {
- file := filepath.Join(t.TempDir(), "foo.api")
- err := ioutil.WriteFile(file, []byte(ambiguousService), os.ModePerm)
- if err != nil {
- return
- }
- _, err = parser.ParseContent(fmt.Sprintf(`
- import "%s"
-
- service foo-api{
- @handler foo
- post /foo
- }
- `, file))
- assert.Error(t, err)
- fmt.Printf("%+v\n", err)
- })
- t.Run("duplicateHandler", func(t *testing.T) {
- _, err := parser.ParseContent(`
- service foo-api{
- @handler foo
- post /foo
-
- @handler foo
- post /bar
- }
- `)
- assert.Error(t, err)
- file := filepath.Join(t.TempDir(), "foo.api")
- err = ioutil.WriteFile(file, []byte(duplicateHandler), os.ModePerm)
- if err != nil {
- return
- }
- _, err = parser.ParseContent(fmt.Sprintf(`
- import "%s"
- service bar-api{
- @handler foo
- post /foo
- }
- `, file))
- assert.Error(t, err)
- fmt.Printf("%+v\n", err)
- })
- t.Run("duplicateRoute", func(t *testing.T) {
- _, err := parser.ParseContent(`
- service foo-api{
- @handler foo
- post /foo
-
- @handler bar
- post /foo
- }
- `)
- assert.Error(t, err)
- file := filepath.Join(t.TempDir(), "foo.api")
- err = ioutil.WriteFile(file, []byte(duplicateRoute), os.ModePerm)
- if err != nil {
- return
- }
- _, err = parser.ParseContent(fmt.Sprintf(`
- import "%s"
- service bar-api{
- @handler foo
- post /foo
- }
- `, file))
- assert.Error(t, err)
- fmt.Printf("%+v\n", err)
- })
- t.Run("duplicateType", func(t *testing.T) {
- _, err := parser.ParseContent(`
- type Foo int
- type Foo bool
- `)
- assert.Error(t, err)
- file := filepath.Join(t.TempDir(), "foo.api")
- err = ioutil.WriteFile(file, []byte(duplicateType), os.ModePerm)
- if err != nil {
- return
- }
- _, err = parser.ParseContent(fmt.Sprintf(`
- import "%s"
-
- type Foo bool
- `, file))
- assert.Error(t, err)
- fmt.Printf("%+v\n", err)
- })
- t.Run("normal", func(t *testing.T) {
- v, err := parser.ParseContent(normalAPI)
- assert.Nil(t, err)
- body := &ast.Body{
- Lp: ast.NewTextExpr("("),
- Rp: ast.NewTextExpr(")"),
- Name: &ast.Literal{Literal: ast.NewTextExpr("Foo")},
- }
- assert.True(t, v.Equal(&ast.Api{
- Syntax: &ast.SyntaxExpr{
- Syntax: ast.NewTextExpr("syntax"),
- Assign: ast.NewTextExpr("="),
- Version: ast.NewTextExpr(`"v1"`),
- },
- Info: &ast.InfoExpr{
- Info: ast.NewTextExpr("info"),
- Lp: ast.NewTextExpr("("),
- Rp: ast.NewTextExpr(")"),
- Kvs: []*ast.KvExpr{
- {
- Key: ast.NewTextExpr("foo"),
- Value: ast.NewTextExpr("bar"),
- },
- },
- },
- Type: []ast.TypeExpr{
- &ast.TypeStruct{
- Name: ast.NewTextExpr("Foo"),
- LBrace: ast.NewTextExpr("{"),
- RBrace: ast.NewTextExpr("}"),
- Fields: []*ast.TypeField{
- {
- Name: ast.NewTextExpr("Bar"),
- DataType: &ast.Literal{Literal: ast.NewTextExpr("int")},
- },
- },
- },
- },
- Service: []*ast.Service{
- {
- AtServer: &ast.AtServer{
- AtServerToken: ast.NewTextExpr("@server"),
- Lp: ast.NewTextExpr("("),
- Rp: ast.NewTextExpr(")"),
- Kv: []*ast.KvExpr{
- {
- Key: ast.NewTextExpr("foo"),
- Value: ast.NewTextExpr("bar"),
- },
- },
- },
- ServiceApi: &ast.ServiceApi{
- ServiceToken: ast.NewTextExpr("service"),
- Name: ast.NewTextExpr("foo-api"),
- Lbrace: ast.NewTextExpr("{"),
- Rbrace: ast.NewTextExpr("}"),
- ServiceRoute: []*ast.ServiceRoute{
- {
- AtDoc: &ast.AtDoc{
- AtDocToken: ast.NewTextExpr("@doc"),
- Lp: ast.NewTextExpr("("),
- Rp: ast.NewTextExpr(")"),
- LineDoc: ast.NewTextExpr(`"foo"`),
- },
- AtHandler: &ast.AtHandler{
- AtHandlerToken: ast.NewTextExpr("@handler"),
- Name: ast.NewTextExpr("foo"),
- },
- Route: &ast.Route{
- Method: ast.NewTextExpr("post"),
- Path: ast.NewTextExpr("/foo"),
- Req: body,
- ReturnToken: ast.NewTextExpr("returns"),
- Reply: &ast.Body{
- Lp: ast.NewTextExpr("("),
- Rp: ast.NewTextExpr(")"),
- Name: &ast.Array{
- ArrayExpr: ast.NewTextExpr("[]int"),
- LBrack: ast.NewTextExpr("["),
- RBrack: ast.NewTextExpr("]"),
- Literal: &ast.Literal{Literal: ast.NewTextExpr("int")},
- },
- },
- },
- },
- },
- },
- },
- },
- }))
- })
- }
|