tinygql 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.github/workflows/ci.yml +46 -0
- data/.gitignore +4 -0
- data/CODE_OF_CONDUCT.md +77 -0
- data/Gemfile +3 -0
- data/LICENSE +201 -0
- data/README.md +71 -0
- data/Rakefile +132 -0
- data/bin/bench.rb +11 -0
- data/lib/tinygql/lexer.rb +256 -0
- data/lib/tinygql/nodes.rb +870 -0
- data/lib/tinygql/nodes.rb.erb +45 -0
- data/lib/tinygql/nodes.yml +205 -0
- data/lib/tinygql/parser.rb +598 -0
- data/lib/tinygql/version.rb +3 -0
- data/lib/tinygql/visitors.rb +442 -0
- data/lib/tinygql/visitors.rb.erb +46 -0
- data/lib/tinygql.rb +10 -0
- data/test/helper.rb +14 -0
- data/test/kitchen-sink.graphql +59 -0
- data/test/lexer_test.rb +93 -0
- data/test/parser_test.rb +144 -0
- data/test/schema-kitchen-sink.graphql +78 -0
- data/tinygql.gemspec +20 -0
- metadata +98 -0
@@ -0,0 +1,442 @@
|
|
1
|
+
module TinyGQL
|
2
|
+
module Visitors
|
3
|
+
module Visitor
|
4
|
+
def handle_document obj
|
5
|
+
obj.definitions.each { _1.accept self }
|
6
|
+
end
|
7
|
+
def handle_operation_definition obj
|
8
|
+
if obj.variable_definitions
|
9
|
+
obj.variable_definitions.each { _1.accept self }
|
10
|
+
end
|
11
|
+
if obj.directives
|
12
|
+
obj.directives.each { _1.accept self }
|
13
|
+
end
|
14
|
+
obj.selection_set.each { _1.accept self }
|
15
|
+
end
|
16
|
+
def handle_variable obj
|
17
|
+
end
|
18
|
+
def handle_named_type obj
|
19
|
+
end
|
20
|
+
def handle_not_null_type obj
|
21
|
+
obj.type.accept self
|
22
|
+
end
|
23
|
+
def handle_list_type obj
|
24
|
+
obj.type.accept self
|
25
|
+
end
|
26
|
+
def handle_variable_definition obj
|
27
|
+
obj.variable.accept self
|
28
|
+
obj.type.accept self
|
29
|
+
if obj.default_value
|
30
|
+
obj.default_value.accept self
|
31
|
+
end
|
32
|
+
end
|
33
|
+
def handle_value obj
|
34
|
+
end
|
35
|
+
def handle_argument obj
|
36
|
+
obj.value.accept self
|
37
|
+
end
|
38
|
+
def handle_field obj
|
39
|
+
if obj.arguments
|
40
|
+
obj.arguments.each { _1.accept self }
|
41
|
+
end
|
42
|
+
if obj.directives
|
43
|
+
obj.directives.each { _1.accept self }
|
44
|
+
end
|
45
|
+
if obj.selection_set
|
46
|
+
obj.selection_set.each { _1.accept self }
|
47
|
+
end
|
48
|
+
end
|
49
|
+
def handle_object_field obj
|
50
|
+
obj.value.accept self
|
51
|
+
end
|
52
|
+
def handle_int_value obj
|
53
|
+
end
|
54
|
+
def handle_float_value obj
|
55
|
+
end
|
56
|
+
def handle_string_value obj
|
57
|
+
end
|
58
|
+
def handle_boolean_value obj
|
59
|
+
end
|
60
|
+
def handle_null_value obj
|
61
|
+
end
|
62
|
+
def handle_enum_value obj
|
63
|
+
end
|
64
|
+
def handle_list_value obj
|
65
|
+
end
|
66
|
+
def handle_object_value obj
|
67
|
+
obj.values.each { _1.accept self }
|
68
|
+
end
|
69
|
+
def handle_directive obj
|
70
|
+
obj.arguments.each { _1.accept self }
|
71
|
+
end
|
72
|
+
def handle_type_condition obj
|
73
|
+
obj.named_type.accept self
|
74
|
+
end
|
75
|
+
def handle_inline_fragment obj
|
76
|
+
if obj.type_condition
|
77
|
+
obj.type_condition.accept self
|
78
|
+
end
|
79
|
+
if obj.directives
|
80
|
+
obj.directives.each { _1.accept self }
|
81
|
+
end
|
82
|
+
obj.selection_set.each { _1.accept self }
|
83
|
+
end
|
84
|
+
def handle_fragment_spread obj
|
85
|
+
obj.fragment_name.accept self
|
86
|
+
if obj.directives
|
87
|
+
obj.directives.each { _1.accept self }
|
88
|
+
end
|
89
|
+
end
|
90
|
+
def handle_fragment_definition obj
|
91
|
+
obj.fragment_name.accept self
|
92
|
+
obj.type_condition.accept self
|
93
|
+
if obj.directives
|
94
|
+
obj.directives.each { _1.accept self }
|
95
|
+
end
|
96
|
+
obj.selection_set.each { _1.accept self }
|
97
|
+
end
|
98
|
+
def handle_root_operation_type_definition obj
|
99
|
+
obj.operation_type.accept self
|
100
|
+
obj.named_type.accept self
|
101
|
+
end
|
102
|
+
def handle_schema_definition obj
|
103
|
+
if obj.directives
|
104
|
+
obj.directives.each { _1.accept self }
|
105
|
+
end
|
106
|
+
obj.root_operation_definitions.each { _1.accept self }
|
107
|
+
end
|
108
|
+
def handle_field_definition obj
|
109
|
+
if obj.arguments_definition
|
110
|
+
obj.arguments_definition.each { _1.accept self }
|
111
|
+
end
|
112
|
+
obj.type.accept self
|
113
|
+
if obj.directives
|
114
|
+
obj.directives.each { _1.accept self }
|
115
|
+
end
|
116
|
+
end
|
117
|
+
def handle_input_value_definition obj
|
118
|
+
obj.type.accept self
|
119
|
+
if obj.default_value
|
120
|
+
obj.default_value.accept self
|
121
|
+
end
|
122
|
+
if obj.directives
|
123
|
+
obj.directives.each { _1.accept self }
|
124
|
+
end
|
125
|
+
end
|
126
|
+
def handle_object_type_definition obj
|
127
|
+
if obj.implements_interfaces
|
128
|
+
obj.implements_interfaces.each { _1.accept self }
|
129
|
+
end
|
130
|
+
if obj.directives
|
131
|
+
obj.directives.each { _1.accept self }
|
132
|
+
end
|
133
|
+
if obj.fields_definition
|
134
|
+
obj.fields_definition.each { _1.accept self }
|
135
|
+
end
|
136
|
+
end
|
137
|
+
def handle_interface_type_definition obj
|
138
|
+
if obj.directives
|
139
|
+
obj.directives.each { _1.accept self }
|
140
|
+
end
|
141
|
+
if obj.fields_definition
|
142
|
+
obj.fields_definition.each { _1.accept self }
|
143
|
+
end
|
144
|
+
end
|
145
|
+
def handle_union_type_definition obj
|
146
|
+
if obj.directives
|
147
|
+
obj.directives.each { _1.accept self }
|
148
|
+
end
|
149
|
+
if obj.union_member_types
|
150
|
+
obj.union_member_types.each { _1.accept self }
|
151
|
+
end
|
152
|
+
end
|
153
|
+
def handle_scalar_type_definition obj
|
154
|
+
if obj.directives
|
155
|
+
obj.directives.each { _1.accept self }
|
156
|
+
end
|
157
|
+
end
|
158
|
+
def handle_enum_value_definition obj
|
159
|
+
obj.enum_value.accept self
|
160
|
+
if obj.directives
|
161
|
+
obj.directives.each { _1.accept self }
|
162
|
+
end
|
163
|
+
end
|
164
|
+
def handle_enum_type_definition obj
|
165
|
+
if obj.directives
|
166
|
+
obj.directives.each { _1.accept self }
|
167
|
+
end
|
168
|
+
if obj.enum_value_definition
|
169
|
+
obj.enum_value_definition.each { _1.accept self }
|
170
|
+
end
|
171
|
+
end
|
172
|
+
def handle_input_object_type_definition obj
|
173
|
+
if obj.directives
|
174
|
+
obj.directives.each { _1.accept self }
|
175
|
+
end
|
176
|
+
if obj.input_fields_definition
|
177
|
+
obj.input_fields_definition.each { _1.accept self }
|
178
|
+
end
|
179
|
+
end
|
180
|
+
def handle_object_type_extension obj
|
181
|
+
if obj.implements_interfaces
|
182
|
+
obj.implements_interfaces.each { _1.accept self }
|
183
|
+
end
|
184
|
+
if obj.directives
|
185
|
+
obj.directives.each { _1.accept self }
|
186
|
+
end
|
187
|
+
if obj.fields_definition
|
188
|
+
obj.fields_definition.each { _1.accept self }
|
189
|
+
end
|
190
|
+
end
|
191
|
+
def handle_executable_directive_location obj
|
192
|
+
end
|
193
|
+
def handle_type_system_directive_location obj
|
194
|
+
end
|
195
|
+
def handle_directive_definition obj
|
196
|
+
if obj.arguments_definition
|
197
|
+
obj.arguments_definition.each { _1.accept self }
|
198
|
+
end
|
199
|
+
obj.directive_locations.each { _1.accept self }
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
module Fold
|
204
|
+
def handle_document obj, seed
|
205
|
+
obj.definitions.each { seed = _1.fold(self, seed) }
|
206
|
+
seed
|
207
|
+
end
|
208
|
+
def handle_operation_definition obj, seed
|
209
|
+
if obj.variable_definitions
|
210
|
+
obj.variable_definitions.each { seed = _1.fold(self, seed) }
|
211
|
+
end
|
212
|
+
if obj.directives
|
213
|
+
obj.directives.each { seed = _1.fold(self, seed) }
|
214
|
+
end
|
215
|
+
obj.selection_set.each { seed = _1.fold(self, seed) }
|
216
|
+
seed
|
217
|
+
end
|
218
|
+
def handle_variable obj, seed
|
219
|
+
seed
|
220
|
+
end
|
221
|
+
def handle_named_type obj, seed
|
222
|
+
seed
|
223
|
+
end
|
224
|
+
def handle_not_null_type obj, seed
|
225
|
+
seed = obj.type.fold self, seed
|
226
|
+
seed
|
227
|
+
end
|
228
|
+
def handle_list_type obj, seed
|
229
|
+
seed = obj.type.fold self, seed
|
230
|
+
seed
|
231
|
+
end
|
232
|
+
def handle_variable_definition obj, seed
|
233
|
+
seed = obj.variable.fold self, seed
|
234
|
+
seed = obj.type.fold self, seed
|
235
|
+
if obj.default_value
|
236
|
+
seed = obj.default_value.fold self, seed
|
237
|
+
end
|
238
|
+
seed
|
239
|
+
end
|
240
|
+
def handle_value obj, seed
|
241
|
+
seed
|
242
|
+
end
|
243
|
+
def handle_argument obj, seed
|
244
|
+
seed = obj.value.fold self, seed
|
245
|
+
seed
|
246
|
+
end
|
247
|
+
def handle_field obj, seed
|
248
|
+
if obj.arguments
|
249
|
+
obj.arguments.each { seed = _1.fold(self, seed) }
|
250
|
+
end
|
251
|
+
if obj.directives
|
252
|
+
obj.directives.each { seed = _1.fold(self, seed) }
|
253
|
+
end
|
254
|
+
if obj.selection_set
|
255
|
+
obj.selection_set.each { seed = _1.fold(self, seed) }
|
256
|
+
end
|
257
|
+
seed
|
258
|
+
end
|
259
|
+
def handle_object_field obj, seed
|
260
|
+
seed = obj.value.fold self, seed
|
261
|
+
seed
|
262
|
+
end
|
263
|
+
def handle_int_value obj, seed
|
264
|
+
seed
|
265
|
+
end
|
266
|
+
def handle_float_value obj, seed
|
267
|
+
seed
|
268
|
+
end
|
269
|
+
def handle_string_value obj, seed
|
270
|
+
seed
|
271
|
+
end
|
272
|
+
def handle_boolean_value obj, seed
|
273
|
+
seed
|
274
|
+
end
|
275
|
+
def handle_null_value obj, seed
|
276
|
+
seed
|
277
|
+
end
|
278
|
+
def handle_enum_value obj, seed
|
279
|
+
seed
|
280
|
+
end
|
281
|
+
def handle_list_value obj, seed
|
282
|
+
seed
|
283
|
+
end
|
284
|
+
def handle_object_value obj, seed
|
285
|
+
obj.values.each { seed = _1.fold(self, seed) }
|
286
|
+
seed
|
287
|
+
end
|
288
|
+
def handle_directive obj, seed
|
289
|
+
obj.arguments.each { seed = _1.fold(self, seed) }
|
290
|
+
seed
|
291
|
+
end
|
292
|
+
def handle_type_condition obj, seed
|
293
|
+
seed = obj.named_type.fold self, seed
|
294
|
+
seed
|
295
|
+
end
|
296
|
+
def handle_inline_fragment obj, seed
|
297
|
+
if obj.type_condition
|
298
|
+
seed = obj.type_condition.fold self, seed
|
299
|
+
end
|
300
|
+
if obj.directives
|
301
|
+
obj.directives.each { seed = _1.fold(self, seed) }
|
302
|
+
end
|
303
|
+
obj.selection_set.each { seed = _1.fold(self, seed) }
|
304
|
+
seed
|
305
|
+
end
|
306
|
+
def handle_fragment_spread obj, seed
|
307
|
+
seed = obj.fragment_name.fold self, seed
|
308
|
+
if obj.directives
|
309
|
+
obj.directives.each { seed = _1.fold(self, seed) }
|
310
|
+
end
|
311
|
+
seed
|
312
|
+
end
|
313
|
+
def handle_fragment_definition obj, seed
|
314
|
+
seed = obj.fragment_name.fold self, seed
|
315
|
+
seed = obj.type_condition.fold self, seed
|
316
|
+
if obj.directives
|
317
|
+
obj.directives.each { seed = _1.fold(self, seed) }
|
318
|
+
end
|
319
|
+
obj.selection_set.each { seed = _1.fold(self, seed) }
|
320
|
+
seed
|
321
|
+
end
|
322
|
+
def handle_root_operation_type_definition obj, seed
|
323
|
+
seed = obj.operation_type.fold self, seed
|
324
|
+
seed = obj.named_type.fold self, seed
|
325
|
+
seed
|
326
|
+
end
|
327
|
+
def handle_schema_definition obj, seed
|
328
|
+
if obj.directives
|
329
|
+
obj.directives.each { seed = _1.fold(self, seed) }
|
330
|
+
end
|
331
|
+
obj.root_operation_definitions.each { seed = _1.fold(self, seed) }
|
332
|
+
seed
|
333
|
+
end
|
334
|
+
def handle_field_definition obj, seed
|
335
|
+
if obj.arguments_definition
|
336
|
+
obj.arguments_definition.each { seed = _1.fold(self, seed) }
|
337
|
+
end
|
338
|
+
seed = obj.type.fold self, seed
|
339
|
+
if obj.directives
|
340
|
+
obj.directives.each { seed = _1.fold(self, seed) }
|
341
|
+
end
|
342
|
+
seed
|
343
|
+
end
|
344
|
+
def handle_input_value_definition obj, seed
|
345
|
+
seed = obj.type.fold self, seed
|
346
|
+
if obj.default_value
|
347
|
+
seed = obj.default_value.fold self, seed
|
348
|
+
end
|
349
|
+
if obj.directives
|
350
|
+
obj.directives.each { seed = _1.fold(self, seed) }
|
351
|
+
end
|
352
|
+
seed
|
353
|
+
end
|
354
|
+
def handle_object_type_definition obj, seed
|
355
|
+
if obj.implements_interfaces
|
356
|
+
obj.implements_interfaces.each { seed = _1.fold(self, seed) }
|
357
|
+
end
|
358
|
+
if obj.directives
|
359
|
+
obj.directives.each { seed = _1.fold(self, seed) }
|
360
|
+
end
|
361
|
+
if obj.fields_definition
|
362
|
+
obj.fields_definition.each { seed = _1.fold(self, seed) }
|
363
|
+
end
|
364
|
+
seed
|
365
|
+
end
|
366
|
+
def handle_interface_type_definition obj, seed
|
367
|
+
if obj.directives
|
368
|
+
obj.directives.each { seed = _1.fold(self, seed) }
|
369
|
+
end
|
370
|
+
if obj.fields_definition
|
371
|
+
obj.fields_definition.each { seed = _1.fold(self, seed) }
|
372
|
+
end
|
373
|
+
seed
|
374
|
+
end
|
375
|
+
def handle_union_type_definition obj, seed
|
376
|
+
if obj.directives
|
377
|
+
obj.directives.each { seed = _1.fold(self, seed) }
|
378
|
+
end
|
379
|
+
if obj.union_member_types
|
380
|
+
obj.union_member_types.each { seed = _1.fold(self, seed) }
|
381
|
+
end
|
382
|
+
seed
|
383
|
+
end
|
384
|
+
def handle_scalar_type_definition obj, seed
|
385
|
+
if obj.directives
|
386
|
+
obj.directives.each { seed = _1.fold(self, seed) }
|
387
|
+
end
|
388
|
+
seed
|
389
|
+
end
|
390
|
+
def handle_enum_value_definition obj, seed
|
391
|
+
seed = obj.enum_value.fold self, seed
|
392
|
+
if obj.directives
|
393
|
+
obj.directives.each { seed = _1.fold(self, seed) }
|
394
|
+
end
|
395
|
+
seed
|
396
|
+
end
|
397
|
+
def handle_enum_type_definition obj, seed
|
398
|
+
if obj.directives
|
399
|
+
obj.directives.each { seed = _1.fold(self, seed) }
|
400
|
+
end
|
401
|
+
if obj.enum_value_definition
|
402
|
+
obj.enum_value_definition.each { seed = _1.fold(self, seed) }
|
403
|
+
end
|
404
|
+
seed
|
405
|
+
end
|
406
|
+
def handle_input_object_type_definition obj, seed
|
407
|
+
if obj.directives
|
408
|
+
obj.directives.each { seed = _1.fold(self, seed) }
|
409
|
+
end
|
410
|
+
if obj.input_fields_definition
|
411
|
+
obj.input_fields_definition.each { seed = _1.fold(self, seed) }
|
412
|
+
end
|
413
|
+
seed
|
414
|
+
end
|
415
|
+
def handle_object_type_extension obj, seed
|
416
|
+
if obj.implements_interfaces
|
417
|
+
obj.implements_interfaces.each { seed = _1.fold(self, seed) }
|
418
|
+
end
|
419
|
+
if obj.directives
|
420
|
+
obj.directives.each { seed = _1.fold(self, seed) }
|
421
|
+
end
|
422
|
+
if obj.fields_definition
|
423
|
+
obj.fields_definition.each { seed = _1.fold(self, seed) }
|
424
|
+
end
|
425
|
+
seed
|
426
|
+
end
|
427
|
+
def handle_executable_directive_location obj, seed
|
428
|
+
seed
|
429
|
+
end
|
430
|
+
def handle_type_system_directive_location obj, seed
|
431
|
+
seed
|
432
|
+
end
|
433
|
+
def handle_directive_definition obj, seed
|
434
|
+
if obj.arguments_definition
|
435
|
+
obj.arguments_definition.each { seed = _1.fold(self, seed) }
|
436
|
+
end
|
437
|
+
obj.directive_locations.each { seed = _1.fold(self, seed) }
|
438
|
+
seed
|
439
|
+
end
|
440
|
+
end
|
441
|
+
end
|
442
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module TinyGQL
|
2
|
+
module Visitors
|
3
|
+
module Visitor
|
4
|
+
<%- nodes.each do |node| -%>
|
5
|
+
def handle_<%= node.human_name %> obj
|
6
|
+
<%- node.fields.find_all(&:visitable?).each do |field| -%>
|
7
|
+
<%- if field.nullable? -%>
|
8
|
+
if obj.<%= field.name %>
|
9
|
+
<%- end -%>
|
10
|
+
<%- if field.list? -%>
|
11
|
+
obj.<%= field.name %>.each { _1.accept self }
|
12
|
+
<%- end -%>
|
13
|
+
<%- if field.node? -%>
|
14
|
+
obj.<%= field.name %>.accept self
|
15
|
+
<%- end -%>
|
16
|
+
<%- if field.nullable? -%>
|
17
|
+
end
|
18
|
+
<%- end -%>
|
19
|
+
<%- end -%>
|
20
|
+
end
|
21
|
+
<%- end -%>
|
22
|
+
end
|
23
|
+
|
24
|
+
module Fold
|
25
|
+
<%- nodes.each do |node| -%>
|
26
|
+
def handle_<%= node.human_name %> obj, seed
|
27
|
+
<%- node.fields.find_all(&:visitable?).each do |field| -%>
|
28
|
+
<%- if field.nullable? -%>
|
29
|
+
if obj.<%= field.name %>
|
30
|
+
<%- end -%>
|
31
|
+
<%- if field.list? -%>
|
32
|
+
obj.<%= field.name %>.each { seed = _1.fold(self, seed) }
|
33
|
+
<%- end -%>
|
34
|
+
<%- if field.node? -%>
|
35
|
+
seed = obj.<%= field.name %>.fold self, seed
|
36
|
+
<%- end -%>
|
37
|
+
<%- if field.nullable? -%>
|
38
|
+
end
|
39
|
+
<%- end -%>
|
40
|
+
<%- end -%>
|
41
|
+
seed
|
42
|
+
end
|
43
|
+
<%- end -%>
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
data/lib/tinygql.rb
ADDED
data/test/helper.rb
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
# Copyright (c) 2015-present, Facebook, Inc.
|
2
|
+
#
|
3
|
+
# This source code is licensed under the MIT license found in the
|
4
|
+
# LICENSE file in the root directory of this source tree.
|
5
|
+
|
6
|
+
query queryName($foo: ComplexType, $site: Site = MOBILE) {
|
7
|
+
whoever123is: node(id: [123, 456]) {
|
8
|
+
id ,
|
9
|
+
... on User @defer {
|
10
|
+
field2 {
|
11
|
+
id ,
|
12
|
+
alias: field1(first:10, after:$foo,) @include(if: $foo) {
|
13
|
+
id,
|
14
|
+
...frag
|
15
|
+
}
|
16
|
+
}
|
17
|
+
}
|
18
|
+
... @skip(unless: $foo) {
|
19
|
+
id
|
20
|
+
}
|
21
|
+
... {
|
22
|
+
id
|
23
|
+
}
|
24
|
+
}
|
25
|
+
}
|
26
|
+
|
27
|
+
mutation likeStory {
|
28
|
+
like(story: 123) @defer {
|
29
|
+
story {
|
30
|
+
id
|
31
|
+
}
|
32
|
+
}
|
33
|
+
}
|
34
|
+
|
35
|
+
subscription StoryLikeSubscription($input: StoryLikeSubscribeInput) {
|
36
|
+
storyLikeSubscribe(input: $input) {
|
37
|
+
story {
|
38
|
+
likers {
|
39
|
+
count
|
40
|
+
}
|
41
|
+
likeSentence {
|
42
|
+
text
|
43
|
+
}
|
44
|
+
}
|
45
|
+
}
|
46
|
+
}
|
47
|
+
|
48
|
+
fragment frag on Friend {
|
49
|
+
foo(size: $size, bar: $b, obj: {key: "value", block: """
|
50
|
+
|
51
|
+
block string uses \"""
|
52
|
+
|
53
|
+
"""})
|
54
|
+
}
|
55
|
+
|
56
|
+
{
|
57
|
+
unnamed(truthy: true, falsey: false, nullish: null),
|
58
|
+
query
|
59
|
+
}
|
data/test/lexer_test.rb
ADDED
@@ -0,0 +1,93 @@
|
|
1
|
+
require "helper"
|
2
|
+
|
3
|
+
module TinyGQL
|
4
|
+
class LexerTest < Test
|
5
|
+
PUNC_LUT = {"!"=>[:BANG, "!"],
|
6
|
+
"$"=>[:VAR_SIGN, "$"],
|
7
|
+
"("=>[:LPAREN, "("],
|
8
|
+
")"=>[:RPAREN, ")"],
|
9
|
+
"..."=>[:ELLIPSIS, "..."],
|
10
|
+
":"=>[:COLON, ":"],
|
11
|
+
"="=>[:EQUALS, "="],
|
12
|
+
"@"=>[:DIR_SIGN, "@"],
|
13
|
+
"["=>[:LBRACKET, "["],
|
14
|
+
"]"=>[:RBRACKET, "]"],
|
15
|
+
"{"=>[:LCURLY, "{"],
|
16
|
+
"|"=>[:PIPE, "|"],
|
17
|
+
"}"=>[:RCURLY, "}"]}
|
18
|
+
|
19
|
+
def test_punc
|
20
|
+
%w{ ! $ ( ) ... : = @ [ ] { | } }.each do |punc|
|
21
|
+
lexer = Lexer.new punc
|
22
|
+
token = lexer.next_token
|
23
|
+
expected = PUNC_LUT[punc]
|
24
|
+
assert_equal(expected || [:ON, "on"], token)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_regular_string
|
29
|
+
str = "hello\n# foo\n\"world\"# lol \nlol"
|
30
|
+
lexer = Lexer.new str
|
31
|
+
assert_equal [:IDENTIFIER, "hello"], lexer.next_token
|
32
|
+
assert_equal [:STRING, "world"], lexer.next_token
|
33
|
+
assert_equal [:IDENTIFIER, "lol"], lexer.next_token
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_multiline_comment
|
37
|
+
str = "hello\n# foo\n# lol \nlol"
|
38
|
+
lexer = Lexer.new str
|
39
|
+
assert_equal [:IDENTIFIER, "hello"], lexer.next_token
|
40
|
+
assert_equal [:IDENTIFIER, "lol"], lexer.next_token
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_block_string
|
44
|
+
doc = <<-eos
|
45
|
+
"""
|
46
|
+
|
47
|
+
block string uses \\"""
|
48
|
+
|
49
|
+
"""
|
50
|
+
eos
|
51
|
+
lexer = Lexer.new doc
|
52
|
+
assert_equal :STRING, lexer.next_token.first
|
53
|
+
end
|
54
|
+
|
55
|
+
def test_tokenize
|
56
|
+
lexer = Lexer.new "on"
|
57
|
+
token = lexer.next_token
|
58
|
+
assert_equal [:ON, "on"], token
|
59
|
+
end
|
60
|
+
|
61
|
+
def test_multi_tok
|
62
|
+
doc = <<-eod
|
63
|
+
mutation {
|
64
|
+
likeStory(storyID: 12345) {
|
65
|
+
story {
|
66
|
+
likeCount
|
67
|
+
}
|
68
|
+
}
|
69
|
+
}
|
70
|
+
eod
|
71
|
+
lexer = Lexer.new doc
|
72
|
+
toks = []
|
73
|
+
while tok = lexer.next_token
|
74
|
+
toks << tok
|
75
|
+
end
|
76
|
+
assert_equal [[:MUTATION, "mutation"],
|
77
|
+
[:LCURLY, "{"],
|
78
|
+
[:IDENTIFIER, "likeStory"],
|
79
|
+
[:LPAREN, "("],
|
80
|
+
[:IDENTIFIER, "storyID"],
|
81
|
+
[:COLON, ":"],
|
82
|
+
[:INT, "12345"],
|
83
|
+
[:RPAREN, ")"],
|
84
|
+
[:LCURLY, "{"],
|
85
|
+
[:IDENTIFIER, "story"],
|
86
|
+
[:LCURLY, "{"],
|
87
|
+
[:IDENTIFIER, "likeCount"],
|
88
|
+
[:RCURLY, "}"],
|
89
|
+
[:RCURLY, "}"],
|
90
|
+
[:RCURLY, "}"]], toks
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|