tinygql 0.1.2 → 0.1.4
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 +138 -17
- data/lib/tinygql/nodes.yml +45 -14
- data/lib/tinygql/parser.rb +76 -23
- data/lib/tinygql/version.rb +1 -1
- data/lib/tinygql/visitors.rb +261 -238
- data/lib/tinygql/visitors.rb.erb +8 -20
- data/test/parser_test.rb +77 -0
- data/test/schema-extensions.graphql +48 -0
- metadata +6 -2
data/lib/tinygql/visitors.rb.erb
CHANGED
@@ -1,46 +1,34 @@
|
|
1
1
|
module TinyGQL
|
2
2
|
module Visitors
|
3
3
|
module Visitor
|
4
|
-
|
4
|
+
<% nodes.each do |node| %>
|
5
5
|
def handle_<%= node.human_name %> obj
|
6
6
|
<%- node.fields.find_all(&:visitable?).each do |field| -%>
|
7
|
-
<%- if field.nullable? -%>
|
8
|
-
if obj.<%= field.name %>
|
9
|
-
<%- end -%>
|
10
7
|
<%- if field.list? -%>
|
11
|
-
|
8
|
+
obj.<%= field.name %>.each { |v| v.accept self }<% if field.nullable? %> if obj.<%= field.name %><% end %>
|
12
9
|
<%- end -%>
|
13
10
|
<%- if field.node? -%>
|
14
|
-
|
15
|
-
<%- end -%>
|
16
|
-
<%- if field.nullable? -%>
|
17
|
-
end
|
11
|
+
obj.<%= field.name %>.accept(self)<% if field.nullable? %> if obj.<%= field.name %><% end %>
|
18
12
|
<%- end -%>
|
19
13
|
<%- end -%>
|
20
14
|
end
|
21
|
-
|
15
|
+
<% end %>
|
22
16
|
end
|
23
17
|
|
24
18
|
module Fold
|
25
|
-
|
19
|
+
<% nodes.each do |node| %>
|
26
20
|
def handle_<%= node.human_name %> obj, seed
|
27
21
|
<%- node.fields.find_all(&:visitable?).each do |field| -%>
|
28
|
-
<%- if field.nullable? -%>
|
29
|
-
if obj.<%= field.name %>
|
30
|
-
<%- end -%>
|
31
22
|
<%- if field.list? -%>
|
32
|
-
|
23
|
+
obj.<%= field.name %>.each { |v| seed = v.fold(self, seed) }<% if field.nullable? %> if obj.<%= field.name %><% end %>
|
33
24
|
<%- end -%>
|
34
25
|
<%- if field.node? -%>
|
35
|
-
|
36
|
-
<%- end -%>
|
37
|
-
<%- if field.nullable? -%>
|
38
|
-
end
|
26
|
+
seed = obj.<%= field.name %>.fold(self, seed)<% if field.nullable? %> if obj.<%= field.name %><% end %>
|
39
27
|
<%- end -%>
|
40
28
|
<%- end -%>
|
41
29
|
seed
|
42
30
|
end
|
43
|
-
|
31
|
+
<% end %>
|
44
32
|
end
|
45
33
|
end
|
46
34
|
end
|
data/test/parser_test.rb
CHANGED
@@ -3,6 +3,13 @@ require "tinygql"
|
|
3
3
|
|
4
4
|
module TinyGQL
|
5
5
|
class ParserTest < Test
|
6
|
+
def test_homogeneous_ast
|
7
|
+
%w{ kitchen-sink.graphql schema-extensions.graphql schema-kitchen-sink.graphql }.each do |f|
|
8
|
+
ast = Parser.parse File.read(File.join(__dir__, f))
|
9
|
+
assert ast.all? { |x| x.is_a?(TinyGQL::Nodes::Node) }
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
6
13
|
def test_multi_tok
|
7
14
|
doc = <<-eod
|
8
15
|
mutation aaron($neat: Int = 123) @foo(lol: { lon: 456 }) {
|
@@ -161,5 +168,75 @@ eod
|
|
161
168
|
node = ast.find(&:object_type_definition?).first
|
162
169
|
assert_equal ["a", "b", "c"], node.implements_interfaces.map(&:name)
|
163
170
|
end
|
171
|
+
|
172
|
+
def test_schemas_have_descriptions
|
173
|
+
doc = <<-eod
|
174
|
+
"foo bar"
|
175
|
+
schema {
|
176
|
+
query: QueryType
|
177
|
+
mutation: MutationType
|
178
|
+
}
|
179
|
+
eod
|
180
|
+
ast = TinyGQL::Parser.parse doc
|
181
|
+
node = ast.find(&:schema_definition?)
|
182
|
+
assert node
|
183
|
+
assert_equal "foo bar", node.description.value
|
184
|
+
end
|
185
|
+
|
186
|
+
def test_directives_have_descriptions
|
187
|
+
doc = <<-eod
|
188
|
+
"""neat!"""
|
189
|
+
directive @skip(if: Boolean!) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT
|
190
|
+
eod
|
191
|
+
ast = TinyGQL::Parser.parse doc
|
192
|
+
node = ast.find(&:directive_definition?)
|
193
|
+
assert node
|
194
|
+
assert_equal "neat!", node.description.value
|
195
|
+
assert_equal ["FIELD", "FRAGMENT_SPREAD", "INLINE_FRAGMENT"], node.directive_locations.map(&:name)
|
196
|
+
end
|
197
|
+
|
198
|
+
def test_scalar_schema_extensions
|
199
|
+
ast = Parser.parse File.read(File.join(__dir__, "schema-extensions.graphql"))
|
200
|
+
node = ast.find { |x| x.scalar_type_extension? && x.name == "PositiveInt" }
|
201
|
+
assert node
|
202
|
+
assert_equal 2, node.directives.length
|
203
|
+
end
|
204
|
+
|
205
|
+
def test_scalar_schema_extensions_no_directives
|
206
|
+
ast = Parser.parse File.read(File.join(__dir__, "schema-extensions.graphql"))
|
207
|
+
node = ast.find { |x| x.scalar_type_extension? && x.name == "Aaron" }
|
208
|
+
assert node
|
209
|
+
assert_nil node.directives
|
210
|
+
end
|
211
|
+
|
212
|
+
def test_interface_extension
|
213
|
+
ast = Parser.parse File.read(File.join(__dir__, "schema-extensions.graphql"))
|
214
|
+
node = ast.find { |x| x.interface_type_extension? && x.name == "NamedEntity" }
|
215
|
+
assert node
|
216
|
+
assert_nil node.directives
|
217
|
+
assert node.fields_definition
|
218
|
+
end
|
219
|
+
|
220
|
+
def test_union_extension
|
221
|
+
ast = Parser.parse File.read(File.join(__dir__, "schema-extensions.graphql"))
|
222
|
+
node = ast.find { |x| x.union_type_extension? && x.name == "Cool" }
|
223
|
+
assert node
|
224
|
+
assert_equal 1, node.directives.length
|
225
|
+
assert_equal "foo", node.directives.first.name
|
226
|
+
end
|
227
|
+
|
228
|
+
def test_enum_extension
|
229
|
+
ast = Parser.parse File.read(File.join(__dir__, "schema-extensions.graphql"))
|
230
|
+
assert ast.find { |x| x.enum_type_extension? && x.name == "Direction" }
|
231
|
+
assert ast.find { |x| x.enum_type_extension? && x.name == "AnnotatedEnum" }
|
232
|
+
assert ast.find { |x| x.enum_type_extension? && x.name == "Neat" }
|
233
|
+
end
|
234
|
+
|
235
|
+
def test_input_extension
|
236
|
+
ast = Parser.parse File.read(File.join(__dir__, "schema-extensions.graphql"))
|
237
|
+
assert ast.find { |x| x.input_object_type_extension? && x.name == "InputType" }
|
238
|
+
assert ast.find { |x| x.input_object_type_extension? && x.name == "AnnotatedInput" }
|
239
|
+
assert ast.find { |x| x.input_object_type_extension? && x.name == "NeatInput" }
|
240
|
+
end
|
164
241
|
end
|
165
242
|
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
extend scalar PositiveInt
|
2
|
+
@serializationType(name: "global::System.Int32")
|
3
|
+
@runtimeType(name: "global::System.Int32")
|
4
|
+
|
5
|
+
extend scalar Aaron
|
6
|
+
|
7
|
+
extend interface NamedEntity {
|
8
|
+
nickname: String
|
9
|
+
}
|
10
|
+
|
11
|
+
extend type Person {
|
12
|
+
nickname: String
|
13
|
+
}
|
14
|
+
|
15
|
+
extend type Business {
|
16
|
+
nickname: String
|
17
|
+
}
|
18
|
+
|
19
|
+
extend interface NamedEntity @addedDirective
|
20
|
+
|
21
|
+
extend union Cool @foo
|
22
|
+
|
23
|
+
extend union Great @onUnion = A | B
|
24
|
+
|
25
|
+
extend enum Direction {
|
26
|
+
NORTH
|
27
|
+
EAST
|
28
|
+
SOUTH
|
29
|
+
WEST
|
30
|
+
}
|
31
|
+
|
32
|
+
extend enum AnnotatedEnum @onEnum {
|
33
|
+
ANNOTATED_VALUE @onEnumValue
|
34
|
+
OTHER_VALUE
|
35
|
+
}
|
36
|
+
|
37
|
+
extend enum Neat @onEnum
|
38
|
+
|
39
|
+
extend input InputType {
|
40
|
+
key: String!
|
41
|
+
answer: Int = 42
|
42
|
+
}
|
43
|
+
|
44
|
+
extend input AnnotatedInput @onInputObjectType {
|
45
|
+
annotatedField: Type @onField
|
46
|
+
}
|
47
|
+
|
48
|
+
extend input NeatInput @onInputObjectType
|
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.4
|
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-13 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
|
@@ -65,6 +67,7 @@ files:
|
|
65
67
|
- test/kitchen-sink.graphql
|
66
68
|
- test/lexer_test.rb
|
67
69
|
- test/parser_test.rb
|
70
|
+
- test/schema-extensions.graphql
|
68
71
|
- test/schema-kitchen-sink.graphql
|
69
72
|
- tinygql.gemspec
|
70
73
|
homepage: https://github.com/tenderlove/tinygql
|
@@ -95,4 +98,5 @@ test_files:
|
|
95
98
|
- test/kitchen-sink.graphql
|
96
99
|
- test/lexer_test.rb
|
97
100
|
- test/parser_test.rb
|
101
|
+
- test/schema-extensions.graphql
|
98
102
|
- test/schema-kitchen-sink.graphql
|