service_test.go 17 KB

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