tinygql 0.1.2 → 0.1.3
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 +4 -4
- data/Gemfile +3 -0
- data/Rakefile +11 -0
- data/benchmark/fixtures/negotiate.gql +3643 -0
- data/bin/bench.rb +15 -4
- data/bin/profile.rb +5 -0
- data/lib/tinygql/nodes.rb +3 -2
- data/lib/tinygql/nodes.yml +11 -10
- data/lib/tinygql/parser.rb +23 -15
- data/lib/tinygql/version.rb +1 -1
- data/lib/tinygql/visitors.rb +66 -0
- data/test/parser_test.rb +26 -0
- metadata +4 -2
data/bin/bench.rb
CHANGED
@@ -1,11 +1,22 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
$:.unshift(File.expand_path("../lib", __dir__))
|
4
3
|
require "tinygql"
|
5
|
-
require "benchmark"
|
4
|
+
require "benchmark/ips"
|
6
5
|
|
7
6
|
source = File.read(File.expand_path("../test/kitchen-sink.graphql", __dir__))
|
8
7
|
|
9
|
-
|
10
|
-
|
8
|
+
files = Dir[File.join(File.expand_path("../benchmark", __dir__), "**/*")].select { |f| File.file? f }
|
9
|
+
|
10
|
+
Benchmark.ips do |x|
|
11
|
+
x.report "kitchen-sink" do
|
12
|
+
TinyGQL.parse source
|
13
|
+
end
|
14
|
+
|
15
|
+
files.each do |file_name|
|
16
|
+
data = File.read file_name
|
17
|
+
name = File.basename(file_name, File.extname(file_name))
|
18
|
+
x.report name do
|
19
|
+
TinyGQL.parse data
|
20
|
+
end
|
21
|
+
end
|
11
22
|
end
|
data/bin/profile.rb
ADDED
data/lib/tinygql/nodes.rb
CHANGED
@@ -538,9 +538,10 @@ module TinyGQL
|
|
538
538
|
end
|
539
539
|
end
|
540
540
|
class SchemaDefinition < Node
|
541
|
-
attr_reader :directives, :root_operation_definitions
|
541
|
+
attr_reader :description, :directives, :root_operation_definitions
|
542
542
|
|
543
|
-
def initialize directives, root_operation_definitions
|
543
|
+
def initialize description, directives, root_operation_definitions
|
544
|
+
@description = description
|
544
545
|
@directives = directives
|
545
546
|
@root_operation_definitions = root_operation_definitions
|
546
547
|
end
|
data/lib/tinygql/nodes.yml
CHANGED
@@ -115,12 +115,13 @@ nodes:
|
|
115
115
|
|
116
116
|
- name: SchemaDefinition
|
117
117
|
fields:
|
118
|
+
- description?
|
118
119
|
- directives?: list
|
119
120
|
- root_operation_definitions: list
|
120
121
|
|
121
122
|
- name: FieldDefinition
|
122
123
|
fields:
|
123
|
-
- description
|
124
|
+
- description?
|
124
125
|
- name: literal
|
125
126
|
- arguments_definition?: list
|
126
127
|
- type
|
@@ -128,7 +129,7 @@ nodes:
|
|
128
129
|
|
129
130
|
- name: InputValueDefinition
|
130
131
|
fields:
|
131
|
-
- description
|
132
|
+
- description?
|
132
133
|
- name: literal
|
133
134
|
- type
|
134
135
|
- default_value?
|
@@ -136,7 +137,7 @@ nodes:
|
|
136
137
|
|
137
138
|
- name: ObjectTypeDefinition
|
138
139
|
fields:
|
139
|
-
- description
|
140
|
+
- description?
|
140
141
|
- name: literal
|
141
142
|
- implements_interfaces?: list
|
142
143
|
- directives?: list
|
@@ -144,40 +145,40 @@ nodes:
|
|
144
145
|
|
145
146
|
- name: InterfaceTypeDefinition
|
146
147
|
fields:
|
147
|
-
- description
|
148
|
+
- description?
|
148
149
|
- name: literal
|
149
150
|
- directives?: list
|
150
151
|
- fields_definition?: list
|
151
152
|
|
152
153
|
- name: UnionTypeDefinition
|
153
154
|
fields:
|
154
|
-
- description
|
155
|
+
- description?
|
155
156
|
- name: literal
|
156
157
|
- directives?: list
|
157
158
|
- union_member_types?: list
|
158
159
|
|
159
160
|
- name: ScalarTypeDefinition
|
160
161
|
fields:
|
161
|
-
- description
|
162
|
+
- description?
|
162
163
|
- name: literal
|
163
164
|
- directives?: list
|
164
165
|
|
165
166
|
- name: EnumValueDefinition
|
166
167
|
fields:
|
167
|
-
- description
|
168
|
+
- description?
|
168
169
|
- enum_value
|
169
170
|
- directives?: list
|
170
171
|
|
171
172
|
- name: EnumTypeDefinition
|
172
173
|
fields:
|
173
|
-
- description
|
174
|
+
- description?
|
174
175
|
- name: literal
|
175
176
|
- directives?: list
|
176
177
|
- enum_value_definition?: list
|
177
178
|
|
178
179
|
- name: InputObjectTypeDefinition
|
179
180
|
fields:
|
180
|
-
- description
|
181
|
+
- description?
|
181
182
|
- name: literal
|
182
183
|
- directives?: list
|
183
184
|
- input_fields_definition?: list
|
@@ -199,7 +200,7 @@ nodes:
|
|
199
200
|
|
200
201
|
- name: DirectiveDefinition
|
201
202
|
fields:
|
202
|
-
- description
|
203
|
+
- description?
|
203
204
|
- name: literal
|
204
205
|
- arguments_definition?: list
|
205
206
|
- directive_locations: list
|
data/lib/tinygql/parser.rb
CHANGED
@@ -7,7 +7,9 @@ module TinyGQL
|
|
7
7
|
class Parser
|
8
8
|
class UnexpectedToken < StandardError; end
|
9
9
|
|
10
|
-
|
10
|
+
def self.parse doc
|
11
|
+
new(doc).parse
|
12
|
+
end
|
11
13
|
|
12
14
|
def initialize doc
|
13
15
|
@lexer = Lexer.new doc
|
@@ -21,6 +23,8 @@ module TinyGQL
|
|
21
23
|
|
22
24
|
private
|
23
25
|
|
26
|
+
attr_reader :token_name
|
27
|
+
|
24
28
|
def document
|
25
29
|
Nodes::Document.new definition_list
|
26
30
|
end
|
@@ -40,7 +44,9 @@ module TinyGQL
|
|
40
44
|
when :EXTEND
|
41
45
|
type_system_extension
|
42
46
|
else
|
43
|
-
|
47
|
+
desc = if at?(:STRING); string_value; end
|
48
|
+
|
49
|
+
type_system_definition desc
|
44
50
|
end
|
45
51
|
end
|
46
52
|
|
@@ -62,12 +68,12 @@ module TinyGQL
|
|
62
68
|
Nodes::ObjectTypeExtension.new(name, implements_interfaces, directives, fields_definition)
|
63
69
|
end
|
64
70
|
|
65
|
-
def type_system_definition
|
71
|
+
def type_system_definition desc
|
66
72
|
case token_name
|
67
|
-
when :SCHEMA then schema_definition
|
68
|
-
when :DIRECTIVE then directive_defintion(
|
73
|
+
when :SCHEMA then schema_definition(desc)
|
74
|
+
when :DIRECTIVE then directive_defintion(desc)
|
69
75
|
else
|
70
|
-
type_definition(
|
76
|
+
type_definition(desc)
|
71
77
|
end
|
72
78
|
end
|
73
79
|
|
@@ -91,9 +97,11 @@ module TinyGQL
|
|
91
97
|
end
|
92
98
|
|
93
99
|
def directive_location
|
94
|
-
|
100
|
+
directive = expect_token_value :IDENTIFIER
|
101
|
+
|
102
|
+
case directive
|
95
103
|
when "QUERY", "MUTATION", "SUBSCRIPTION", "FIELD", "FRAGMENT_DEFINITION", "FRAGMENT_SPREAD", "INLINE_FRAGMENT"
|
96
|
-
Nodes::ExecutableDirectiveLocation.new(
|
104
|
+
Nodes::ExecutableDirectiveLocation.new(directive)
|
97
105
|
when "SCHEMA",
|
98
106
|
"SCALAR",
|
99
107
|
"OBJECT",
|
@@ -105,9 +113,9 @@ module TinyGQL
|
|
105
113
|
"ENUM_VALUE",
|
106
114
|
"INPUT_OBJECT",
|
107
115
|
"INPUT_FIELD_DEFINITION"
|
108
|
-
Nodes::TypeSystemDirectiveLocation.new(
|
116
|
+
Nodes::TypeSystemDirectiveLocation.new(directive)
|
109
117
|
else
|
110
|
-
|
118
|
+
raise UnexpectedToken, "Expected directive #{directive}"
|
111
119
|
end
|
112
120
|
end
|
113
121
|
|
@@ -161,7 +169,7 @@ module TinyGQL
|
|
161
169
|
end
|
162
170
|
|
163
171
|
def enum_value_definition
|
164
|
-
description = if at?(:STRING);
|
172
|
+
description = if at?(:STRING); string_value; end
|
165
173
|
enum_value = self.enum_value
|
166
174
|
directives = if at?(:DIR_SIGN); self.directives; end
|
167
175
|
Nodes::EnumValueDefinition.new(description, enum_value, directives)
|
@@ -221,7 +229,7 @@ module TinyGQL
|
|
221
229
|
end
|
222
230
|
|
223
231
|
def field_definition
|
224
|
-
description = if at?(:STRING);
|
232
|
+
description = if at?(:STRING); string_value; end
|
225
233
|
name = self.name
|
226
234
|
arguments_definition = if at?(:LPAREN); self.arguments_definition; end
|
227
235
|
expect_token :COLON
|
@@ -242,7 +250,7 @@ module TinyGQL
|
|
242
250
|
end
|
243
251
|
|
244
252
|
def input_value_definition
|
245
|
-
description = if at?(:STRING);
|
253
|
+
description = if at?(:STRING); string_value; end
|
246
254
|
name = self.name
|
247
255
|
expect_token :COLON
|
248
256
|
type = self.type
|
@@ -262,14 +270,14 @@ module TinyGQL
|
|
262
270
|
list
|
263
271
|
end
|
264
272
|
|
265
|
-
def schema_definition
|
273
|
+
def schema_definition desc
|
266
274
|
expect_token :SCHEMA
|
267
275
|
|
268
276
|
directives = if at?(:DIR_SIGN); self.directives; end
|
269
277
|
expect_token :LCURLY
|
270
278
|
defs = root_operation_type_definition
|
271
279
|
expect_token :RCURLY
|
272
|
-
Nodes::SchemaDefinition.new(directives, defs)
|
280
|
+
Nodes::SchemaDefinition.new(desc, directives, defs)
|
273
281
|
end
|
274
282
|
|
275
283
|
def root_operation_type_definition
|
data/lib/tinygql/version.rb
CHANGED
data/lib/tinygql/visitors.rb
CHANGED
@@ -100,12 +100,18 @@ module TinyGQL
|
|
100
100
|
obj.named_type.accept self
|
101
101
|
end
|
102
102
|
def handle_schema_definition obj
|
103
|
+
if obj.description
|
104
|
+
obj.description.accept self
|
105
|
+
end
|
103
106
|
if obj.directives
|
104
107
|
obj.directives.each { |v| v.accept self }
|
105
108
|
end
|
106
109
|
obj.root_operation_definitions.each { |v| v.accept self }
|
107
110
|
end
|
108
111
|
def handle_field_definition obj
|
112
|
+
if obj.description
|
113
|
+
obj.description.accept self
|
114
|
+
end
|
109
115
|
if obj.arguments_definition
|
110
116
|
obj.arguments_definition.each { |v| v.accept self }
|
111
117
|
end
|
@@ -115,6 +121,9 @@ module TinyGQL
|
|
115
121
|
end
|
116
122
|
end
|
117
123
|
def handle_input_value_definition obj
|
124
|
+
if obj.description
|
125
|
+
obj.description.accept self
|
126
|
+
end
|
118
127
|
obj.type.accept self
|
119
128
|
if obj.default_value
|
120
129
|
obj.default_value.accept self
|
@@ -124,6 +133,9 @@ module TinyGQL
|
|
124
133
|
end
|
125
134
|
end
|
126
135
|
def handle_object_type_definition obj
|
136
|
+
if obj.description
|
137
|
+
obj.description.accept self
|
138
|
+
end
|
127
139
|
if obj.implements_interfaces
|
128
140
|
obj.implements_interfaces.each { |v| v.accept self }
|
129
141
|
end
|
@@ -135,6 +147,9 @@ module TinyGQL
|
|
135
147
|
end
|
136
148
|
end
|
137
149
|
def handle_interface_type_definition obj
|
150
|
+
if obj.description
|
151
|
+
obj.description.accept self
|
152
|
+
end
|
138
153
|
if obj.directives
|
139
154
|
obj.directives.each { |v| v.accept self }
|
140
155
|
end
|
@@ -143,6 +158,9 @@ module TinyGQL
|
|
143
158
|
end
|
144
159
|
end
|
145
160
|
def handle_union_type_definition obj
|
161
|
+
if obj.description
|
162
|
+
obj.description.accept self
|
163
|
+
end
|
146
164
|
if obj.directives
|
147
165
|
obj.directives.each { |v| v.accept self }
|
148
166
|
end
|
@@ -151,17 +169,26 @@ module TinyGQL
|
|
151
169
|
end
|
152
170
|
end
|
153
171
|
def handle_scalar_type_definition obj
|
172
|
+
if obj.description
|
173
|
+
obj.description.accept self
|
174
|
+
end
|
154
175
|
if obj.directives
|
155
176
|
obj.directives.each { |v| v.accept self }
|
156
177
|
end
|
157
178
|
end
|
158
179
|
def handle_enum_value_definition obj
|
180
|
+
if obj.description
|
181
|
+
obj.description.accept self
|
182
|
+
end
|
159
183
|
obj.enum_value.accept self
|
160
184
|
if obj.directives
|
161
185
|
obj.directives.each { |v| v.accept self }
|
162
186
|
end
|
163
187
|
end
|
164
188
|
def handle_enum_type_definition obj
|
189
|
+
if obj.description
|
190
|
+
obj.description.accept self
|
191
|
+
end
|
165
192
|
if obj.directives
|
166
193
|
obj.directives.each { |v| v.accept self }
|
167
194
|
end
|
@@ -170,6 +197,9 @@ module TinyGQL
|
|
170
197
|
end
|
171
198
|
end
|
172
199
|
def handle_input_object_type_definition obj
|
200
|
+
if obj.description
|
201
|
+
obj.description.accept self
|
202
|
+
end
|
173
203
|
if obj.directives
|
174
204
|
obj.directives.each { |v| v.accept self }
|
175
205
|
end
|
@@ -193,6 +223,9 @@ module TinyGQL
|
|
193
223
|
def handle_type_system_directive_location obj
|
194
224
|
end
|
195
225
|
def handle_directive_definition obj
|
226
|
+
if obj.description
|
227
|
+
obj.description.accept self
|
228
|
+
end
|
196
229
|
if obj.arguments_definition
|
197
230
|
obj.arguments_definition.each { |v| v.accept self }
|
198
231
|
end
|
@@ -325,6 +358,9 @@ module TinyGQL
|
|
325
358
|
seed
|
326
359
|
end
|
327
360
|
def handle_schema_definition obj, seed
|
361
|
+
if obj.description
|
362
|
+
seed = obj.description.fold self, seed
|
363
|
+
end
|
328
364
|
if obj.directives
|
329
365
|
obj.directives.each { |v| seed = v.fold(self, seed) }
|
330
366
|
end
|
@@ -332,6 +368,9 @@ module TinyGQL
|
|
332
368
|
seed
|
333
369
|
end
|
334
370
|
def handle_field_definition obj, seed
|
371
|
+
if obj.description
|
372
|
+
seed = obj.description.fold self, seed
|
373
|
+
end
|
335
374
|
if obj.arguments_definition
|
336
375
|
obj.arguments_definition.each { |v| seed = v.fold(self, seed) }
|
337
376
|
end
|
@@ -342,6 +381,9 @@ module TinyGQL
|
|
342
381
|
seed
|
343
382
|
end
|
344
383
|
def handle_input_value_definition obj, seed
|
384
|
+
if obj.description
|
385
|
+
seed = obj.description.fold self, seed
|
386
|
+
end
|
345
387
|
seed = obj.type.fold self, seed
|
346
388
|
if obj.default_value
|
347
389
|
seed = obj.default_value.fold self, seed
|
@@ -352,6 +394,9 @@ module TinyGQL
|
|
352
394
|
seed
|
353
395
|
end
|
354
396
|
def handle_object_type_definition obj, seed
|
397
|
+
if obj.description
|
398
|
+
seed = obj.description.fold self, seed
|
399
|
+
end
|
355
400
|
if obj.implements_interfaces
|
356
401
|
obj.implements_interfaces.each { |v| seed = v.fold(self, seed) }
|
357
402
|
end
|
@@ -364,6 +409,9 @@ module TinyGQL
|
|
364
409
|
seed
|
365
410
|
end
|
366
411
|
def handle_interface_type_definition obj, seed
|
412
|
+
if obj.description
|
413
|
+
seed = obj.description.fold self, seed
|
414
|
+
end
|
367
415
|
if obj.directives
|
368
416
|
obj.directives.each { |v| seed = v.fold(self, seed) }
|
369
417
|
end
|
@@ -373,6 +421,9 @@ module TinyGQL
|
|
373
421
|
seed
|
374
422
|
end
|
375
423
|
def handle_union_type_definition obj, seed
|
424
|
+
if obj.description
|
425
|
+
seed = obj.description.fold self, seed
|
426
|
+
end
|
376
427
|
if obj.directives
|
377
428
|
obj.directives.each { |v| seed = v.fold(self, seed) }
|
378
429
|
end
|
@@ -382,12 +433,18 @@ module TinyGQL
|
|
382
433
|
seed
|
383
434
|
end
|
384
435
|
def handle_scalar_type_definition obj, seed
|
436
|
+
if obj.description
|
437
|
+
seed = obj.description.fold self, seed
|
438
|
+
end
|
385
439
|
if obj.directives
|
386
440
|
obj.directives.each { |v| seed = v.fold(self, seed) }
|
387
441
|
end
|
388
442
|
seed
|
389
443
|
end
|
390
444
|
def handle_enum_value_definition obj, seed
|
445
|
+
if obj.description
|
446
|
+
seed = obj.description.fold self, seed
|
447
|
+
end
|
391
448
|
seed = obj.enum_value.fold self, seed
|
392
449
|
if obj.directives
|
393
450
|
obj.directives.each { |v| seed = v.fold(self, seed) }
|
@@ -395,6 +452,9 @@ module TinyGQL
|
|
395
452
|
seed
|
396
453
|
end
|
397
454
|
def handle_enum_type_definition obj, seed
|
455
|
+
if obj.description
|
456
|
+
seed = obj.description.fold self, seed
|
457
|
+
end
|
398
458
|
if obj.directives
|
399
459
|
obj.directives.each { |v| seed = v.fold(self, seed) }
|
400
460
|
end
|
@@ -404,6 +464,9 @@ module TinyGQL
|
|
404
464
|
seed
|
405
465
|
end
|
406
466
|
def handle_input_object_type_definition obj, seed
|
467
|
+
if obj.description
|
468
|
+
seed = obj.description.fold self, seed
|
469
|
+
end
|
407
470
|
if obj.directives
|
408
471
|
obj.directives.each { |v| seed = v.fold(self, seed) }
|
409
472
|
end
|
@@ -431,6 +494,9 @@ module TinyGQL
|
|
431
494
|
seed
|
432
495
|
end
|
433
496
|
def handle_directive_definition obj, seed
|
497
|
+
if obj.description
|
498
|
+
seed = obj.description.fold self, seed
|
499
|
+
end
|
434
500
|
if obj.arguments_definition
|
435
501
|
obj.arguments_definition.each { |v| seed = v.fold(self, seed) }
|
436
502
|
end
|
data/test/parser_test.rb
CHANGED
@@ -161,5 +161,31 @@ eod
|
|
161
161
|
node = ast.find(&:object_type_definition?).first
|
162
162
|
assert_equal ["a", "b", "c"], node.implements_interfaces.map(&:name)
|
163
163
|
end
|
164
|
+
|
165
|
+
def test_schemas_have_descriptions
|
166
|
+
doc = <<-eod
|
167
|
+
"foo bar"
|
168
|
+
schema {
|
169
|
+
query: QueryType
|
170
|
+
mutation: MutationType
|
171
|
+
}
|
172
|
+
eod
|
173
|
+
ast = TinyGQL::Parser.parse doc
|
174
|
+
node = ast.find(&:schema_definition?)
|
175
|
+
assert node
|
176
|
+
assert_equal "foo bar", node.description.value
|
177
|
+
end
|
178
|
+
|
179
|
+
def test_directives_have_descriptions
|
180
|
+
doc = <<-eod
|
181
|
+
"""neat!"""
|
182
|
+
directive @skip(if: Boolean!) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT
|
183
|
+
eod
|
184
|
+
ast = TinyGQL::Parser.parse doc
|
185
|
+
node = ast.find(&:directive_definition?)
|
186
|
+
assert node
|
187
|
+
assert_equal "neat!", node.description.value
|
188
|
+
assert_equal ["FIELD", "FRAGMENT_SPREAD", "INLINE_FRAGMENT"], node.directive_locations.map(&:name)
|
189
|
+
end
|
164
190
|
end
|
165
191
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tinygql
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Aaron Patterson
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-08-
|
11
|
+
date: 2023-08-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -51,7 +51,9 @@ files:
|
|
51
51
|
- LICENSE
|
52
52
|
- README.md
|
53
53
|
- Rakefile
|
54
|
+
- benchmark/fixtures/negotiate.gql
|
54
55
|
- bin/bench.rb
|
56
|
+
- bin/profile.rb
|
55
57
|
- lib/tinygql.rb
|
56
58
|
- lib/tinygql/lexer.rb
|
57
59
|
- lib/tinygql/nodes.rb
|