service_test.go 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686
  1. package test
  2. import (
  3. "testing"
  4. "github.com/stretchr/testify/assert"
  5. "github.com/tal-tech/go-zero/tools/goctl/api/parser/g4/ast"
  6. "github.com/tal-tech/go-zero/tools/goctl/api/parser/g4/gen/api"
  7. )
  8. func TestBody(t *testing.T) {
  9. fn := func(p *api.ApiParserParser, v *ast.ApiVisitor) interface{} {
  10. return p.Body().Accept(v)
  11. }
  12. t.Run("normal", func(t *testing.T) {
  13. v, err := parser.Accept(fn, `(Foo)`)
  14. assert.Nil(t, err)
  15. body := v.(*ast.Body)
  16. assert.True(t, body.Equal(&ast.Body{
  17. Lp: ast.NewTextExpr("("),
  18. Rp: ast.NewTextExpr(")"),
  19. Name: &ast.Literal{Literal: ast.NewTextExpr("Foo")},
  20. }))
  21. })
  22. t.Run("wrong", func(t *testing.T) {
  23. _, err := parser.Accept(fn, `(var)`)
  24. assert.Error(t, err)
  25. _, err = parser.Accept(fn, `()`)
  26. assert.Nil(t, err)
  27. })
  28. }
  29. func TestRoute(t *testing.T) {
  30. fn := func(p *api.ApiParserParser, v *ast.ApiVisitor) interface{} {
  31. return p.Route().Accept(v)
  32. }
  33. t.Run("normal", func(t *testing.T) {
  34. v, err := parser.Accept(fn, `post /foo/foo-bar/:bar (Foo) returns (Bar)`)
  35. assert.Nil(t, err)
  36. route := v.(*ast.Route)
  37. assert.True(t, route.Equal(&ast.Route{
  38. Method: ast.NewTextExpr("post"),
  39. Path: ast.NewTextExpr("/foo/foo-bar/:bar"),
  40. Req: &ast.Body{
  41. Lp: ast.NewTextExpr("("),
  42. Rp: ast.NewTextExpr(")"),
  43. Name: &ast.Literal{Literal: ast.NewTextExpr("Foo")},
  44. },
  45. ReturnToken: ast.NewTextExpr("returns"),
  46. Reply: &ast.Body{
  47. Lp: ast.NewTextExpr("("),
  48. Rp: ast.NewTextExpr(")"),
  49. Name: &ast.Literal{Literal: ast.NewTextExpr("Bar")},
  50. },
  51. }))
  52. v, err = parser.Accept(fn, `post /foo/foo-bar/:bar (Foo)`)
  53. assert.Nil(t, err)
  54. route = v.(*ast.Route)
  55. assert.True(t, route.Equal(&ast.Route{
  56. Method: ast.NewTextExpr("post"),
  57. Path: ast.NewTextExpr("/foo/foo-bar/:bar"),
  58. Req: &ast.Body{
  59. Lp: ast.NewTextExpr("("),
  60. Rp: ast.NewTextExpr(")"),
  61. Name: &ast.Literal{Literal: ast.NewTextExpr("Foo")},
  62. },
  63. }))
  64. v, err = parser.Accept(fn, `post /foo/foo-bar/:bar returns (Bar)`)
  65. assert.Nil(t, err)
  66. route = v.(*ast.Route)
  67. assert.True(t, route.Equal(&ast.Route{
  68. Method: ast.NewTextExpr("post"),
  69. Path: ast.NewTextExpr("/foo/foo-bar/:bar"),
  70. ReturnToken: ast.NewTextExpr("returns"),
  71. Reply: &ast.Body{
  72. Lp: ast.NewTextExpr("("),
  73. Rp: ast.NewTextExpr(")"),
  74. Name: &ast.Literal{Literal: ast.NewTextExpr("Bar")},
  75. },
  76. }))
  77. v, err = parser.Accept(fn, `post /foo/foo-bar/:bar returns ([]Bar)`)
  78. assert.Nil(t, err)
  79. route = v.(*ast.Route)
  80. assert.True(t, route.Equal(&ast.Route{
  81. Method: ast.NewTextExpr("post"),
  82. Path: ast.NewTextExpr("/foo/foo-bar/:bar"),
  83. ReturnToken: ast.NewTextExpr("returns"),
  84. Reply: &ast.Body{
  85. Lp: ast.NewTextExpr("("),
  86. Rp: ast.NewTextExpr(")"),
  87. Name: &ast.Array{
  88. ArrayExpr: ast.NewTextExpr("[]Bar"),
  89. LBrack: ast.NewTextExpr("["),
  90. RBrack: ast.NewTextExpr("]"),
  91. Literal: &ast.Literal{Literal: ast.NewTextExpr("Bar")},
  92. },
  93. },
  94. }))
  95. v, err = parser.Accept(fn, `post /foo/foo-bar/:bar returns ([]*Bar)`)
  96. assert.Nil(t, err)
  97. route = v.(*ast.Route)
  98. assert.True(t, route.Equal(&ast.Route{
  99. Method: ast.NewTextExpr("post"),
  100. Path: ast.NewTextExpr("/foo/foo-bar/:bar"),
  101. ReturnToken: ast.NewTextExpr("returns"),
  102. Reply: &ast.Body{
  103. Lp: ast.NewTextExpr("("),
  104. Rp: ast.NewTextExpr(")"),
  105. Name: &ast.Array{
  106. ArrayExpr: ast.NewTextExpr("[]*Bar"),
  107. LBrack: ast.NewTextExpr("["),
  108. RBrack: ast.NewTextExpr("]"),
  109. Literal: &ast.Pointer{
  110. PointerExpr: ast.NewTextExpr("*Bar"),
  111. Star: ast.NewTextExpr("*"),
  112. Name: ast.NewTextExpr("Bar"),
  113. }},
  114. },
  115. }))
  116. v, err = parser.Accept(fn, `post /foo/foo-bar/:bar`)
  117. assert.Nil(t, err)
  118. route = v.(*ast.Route)
  119. assert.True(t, route.Equal(&ast.Route{
  120. Method: ast.NewTextExpr("post"),
  121. Path: ast.NewTextExpr("/foo/foo-bar/:bar"),
  122. }))
  123. v, err = parser.Accept(fn, `
  124. // foo
  125. post /foo/foo-bar/:bar // bar`)
  126. assert.Nil(t, err)
  127. route = v.(*ast.Route)
  128. assert.True(t, route.Equal(&ast.Route{
  129. Method: ast.NewTextExpr("post"),
  130. Path: ast.NewTextExpr("/foo/foo-bar/:bar"),
  131. DocExpr: []ast.Expr{
  132. ast.NewTextExpr("// foo"),
  133. },
  134. CommentExpr: ast.NewTextExpr("// bar"),
  135. }))
  136. })
  137. t.Run("wrong", func(t *testing.T) {
  138. _, err := parser.Accept(fn, `posts /foo`)
  139. assert.Error(t, err)
  140. _, err = parser.Accept(fn, `gets /foo`)
  141. assert.Error(t, err)
  142. _, err = parser.Accept(fn, `post /foo/:`)
  143. assert.Error(t, err)
  144. _, err = parser.Accept(fn, `post /foo/`)
  145. assert.Error(t, err)
  146. _, err = parser.Accept(fn, `post foo/bar`)
  147. assert.Error(t, err)
  148. _, err = parser.Accept(fn, `post /foo/bar return (Bar)`)
  149. assert.Error(t, err)
  150. _, err = parser.Accept(fn, ` /foo/bar returns (Bar)`)
  151. assert.Error(t, err)
  152. _, err = parser.Accept(fn, ` post returns (Bar)`)
  153. assert.Error(t, err)
  154. _, err = parser.Accept(fn, ` post /foo/bar returns (int)`)
  155. assert.Error(t, err)
  156. _, err = parser.Accept(fn, ` post /foo/bar returns (*int)`)
  157. assert.Error(t, err)
  158. _, err = parser.Accept(fn, ` post /foo/bar returns ([]var)`)
  159. assert.Error(t, err)
  160. _, err = parser.Accept(fn, ` post /foo/bar returns (const)`)
  161. assert.Error(t, err)
  162. })
  163. }
  164. func TestAtHandler(t *testing.T) {
  165. fn := func(p *api.ApiParserParser, v *ast.ApiVisitor) interface{} {
  166. return p.AtHandler().Accept(v)
  167. }
  168. t.Run("normal", func(t *testing.T) {
  169. v, err := parser.Accept(fn, `@handler foo`)
  170. assert.Nil(t, err)
  171. atHandler := v.(*ast.AtHandler)
  172. assert.True(t, atHandler.Equal(&ast.AtHandler{
  173. AtHandlerToken: ast.NewTextExpr("@handler"),
  174. Name: ast.NewTextExpr("foo"),
  175. }))
  176. v, err = parser.Accept(fn, `
  177. // foo
  178. @handler foo // bar`)
  179. assert.Nil(t, err)
  180. atHandler = v.(*ast.AtHandler)
  181. assert.True(t, atHandler.Equal(&ast.AtHandler{
  182. AtHandlerToken: ast.NewTextExpr("@handler"),
  183. Name: ast.NewTextExpr("foo"),
  184. DocExpr: []ast.Expr{
  185. ast.NewTextExpr("// foo"),
  186. },
  187. CommentExpr: ast.NewTextExpr("// bar"),
  188. }))
  189. })
  190. t.Run("wrong", func(t *testing.T) {
  191. _, err := parser.Accept(fn, ``)
  192. assert.Error(t, err)
  193. _, err = parser.Accept(fn, `@handler`)
  194. assert.Error(t, err)
  195. _, err = parser.Accept(fn, `@handler "foo"`)
  196. assert.Error(t, err)
  197. })
  198. }
  199. func TestAtDoc(t *testing.T) {
  200. fn := func(p *api.ApiParserParser, v *ast.ApiVisitor) interface{} {
  201. return p.AtDoc().Accept(v)
  202. }
  203. t.Run("normal", func(t *testing.T) {
  204. v, err := parser.Accept(fn, `@doc "foo"`)
  205. assert.Nil(t, err)
  206. atDoc := v.(*ast.AtDoc)
  207. assert.True(t, atDoc.Equal(&ast.AtDoc{
  208. AtDocToken: ast.NewTextExpr("@doc"),
  209. LineDoc: ast.NewTextExpr(`"foo"`),
  210. }))
  211. v, err = parser.Accept(fn, `@doc("foo")`)
  212. assert.Nil(t, err)
  213. atDoc = v.(*ast.AtDoc)
  214. assert.True(t, atDoc.Equal(&ast.AtDoc{
  215. AtDocToken: ast.NewTextExpr("@doc"),
  216. Lp: ast.NewTextExpr("("),
  217. Rp: ast.NewTextExpr(")"),
  218. LineDoc: ast.NewTextExpr(`"foo"`),
  219. }))
  220. v, err = parser.Accept(fn, `@doc(
  221. foo: bar
  222. )`)
  223. assert.Nil(t, err)
  224. atDoc = v.(*ast.AtDoc)
  225. assert.True(t, atDoc.Equal(&ast.AtDoc{
  226. AtDocToken: ast.NewTextExpr("@doc"),
  227. Lp: ast.NewTextExpr("("),
  228. Rp: ast.NewTextExpr(")"),
  229. Kv: []*ast.KvExpr{
  230. {
  231. Key: ast.NewTextExpr("foo"),
  232. Value: ast.NewTextExpr("bar"),
  233. },
  234. },
  235. }))
  236. v, err = parser.Accept(fn, `@doc(
  237. // foo
  238. foo: bar // bar
  239. )`)
  240. assert.Nil(t, err)
  241. atDoc = v.(*ast.AtDoc)
  242. assert.True(t, atDoc.Equal(&ast.AtDoc{
  243. AtDocToken: ast.NewTextExpr("@doc"),
  244. Lp: ast.NewTextExpr("("),
  245. Rp: ast.NewTextExpr(")"),
  246. Kv: []*ast.KvExpr{
  247. {
  248. Key: ast.NewTextExpr("foo"),
  249. Value: ast.NewTextExpr("bar"),
  250. DocExpr: []ast.Expr{
  251. ast.NewTextExpr("// foo"),
  252. },
  253. CommentExpr: ast.NewTextExpr("// bar"),
  254. },
  255. },
  256. }))
  257. })
  258. t.Run("wrong", func(t *testing.T) {
  259. _, err := parser.Accept(fn, `@doc("foo"`)
  260. assert.Error(t, err)
  261. _, err = parser.Accept(fn, `@doc "foo")`)
  262. assert.Error(t, err)
  263. })
  264. }
  265. func TestServiceRoute(t *testing.T) {
  266. fn := func(p *api.ApiParserParser, v *ast.ApiVisitor) interface{} {
  267. return p.ServiceRoute().Accept(v)
  268. }
  269. t.Run("normal", func(t *testing.T) {
  270. v, err := parser.Accept(fn, `
  271. @doc("foo")
  272. // foo/bar
  273. // foo
  274. @handler foo // bar
  275. // foo/bar
  276. // foo
  277. post /foo (Foo) returns (Bar) // bar
  278. `)
  279. assert.Nil(t, err)
  280. sr := v.(*ast.ServiceRoute)
  281. assert.True(t, sr.Equal(&ast.ServiceRoute{
  282. AtDoc: &ast.AtDoc{
  283. AtDocToken: ast.NewTextExpr("@doc"),
  284. Lp: ast.NewTextExpr("("),
  285. Rp: ast.NewTextExpr(")"),
  286. LineDoc: ast.NewTextExpr(`"foo"`),
  287. },
  288. AtHandler: &ast.AtHandler{
  289. AtHandlerToken: ast.NewTextExpr("@handler"),
  290. Name: ast.NewTextExpr("foo"),
  291. DocExpr: []ast.Expr{
  292. ast.NewTextExpr("// foo"),
  293. },
  294. CommentExpr: ast.NewTextExpr("// bar"),
  295. },
  296. Route: &ast.Route{
  297. Method: ast.NewTextExpr("post"),
  298. Path: ast.NewTextExpr("/foo"),
  299. Req: &ast.Body{
  300. Lp: ast.NewTextExpr("("),
  301. Rp: ast.NewTextExpr(")"),
  302. Name: &ast.Literal{Literal: ast.NewTextExpr("Foo")},
  303. },
  304. ReturnToken: ast.NewTextExpr("returns"),
  305. Reply: &ast.Body{
  306. Lp: ast.NewTextExpr("("),
  307. Rp: ast.NewTextExpr(")"),
  308. Name: &ast.Literal{Literal: ast.NewTextExpr("Bar")},
  309. },
  310. DocExpr: []ast.Expr{
  311. ast.NewTextExpr("// foo"),
  312. },
  313. CommentExpr: ast.NewTextExpr("// bar"),
  314. },
  315. }))
  316. })
  317. t.Run("wrong", func(t *testing.T) {
  318. _, err := parser.Accept(fn, `post /foo (Foo) returns (Bar) // bar`)
  319. assert.Error(t, err)
  320. _, err = parser.Accept(fn, `@handler foo`)
  321. assert.Error(t, err)
  322. })
  323. }
  324. func TestServiceApi(t *testing.T) {
  325. fn := func(p *api.ApiParserParser, v *ast.ApiVisitor) interface{} {
  326. return p.ServiceApi().Accept(v)
  327. }
  328. t.Run("normal", func(t *testing.T) {
  329. v, err := parser.Accept(fn, `
  330. service foo-api{
  331. @doc("foo")
  332. // foo/bar
  333. // foo
  334. @handler foo // bar
  335. // foo/bar
  336. // foo
  337. post /foo (Foo) returns (Bar) // bar
  338. }
  339. `)
  340. assert.Nil(t, err)
  341. api := v.(*ast.ServiceApi)
  342. assert.True(t, api.Equal(&ast.ServiceApi{
  343. ServiceToken: ast.NewTextExpr("service"),
  344. Name: ast.NewTextExpr("foo-api"),
  345. Lbrace: ast.NewTextExpr("{"),
  346. Rbrace: ast.NewTextExpr("}"),
  347. ServiceRoute: []*ast.ServiceRoute{
  348. {
  349. AtDoc: &ast.AtDoc{
  350. AtDocToken: ast.NewTextExpr("@doc"),
  351. Lp: ast.NewTextExpr("("),
  352. Rp: ast.NewTextExpr(")"),
  353. LineDoc: ast.NewTextExpr(`"foo"`),
  354. },
  355. AtHandler: &ast.AtHandler{
  356. AtHandlerToken: ast.NewTextExpr("@handler"),
  357. Name: ast.NewTextExpr("foo"),
  358. DocExpr: []ast.Expr{
  359. ast.NewTextExpr("// foo"),
  360. },
  361. CommentExpr: ast.NewTextExpr("// bar"),
  362. },
  363. Route: &ast.Route{
  364. Method: ast.NewTextExpr("post"),
  365. Path: ast.NewTextExpr("/foo"),
  366. Req: &ast.Body{
  367. Lp: ast.NewTextExpr("("),
  368. Rp: ast.NewTextExpr(")"),
  369. Name: &ast.Literal{Literal: ast.NewTextExpr("Foo")},
  370. },
  371. ReturnToken: ast.NewTextExpr("returns"),
  372. Reply: &ast.Body{
  373. Lp: ast.NewTextExpr("("),
  374. Rp: ast.NewTextExpr(")"),
  375. Name: &ast.Literal{Literal: ast.NewTextExpr("Bar")},
  376. },
  377. DocExpr: []ast.Expr{
  378. ast.NewTextExpr("// foo"),
  379. },
  380. CommentExpr: ast.NewTextExpr("// bar"),
  381. },
  382. },
  383. },
  384. }))
  385. })
  386. t.Run("wrong", func(t *testing.T) {
  387. _, err := parser.Accept(fn, `services foo-api{}`)
  388. assert.Error(t, err)
  389. _, err = parser.Accept(fn, `service foo-api{`)
  390. assert.Error(t, err)
  391. _, err = parser.Accept(fn, `service foo-api{
  392. post /foo
  393. }`)
  394. assert.Error(t, err)
  395. _, err = parser.Accept(fn, `service foo-api{
  396. @handler foo
  397. }`)
  398. assert.Error(t, err)
  399. })
  400. }
  401. func TestAtServer(t *testing.T) {
  402. fn := func(p *api.ApiParserParser, v *ast.ApiVisitor) interface{} {
  403. return p.AtServer().Accept(v)
  404. }
  405. t.Run("normal", func(t *testing.T) {
  406. v, err := parser.Accept(fn, `
  407. @server(
  408. // foo
  409. foo1: bar1 // bar
  410. // foo
  411. foo2: "bar2" // bar
  412. /**foo*/
  413. foo3: "foo
  414. bar" /**bar*/
  415. )
  416. `)
  417. assert.Nil(t, err)
  418. as := v.(*ast.AtServer)
  419. assert.True(t, as.Equal(&ast.AtServer{
  420. AtServerToken: ast.NewTextExpr("@server"),
  421. Lp: ast.NewTextExpr("("),
  422. Rp: ast.NewTextExpr(")"),
  423. Kv: []*ast.KvExpr{
  424. {
  425. Key: ast.NewTextExpr("foo1"),
  426. Value: ast.NewTextExpr("bar1"),
  427. DocExpr: []ast.Expr{
  428. ast.NewTextExpr("// foo"),
  429. },
  430. CommentExpr: ast.NewTextExpr("// bar"),
  431. },
  432. {
  433. Key: ast.NewTextExpr("foo2"),
  434. Value: ast.NewTextExpr(`"bar2"`),
  435. DocExpr: []ast.Expr{
  436. ast.NewTextExpr("// foo"),
  437. },
  438. CommentExpr: ast.NewTextExpr("// bar"),
  439. },
  440. {
  441. Key: ast.NewTextExpr("foo3"),
  442. Value: ast.NewTextExpr(`"foo
  443. bar"`),
  444. DocExpr: []ast.Expr{
  445. ast.NewTextExpr("/**foo*/"),
  446. },
  447. CommentExpr: ast.NewTextExpr("/**bar*/"),
  448. },
  449. },
  450. }))
  451. })
  452. t.Run("wrong", func(t *testing.T) {
  453. _, err := parser.Accept(fn, `server (
  454. foo:bar
  455. )`)
  456. assert.Error(t, err)
  457. _, err = parser.Accept(fn, `@server ()`)
  458. assert.Error(t, err)
  459. _, err = parser.Accept(fn, `@server (
  460. foo: bar
  461. `)
  462. assert.Error(t, err)
  463. })
  464. }
  465. func TestServiceSpec(t *testing.T) {
  466. fn := func(p *api.ApiParserParser, v *ast.ApiVisitor) interface{} {
  467. return p.ServiceSpec().Accept(v)
  468. }
  469. t.Run("normal", func(t *testing.T) {
  470. _, err := parser.Accept(fn, `
  471. service foo-api{
  472. @handler foo
  473. post /foo returns ([]int)
  474. }
  475. `)
  476. assert.Nil(t, err)
  477. v, err := parser.Accept(fn, `
  478. @server(
  479. // foo
  480. foo1: bar1 // bar
  481. // foo
  482. foo2: "bar2" // bar
  483. /**foo*/
  484. foo3: "foo
  485. bar" /**bar*/
  486. )
  487. service foo-api{
  488. @doc("foo")
  489. // foo/bar
  490. // foo
  491. @handler foo // bar
  492. // foo/bar
  493. // foo
  494. post /foo (Foo) returns (Bar) // bar
  495. }
  496. `)
  497. assert.Nil(t, err)
  498. service := v.(*ast.Service)
  499. assert.True(t, service.Equal(&ast.Service{
  500. AtServer: &ast.AtServer{
  501. AtServerToken: ast.NewTextExpr("@server"),
  502. Lp: ast.NewTextExpr("("),
  503. Rp: ast.NewTextExpr(")"),
  504. Kv: []*ast.KvExpr{
  505. {
  506. Key: ast.NewTextExpr("foo1"),
  507. Value: ast.NewTextExpr("bar1"),
  508. DocExpr: []ast.Expr{
  509. ast.NewTextExpr("// foo"),
  510. },
  511. CommentExpr: ast.NewTextExpr("// bar"),
  512. },
  513. {
  514. Key: ast.NewTextExpr("foo2"),
  515. Value: ast.NewTextExpr(`"bar2"`),
  516. DocExpr: []ast.Expr{
  517. ast.NewTextExpr("// foo"),
  518. },
  519. CommentExpr: ast.NewTextExpr("// bar"),
  520. },
  521. {
  522. Key: ast.NewTextExpr("foo3"),
  523. Value: ast.NewTextExpr(`"foo
  524. bar"`),
  525. DocExpr: []ast.Expr{
  526. ast.NewTextExpr("/**foo*/"),
  527. },
  528. CommentExpr: ast.NewTextExpr("/**bar*/"),
  529. },
  530. },
  531. },
  532. ServiceApi: &ast.ServiceApi{
  533. ServiceToken: ast.NewTextExpr("service"),
  534. Name: ast.NewTextExpr("foo-api"),
  535. Lbrace: ast.NewTextExpr("{"),
  536. Rbrace: ast.NewTextExpr("}"),
  537. ServiceRoute: []*ast.ServiceRoute{
  538. {
  539. AtDoc: &ast.AtDoc{
  540. AtDocToken: ast.NewTextExpr("@doc"),
  541. Lp: ast.NewTextExpr("("),
  542. Rp: ast.NewTextExpr(")"),
  543. LineDoc: ast.NewTextExpr(`"foo"`),
  544. },
  545. AtHandler: &ast.AtHandler{
  546. AtHandlerToken: ast.NewTextExpr("@handler"),
  547. Name: ast.NewTextExpr("foo"),
  548. DocExpr: []ast.Expr{
  549. ast.NewTextExpr("// foo"),
  550. },
  551. CommentExpr: ast.NewTextExpr("// bar"),
  552. },
  553. Route: &ast.Route{
  554. Method: ast.NewTextExpr("post"),
  555. Path: ast.NewTextExpr("/foo"),
  556. Req: &ast.Body{
  557. Lp: ast.NewTextExpr("("),
  558. Rp: ast.NewTextExpr(")"),
  559. Name: &ast.Literal{Literal: ast.NewTextExpr("Foo")},
  560. },
  561. ReturnToken: ast.NewTextExpr("returns"),
  562. Reply: &ast.Body{
  563. Lp: ast.NewTextExpr("("),
  564. Rp: ast.NewTextExpr(")"),
  565. Name: &ast.Literal{Literal: ast.NewTextExpr("Bar")},
  566. },
  567. DocExpr: []ast.Expr{
  568. ast.NewTextExpr("// foo"),
  569. },
  570. CommentExpr: ast.NewTextExpr("// bar"),
  571. },
  572. },
  573. },
  574. },
  575. }))
  576. v, err = parser.Accept(fn, `
  577. service foo-api{
  578. @doc("foo")
  579. // foo/bar
  580. // foo
  581. @handler foo // bar
  582. // foo/bar
  583. // foo
  584. post /foo (Foo) returns (Bar) // bar
  585. }
  586. `)
  587. assert.Nil(t, err)
  588. service = v.(*ast.Service)
  589. assert.True(t, service.Equal(&ast.Service{
  590. ServiceApi: &ast.ServiceApi{
  591. ServiceToken: ast.NewTextExpr("service"),
  592. Name: ast.NewTextExpr("foo-api"),
  593. Lbrace: ast.NewTextExpr("{"),
  594. Rbrace: ast.NewTextExpr("}"),
  595. ServiceRoute: []*ast.ServiceRoute{
  596. {
  597. AtDoc: &ast.AtDoc{
  598. AtDocToken: ast.NewTextExpr("@doc"),
  599. Lp: ast.NewTextExpr("("),
  600. Rp: ast.NewTextExpr(")"),
  601. LineDoc: ast.NewTextExpr(`"foo"`),
  602. },
  603. AtHandler: &ast.AtHandler{
  604. AtHandlerToken: ast.NewTextExpr("@handler"),
  605. Name: ast.NewTextExpr("foo"),
  606. DocExpr: []ast.Expr{
  607. ast.NewTextExpr("// foo"),
  608. },
  609. CommentExpr: ast.NewTextExpr("// bar"),
  610. },
  611. Route: &ast.Route{
  612. Method: ast.NewTextExpr("post"),
  613. Path: ast.NewTextExpr("/foo"),
  614. Req: &ast.Body{
  615. Lp: ast.NewTextExpr("("),
  616. Rp: ast.NewTextExpr(")"),
  617. Name: &ast.Literal{Literal: ast.NewTextExpr("Foo")},
  618. },
  619. ReturnToken: ast.NewTextExpr("returns"),
  620. Reply: &ast.Body{
  621. Lp: ast.NewTextExpr("("),
  622. Rp: ast.NewTextExpr(")"),
  623. Name: &ast.Literal{Literal: ast.NewTextExpr("Bar")},
  624. },
  625. DocExpr: []ast.Expr{
  626. ast.NewTextExpr("// foo"),
  627. },
  628. CommentExpr: ast.NewTextExpr("// bar"),
  629. },
  630. },
  631. },
  632. },
  633. }))
  634. })
  635. }