tinygql 0.1.3 → 0.2.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.
@@ -1,46 +1,34 @@
1
1
  module TinyGQL
2
2
  module Visitors
3
3
  module Visitor
4
- <%- nodes.each do |node| -%>
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
- obj.<%= field.name %>.each { |v| v.accept self }
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
- obj.<%= field.name %>.accept self
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
- <%- end -%>
15
+ <% end %>
22
16
  end
23
17
 
24
18
  module Fold
25
- <%- nodes.each do |node| -%>
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
- obj.<%= field.name %>.each { |v| seed = v.fold(self, seed) }
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
- seed = obj.<%= field.name %>.fold self, seed
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
- <%- end -%>
31
+ <% end %>
44
32
  end
45
33
  end
46
34
  end
data/test/lexer_test.rb CHANGED
@@ -101,5 +101,83 @@ eod
101
101
  [:RCURLY, "}"],
102
102
  [:RCURLY, "}"]], toks
103
103
  end
104
+
105
+ def test_lex_4
106
+ words = ["true", "null", "enum", "type"]
107
+ doc = words.join(" ")
108
+
109
+ lexer = Lexer.new doc
110
+ toks = []
111
+ while tok = lexer.next_token
112
+ toks << tok
113
+ end
114
+
115
+ assert_equal words.map { |x| [x.upcase.to_sym, x] }, toks
116
+ end
117
+
118
+ def test_lex_5
119
+ words = ["input", "false", "query", "union"]
120
+ doc = words.join(" ")
121
+
122
+ lexer = Lexer.new doc
123
+ toks = []
124
+ while tok = lexer.next_token
125
+ toks << tok
126
+ end
127
+
128
+ assert_equal words.map { |x| [x.upcase.to_sym, x] }, toks
129
+ end
130
+
131
+ def test_lex_6
132
+ words = ["extend", "scalar", "schema"]
133
+ doc = words.join(" ")
134
+
135
+ lexer = Lexer.new doc
136
+ toks = []
137
+ while tok = lexer.next_token
138
+ toks << tok
139
+ end
140
+
141
+ assert_equal words.map { |x| [x.upcase.to_sym, x] }, toks
142
+ end
143
+
144
+ def test_lex_8
145
+ words = ["mutation", "fragment"]
146
+ doc = words.join(" ")
147
+
148
+ lexer = Lexer.new doc
149
+ toks = []
150
+ while tok = lexer.next_token
151
+ toks << tok
152
+ end
153
+
154
+ assert_equal words.map { |x| [x.upcase.to_sym, x] }, toks
155
+ end
156
+
157
+ def test_lex_9
158
+ words = ["interface", "directive"]
159
+ doc = words.join(" ")
160
+
161
+ lexer = Lexer.new doc
162
+ toks = []
163
+ while tok = lexer.next_token
164
+ toks << tok
165
+ end
166
+
167
+ assert_equal words.map { |x| [x.upcase.to_sym, x] }, toks
168
+ end
169
+
170
+ def test_kw_lex
171
+ words = ["on", "fragment", "true", "false", "null", "query", "mutation", "subscription", "schema", "scalar", "type", "extend", "implements", "interface", "union", "enum", "input", "directive", "repeatable"]
172
+ doc = words.join(" ")
173
+
174
+ lexer = Lexer.new doc
175
+ toks = []
176
+ while tok = lexer.next_token
177
+ toks << tok
178
+ end
179
+
180
+ assert_equal words.map { |x| [x.upcase.to_sym, x] }, toks
181
+ end
104
182
  end
