parser_test.go 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236
  1. /*
  2. * Public Domain Software
  3. *
  4. * I (Matthias Ladkau) am the author of the source code in this file.
  5. * I have placed the source code in this file in the public domain.
  6. *
  7. * For further information see: http://creativecommons.org/publicdomain/zero/1.0/
  8. */
  9. package parser
  10. import (
  11. "encoding/json"
  12. "fmt"
  13. "testing"
  14. )
  15. /*
  16. Test RuntimeProvider provides runtime components for a parse tree.
  17. */
  18. type TestRuntimeProvider struct {
  19. }
  20. /*
  21. Runtime returns a runtime component for a given ASTNode.
  22. */
  23. func (trp *TestRuntimeProvider) Runtime(node *ASTNode) Runtime {
  24. return &TestRuntime{}
  25. }
  26. /*
  27. Test Runtime provides the runtime for an ASTNode.
  28. */
  29. type TestRuntime struct {
  30. }
  31. /*
  32. Validate this runtime component and all its child components.
  33. */
  34. func (tr *TestRuntime) Validate() error {
  35. return nil
  36. }
  37. /*
  38. Eval evaluate this runtime component.
  39. */
  40. func (tr *TestRuntime) Eval() (map[string]interface{}, error) {
  41. return nil, nil
  42. }
  43. func TestInputValueParsing(t *testing.T) {
  44. input := `{
  45. foo(bar: $Hello) # Variable value
  46. foo(bar: 1) # Int value
  47. foo(bar: 1.1) # Float value
  48. foo(bar: "Hello") # String value
  49. foo(bar: """
  50. Hello
  51. test123
  52. """) # Block string value
  53. foo(bar: false) # Boolean value
  54. foo(bar: null) # Null value
  55. foo(bar: MOBILE_WEB) # Enum value
  56. foo(bar: [1,2,[A,"B"]]) # List value
  57. foo(bar: {foo:"bar"
  58. foo2 : [12],
  59. foo3 : { X:Y }
  60. }) # Object value
  61. }
  62. `
  63. expectedOutput := `
  64. Document
  65. ExecutableDefinition
  66. OperationDefinition
  67. SelectionSet
  68. Field
  69. Name: foo
  70. Arguments
  71. Argument
  72. Name: bar
  73. Variable: Hello
  74. Field
  75. Name: foo
  76. Arguments
  77. Argument
  78. Name: bar
  79. Value: 1
  80. Field
  81. Name: foo
  82. Arguments
  83. Argument
  84. Name: bar
  85. Value: 1.1
  86. Field
  87. Name: foo
  88. Arguments
  89. Argument
  90. Name: bar
  91. Value: Hello
  92. Field
  93. Name: foo
  94. Arguments
  95. Argument
  96. Name: bar
  97. Value: Hello
  98. test123
  99. Field
  100. Name: foo
  101. Arguments
  102. Argument
  103. Name: bar
  104. Value: false
  105. Field
  106. Name: foo
  107. Arguments
  108. Argument
  109. Name: bar
  110. Value: null
  111. Field
  112. Name: foo
  113. Arguments
  114. Argument
  115. Name: bar
  116. EnumValue: MOBILE_WEB
  117. Field
  118. Name: foo
  119. Arguments
  120. Argument
  121. Name: bar
  122. ListValue
  123. Value: 1
  124. Value: 2
  125. ListValue
  126. EnumValue: A
  127. Value: B
  128. Field
  129. Name: foo
  130. Arguments
  131. Argument
  132. Name: bar
  133. ObjectValue
  134. ObjectField: foo
  135. Value: bar
  136. ObjectField: foo2
  137. ListValue
  138. Value: 12
  139. ObjectField: foo3
  140. ObjectValue
  141. ObjectField: X
  142. EnumValue: Y
  143. `[1:]
  144. if res, err := ParseWithRuntime("mytest", input, &TestRuntimeProvider{}); err != nil || fmt.Sprint(res) != expectedOutput {
  145. t.Error("Unexpected parser output:\n", res, "expected was:\n", expectedOutput, "Error:", err)
  146. return
  147. }
  148. }
  149. func TestOperationDefinitionParsing(t *testing.T) {
  150. input := `query {
  151. likeStory(storyID: 12345) {
  152. story {
  153. likeCount
  154. }
  155. }
  156. }
  157. `
  158. expectedOutput := `
  159. Document
  160. ExecutableDefinition
  161. OperationDefinition
  162. OperationType: query
  163. SelectionSet
  164. Field
  165. Name: likeStory
  166. Arguments
  167. Argument
  168. Name: storyID
  169. Value: 12345
  170. SelectionSet
  171. Field
  172. Name: story
  173. SelectionSet
  174. Field
  175. Name: likeCount
  176. `[1:]
  177. if res, err := Parse("mytest", input); err != nil || fmt.Sprint(res) != expectedOutput {
  178. t.Error("Unexpected parser output:\n", res, "expected was:\n", expectedOutput, "Error:", err)
  179. return
  180. }
  181. expectedOutput = `
  182. {
  183. "children": [
  184. {
  185. "children": [
  186. {
  187. "children": [
  188. {
  189. "name": "OperationType",
  190. "value": "query"
  191. },
  192. {
  193. "children": [
  194. {
  195. "children": [
  196. {
  197. "name": "Name",
  198. "value": "likeStory"
  199. },
  200. {
  201. "children": [
  202. {
  203. "children": [
  204. {
  205. "name": "Name",
  206. "value": "storyID"
  207. },
  208. {
  209. "name": "Value",
  210. "value": "12345"
  211. }
  212. ],
  213. "name": "Argument"
  214. }
  215. ],
  216. "name": "Arguments"
  217. },
  218. {
  219. "children": [
  220. {
  221. "children": [
  222. {
  223. "name": "Name",
  224. "value": "story"
  225. },
  226. {
  227. "children": [
  228. {
  229. "children": [
  230. {
  231. "name": "Name",
  232. "value": "likeCount"
  233. }
  234. ],
  235. "name": "Field"
  236. }
  237. ],
  238. "name": "SelectionSet"
  239. }
  240. ],
  241. "name": "Field"
  242. }
  243. ],
  244. "name": "SelectionSet"
  245. }
  246. ],
  247. "name": "Field"
  248. }
  249. ],
  250. "name": "SelectionSet"
  251. }
  252. ],
  253. "name": "OperationDefinition"
  254. }
  255. ],
  256. "name": "ExecutableDefinition"
  257. }
  258. ],
  259. "name": "Document"
  260. }`[1:]
  261. res, err := Parse("mytest", input)
  262. plain, _ := json.MarshalIndent(res.Plain(), "", " ")
  263. plainString := string(plain)
  264. if err != nil || plainString != expectedOutput {
  265. t.Error("Unexpected parser output:\n", plainString, "expected was:\n", expectedOutput, "Error:", err)
  266. return
  267. }
  268. input = `query hans {
  269. likeStory(storyID: 12345) {
  270. story {
  271. likeCount
  272. }
  273. }
  274. }
  275. `
  276. expectedOutput = `
  277. Document
  278. ExecutableDefinition
  279. OperationDefinition
  280. OperationType: query
  281. Name: hans
  282. SelectionSet
  283. Field
  284. Name: likeStory
  285. Arguments
  286. Argument
  287. Name: storyID
  288. Value: 12345
  289. SelectionSet
  290. Field
  291. Name: story
  292. SelectionSet
  293. Field
  294. Name: likeCount
  295. `[1:]
  296. if res, err := Parse("mytest", input); err != nil || fmt.Sprint(res) != expectedOutput {
  297. t.Error("Unexpected parser output:\n", res, "expected was:\n", expectedOutput, "Error:", err)
  298. return
  299. }
  300. input = `subscription hans @foo(a:1) @bar(b:2) {
  301. likeCount
  302. }
  303. `
  304. expectedOutput = `
  305. Document
  306. ExecutableDefinition
  307. OperationDefinition
  308. OperationType: subscription
  309. Name: hans
  310. Directives
  311. Directive
  312. Name: foo
  313. Arguments
  314. Argument
  315. Name: a
  316. Value: 1
  317. Directive
  318. Name: bar
  319. Arguments
  320. Argument
  321. Name: b
  322. Value: 2
  323. SelectionSet
  324. Field
  325. Name: likeCount
  326. `[1:]
  327. if res, err := Parse("mytest", input); err != nil || fmt.Sprint(res) != expectedOutput {
  328. t.Error("Unexpected parser output:\n", res, "expected was:\n", expectedOutput, "Error:", err)
  329. return
  330. }
  331. input = `
  332. query getBozoProfile($devicePicSize: Int, $foo: bar=123) {
  333. user(id: 4) {
  334. id
  335. name
  336. profilePic(size: $devicePicSize)
  337. }
  338. }
  339. `
  340. expectedOutput = `
  341. Document
  342. ExecutableDefinition
  343. OperationDefinition
  344. OperationType: query
  345. Name: getBozoProfile
  346. VariableDefinitions
  347. VariableDefinition
  348. Variable: devicePicSize
  349. Type: Int
  350. VariableDefinition
  351. Variable: foo
  352. Type: bar
  353. DefaultValue: 123
  354. SelectionSet
  355. Field
  356. Name: user
  357. Arguments
  358. Argument
  359. Name: id
  360. Value: 4
  361. SelectionSet
  362. Field
  363. Name: id
  364. Field
  365. Name: name
  366. Field
  367. Name: profilePic
  368. Arguments
  369. Argument
  370. Name: size
  371. Variable: devicePicSize
  372. `[1:]
  373. if res, err := Parse("mytest", input); err != nil || fmt.Sprint(res) != expectedOutput {
  374. t.Error("Unexpected parser output:\n", res, "expected was:\n", expectedOutput, "Error:", err)
  375. return
  376. }
  377. input = `query (foo:bar) {}`
  378. if out, err := Parse("mytest", input); err == nil || err.Error() !=
  379. "Parse error in mytest: Variable expected (<foo>) (Line:1 Pos:8)" {
  380. t.Error("Unexpected output:", out, err)
  381. return
  382. }
  383. input = `query @foo() () {}`
  384. if out, err := Parse("mytest", input); err == nil || err.Error() !=
  385. `Parse error in mytest: Selection Set expected (@) (Line:1 Pos:7)` {
  386. t.Error("Unexpected output:", out, err)
  387. return
  388. }
  389. }
  390. func TestParserErrors(t *testing.T) {
  391. input := `"bl\*a`
  392. if _, err := Parse("mytest", input); err.Error() !=
  393. "Parse error in mytest: Lexical error (EOF inside quotes) (Line:1 Pos:1)" {
  394. t.Error(err)
  395. return
  396. }
  397. input = `"bl\*a"`
  398. if _, err := Parse("mytest", input); err.Error() !=
  399. "Parse error in mytest: Lexical error (Could not interpret escape sequence: invalid syntax) (Line:1 Pos:1)" {
  400. t.Error(err)
  401. return
  402. }
  403. input = `{ "bla"`
  404. if _, err := Parse("mytest", input); err.Error() !=
  405. "Parse error in mytest: Unexpected end (Line:1 Pos:7)" {
  406. t.Error(err)
  407. return
  408. }
  409. input = `{ bla : "bla" }`
  410. if _, err := Parse("mytest", input); err.Error() !=
  411. `Parse error in mytest: Name expected ("bla") (Line:1 Pos:9)` {
  412. t.Error(err)
  413. return
  414. }
  415. tokens := make(chan LexToken, 1)
  416. close(tokens)
  417. p := &parser{"test", nil, tokens, nil, false, false}
  418. if _, err := p.next(); err == nil || err.Error() != "Parse error in test: Unexpected end (Line:0 Pos:0)" {
  419. t.Error(err)
  420. return
  421. }
  422. tokens = make(chan LexToken, 1)
  423. tokens <- LexToken{-1, 0, "foo", 0, 0}
  424. close(tokens)
  425. p = &parser{"test", nil, tokens, nil, false, false}
  426. if _, err := p.next(); err == nil || err.Error() != `Parse error in test: Unknown term (id:-1 (foo)) (Line:0 Pos:0)` {
  427. t.Error(err)
  428. return
  429. }
  430. // Test incomplete expression
  431. input = `{ a `
  432. if _, err := Parse("mytest", input); err.Error() !=
  433. "Parse error in mytest: Unexpected end (Line:1 Pos:4)" {
  434. t.Error(err)
  435. return
  436. }
  437. input = `[ 11, "tes`
  438. if _, err := Parse("mytest", input); err == nil || err.Error() !=
  439. "Parse error in mytest: Lexical error (EOF inside quotes) (Line:1 Pos:7)" {
  440. t.Error(err)
  441. return
  442. }
  443. input = `[ { "a"`
  444. if _, err := Parse("mytest", input); err == nil || err.Error() !=
  445. `Parse error in mytest: Name expected ("a") (Line:1 Pos:5)` {
  446. t.Error(err)
  447. return
  448. }
  449. input = `{
  450. foo(bar: {)
  451. }`
  452. if _, err := Parse("mytest", input); err == nil || err.Error() !=
  453. `Parse error in mytest: Term cannot start an expression (}) (Line:3 Pos:2)` {
  454. t.Error(err)
  455. return
  456. }
  457. input = `{
  458. foo(bar: { a b })
  459. }`
  460. if _, err := Parse("mytest", input); err == nil || err.Error() !=
  461. `Parse error in mytest: Unexpected term (b) (Line:2 Pos:17)` {
  462. t.Error(err)
  463. return
  464. }
  465. input = `@1`
  466. if _, err := Parse("mytest", input); err == nil || err.Error() !=
  467. `Parse error in mytest: Unexpected term (1) (Line:1 Pos:2)` {
  468. t.Error(err)
  469. return
  470. }
  471. }
  472. func TestQueryShorthandParsing(t *testing.T) {
  473. // Test shorthand operation
  474. input := `{ field }`
  475. expectedOutput := `
  476. Document
  477. ExecutableDefinition
  478. OperationDefinition
  479. SelectionSet
  480. Field
  481. Name: field
  482. `[1:]
  483. if res, err := Parse("mytest", input); err != nil || fmt.Sprint(res) != expectedOutput {
  484. t.Error("Unexpected parser output:\n", res, "expected was:\n", expectedOutput, "Error:", err)
  485. return
  486. }
  487. input = `{ field }{ field }`
  488. if _, err := Parse("mytest", input); err.Error() !=
  489. `Parse error in mytest: Query shorthand only allowed for one query operation ({) (Line:1 Pos:10)` {
  490. t.Error(err)
  491. return
  492. }
  493. input = `{
  494. my : field
  495. }`
  496. expectedOutput = `
  497. Document
  498. ExecutableDefinition
  499. OperationDefinition
  500. SelectionSet
  501. Field
  502. Alias: my
  503. Name: field
  504. `[1:]
  505. if res, err := Parse("mytest", input); err != nil || fmt.Sprint(res) != expectedOutput {
  506. t.Error("Unexpected parser output:\n", res, "expected was:\n", expectedOutput, "Error:", err)
  507. return
  508. }
  509. input = `{
  510. my : field
  511. foo,
  512. bar
  513. }`
  514. expectedOutput = `
  515. Document
  516. ExecutableDefinition
  517. OperationDefinition
  518. SelectionSet
  519. Field
  520. Alias: my
  521. Name: field
  522. Field
  523. Name: foo
  524. Field
  525. Name: bar
  526. `[1:]
  527. if res, err := Parse("mytest", input); err != nil || fmt.Sprint(res) != expectedOutput {
  528. t.Error("Unexpected parser output:\n", res, "expected was:\n", expectedOutput, "Error:", err)
  529. return
  530. }
  531. input = `{
  532. my : field(size : 4)
  533. }`
  534. expectedOutput = `
  535. Document
  536. ExecutableDefinition
  537. OperationDefinition
  538. SelectionSet
  539. Field
  540. Alias: my
  541. Name: field
  542. Arguments
  543. Argument
  544. Name: size
  545. Value: 4
  546. `[1:]
  547. if res, err := Parse("mytest", input); err != nil || fmt.Sprint(res) != expectedOutput {
  548. t.Error("Unexpected parser output:\n", res, "expected was:\n", expectedOutput, "Error:", err)
  549. return
  550. }
  551. input = `{ my : field(4 : 4) }`
  552. if _, err := Parse("mytest", input); err == nil || err.Error() !=
  553. "Parse error in mytest: Name expected (int(4)) (Line:1 Pos:14)" {
  554. t.Error("Unexpected result:", err)
  555. return
  556. }
  557. input = `{
  558. my : field(size : 4, fred : "boo"),
  559. test(x:12.5e-50)
  560. foo
  561. bar(x:"[")
  562. }`
  563. expectedOutput = `
  564. Document
  565. ExecutableDefinition
  566. OperationDefinition
  567. SelectionSet
  568. Field
  569. Alias: my
  570. Name: field
  571. Arguments
  572. Argument
  573. Name: size
  574. Value: 4
  575. Argument
  576. Name: fred
  577. Value: boo
  578. Field
  579. Name: test
  580. Arguments
  581. Argument
  582. Name: x
  583. Value: 12.5e-50
  584. Field
  585. Name: foo
  586. Field
  587. Name: bar
  588. Arguments
  589. Argument
  590. Name: x
  591. Value: [
  592. `[1:]
  593. if res, err := Parse("mytest", input); err != nil || fmt.Sprint(res) != expectedOutput {
  594. t.Error("Unexpected parser output:\n", res, "expected was:\n", expectedOutput, "Error:", err)
  595. return
  596. }
  597. input = `{
  598. my : field(size : 4) @include(if: true)
  599. }`
  600. expectedOutput = `
  601. Document
  602. ExecutableDefinition
  603. OperationDefinition
  604. SelectionSet
  605. Field
  606. Alias: my
  607. Name: field
  608. Arguments
  609. Argument
  610. Name: size
  611. Value: 4
  612. Directives
  613. Directive
  614. Name: include
  615. Arguments
  616. Argument
  617. Name: if
  618. Value: true
  619. `[1:]
  620. if res, err := Parse("mytest", input); err != nil || fmt.Sprint(res) != expectedOutput {
  621. t.Error("Unexpected parser output:\n", res, "expected was:\n", expectedOutput, "Error:", err)
  622. return
  623. }
  624. input = `{
  625. my : field(size : 4) @include(if: true) @id() @foo(x:1 y:"z")
  626. }`
  627. expectedOutput = `
  628. Document
  629. ExecutableDefinition
  630. OperationDefinition
  631. SelectionSet
  632. Field
  633. Alias: my
  634. Name: field
  635. Arguments
  636. Argument
  637. Name: size
  638. Value: 4
  639. Directives
  640. Directive
  641. Name: include
  642. Arguments
  643. Argument
  644. Name: if
  645. Value: true
  646. Directive
  647. Name: id
  648. Arguments
  649. Directive
  650. Name: foo
  651. Arguments
  652. Argument
  653. Name: x
  654. Value: 1
  655. Argument
  656. Name: y
  657. Value: z
  658. `[1:]
  659. if res, err := Parse("mytest", input); err != nil || fmt.Sprint(res) != expectedOutput {
  660. t.Error("Unexpected parser output:\n", res, "expected was:\n", expectedOutput, "Error:", err)
  661. return
  662. }
  663. input = `# "user" represents one of many users in a graph of data, referred to by a
  664. # unique identifier.
  665. {
  666. user(id: 4) {
  667. name
  668. }
  669. }`
  670. expectedOutput = `
  671. Document
  672. ExecutableDefinition
  673. OperationDefinition
  674. SelectionSet
  675. Field
  676. Name: user
  677. Arguments
  678. Argument
  679. Name: id
  680. Value: 4
  681. SelectionSet
  682. Field
  683. Name: name
  684. `[1:]
  685. if res, err := Parse("mytest", input); err != nil || fmt.Sprint(res) != expectedOutput {
  686. t.Error("Unexpected parser output:\n", res, "expected was:\n", expectedOutput, "Error:", err)
  687. return
  688. }
  689. input = `{
  690. me {
  691. id
  692. firstName
  693. lastName
  694. birthday {
  695. month
  696. day
  697. }
  698. friends {
  699. name
  700. }
  701. }
  702. }
  703. `
  704. expectedOutput = `
  705. Document
  706. ExecutableDefinition
  707. OperationDefinition
  708. SelectionSet
  709. Field
  710. Name: me
  711. SelectionSet
  712. Field
  713. Name: id
  714. Field
  715. Name: firstName
  716. Field
  717. Name: lastName
  718. Field
  719. Name: birthday
  720. SelectionSet
  721. Field
  722. Name: month
  723. Field
  724. Name: day
  725. Field
  726. Name: friends
  727. SelectionSet
  728. Field
  729. Name: name
  730. `[1:]
  731. if res, err := Parse("mytest", input); err != nil || fmt.Sprint(res) != expectedOutput {
  732. t.Error("Unexpected parser output:\n", res, "expected was:\n", expectedOutput, "Error:", err)
  733. return
  734. }
  735. input = `{
  736. my : field(size : 4) @x(a:"b") @y(a:$b,c:$d) {
  737. foo : field(size : 4) @x(a:"b") @y(a:"b",c:"d")
  738. bar : test,
  739. }
  740. }`
  741. expectedOutput = `
  742. Document
  743. ExecutableDefinition
  744. OperationDefinition
  745. SelectionSet
  746. Field
  747. Alias: my
  748. Name: field
  749. Arguments
  750. Argument
  751. Name: size
  752. Value: 4
  753. Directives
  754. Directive
  755. Name: x
  756. Arguments
  757. Argument
  758. Name: a
  759. Value: b
  760. Directive
  761. Name: y
  762. Arguments
  763. Argument
  764. Name: a
  765. Variable: b
  766. Argument
  767. Name: c
  768. Variable: d
  769. SelectionSet
  770. Field
  771. Alias: foo
  772. Name: field
  773. Arguments
  774. Argument
  775. Name: size
  776. Value: 4
  777. Directives
  778. Directive
  779. Name: x
  780. Arguments
  781. Argument
  782. Name: a
  783. Value: b
  784. Directive
  785. Name: y
  786. Arguments
  787. Argument
  788. Name: a
  789. Value: b
  790. Argument
  791. Name: c
  792. Value: d
  793. Field
  794. Alias: bar
  795. Name: test
  796. `[1:]
  797. if res, err := Parse("mytest", input); err != nil || fmt.Sprint(res) != expectedOutput {
  798. t.Error("Unexpected parser output:\n", res, "expected was:\n", expectedOutput, "Error:", err)
  799. return
  800. }
  801. }
  802. func TestFragmentParsing(t *testing.T) {
  803. input := `
  804. fragment friendFields on User {
  805. id
  806. name
  807. profilePic(size: 50)
  808. }
  809. `
  810. expectedOutput := `
  811. Document
  812. ExecutableDefinition
  813. FragmentDefinition
  814. FragmentName: friendFields
  815. TypeCondition: User
  816. SelectionSet
  817. Field
  818. Name: id
  819. Field
  820. Name: name
  821. Field
  822. Name: profilePic
  823. Arguments
  824. Argument
  825. Name: size
  826. Value: 50
  827. `[1:]
  828. if res, err := Parse("mytest", input); err != nil || fmt.Sprint(res) != expectedOutput {
  829. t.Error("Unexpected parser output:\n", res, "expected was:\n", expectedOutput, "Error:", err)
  830. return
  831. }
  832. input = `
  833. fragment friendFields on User @foo() {
  834. id
  835. name
  836. profilePic(size: 50)
  837. }
  838. `
  839. expectedOutput = `
  840. Document
  841. ExecutableDefinition
  842. FragmentDefinition
  843. FragmentName: friendFields
  844. TypeCondition: User
  845. Directives
  846. Directive
  847. Name: foo
  848. Arguments
  849. SelectionSet
  850. Field
  851. Name: id
  852. Field
  853. Name: name
  854. Field
  855. Name: profilePic
  856. Arguments
  857. Argument
  858. Name: size
  859. Value: 50
  860. `[1:]
  861. if res, err := Parse("mytest", input); err != nil || fmt.Sprint(res) != expectedOutput {
  862. t.Error("Unexpected parser output:\n", res, "expected was:\n", expectedOutput, "Error:", err)
  863. return
  864. }
  865. input = `
  866. query withNestedFragments {
  867. user(id: 4) {
  868. friends(first: 10) {
  869. ...friendFields
  870. }
  871. mutualFriends(first: 10) {
  872. ...friendFields
  873. }
  874. }
  875. }
  876. fragment friendFields on User {
  877. id
  878. name
  879. ...standardProfilePic
  880. }
  881. fragment standardProfilePic on User {
  882. profilePic(size: 50)
  883. }
  884. `
  885. expectedOutput = `
  886. Document
  887. ExecutableDefinition
  888. OperationDefinition
  889. OperationType: query
  890. Name: withNestedFragments
  891. SelectionSet
  892. Field
  893. Name: user
  894. Arguments
  895. Argument
  896. Name: id
  897. Value: 4
  898. SelectionSet
  899. Field
  900. Name: friends
  901. Arguments
  902. Argument
  903. Name: first
  904. Value: 10
  905. SelectionSet
  906. FragmentSpread: friendFields
  907. Field
  908. Name: mutualFriends
  909. Arguments
  910. Argument
  911. Name: first
  912. Value: 10
  913. SelectionSet
  914. FragmentSpread: friendFields
  915. ExecutableDefinition
  916. FragmentDefinition
  917. FragmentName: friendFields
  918. TypeCondition: User
  919. SelectionSet
  920. Field
  921. Name: id
  922. Field
  923. Name: name
  924. FragmentSpread: standardProfilePic
  925. ExecutableDefinition
  926. FragmentDefinition
  927. FragmentName: standardProfilePic
  928. TypeCondition: User
  929. SelectionSet
  930. Field
  931. Name: profilePic
  932. Arguments
  933. Argument
  934. Name: size
  935. Value: 50
  936. `[1:]
  937. if res, err := Parse("mytest", input); err != nil || fmt.Sprint(res) != expectedOutput {
  938. t.Error("Unexpected parser output:\n", res, "expected was:\n", expectedOutput, "Error:", err)
  939. return
  940. }
  941. input = `
  942. query inlineFragmentTyping {
  943. profiles(handles: ["zuck", "cocacola"]) {
  944. handle
  945. ... on User {
  946. friends {
  947. count
  948. }
  949. }
  950. ... on Page {
  951. likers {
  952. count
  953. }
  954. }
  955. }
  956. }
  957. `
  958. expectedOutput = `
  959. Document
  960. ExecutableDefinition
  961. OperationDefinition
  962. OperationType: query
  963. Name: inlineFragmentTyping
  964. SelectionSet
  965. Field
  966. Name: profiles
  967. Arguments
  968. Argument
  969. Name: handles
  970. ListValue
  971. Value: zuck
  972. Value: cocacola
  973. SelectionSet
  974. Field
  975. Name: handle
  976. InlineFragment
  977. TypeCondition: User
  978. SelectionSet
  979. Field
  980. Name: friends
  981. SelectionSet
  982. Field
  983. Name: count
  984. InlineFragment
  985. TypeCondition: Page
  986. SelectionSet
  987. Field
  988. Name: likers
  989. SelectionSet
  990. Field
  991. Name: count
  992. `[1:]
  993. if res, err := Parse("mytest", input); err != nil || fmt.Sprint(res) != expectedOutput {
  994. t.Error("Unexpected parser output:\n", res, "expected was:\n", expectedOutput, "Error:", err)
  995. return
  996. }
  997. input = `
  998. query inlineFragmentNoType($expandedInfo: Boolean) {
  999. user(handle: "zuck") {
  1000. id
  1001. name
  1002. ... @include(if: $expandedInfo) {
  1003. firstName
  1004. lastName
  1005. birthday
  1006. }
  1007. }
  1008. }
  1009. `
  1010. expectedOutput = `
  1011. Document
  1012. ExecutableDefinition
  1013. OperationDefinition
  1014. OperationType: query
  1015. Name: inlineFragmentNoType
  1016. VariableDefinitions
  1017. VariableDefinition
  1018. Variable: expandedInfo
  1019. Type: Boolean
  1020. SelectionSet
  1021. Field
  1022. Name: user
  1023. Arguments
  1024. Argument
  1025. Name: handle
  1026. Value: zuck
  1027. SelectionSet
  1028. Field
  1029. Name: id
  1030. Field
  1031. Name: name
  1032. InlineFragment
  1033. Directives
  1034. Directive
  1035. Name: include
  1036. Arguments
  1037. Argument
  1038. Name: if
  1039. Variable: expandedInfo
  1040. SelectionSet
  1041. Field
  1042. Name: firstName
  1043. Field
  1044. Name: lastName
  1045. Field
  1046. Name: birthday
  1047. `[1:]
  1048. if res, err := Parse("mytest", input); err != nil || fmt.Sprint(res) != expectedOutput {
  1049. t.Error("Unexpected parser output:\n", res, "expected was:\n", expectedOutput, "Error:", err)
  1050. return
  1051. }
  1052. input = `fragment foo {}`
  1053. if out, err := Parse("mytest", input); err == nil || err.Error() !=
  1054. `Parse error in mytest: Type condition starting with 'on' expected ({) (Line:1 Pos:14)` {
  1055. t.Error("Unexpected output:", out, err)
  1056. return
  1057. }
  1058. input = `fragment on foo {}`
  1059. if out, err := Parse("mytest", input); err == nil || err.Error() !=
  1060. `Parse error in mytest: Type condition starting with 'on' expected (<foo>) (Line:1 Pos:13)` {
  1061. t.Error("Unexpected output:", out, err)
  1062. return
  1063. }
  1064. input = `
  1065. {
  1066. user(n:1) {
  1067. ...on
  1068. }
  1069. }
  1070. fragment on on User {
  1071. id
  1072. }
  1073. `
  1074. expectedOutput = `
  1075. Document
  1076. ExecutableDefinition
  1077. OperationDefinition
  1078. SelectionSet
  1079. Field
  1080. Name: user
  1081. Arguments
  1082. Argument
  1083. Name: n
  1084. Value: 1
  1085. SelectionSet
  1086. FragmentSpread: on
  1087. ExecutableDefinition
  1088. FragmentDefinition
  1089. FragmentName: on
  1090. TypeCondition: User
  1091. SelectionSet
  1092. Field
  1093. Name: id
  1094. `[1:]
  1095. if res, err := Parse("mytest", input); err != nil || fmt.Sprint(res) != expectedOutput {
  1096. t.Error("Unexpected parser output:\n", res, "expected was:\n", expectedOutput, "Error:", err)
  1097. return
  1098. }
  1099. input = `
  1100. {
  1101. ...1
  1102. }
  1103. `[1:]
  1104. if out, err := Parse("mytest", input); err == nil || err.Error() !=
  1105. `Parse error in mytest: Name expected (int(1)) (Line:2 Pos:9)` {
  1106. t.Error("Unexpected output:", out, err)
  1107. return
  1108. }
  1109. input = `
  1110. fragment {
  1111. field
  1112. }
  1113. `[1:]
  1114. if out, err := Parse("mytest", input); err == nil || err.Error() !=
  1115. `Parse error in mytest: Name expected ({) (Line:1 Pos:10)` {
  1116. t.Error("Unexpected output:", out, err)
  1117. return
  1118. }
  1119. input = `
  1120. fragment foo on {
  1121. field
  1122. }
  1123. `[1:]
  1124. if out, err := Parse("mytest", input); err == nil || err.Error() !=
  1125. `Parse error in mytest: Name expected ({) (Line:1 Pos:17)` {
  1126. t.Error("Unexpected output:", out, err)
  1127. return
  1128. }
  1129. input = `
  1130. fragment foo on bar
  1131. `[1:]
  1132. if out, err := Parse("mytest", input); err == nil || err.Error() !=
  1133. `Parse error in mytest: Selection Set expected (EOF) (Line:2 Pos:1)` {
  1134. t.Error("Unexpected output:", out, err)
  1135. return
  1136. }
  1137. }