gen_test.go 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332
  1. package gogen
  2. import (
  3. goformat "go/format"
  4. "io/ioutil"
  5. "os"
  6. "path/filepath"
  7. "strings"
  8. "testing"
  9. "github.com/stretchr/testify/assert"
  10. "github.com/tal-tech/go-zero/tools/goctl/api/parser"
  11. )
  12. const testApiTemplate = `
  13. info(
  14. title: doc title
  15. desc: >
  16. doc description first part,
  17. doc description second part<
  18. version: 1.0
  19. )
  20. type Request struct {
  21. Name string ` + "`" + `path:"name,options=you|me"` + "`" + `
  22. }
  23. type Response struct {
  24. Message string ` + "`" + `json:"message"` + "`" + `
  25. }
  26. service A-api {
  27. @server(
  28. handler: GreetHandler
  29. )
  30. get /greet/from/:name(Request) returns (Response)
  31. @server(
  32. handler: NoResponseHandler
  33. )
  34. get /greet/get(Request) returns
  35. }
  36. `
  37. const testMultiServiceTemplate = `
  38. info(
  39. title: doc title
  40. desc: >
  41. doc description first part,
  42. doc description second part<
  43. version: 1.0
  44. )
  45. type Request struct {
  46. Name string ` + "`" + `path:"name,options=you|me"` + "`" + `
  47. }
  48. type Response struct {
  49. Message string ` + "`" + `json:"message"` + "`" + `
  50. }
  51. service A-api {
  52. @server(
  53. handler: GreetHandler
  54. )
  55. get /greet/from/:name(Request) returns (Response)
  56. }
  57. service A-api {
  58. @server(
  59. handler: NoResponseHandler
  60. )
  61. get /greet/get(Request) returns
  62. }
  63. `
  64. const apiNoInfo = `
  65. type Request struct {
  66. Name string ` + "`" + `path:"name,options=you|me"` + "`" + `
  67. }
  68. type Response struct {
  69. Message string ` + "`" + `json:"message"` + "`" + `
  70. }
  71. service A-api {
  72. @server(
  73. handler: GreetHandler
  74. )
  75. get /greet/from/:name(Request) returns (Response)
  76. }
  77. `
  78. const invalidApiFile = `
  79. type Request struct {
  80. Name string ` + "`" + `path:"name,options=you|me"` + "`" + `
  81. }
  82. type Response struct {
  83. Message string ` + "`" + `json:"message"` + "`" + `
  84. }
  85. service A-api
  86. @server(
  87. handler: GreetHandler
  88. )
  89. get /greet/from/:name(Request) returns (Response)
  90. }
  91. `
  92. const anonymousAnnotation = `
  93. type Request struct {
  94. Name string ` + "`" + `path:"name,options=you|me"` + "`" + `
  95. }
  96. type Response struct {
  97. Message string ` + "`" + `json:"message"` + "`" + `
  98. }
  99. service A-api {
  100. @handler GreetHandler
  101. get /greet/from/:name(Request) returns (Response)
  102. }
  103. `
  104. const apiHasMiddleware = `
  105. type Request struct {
  106. Name string ` + "`" + `path:"name,options=you|me"` + "`" + `
  107. }
  108. type Response struct {
  109. Message string ` + "`" + `json:"message"` + "`" + `
  110. }
  111. @server(
  112. middleware: TokenValidate
  113. )
  114. service A-api {
  115. @handler GreetHandler
  116. get /greet/from/:name(Request) returns (Response)
  117. }
  118. `
  119. const apiJwt = `
  120. type Request struct {
  121. Name string ` + "`" + `path:"name,options=you|me"` + "`" + `
  122. }
  123. type Response struct {
  124. Message string ` + "`" + `json:"message"` + "`" + `
  125. }
  126. @server(
  127. jwt: Auth
  128. )
  129. service A-api {
  130. @handler GreetHandler
  131. get /greet/from/:name(Request) returns (Response)
  132. }
  133. `
  134. const apiJwtWithMiddleware = `
  135. type Request struct {
  136. Name string ` + "`" + `path:"name,options=you|me"` + "`" + `
  137. }
  138. type Response struct {
  139. Message string ` + "`" + `json:"message"` + "`" + `
  140. }
  141. @server(
  142. jwt: Auth
  143. middleware: TokenValidate
  144. )
  145. service A-api {
  146. @handler GreetHandler
  147. get /greet/from/:name(Request) returns (Response)
  148. }
  149. `
  150. func TestParser(t *testing.T) {
  151. filename := "greet.api"
  152. err := ioutil.WriteFile(filename, []byte(testApiTemplate), os.ModePerm)
  153. assert.Nil(t, err)
  154. defer os.Remove(filename)
  155. parser, err := parser.NewParser(filename)
  156. assert.Nil(t, err)
  157. api, err := parser.Parse()
  158. assert.Nil(t, err)
  159. assert.Equal(t, len(api.Types), 2)
  160. assert.Equal(t, len(api.Service.Routes), 2)
  161. assert.Equal(t, api.Service.Routes[0].Path, "/greet/from/:name")
  162. assert.Equal(t, api.Service.Routes[1].Path, "/greet/get")
  163. assert.Equal(t, api.Service.Routes[1].RequestType.Name, "Request")
  164. assert.Equal(t, api.Service.Routes[1].ResponseType.Name, "")
  165. validate(t, filename)
  166. }
  167. func TestMultiService(t *testing.T) {
  168. filename := "greet.api"
  169. err := ioutil.WriteFile(filename, []byte(testMultiServiceTemplate), os.ModePerm)
  170. assert.Nil(t, err)
  171. defer os.Remove(filename)
  172. parser, err := parser.NewParser(filename)
  173. assert.Nil(t, err)
  174. api, err := parser.Parse()
  175. assert.Nil(t, err)
  176. assert.Equal(t, len(api.Service.Routes), 2)
  177. assert.Equal(t, len(api.Service.Groups), 2)
  178. validate(t, filename)
  179. }
  180. func TestApiNoInfo(t *testing.T) {
  181. filename := "greet.api"
  182. err := ioutil.WriteFile(filename, []byte(apiNoInfo), os.ModePerm)
  183. assert.Nil(t, err)
  184. defer os.Remove(filename)
  185. parser, err := parser.NewParser(filename)
  186. assert.Nil(t, err)
  187. _, err = parser.Parse()
  188. assert.Nil(t, err)
  189. validate(t, filename)
  190. }
  191. func TestInvalidApiFile(t *testing.T) {
  192. filename := "greet.api"
  193. err := ioutil.WriteFile(filename, []byte(invalidApiFile), os.ModePerm)
  194. assert.Nil(t, err)
  195. defer os.Remove(filename)
  196. parser, err := parser.NewParser(filename)
  197. assert.Nil(t, err)
  198. _, err = parser.Parse()
  199. assert.NotNil(t, err)
  200. }
  201. func TestAnonymousAnnotation(t *testing.T) {
  202. filename := "greet.api"
  203. err := ioutil.WriteFile(filename, []byte(anonymousAnnotation), os.ModePerm)
  204. assert.Nil(t, err)
  205. defer os.Remove(filename)
  206. parser, err := parser.NewParser(filename)
  207. assert.Nil(t, err)
  208. api, err := parser.Parse()
  209. assert.Nil(t, err)
  210. assert.Equal(t, len(api.Service.Routes), 1)
  211. assert.Equal(t, api.Service.Routes[0].Annotations[0].Value, "GreetHandler")
  212. validate(t, filename)
  213. }
  214. func TestApiHasMiddleware(t *testing.T) {
  215. filename := "greet.api"
  216. err := ioutil.WriteFile(filename, []byte(apiHasMiddleware), os.ModePerm)
  217. assert.Nil(t, err)
  218. defer os.Remove(filename)
  219. parser, err := parser.NewParser(filename)
  220. assert.Nil(t, err)
  221. _, err = parser.Parse()
  222. assert.Nil(t, err)
  223. validate(t, filename)
  224. }
  225. func TestApiHasJwt(t *testing.T) {
  226. filename := "jwt.api"
  227. err := ioutil.WriteFile(filename, []byte(apiJwt), os.ModePerm)
  228. assert.Nil(t, err)
  229. defer os.Remove(filename)
  230. parser, err := parser.NewParser(filename)
  231. assert.Nil(t, err)
  232. _, err = parser.Parse()
  233. assert.Nil(t, err)
  234. validate(t, filename)
  235. }
  236. func TestApiHasJwtAndMiddleware(t *testing.T) {
  237. filename := "jwt.api"
  238. err := ioutil.WriteFile(filename, []byte(apiJwtWithMiddleware), os.ModePerm)
  239. assert.Nil(t, err)
  240. defer os.Remove(filename)
  241. parser, err := parser.NewParser(filename)
  242. assert.Nil(t, err)
  243. _, err = parser.Parse()
  244. assert.Nil(t, err)
  245. validate(t, filename)
  246. }
  247. func validate(t *testing.T, api string) {
  248. dir := "_go"
  249. err := DoGenProject(api, dir, true)
  250. defer os.RemoveAll(dir)
  251. assert.Nil(t, err)
  252. filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
  253. if strings.HasSuffix(path, ".go") {
  254. code, err := ioutil.ReadFile(path)
  255. assert.Nil(t, err)
  256. assert.Nil(t, validateCode(string(code)))
  257. }
  258. return nil
  259. })
  260. }
  261. func validateCode(code string) error {
  262. _, err := goformat.Source([]byte(code))
  263. return err
  264. }