selectionset_test.go 20 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271
  1. /*
  2. * EliasDB
  3. *
  4. * Copyright 2016 Matthias Ladkau. All rights reserved.
  5. *
  6. * This Source Code Form is subject to the terms of the Mozilla Public
  7. * License, v. 2.0. If a copy of the MPL was not distributed with this
  8. * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  9. */
  10. package interpreter
  11. import (
  12. "encoding/json"
  13. "testing"
  14. )
  15. func TestSortingAndLimiting(t *testing.T) {
  16. gm, _ := songGraphGroups()
  17. query := map[string]interface{}{
  18. "operationName": nil,
  19. "query": `
  20. {
  21. Song(ascending:"key") {
  22. key
  23. name
  24. }
  25. }
  26. `,
  27. "variables": nil,
  28. }
  29. if rerr := checkResult(`
  30. {
  31. "data": {
  32. "Song": [
  33. {
  34. "key": "Aria1",
  35. "name": "Aria1"
  36. },
  37. {
  38. "key": "Aria2",
  39. "name": "Aria2"
  40. },
  41. {
  42. "key": "Aria3",
  43. "name": "Aria3"
  44. },
  45. {
  46. "key": "Aria4",
  47. "name": "Aria4"
  48. },
  49. {
  50. "key": "DeadSong2",
  51. "name": "DeadSong2"
  52. },
  53. {
  54. "key": "FightSong4",
  55. "name": "FightSong4"
  56. },
  57. {
  58. "key": "LoveSong3",
  59. "name": "LoveSong3"
  60. },
  61. {
  62. "key": "MyOnlySong3",
  63. "name": "MyOnlySong3"
  64. },
  65. {
  66. "key": "StrangeSong1",
  67. "name": "StrangeSong1"
  68. }
  69. ]
  70. }
  71. }`[1:], query, gm); rerr != nil {
  72. t.Error(rerr)
  73. return
  74. }
  75. query = map[string]interface{}{
  76. "operationName": nil,
  77. "query": `
  78. {
  79. Song(ascending:"name", last: 3) {
  80. key
  81. name
  82. }
  83. }
  84. `,
  85. "variables": nil,
  86. }
  87. if rerr := checkResult(`
  88. {
  89. "data": {
  90. "Song": [
  91. {
  92. "key": "LoveSong3",
  93. "name": "LoveSong3"
  94. },
  95. {
  96. "key": "MyOnlySong3",
  97. "name": "MyOnlySong3"
  98. },
  99. {
  100. "key": "StrangeSong1",
  101. "name": "StrangeSong1"
  102. }
  103. ]
  104. }
  105. }`[1:], query, gm); rerr != nil {
  106. t.Error(rerr)
  107. return
  108. }
  109. query = map[string]interface{}{
  110. "operationName": nil,
  111. "query": `
  112. {
  113. Song(descending:"name", last: 3) {
  114. key
  115. name
  116. }
  117. }
  118. `,
  119. "variables": nil,
  120. }
  121. if rerr := checkResult(`
  122. {
  123. "data": {
  124. "Song": [
  125. {
  126. "key": "Aria3",
  127. "name": "Aria3"
  128. },
  129. {
  130. "key": "Aria2",
  131. "name": "Aria2"
  132. },
  133. {
  134. "key": "Aria1",
  135. "name": "Aria1"
  136. }
  137. ]
  138. }
  139. }`[1:], query, gm); rerr != nil {
  140. t.Error(rerr)
  141. return
  142. }
  143. query = map[string]interface{}{
  144. "operationName": nil,
  145. "query": `
  146. {
  147. Song(ascending:"name", items: 2, last: 3) {
  148. key
  149. name
  150. }
  151. }
  152. `,
  153. "variables": nil,
  154. }
  155. if rerr := checkResult(`
  156. {
  157. "data": {
  158. "Song": [
  159. {
  160. "key": "LoveSong3",
  161. "name": "LoveSong3"
  162. },
  163. {
  164. "key": "MyOnlySong3",
  165. "name": "MyOnlySong3"
  166. }
  167. ]
  168. }
  169. }`[1:], query, gm); rerr != nil {
  170. t.Error(rerr)
  171. return
  172. }
  173. // From the last 3 we retrieve item 1 and the next
  174. query = map[string]interface{}{
  175. "operationName": nil,
  176. "query": `
  177. {
  178. Song(ascending:"name", from : 1, items: 2, last: 3) {
  179. key
  180. name
  181. }
  182. }
  183. `,
  184. "variables": nil,
  185. }
  186. if rerr := checkResult(`
  187. {
  188. "data": {
  189. "Song": [
  190. {
  191. "key": "MyOnlySong3",
  192. "name": "MyOnlySong3"
  193. },
  194. {
  195. "key": "StrangeSong1",
  196. "name": "StrangeSong1"
  197. }
  198. ]
  199. }
  200. }`[1:], query, gm); rerr != nil {
  201. t.Error(rerr)
  202. return
  203. }
  204. query = map[string]interface{}{
  205. "operationName": nil,
  206. "query": `
  207. {
  208. Song(ascending:"name", from : 100, items: 200, last: 2) {
  209. key
  210. name
  211. }
  212. }
  213. `,
  214. "variables": nil,
  215. }
  216. if rerr := checkResult(`
  217. {
  218. "data": {
  219. "Song": [
  220. {
  221. "key": "MyOnlySong3",
  222. "name": "MyOnlySong3"
  223. },
  224. {
  225. "key": "StrangeSong1",
  226. "name": "StrangeSong1"
  227. }
  228. ]
  229. }
  230. }`[1:], query, gm); rerr != nil {
  231. t.Error(rerr)
  232. return
  233. }
  234. query = map[string]interface{}{
  235. "operationName": nil,
  236. "query": `
  237. {
  238. Song(ascending:"name", descending:"key") {
  239. key
  240. name
  241. }
  242. }
  243. `,
  244. "variables": nil,
  245. }
  246. if rerr := checkResult(`
  247. {
  248. "data": {
  249. "Song": []
  250. },
  251. "errors": [
  252. {
  253. "locations": [
  254. {
  255. "column": 45,
  256. "line": 3
  257. }
  258. ],
  259. "message": "Cannot specify ascending and descending sorting",
  260. "path": [
  261. "Song"
  262. ]
  263. }
  264. ]
  265. }`[1:], query, gm); rerr != nil {
  266. t.Error(rerr)
  267. return
  268. }
  269. query = map[string]interface{}{
  270. "operationName": nil,
  271. "query": `
  272. {
  273. Song(ascending:"hans") {
  274. key
  275. name
  276. }
  277. }
  278. `,
  279. "variables": nil,
  280. }
  281. if rerr := checkResult(`
  282. {
  283. "data": {
  284. "Song": [
  285. {
  286. "key": "StrangeSong1",
  287. "name": "StrangeSong1"
  288. },
  289. {
  290. "key": "FightSong4",
  291. "name": "FightSong4"
  292. },
  293. {
  294. "key": "DeadSong2",
  295. "name": "DeadSong2"
  296. },
  297. {
  298. "key": "LoveSong3",
  299. "name": "LoveSong3"
  300. },
  301. {
  302. "key": "MyOnlySong3",
  303. "name": "MyOnlySong3"
  304. },
  305. {
  306. "key": "Aria1",
  307. "name": "Aria1"
  308. },
  309. {
  310. "key": "Aria2",
  311. "name": "Aria2"
  312. },
  313. {
  314. "key": "Aria3",
  315. "name": "Aria3"
  316. },
  317. {
  318. "key": "Aria4",
  319. "name": "Aria4"
  320. }
  321. ]
  322. }
  323. }`[1:], query, gm); rerr != nil {
  324. t.Error(rerr)
  325. return
  326. }
  327. }
  328. func TestFragments(t *testing.T) {
  329. gm, _ := songGraphGroups()
  330. // Test fragments for different return types
  331. query := map[string]interface{}{
  332. "operationName": nil,
  333. "query": `
  334. {
  335. Song(key : "StrangeSong1") {
  336. song_key : key
  337. foo : bar(traverse : ":::") {
  338. key
  339. kind
  340. ...groupFields
  341. ...authorFields @skip(if: false)
  342. }
  343. }
  344. }
  345. fragment groupFields on group {
  346. owner
  347. }
  348. fragment authorFields on Author {
  349. name
  350. }
  351. `,
  352. "variables": nil,
  353. }
  354. if rerr := checkResult(`
  355. {
  356. "data": {
  357. "Song": [
  358. {
  359. "foo": [
  360. {
  361. "key": "123",
  362. "kind": "Author",
  363. "name": "Mike"
  364. },
  365. {
  366. "key": "Best",
  367. "kind": "group",
  368. "owner": "noowner"
  369. }
  370. ],
  371. "song_key": "StrangeSong1"
  372. }
  373. ]
  374. }
  375. }`[1:], query, gm); rerr != nil {
  376. t.Error(rerr)
  377. return
  378. }
  379. // Test fragments for different return types - now using inline fragments
  380. query = map[string]interface{}{
  381. "operationName": nil,
  382. "query": `
  383. {
  384. Song(key : "StrangeSong1") {
  385. song_key : key
  386. foo : bar(traverse : ":::") {
  387. key
  388. kind
  389. ... on group @skip(if: false) {
  390. owner
  391. }
  392. ... on Author {
  393. name
  394. }
  395. }
  396. }
  397. }
  398. `,
  399. "variables": nil,
  400. }
  401. if rerr := checkResult(`
  402. {
  403. "data": {
  404. "Song": [
  405. {
  406. "foo": [
  407. {
  408. "key": "123",
  409. "kind": "Author",
  410. "name": "Mike"
  411. },
  412. {
  413. "key": "Best",
  414. "kind": "group",
  415. "owner": "noowner"
  416. }
  417. ],
  418. "song_key": "StrangeSong1"
  419. }
  420. ]
  421. }
  422. }`[1:], query, gm); rerr != nil {
  423. t.Error(rerr)
  424. return
  425. }
  426. query = map[string]interface{}{
  427. "operationName": nil,
  428. "query": `
  429. {
  430. key
  431. name1 : name
  432. ...SongKind
  433. ...foo
  434. }
  435. fragment SongKind on Song {
  436. kind
  437. name2 : name
  438. key
  439. }
  440. `,
  441. "variables": nil,
  442. }
  443. if rerr := checkResult("", query, gm); rerr == nil ||
  444. rerr.Error() != "Fatal GraphQL query error in test: Invalid construct (Fragment foo is not defined) (Line:2 Pos:2)" {
  445. t.Error(rerr)
  446. return
  447. }
  448. query = map[string]interface{}{
  449. "operationName": nil,
  450. "query": `
  451. {
  452. key
  453. name1 : name
  454. ...SongKind
  455. ...foo
  456. }
  457. fragment SongKind on Song {
  458. kind
  459. name2 : name
  460. key
  461. }
  462. fragment SongKind on Song {
  463. kind
  464. name2 : name
  465. key
  466. }
  467. `,
  468. "variables": nil,
  469. }
  470. if rerr := checkResult("", query, gm); rerr == nil ||
  471. rerr.Error() != "Fatal GraphQL query error in test: Ambiguous definition (Fragment SongKind defined multiple times) (Line:2 Pos:2)" {
  472. t.Error(rerr)
  473. return
  474. }
  475. }
  476. func TestMutation(t *testing.T) {
  477. gm, _ := songGraphGroups()
  478. query := map[string]interface{}{
  479. "operationName": nil,
  480. "query": `
  481. {
  482. Song(storeNode : {
  483. key:"newsongkey",
  484. name:"newsongname"
  485. }, key : "newsongkey") {
  486. key,
  487. name
  488. }
  489. }
  490. `,
  491. "variables": nil,
  492. }
  493. if rerr := checkResult(`
  494. {
  495. "data": {
  496. "Song": []
  497. },
  498. "errors": [
  499. {
  500. "locations": [
  501. {
  502. "column": 25,
  503. "line": 6
  504. }
  505. ],
  506. "message": "Operation must be a mutation to modify data",
  507. "path": [
  508. "Song"
  509. ]
  510. }
  511. ]
  512. }`[1:], query, gm); rerr != nil {
  513. t.Error(rerr)
  514. return
  515. }
  516. query = map[string]interface{}{
  517. "operationName": nil,
  518. "query": `
  519. mutation {
  520. Song(storeNode : {
  521. key : "newsongkey",
  522. name : "newsongname"
  523. }, storeEdge : {
  524. key : "newedgekey",
  525. kind : "newedgekind"
  526. end1key : "newsongkey",
  527. end1kind : "Song",
  528. end1role : "song",
  529. end1cascading : false,
  530. end2key : "Best",
  531. end2kind : "group",
  532. end2role : "group",
  533. end2cascading : false,
  534. },key : "newsongkey") {
  535. key,
  536. name,
  537. group(traverse : ":::group") {
  538. key
  539. otherMembers(traverse : ":::Song", matches : {
  540. not_key : "newsongkey",
  541. name : "^.*Song[0-9]$"
  542. }) {
  543. key,
  544. kind,
  545. name,
  546. }
  547. }
  548. }
  549. }
  550. `,
  551. "variables": nil,
  552. }
  553. result, _ := runQuery("test", "main", query, gm, nil, true)
  554. actualResultBytes, _ := json.MarshalIndent(result, "", " ")
  555. actualResult := string(actualResultBytes)
  556. if actualResult != `{
  557. "data": {
  558. "Song": []
  559. },
  560. "errors": [
  561. {
  562. "locations": [
  563. {
  564. "column": 26,
  565. "line": 17
  566. }
  567. ],
  568. "message": "Can only perform read operations",
  569. "path": [
  570. "Song"
  571. ]
  572. }
  573. ]
  574. }` {
  575. t.Error("Unexpected result:", actualResult)
  576. return
  577. }
  578. if rerr := checkResult(`
  579. {
  580. "data": {
  581. "Song": [
  582. {
  583. "group": [
  584. {
  585. "key": "Best",
  586. "otherMembers": [
  587. {
  588. "key": "LoveSong3",
  589. "kind": "Song",
  590. "name": "LoveSong3"
  591. },
  592. {
  593. "key": "MyOnlySong3",
  594. "kind": "Song",
  595. "name": "MyOnlySong3"
  596. },
  597. {
  598. "key": "StrangeSong1",
  599. "kind": "Song",
  600. "name": "StrangeSong1"
  601. }
  602. ]
  603. }
  604. ],
  605. "key": "newsongkey",
  606. "name": "newsongname"
  607. }
  608. ]
  609. }
  610. }`[1:], query, gm); rerr != nil {
  611. t.Error(rerr)
  612. return
  613. }
  614. query = map[string]interface{}{
  615. "operationName": nil,
  616. "query": `
  617. mutation {
  618. Song(removeNode : {
  619. key : "newsongkey",
  620. }, removeEdge : {
  621. key : "newedgekey",
  622. kind : "newedgekind"
  623. },key : "newsongkey") {
  624. key,
  625. name,
  626. group(traverse : ":::group") {
  627. key
  628. otherMembers(traverse : ":::Song", matches : {
  629. not_key : "newsongkey",
  630. name : "^.*Song[0-9]$"
  631. }) {
  632. key,
  633. kind,
  634. name,
  635. }
  636. }
  637. }
  638. }
  639. `,
  640. "variables": nil,
  641. }
  642. if rerr := checkResult(`
  643. {
  644. "data": {
  645. "Song": []
  646. }
  647. }`[1:], query, gm); rerr != nil {
  648. t.Error(rerr)
  649. return
  650. }
  651. query = map[string]interface{}{
  652. "operationName": nil,
  653. "query": `
  654. mutation {
  655. Song(storeNode : "Hans", storeEdge : "Franz", key : "Honk") {
  656. key,
  657. name,
  658. }
  659. }`,
  660. "variables": nil,
  661. }
  662. if rerr := checkResult(`{
  663. "data": {
  664. "Song": []
  665. },
  666. "errors": [
  667. {
  668. "locations": [
  669. {
  670. "column": 64,
  671. "line": 3
  672. }
  673. ],
  674. "message": "Object required for node attributes and values",
  675. "path": [
  676. "Song"
  677. ]
  678. },
  679. {
  680. "locations": [
  681. {
  682. "column": 64,
  683. "line": 3
  684. }
  685. ],
  686. "message": "Object required for edge attributes and values",
  687. "path": [
  688. "Song"
  689. ]
  690. }
  691. ]
  692. }`, query, gm); rerr != nil {
  693. t.Error(rerr)
  694. return
  695. }
  696. query = map[string]interface{}{
  697. "operationName": nil,
  698. "query": `
  699. mutation {
  700. Song(removeNode : "Hans", removeEdge : "Franz", key : "Honk") {
  701. key,
  702. name,
  703. }
  704. }`,
  705. "variables": nil,
  706. }
  707. if rerr := checkResult(`{
  708. "data": {
  709. "Song": []
  710. },
  711. "errors": [
  712. {
  713. "locations": [
  714. {
  715. "column": 66,
  716. "line": 3
  717. }
  718. ],
  719. "message": "Object required for node key and kind",
  720. "path": [
  721. "Song"
  722. ]
  723. },
  724. {
  725. "locations": [
  726. {
  727. "column": 66,
  728. "line": 3
  729. }
  730. ],
  731. "message": "Object required for edge key and kind",
  732. "path": [
  733. "Song"
  734. ]
  735. }
  736. ]
  737. }`, query, gm); rerr != nil {
  738. t.Error(rerr)
  739. return
  740. }
  741. }
  742. func TestTraversals(t *testing.T) {
  743. gm, _ := songGraphGroups()
  744. query := map[string]interface{}{
  745. "operationName": nil,
  746. "query": `
  747. {
  748. Song(key : "StrangeSong1") {
  749. song_key : key
  750. foo : bar(traverse : ":::") {
  751. key
  752. kind
  753. Name : name
  754. }
  755. }
  756. }
  757. `,
  758. "variables": nil,
  759. }
  760. if rerr := checkResult(`
  761. {
  762. "data": {
  763. "Song": [
  764. {
  765. "foo": [
  766. {
  767. "Name": "Mike",
  768. "key": "123",
  769. "kind": "Author"
  770. },
  771. {
  772. "Name": null,
  773. "key": "Best",
  774. "kind": "group"
  775. }
  776. ],
  777. "song_key": "StrangeSong1"
  778. }
  779. ]
  780. }
  781. }`[1:], query, gm); rerr != nil {
  782. t.Error(rerr)
  783. return
  784. }
  785. query = map[string]interface{}{
  786. "operationName": nil,
  787. "query": `
  788. {
  789. Song(key : "StrangeSong1") {
  790. song_key : key
  791. foo : bar(traverse : ":::Author") {
  792. kind() {}
  793. }
  794. }
  795. }
  796. `,
  797. "variables": nil,
  798. }
  799. if rerr := checkResult(`
  800. {
  801. "data": {
  802. "Song": [
  803. {
  804. "foo": [
  805. {
  806. "kind": "Author"
  807. }
  808. ],
  809. "song_key": "StrangeSong1"
  810. }
  811. ]
  812. },
  813. "errors": [
  814. {
  815. "locations": [
  816. {
  817. "column": 9,
  818. "line": 6
  819. }
  820. ],
  821. "message": "Traversal argument is missing",
  822. "path": [
  823. "Song",
  824. ":::Author"
  825. ]
  826. }
  827. ]
  828. }`[1:], query, gm); rerr != nil {
  829. t.Error(rerr)
  830. return
  831. }
  832. }
  833. func TestListQueries(t *testing.T) {
  834. gm, _ := songGraphGroups()
  835. query := map[string]interface{}{
  836. "operationName": "foo",
  837. "query": `
  838. {
  839. Song {
  840. key
  841. }
  842. }
  843. `,
  844. "variables": nil,
  845. }
  846. _, err := runQuery("test", "main", query, gm, nil, false)
  847. if err == nil || err.Error() != "Fatal GraphQL operation error in test: Missing operation (Operation foo not found) (Line:2 Pos:2)" {
  848. t.Error("Unexpected result:", err)
  849. return
  850. }
  851. query = map[string]interface{}{
  852. "operationName": nil,
  853. "query": `
  854. fragment friendFields on User {
  855. id
  856. name
  857. profilePic(size: 50)
  858. }
  859. `,
  860. "variables": nil,
  861. }
  862. res, err := runQuery("test", "main", query, gm, nil, false)
  863. if err == nil || err.Error() != "Fatal GraphQL operation error in test: Missing operation (No executable expression found) (Line:2 Pos:2)" {
  864. t.Error("Unexpected result:", res, err)
  865. return
  866. }
  867. query = map[string]interface{}{
  868. "operationName": nil,
  869. "query": `
  870. {
  871. Song1 : Song {
  872. song_key : key
  873. song_key1 : key
  874. song_key1 : name # This is illegal and will be ignored
  875. song_key1 : key
  876. name
  877. name
  878. }
  879. group {
  880. key
  881. },
  882. }
  883. `,
  884. "variables": nil,
  885. }
  886. if rerr := checkResult(`
  887. {
  888. "data": {
  889. "Song1": [
  890. {
  891. "name": "StrangeSong1",
  892. "song_key": "StrangeSong1",
  893. "song_key1": "StrangeSong1"
  894. },
  895. {
  896. "name": "FightSong4",
  897. "song_key": "FightSong4",
  898. "song_key1": "FightSong4"
  899. },
  900. {
  901. "name": "DeadSong2",
  902. "song_key": "DeadSong2",
  903. "song_key1": "DeadSong2"
  904. },
  905. {
  906. "name": "LoveSong3",
  907. "song_key": "LoveSong3",
  908. "song_key1": "LoveSong3"
  909. },
  910. {
  911. "name": "MyOnlySong3",
  912. "song_key": "MyOnlySong3",
  913. "song_key1": "MyOnlySong3"
  914. },
  915. {
  916. "name": "Aria1",
  917. "song_key": "Aria1",
  918. "song_key1": "Aria1"
  919. },
  920. {
  921. "name": "Aria2",
  922. "song_key": "Aria2",
  923. "song_key1": "Aria2"
  924. },
  925. {
  926. "name": "Aria3",
  927. "song_key": "Aria3",
  928. "song_key1": "Aria3"
  929. },
  930. {
  931. "name": "Aria4",
  932. "song_key": "Aria4",
  933. "song_key1": "Aria4"
  934. }
  935. ],
  936. "group": [
  937. {
  938. "key": "Best"
  939. }
  940. ]
  941. },
  942. "errors": [
  943. {
  944. "locations": [
  945. {
  946. "column": 17,
  947. "line": 3
  948. }
  949. ],
  950. "message": "Field identifier song_key1 used multiple times",
  951. "path": [
  952. "Song1"
  953. ]
  954. },
  955. {
  956. "locations": [
  957. {
  958. "column": 17,
  959. "line": 3
  960. }
  961. ],
  962. "message": "Field identifier name used multiple times",
  963. "path": [
  964. "Song1"
  965. ]
  966. }
  967. ]
  968. }`[1:], query, gm); rerr != nil {
  969. t.Error(rerr)
  970. return
  971. }
  972. query = map[string]interface{}{
  973. "operationName": nil,
  974. "query": `
  975. {
  976. Song(key : "StrangeSong1") {
  977. song_key : key
  978. name
  979. }
  980. }
  981. `,
  982. "variables": nil,
  983. }
  984. if rerr := checkResult(`
  985. {
  986. "data": {
  987. "Song": [
  988. {
  989. "name": "StrangeSong1",
  990. "song_key": "StrangeSong1"
  991. }
  992. ]
  993. }
  994. }`[1:], query, gm); rerr != nil {
  995. t.Error(rerr)
  996. return
  997. }
  998. query = map[string]interface{}{
  999. "operationName": nil,
  1000. "query": `
  1001. {
  1002. Song(matches : { name : "Aria[2-4]", not_name : "Aria4", foo : "a[" }) {
  1003. song_key : key
  1004. }
  1005. }
  1006. `,
  1007. "variables": nil,
  1008. }
  1009. if rerr := checkResult(`
  1010. {
  1011. "data": {
  1012. "Song": [
  1013. {
  1014. "song_key": "Aria2"
  1015. },
  1016. {
  1017. "song_key": "Aria3"
  1018. }
  1019. ]
  1020. },
  1021. "errors": [
  1022. {
  1023. "locations": [
  1024. {
  1025. "column": 79,
  1026. "line": 3
  1027. }
  1028. ],
  1029. "message": "Regex a[ did not compile: error parsing regexp: missing closing ]: `[1:]+"`[`"+`",
  1030. "path": [
  1031. "Song"
  1032. ]
  1033. }
  1034. ]
  1035. }`, query, gm); rerr != nil {
  1036. t.Error(rerr)
  1037. return
  1038. }
  1039. query = map[string]interface{}{
  1040. "operationName": nil,
  1041. "query": `
  1042. {
  1043. Song(matches : { name1 : "test" }) {
  1044. song_key : key
  1045. }
  1046. }
  1047. `,
  1048. "variables": nil,
  1049. }
  1050. if rerr := checkResult(`{
  1051. "data": {
  1052. "Song": []
  1053. }
  1054. }`, query, gm); rerr != nil {
  1055. t.Error(rerr)
  1056. return
  1057. }
  1058. query = map[string]interface{}{
  1059. "operationName": nil,
  1060. "query": `
  1061. {
  1062. Song(matches : [ "name1", "test" ]) {
  1063. }
  1064. }
  1065. `,
  1066. "variables": nil,
  1067. }
  1068. if rerr := checkResult(`{
  1069. "data": {
  1070. "Song": [
  1071. {},
  1072. {},
  1073. {},
  1074. {},
  1075. {},
  1076. {},
  1077. {},
  1078. {},
  1079. {}
  1080. ]
  1081. },
  1082. "errors": [
  1083. {
  1084. "locations": [
  1085. {
  1086. "column": 45,
  1087. "line": 3
  1088. }
  1089. ],
  1090. "message": "Matches expression is not a map",
  1091. "path": [
  1092. "Song"
  1093. ]
  1094. }
  1095. ]
  1096. }`, query, gm); rerr != nil {
  1097. t.Error(rerr)
  1098. return
  1099. }
  1100. query = map[string]interface{}{
  1101. "operationName": nil,
  1102. "query": `
  1103. fragment Song on Song {
  1104. key
  1105. name1 : name
  1106. ...SongKind
  1107. }
  1108. query b { # This should be executed
  1109. Song {
  1110. key
  1111. ...Song
  1112. }
  1113. }
  1114. query a {
  1115. Song1 {
  1116. key1
  1117. }
  1118. }
  1119. fragment SongKind on Song {
  1120. kind
  1121. name2 : name
  1122. key
  1123. }
  1124. `,
  1125. "variables": nil,
  1126. }
  1127. if rerr := checkResult(`
  1128. {
  1129. "data": {
  1130. "Song": [
  1131. {
  1132. "key": "StrangeSong1",
  1133. "kind": "Song",
  1134. "name1": "StrangeSong1",
  1135. "name2": "StrangeSong1"
  1136. },
  1137. {
  1138. "key": "FightSong4",
  1139. "kind": "Song",
  1140. "name1": "FightSong4",
  1141. "name2": "FightSong4"
  1142. },
  1143. {
  1144. "key": "DeadSong2",
  1145. "kind": "Song",
  1146. "name1": "DeadSong2",
  1147. "name2": "DeadSong2"
  1148. },
  1149. {
  1150. "key": "LoveSong3",
  1151. "kind": "Song",
  1152. "name1": "LoveSong3",
  1153. "name2": "LoveSong3"
  1154. },
  1155. {
  1156. "key": "MyOnlySong3",
  1157. "kind": "Song",
  1158. "name1": "MyOnlySong3",
  1159. "name2": "MyOnlySong3"
  1160. },
  1161. {
  1162. "key": "Aria1",
  1163. "kind": "Song",
  1164. "name1": "Aria1",
  1165. "name2": "Aria1"
  1166. },
  1167. {
  1168. "key": "Aria2",
  1169. "kind": "Song",
  1170. "name1": "Aria2",
  1171. "name2": "Aria2"
  1172. },
  1173. {
  1174. "key": "Aria3",
  1175. "kind": "Song",
  1176. "name1": "Aria3",
  1177. "name2": "Aria3"
  1178. },
  1179. {
  1180. "key": "Aria4",
  1181. "kind": "Song",
  1182. "name1": "Aria4",
  1183. "name2": "Aria4"
  1184. }
  1185. ]
  1186. },
  1187. "errors": [
  1188. {
  1189. "locations": [
  1190. {
  1191. "column": 9,
  1192. "line": 8
  1193. }
  1194. ],
  1195. "message": "Field identifier key used multiple times",
  1196. "path": [
  1197. "Song"
  1198. ]
  1199. }
  1200. ]
  1201. }`[1:], query, gm); rerr != nil {
  1202. t.Error(rerr)
  1203. return
  1204. }
  1205. }