gen_test.go 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354
  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. const apiHasNoRequest = `
  151. service A-api {
  152. @handler GreetHandler
  153. post /greet/ping ()
  154. }
  155. `
  156. func TestParser(t *testing.T) {
  157. filename := "greet.api"
  158. err := ioutil.WriteFile(filename, []byte(testApiTemplate), os.ModePerm)
  159. assert.Nil(t, err)
  160. defer os.Remove(filename)
  161. parser, err := parser.NewParser(filename)
  162. assert.Nil(t, err)
  163. api, err := parser.Parse()
  164. assert.Nil(t, err)
  165. assert.Equal(t, len(api.Types), 2)
  166. assert.Equal(t, len(api.Service.Routes), 2)
  167. assert.Equal(t, api.Service.Routes[0].Path, "/greet/from/:name")
  168. assert.Equal(t, api.Service.Routes[1].Path, "/greet/get")
  169. assert.Equal(t, api.Service.Routes[1].RequestType.Name, "Request")
  170. assert.Equal(t, api.Service.Routes[1].ResponseType.Name, "")
  171. validate(t, filename)
  172. }
  173. func TestMultiService(t *testing.T) {
  174. filename := "greet.api"
  175. err := ioutil.WriteFile(filename, []byte(testMultiServiceTemplate), os.ModePerm)
  176. assert.Nil(t, err)
  177. defer os.Remove(filename)
  178. parser, err := parser.NewParser(filename)
  179. assert.Nil(t, err)
  180. api, err := parser.Parse()
  181. assert.Nil(t, err)
  182. assert.Equal(t, len(api.Service.Routes), 2)
  183. assert.Equal(t, len(api.Service.Groups), 2)
  184. validate(t, filename)
  185. }
  186. func TestApiNoInfo(t *testing.T) {
  187. filename := "greet.api"
  188. err := ioutil.WriteFile(filename, []byte(apiNoInfo), os.ModePerm)
  189. assert.Nil(t, err)
  190. defer os.Remove(filename)
  191. parser, err := parser.NewParser(filename)
  192. assert.Nil(t, err)
  193. _, err = parser.Parse()
  194. assert.Nil(t, err)
  195. validate(t, filename)
  196. }
  197. func TestInvalidApiFile(t *testing.T) {
  198. filename := "greet.api"
  199. err := ioutil.WriteFile(filename, []byte(invalidApiFile), os.ModePerm)
  200. assert.Nil(t, err)
  201. defer os.Remove(filename)
  202. parser, err := parser.NewParser(filename)
  203. assert.Nil(t, err)
  204. _, err = parser.Parse()
  205. assert.NotNil(t, err)
  206. }
  207. func TestAnonymousAnnotation(t *testing.T) {
  208. filename := "greet.api"
  209. err := ioutil.WriteFile(filename, []byte(anonymousAnnotation), os.ModePerm)
  210. assert.Nil(t, err)
  211. defer os.Remove(filename)
  212. parser, err := parser.NewParser(filename)
  213. assert.Nil(t, err)
  214. api, err := parser.Parse()
  215. assert.Nil(t, err)
  216. assert.Equal(t, len(api.Service.Routes), 1)
  217. assert.Equal(t, api.Service.Routes[0].Annotations[0].Value, "GreetHandler")
  218. validate(t, filename)
  219. }
  220. func TestApiHasMiddleware(t *testing.T) {
  221. filename := "greet.api"
  222. err := ioutil.WriteFile(filename, []byte(apiHasMiddleware), os.ModePerm)
  223. assert.Nil(t, err)
  224. defer os.Remove(filename)
  225. parser, err := parser.NewParser(filename)
  226. assert.Nil(t, err)
  227. _, err = parser.Parse()
  228. assert.Nil(t, err)
  229. validate(t, filename)
  230. }
  231. func TestApiHasJwt(t *testing.T) {
  232. filename := "jwt.api"
  233. err := ioutil.WriteFile(filename, []byte(apiJwt), os.ModePerm)
  234. assert.Nil(t, err)
  235. defer os.Remove(filename)
  236. parser, err := parser.NewParser(filename)
  237. assert.Nil(t, err)
  238. _, err = parser.Parse()
  239. assert.Nil(t, err)
  240. validate(t, filename)
  241. }
  242. func TestApiHasJwtAndMiddleware(t *testing.T) {
  243. filename := "jwt.api"
  244. err := ioutil.WriteFile(filename, []byte(apiJwtWithMiddleware), os.ModePerm)
  245. assert.Nil(t, err)
  246. defer os.Remove(filename)
  247. parser, err := parser.NewParser(filename)
  248. assert.Nil(t, err)
  249. _, err = parser.Parse()
  250. assert.Nil(t, err)
  251. validate(t, filename)
  252. }
  253. func TestApiHasNoRequestBody(t *testing.T) {
  254. filename := "greet.api"
  255. err := ioutil.WriteFile(filename, []byte(apiHasNoRequest), os.ModePerm)
  256. assert.Nil(t, err)
  257. defer os.Remove(filename)
  258. parser, err := parser.NewParser(filename)
  259. assert.Nil(t, err)
  260. _, err = parser.Parse()
  261. assert.Nil(t, err)
  262. validate(t, filename)
  263. }
  264. func validate(t *testing.T, api string) {
  265. dir := "_go"
  266. err := DoGenProject(api, dir, true)
  267. defer os.RemoveAll(dir)
  268. assert.Nil(t, err)
  269. filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
  270. if strings.HasSuffix(path, ".go") {
  271. code, err := ioutil.ReadFile(path)
  272. assert.Nil(t, err)
  273. assert.Nil(t, validateCode(string(code)))
  274. }
  275. return nil
  276. })
  277. }
  278. func validateCode(code string) error {
  279. _, err := goformat.Source([]byte(code))
  280. return err
  281. }