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.
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
- Benchmark.bm do |x|
10
- x.report { 10_000.times { TinyGQL::Parser.new(source).parse } }
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
@@ -0,0 +1,5 @@
1
+ require "vernier"
2
+
3
+ Vernier.trace(out: "time_profile.json") {
4
+ require_relative "bench"
5
+ }
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
@@ -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?: literal
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?: literal
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?: literal
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?: literal
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?: literal
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?: literal
162
+ - description?
162
163
  - name: literal
163
164
  - directives?: list
164
165
 
165
166
  - name: EnumValueDefinition
166
167
  fields:
167
- - description?: literal
168
+ - description?
168
169
  - enum_value
169
170
  - directives?: list
170
171
 
171
172
  - name: EnumTypeDefinition
172
173
  fields:
173
- - description?: literal
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?: literal
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?: literal
203
+ - description?
203
204
  - name: literal
204
205
  - arguments_definition?: list
205
206
  - directive_locations: list
@@ -7,7 +7,9 @@ module TinyGQL
7
7
  class Parser
8
8
  class UnexpectedToken < StandardError; end
9
9
 
10
- attr_reader :token_name
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
- type_system_definition
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(nil)
73
+ when :SCHEMA then schema_definition(desc)
74
+ when :DIRECTIVE then directive_defintion(desc)
69
75
  else
70
- type_definition(nil)
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
- case token_name
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(accept_token_value)
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(accept_token_value)
116
+ Nodes::TypeSystemDirectiveLocation.new(directive)
109
117
  else
110
- expect_token(:IDENTIFIER); nil # error
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); accept_token_value; end
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); accept_token_value; end
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); accept_token_value; end
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
@@ -1,3 +1,3 @@
1
1
  module TinyGQL
2
- VERSION = '0.1.2'
2
+ VERSION = '0.1.3'
3
3
  end
@@ -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.2
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 00:00:00.000000000 Z
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