service_test.go 18 KB

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