parse.lua 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547
  1. describe('parse', function()
  2. local parse = require 'graphql.parse'
  3. test('comments', function()
  4. local document
  5. document = parse('#')
  6. expect(document.definitions).to.equal({})
  7. document = parse('#{}')
  8. expect(document.definitions).to.equal({})
  9. expect(parse('{}').definitions).to_not.equal({})
  10. expect(function() parse('{}#a$b@') end).to_not.fail()
  11. expect(function() parse('{a(b:"#")}') end).to_not.fail()
  12. end)
  13. test('document', function()
  14. local document
  15. expect(function() parse() end).to.fail()
  16. expect(function() parse('foo') end).to.fail()
  17. expect(function() parse('query') end).to.fail()
  18. expect(function() parse('query{} foo') end).to.fail()
  19. document = parse('')
  20. expect(document.kind).to.equal('document')
  21. expect(document.definitions).to.equal({})
  22. document = parse('query{} mutation{} {}')
  23. expect(document.kind).to.equal('document')
  24. expect(#document.definitions).to.equal(3)
  25. end)
  26. describe('operation', function()
  27. local operation
  28. test('shorthand', function()
  29. operation = parse('{}').definitions[1]
  30. expect(operation.kind).to.equal('operation')
  31. expect(operation.name).to_not.exist()
  32. expect(operation.operation).to.equal('query')
  33. end)
  34. test('operationType', function()
  35. operation = parse('query{}').definitions[1]
  36. expect(operation.operation).to.equal('query')
  37. operation = parse('mutation{}').definitions[1]
  38. expect(operation.operation).to.equal('mutation')
  39. expect(function() parse('kneeReplacement{}') end).to.fail()
  40. end)
  41. test('name', function()
  42. operation = parse('query{}').definitions[1]
  43. expect(operation.name).to_not.exist()
  44. operation = parse('query queryName{}').definitions[1]
  45. expect(operation.name).to.exist()
  46. expect(operation.name.value).to.equal('queryName')
  47. end)
  48. test('variableDefinitions', function()
  49. expect(function() parse('query(){}') end).to.fail()
  50. expect(function() parse('query(x){}') end).to.fail()
  51. operation = parse('query name($a:Int,$b:Int){}').definitions[1]
  52. expect(operation.name.value).to.equal('name')
  53. expect(operation.variableDefinitions).to.exist()
  54. expect(#operation.variableDefinitions).to.equal(2)
  55. operation = parse('query($a:Int,$b:Int){}').definitions[1]
  56. expect(operation.variableDefinitions).to.exist()
  57. expect(#operation.variableDefinitions).to.equal(2)
  58. end)
  59. test('directives', function()
  60. local operation = parse('query{}').definitions[1]
  61. expect(operation.directives).to_not.exist()
  62. local operation = parse('query @a{}').definitions[1]
  63. expect(#operation.directives).to.exist()
  64. local operation = parse('query name @a{}').definitions[1]
  65. expect(#operation.directives).to.exist()
  66. local operation = parse('query ($a:Int) @a {}').definitions[1]
  67. expect(#operation.directives).to.exist()
  68. local operation = parse('query name ($a:Int) @a {}').definitions[1]
  69. expect(#operation.directives).to.exist()
  70. end)
  71. end)
  72. describe('fragmentDefinition', function()
  73. local fragment
  74. test('fragmentName', function()
  75. expect(function() parse('fragment {}') end).to.fail()
  76. expect(function() parse('fragment on x {}') end).to.fail()
  77. expect(function() parse('fragment on on x {}') end).to.fail()
  78. fragment = parse('fragment x on y {}').definitions[1]
  79. expect(fragment.kind).to.equal('fragmentDefinition')
  80. expect(fragment.name.value).to.equal('x')
  81. end)
  82. test('typeCondition', function()
  83. expect(function() parse('fragment x {}') end).to.fail()
  84. fragment = parse('fragment x on y {}').definitions[1]
  85. expect(fragment.typeCondition.name.value).to.equal('y')
  86. end)
  87. test('selectionSet', function()
  88. expect(function() parse('fragment x on y') end).to.fail()
  89. fragment = parse('fragment x on y {}').definitions[1]
  90. expect(fragment.selectionSet).to.exist()
  91. end)
  92. end)
  93. test('selectionSet', function()
  94. local selectionSet
  95. expect(function() parse('{') end).to.fail()
  96. expect(function() parse('}') end).to.fail()
  97. selectionSet = parse('{}').definitions[1].selectionSet
  98. expect(selectionSet.kind).to.equal('selectionSet')
  99. expect(selectionSet.selections).to.equal({})
  100. selectionSet = parse('{a b}').definitions[1].selectionSet
  101. expect(#selectionSet.selections).to.equal(2)
  102. end)
  103. describe('field', function()
  104. local field
  105. test('name', function()
  106. expect(function() parse('{$a}') end).to.fail()
  107. expect(function() parse('{@a}') end).to.fail()
  108. expect(function() parse('{.}') end).to.fail()
  109. expect(function() parse('{,}') end).to.fail()
  110. field = parse('{a}').definitions[1].selectionSet.selections[1]
  111. expect(field.kind).to.equal('field')
  112. expect(field.name.value).to.equal('a')
  113. end)
  114. test('alias', function()
  115. expect(function() parse('{a:b:}') end).to.fail()
  116. expect(function() parse('{a:b:c}') end).to.fail()
  117. expect(function() parse('{:a}') end).to.fail()
  118. field = parse('{a}').definitions[1].selectionSet.selections[1]
  119. expect(field.alias).to_not.exist()
  120. field = parse('{a:b}').definitions[1].selectionSet.selections[1]
  121. expect(field.alias).to.exist()
  122. expect(field.alias.kind).to.equal('alias')
  123. expect(field.alias.name.value).to.equal('a')
  124. expect(field.name.value).to.equal('b')
  125. end)
  126. test('arguments', function()
  127. expect(function() parse('{a()}') end).to.fail()
  128. field = parse('{a}').definitions[1].selectionSet.selections[1]
  129. expect(field.arguments).to_not.exist()
  130. field = parse('{a(b:false)}').definitions[1].selectionSet.selections[1]
  131. expect(field.arguments).to.exist()
  132. end)
  133. test('directives', function()
  134. expect(function() parse('{a@skip(b:false)(c:true)}') end).to.fail()
  135. field = parse('{a}').definitions[1].selectionSet.selections[1]
  136. expect(field.directives).to_not.exist()
  137. field = parse('{a@skip}').definitions[1].selectionSet.selections[1]
  138. expect(field.directives).to.exist()
  139. field = parse('{a(b:1)@skip}').definitions[1].selectionSet.selections[1]
  140. expect(field.directives).to.exist()
  141. end)
  142. test('selectionSet', function()
  143. expect(function() parse('{{}}') end).to.fail()
  144. field = parse('{a}').definitions[1].selectionSet.selections[1]
  145. expect(field.selectionSet).to_not.exist()
  146. field = parse('{a{}}').definitions[1].selectionSet.selections[1]
  147. expect(field.selectionSet).to.exist()
  148. field = parse('{a{a}}').definitions[1].selectionSet.selections[1]
  149. expect(field.selectionSet).to.exist()
  150. field = parse('{a(b:1)@skip{a}}').definitions[1].selectionSet.selections[1]
  151. expect(field.selectionSet).to.exist()
  152. end)
  153. end)
  154. describe('fragmentSpread', function()
  155. local fragmentSpread
  156. test('name', function()
  157. expect(function() parse('{..a}') end).to.fail()
  158. expect(function() parse('{...}') end).to.fail()
  159. fragmentSpread = parse('{...a}').definitions[1].selectionSet.selections[1]
  160. expect(fragmentSpread.kind).to.equal('fragmentSpread')
  161. expect(fragmentSpread.name.value).to.equal('a')
  162. end)
  163. test('directives', function()
  164. expect(function() parse('{...a@}') end).to.fail()
  165. fragmentSpread = parse('{...a}').definitions[1].selectionSet.selections[1]
  166. expect(fragmentSpread.directives).to_not.exist()
  167. fragmentSpread = parse('{...a@skip}').definitions[1].selectionSet.selections[1]
  168. expect(fragmentSpread.directives).to.exist()
  169. end)
  170. end)
  171. describe('inlineFragment', function()
  172. local inlineFragment
  173. test('typeCondition', function()
  174. expect(function() parse('{...on{}}') end).to.fail()
  175. inlineFragment = parse('{...{}}').definitions[1].selectionSet.selections[1]
  176. expect(inlineFragment.kind).to.equal('inlineFragment')
  177. expect(inlineFragment.typeCondition).to_not.exist()
  178. inlineFragment = parse('{...on a{}}').definitions[1].selectionSet.selections[1]
  179. expect(inlineFragment.typeCondition).to.exist()
  180. expect(inlineFragment.typeCondition.name.value).to.equal('a')
  181. end)
  182. test('directives', function()
  183. expect(function() parse('{...on a @ {}}') end).to.fail()
  184. inlineFragment = parse('{...{}}').definitions[1].selectionSet.selections[1]
  185. expect(inlineFragment.directives).to_not.exist()
  186. inlineFragment = parse('{...@skip{}}').definitions[1].selectionSet.selections[1]
  187. expect(inlineFragment.directives).to.exist()
  188. inlineFragment = parse('{...on a@skip {}}').definitions[1].selectionSet.selections[1]
  189. expect(inlineFragment.directives).to.exist()
  190. end)
  191. test('selectionSet', function()
  192. expect(function() parse('{... on a}') end).to.fail()
  193. inlineFragment = parse('{...{}}').definitions[1].selectionSet.selections[1]
  194. expect(inlineFragment.selectionSet).to.exist()
  195. inlineFragment = parse('{... on a{}}').definitions[1].selectionSet.selections[1]
  196. expect(inlineFragment.selectionSet).to.exist()
  197. end)
  198. end)
  199. test('arguments', function()
  200. local arguments
  201. expect(function() parse('{a()}') end).to.fail()
  202. arguments = parse('{a(b:1)}').definitions[1].selectionSet.selections[1].arguments
  203. expect(#arguments).to.equal(1)
  204. arguments = parse('{a(b:1 c:1)}').definitions[1].selectionSet.selections[1].arguments
  205. expect(#arguments).to.equal(2)
  206. end)
  207. test('argument', function()
  208. local argument
  209. expect(function() parse('{a(b)}') end).to.fail()
  210. expect(function() parse('{a(@b)}') end).to.fail()
  211. expect(function() parse('{a($b)}') end).to.fail()
  212. expect(function() parse('{a(b::)}') end).to.fail()
  213. expect(function() parse('{a(:1)}') end).to.fail()
  214. expect(function() parse('{a(b:)}') end).to.fail()
  215. expect(function() parse('{a(:)}') end).to.fail()
  216. expect(function() parse('{a(b c)}') end).to.fail()
  217. argument = parse('{a(b:1)}').definitions[1].selectionSet.selections[1].arguments[1]
  218. expect(argument.kind).to.equal('argument')
  219. expect(argument.name.value).to.equal('b')
  220. expect(argument.value.value).to.equal('1')
  221. end)
  222. test('directives', function()
  223. local directives
  224. expect(function() parse('{a@}') end).to.fail()
  225. expect(function() parse('{a@@}') end).to.fail()
  226. directives = parse('{a@b}').definitions[1].selectionSet.selections[1].directives
  227. expect(#directives).to.equal(1)
  228. directives = parse('{a@b(c:1)@d}').definitions[1].selectionSet.selections[1].directives
  229. expect(#directives).to.equal(2)
  230. end)
  231. test('directive', function()
  232. local directive
  233. expect(function() parse('{a@b()}') end).to.fail()
  234. directive = parse('{a@b}').definitions[1].selectionSet.selections[1].directives[1]
  235. expect(directive.kind).to.equal('directive')
  236. expect(directive.name.value).to.equal('b')
  237. expect(directive.arguments).to_not.exist()
  238. directive = parse('{a@b(c:1)}').definitions[1].selectionSet.selections[1].directives[1]
  239. expect(directive.arguments).to.exist()
  240. end)
  241. test('variableDefinitions', function()
  242. local variableDefinitions
  243. expect(function() parse('query(){}') end).to.fail()
  244. expect(function() parse('query(a){}') end).to.fail()
  245. expect(function() parse('query(@a){}') end).to.fail()
  246. expect(function() parse('query($a){}') end).to.fail()
  247. variableDefinitions = parse('query($a:Int){}').definitions[1].variableDefinitions
  248. expect(#variableDefinitions).to.equal(1)
  249. variableDefinitions = parse('query($a:Int $b:Int){}').definitions[1].variableDefinitions
  250. expect(#variableDefinitions).to.equal(2)
  251. end)
  252. describe('variableDefinition', function()
  253. local variableDefinition
  254. test('variable', function()
  255. variableDefinition = parse('query($a:Int){}').definitions[1].variableDefinitions[1]
  256. expect(variableDefinition.kind).to.equal('variableDefinition')
  257. expect(variableDefinition.variable.name.value).to.equal('a')
  258. end)
  259. test('type', function()
  260. expect(function() parse('query($a){}') end).to.fail()
  261. expect(function() parse('query($a:){}') end).to.fail()
  262. expect(function() parse('query($a Int){}') end).to.fail()
  263. variableDefinition = parse('query($a:Int){}').definitions[1].variableDefinitions[1]
  264. expect(variableDefinition.type.name.value).to.equal('Int')
  265. end)
  266. test('defaultValue', function()
  267. expect(function() parse('query($a:Int=){}') end).to.fail()
  268. variableDefinition = parse('query($a:Int){}').definitions[1].variableDefinitions[1]
  269. expect(variableDefinition.defaultValue).to_not.exist()
  270. variableDefinition = parse('query($a:Int=1){}').definitions[1].variableDefinitions[1]
  271. expect(variableDefinition.defaultValue).to.exist()
  272. end)
  273. end)
  274. describe('value', function()
  275. local value
  276. local function run(input, result, type)
  277. local value = parse('{x(y:' .. input .. ')}').definitions[1].selectionSet.selections[1].arguments[1].value
  278. if type then expect(value.kind).to.equal(type) end
  279. if result then expect(value.value).to.equal(result) end
  280. return value
  281. end
  282. test('variable', function()
  283. expect(function() parse('{x(y:$)}') end).to.fail()
  284. expect(function() parse('{x(y:$a$)}') end).to.fail()
  285. value = run('$a')
  286. expect(value.kind).to.equal('variable')
  287. expect(value.name.value).to.equal('a')
  288. end)
  289. test('int', function()
  290. expect(function() parse('{x(y:01)}') end).to.fail()
  291. expect(function() parse('{x(y:-01)}') end).to.fail()
  292. expect(function() parse('{x(y:--1)}') end).to.fail()
  293. expect(function() parse('{x(y:+0)}') end).to.fail()
  294. run('0', '0', 'int')
  295. run('-0', '-0', 'int')
  296. run('1234', '1234', 'int')
  297. run('-1234', '-1234', 'int')
  298. end)
  299. test('float', function()
  300. expect(function() parse('{x(y:.1)}') end).to.fail()
  301. expect(function() parse('{x(y:1.)}') end).to.fail()
  302. expect(function() parse('{x(y:1..)}') end).to.fail()
  303. expect(function() parse('{x(y:0e1.0)}') end).to.fail()
  304. run('0.0', '0.0', 'float')
  305. run('-0.0', '-0.0', 'float')
  306. run('12.34', '12.34', 'float')
  307. run('1e0', '1e0', 'float')
  308. run('1e3', '1e3', 'float')
  309. run('1.0e3', '1.0e3', 'float')
  310. run('1.0e+3', '1.0e+3', 'float')
  311. run('1.0e-3', '1.0e-3', 'float')
  312. run('1.00e-30', '1.00e-30', 'float')
  313. end)
  314. test('boolean', function()
  315. run('true', 'true', 'boolean')
  316. run('false', 'false', 'boolean')
  317. end)
  318. test('string', function()
  319. expect(function() parse('{x(y:")}') end).to.fail()
  320. expect(function() parse('{x(y:\'\')}') end).to.fail()
  321. expect(function() parse('{x(y:"\n")}') end).to.fail()
  322. run('"yarn"', 'yarn', 'string')
  323. run('"th\\"read"', 'th"read', 'string')
  324. end)
  325. test('enum', function()
  326. run('a', 'a', 'enum')
  327. end)
  328. test('list', function()
  329. expect(function() parse('{x(y:[)}') end).to.fail()
  330. value = run('[]')
  331. expect(value.values).to.equal({})
  332. value = run('[a 1]')
  333. expect(value).to.equal({
  334. kind = 'list',
  335. values = {
  336. {
  337. kind = 'enum',
  338. value = 'a'
  339. },
  340. {
  341. kind = 'int',
  342. value = '1'
  343. }
  344. }
  345. })
  346. value = run('[a [b] c]')
  347. expect(value).to.equal({
  348. kind = 'list',
  349. values = {
  350. {
  351. kind = 'enum',
  352. value = 'a'
  353. },
  354. {
  355. kind = 'list',
  356. values = {
  357. {
  358. kind = 'enum',
  359. value = 'b'
  360. }
  361. }
  362. },
  363. {
  364. kind = 'enum',
  365. value = 'c'
  366. }
  367. }
  368. })
  369. end)
  370. test('object', function()
  371. expect(function() parse('{x(y:{a})}') end).to.fail()
  372. expect(function() parse('{x(y:{a:})}') end).to.fail()
  373. expect(function() parse('{x(y:{a::})}') end).to.fail()
  374. expect(function() parse('{x(y:{1:1})}') end).to.fail()
  375. expect(function() parse('{x(y:{"foo":"bar"})}') end).to.fail()
  376. value = run('{}')
  377. expect(value.kind).to.equal('inputObject')
  378. expect(value.values).to.equal({})
  379. value = run('{a:1}')
  380. expect(value.values).to.equal({
  381. {
  382. name = 'a',
  383. value = {
  384. kind = 'int',
  385. value = '1'
  386. }
  387. }
  388. })
  389. value = run('{a:1 b:2}')
  390. expect(#value.values).to.equal(2)
  391. end)
  392. end)
  393. test('namedType', function()
  394. expect(function() parse('query($a:$b){}') end).to.fail()
  395. local namedType = parse('query($a:b){}').definitions[1].variableDefinitions[1].type
  396. expect(namedType.kind).to.equal('namedType')
  397. expect(namedType.name.value).to.equal('b')
  398. end)
  399. test('listType', function()
  400. local listType
  401. expect(function() parse('query($a:[]){}') end).to.fail()
  402. listType = parse('query($a:[b]){}').definitions[1].variableDefinitions[1].type
  403. expect(listType.kind).to.equal('listType')
  404. expect(listType.type.kind).to.equal('namedType')
  405. expect(listType.type.name.value).to.equal('b')
  406. listType = parse('query($a:[[b]]){}').definitions[1].variableDefinitions[1].type
  407. expect(listType.kind).to.equal('listType')
  408. expect(listType.type.kind).to.equal('listType')
  409. end)
  410. test('nonNullType', function()
  411. local nonNullType
  412. expect(function() parse('query($a:!){}') end).to.fail()
  413. expect(function() parse('query($a:b!!){}') end).to.fail()
  414. nonNullType = parse('query($a:b!){}').definitions[1].variableDefinitions[1].type
  415. expect(nonNullType.kind).to.equal('nonNullType')
  416. expect(nonNullType.type.kind).to.equal('namedType')
  417. expect(nonNullType.type.name.value).to.equal('b')
  418. nonNullType = parse('query($a:[b]!){}').definitions[1].variableDefinitions[1].type
  419. expect(nonNullType.kind).to.equal('nonNullType')
  420. expect(nonNullType.type.kind).to.equal('listType')
  421. end)
  422. end)