105
183
  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 }) {
@@ -39,6 +46,23 @@ eod
39
46
  assert_equal ["likeStory", "story", "likeCount"], ast.find_all(&:field?).map(&:name)
40
47
  end
41
48
 
49
+ def test_has_position_and_line
50
+ doc = <<-eod
51
+ mutation {
52
+ likeStory(sturyID: 12345) {
53
+ story {
54
+ likeCount
55
+ }
56
+ }
57
+ }
58
+ eod
59
+ parser = Parser.new doc
60
+ ast = parser.parse
61
+ expected = ["likeStory", "story", "likeCount"].map { |str| doc.index(str) + str.bytesize }
62
+ assert_equal expected, ast.find_all(&:field?).map(&:pos)
63
+ assert_equal [2, 3, 4], ast.find_all(&:field?).map { |n| n.line(doc) }
64
+ end
65
+
42
66
  def test_field_alias
43
67
  doc = <<-eod
44
68
  mutation {
@@ -187,5 +211,49 @@ directive @skip(if: Boolean!) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT
187
211
  assert_equal "neat!", node.description.value
188
212
  assert_equal ["FIELD", "FRAGMENT_SPREAD", "INLINE_FRAGMENT"], node.directive_locations.map(&:name)
189
213
  end
214
+
215
+ def test_scalar_schema_extensions
216
+ ast = Parser.parse File.read(File.join(__dir__, "schema-extensions.graphql"))
217
+ node = ast.find { |x| x.scalar_type_extension? && x.name == "PositiveInt" }
218
+ assert node
219
+ assert_equal 2, node.directives.length
220
+ end
221
+
222
+ def test_scalar_schema_extensions_no_directives
223
+ ast = Parser.parse File.read(File.join(__dir__, "schema-extensions.graphql"))
224
+ node = ast.find { |x| x.scalar_type_extension? && x.name == "Aaron" }
225
+ assert node
226
+ assert_nil node.directives
227
+ end
228
+
229
+ def test_interface_extension
230
+ ast = Parser.parse File.read(File.join(__dir__, "schema-extensions.graphql"))
231
+ node = ast.find { |x| x.interface_type_extension? && x.name == "NamedEntity" }
232
+ assert node
233
+ assert_nil node.directives
234
+ assert node.fields_definition
235
+ end
236
+
237
+ def test_union_extension
238
+ ast = Parser.parse File.read(File.join(__dir__, "schema-extensions.graphql"))
239
+ node = ast.find { |x| x.union_type_extension? && x.name == "Cool" }
240
+ assert node
241
+ assert_equal 1, node.directives.length
242
+ assert_equal "foo", node.directives.first.name
243
+ end
244
+
245
+ def test_enum_extension
246
+ ast = Parser.parse File.read(File.join(__dir__, "schema-extensions.graphql"))
247
+ assert ast.find { |x| x.enum_type_extension? && x.name == "Direction" }
248
+ assert ast.find { |x| x.enum_type_extension? && x.name == "AnnotatedEnum" }
249
+ assert ast.find { |x| x.enum_type_extension? && x.name == "Neat" }
250
+ end
251
+
252
+ def test_input_extension
253
+ ast = Parser.parse File.read(File.join(__dir__, "schema-extensions.graphql"))
254
+ assert ast.find { |x| x.input_object_type_extension? && x.name == "InputType" }
255
+ assert ast.find { |x| x.input_object_type_extension? && x.name == "AnnotatedInput" }
256
+ assert ast.find { |x| x.input_object_type_extension? && x.name == "NeatInput" }
257
+ end
190
258
  end
191
259
  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.3
4
+ version: 0.2.0
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-12 00:00:00.000000000 Z
11
+ date: 2023-08-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -67,6 +67,7 @@ files:
67
67
  - test/kitchen-sink.graphql
68
68
  - test/lexer_test.rb
69
69
  - test/parser_test.rb
70
+ - test/schema-extensions.graphql
70
71
  - test/schema-kitchen-sink.graphql
71
72
  - tinygql.gemspec
72
73
  homepage: https://github.com/tenderlove/tinygql
@@ -97,4 +98,5 @@ test_files:
97
98
  - test/kitchen-sink.graphql
98
99
  - test/lexer_test.rb
99
100
  - test/parser_test.rb
101
+ - test/schema-extensions.graphql
100
102
  - test/schema-kitchen-sink.graphql