graphql 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. checksums.yaml +4 -4
  2. data/lib/graphql.rb +78 -9
  3. data/lib/graphql/call.rb +7 -0
  4. data/lib/graphql/connection.rb +44 -0
  5. data/lib/graphql/field.rb +117 -0
  6. data/lib/graphql/field_definer.rb +29 -0
  7. data/lib/graphql/introspection/call_node.rb +13 -0
  8. data/lib/graphql/introspection/connection.rb +9 -0
  9. data/lib/graphql/introspection/field_node.rb +19 -0
  10. data/lib/graphql/introspection/root_call_argument_node.rb +5 -0
  11. data/lib/graphql/introspection/root_call_node.rb +16 -0
  12. data/lib/graphql/introspection/schema_call.rb +8 -0
  13. data/lib/graphql/introspection/schema_node.rb +17 -0
  14. data/lib/graphql/introspection/type_call.rb +8 -0
  15. data/lib/graphql/introspection/type_node.rb +16 -0
  16. data/lib/graphql/node.rb +141 -34
  17. data/lib/graphql/parser.rb +19 -8
  18. data/lib/graphql/query.rb +64 -21
  19. data/lib/graphql/root_call.rb +176 -0
  20. data/lib/graphql/root_call_argument.rb +8 -0
  21. data/lib/graphql/root_call_argument_definer.rb +20 -0
  22. data/lib/graphql/schema.rb +99 -0
  23. data/lib/graphql/syntax/call.rb +3 -12
  24. data/lib/graphql/syntax/field.rb +4 -2
  25. data/lib/graphql/syntax/node.rb +3 -10
  26. data/lib/graphql/syntax/query.rb +7 -0
  27. data/lib/graphql/syntax/variable.rb +7 -0
  28. data/lib/graphql/transform.rb +14 -5
  29. data/lib/graphql/types/boolean_field.rb +3 -0
  30. data/lib/graphql/types/connection_field.rb +30 -0
  31. data/lib/graphql/types/cursor_field.rb +9 -0
  32. data/lib/graphql/types/number_field.rb +3 -0
  33. data/lib/graphql/types/object_field.rb +8 -0
  34. data/lib/graphql/types/string_field.rb +3 -0
  35. data/lib/graphql/types/type_field.rb +6 -0
  36. data/lib/graphql/version.rb +3 -0
  37. data/readme.md +142 -10
  38. data/spec/graphql/field_spec.rb +66 -0
  39. data/spec/graphql/node_spec.rb +68 -0
  40. data/spec/graphql/parser_spec.rb +75 -25
  41. data/spec/graphql/query_spec.rb +185 -83
  42. data/spec/graphql/root_call_spec.rb +55 -0
  43. data/spec/graphql/schema_spec.rb +128 -0
  44. data/spec/graphql/transform_spec.rb +124 -39
  45. data/spec/spec_helper.rb +2 -1
  46. data/spec/support/dummy_app.rb +43 -23
  47. data/spec/support/nodes.rb +145 -32
  48. metadata +78 -16
  49. data/lib/graphql/collection_edge.rb +0 -62
  50. data/lib/graphql/syntax/edge.rb +0 -12
@@ -1,59 +1,172 @@
1
+ require 'graphql'
2
+ require 'support/dummy_app.rb'
3
+
1
4
  module Nodes
2
- class PostNode < GraphQL::Node
3
- field_reader :id, :title, :content
5
+ class ApplicationNode < GraphQL::Node
6
+ field.number(:id)
4
7
  cursor :id
5
8
 
6
- edges :comments,
7
- collection_class_name: "Nodes::ApplicationCollectionEdge",
8
- edge_class_name: "Nodes::CommentNode"
9
+ class << self
10
+ attr_accessor :model_class
11
+ def node_for(m_class)
12
+ @model_class = m_class
13
+ end
14
+ end
15
+ end
16
+
17
+ class ApplicationConnection < GraphQL::Connection
18
+ default_connection!
19
+ field.number(:count)
20
+ field.boolean(:any)
9
21
 
10
- def teaser
11
- content.length > 10 ? "#{content[0..9]}..." : content
22
+ def count
23
+ items.count
12
24
  end
13
25
 
14
- def self.call(argument)
15
- post = Post.find(argument.to_i)
16
- self.new(post)
26
+ def any
27
+ items.any?
17
28
  end
18
29
  end
19
30
 
20
- class CommentNode < GraphQL::Node
21
- field_reader :id, :post, :content
22
- cursor :id
31
+ class CommentsConnection < ApplicationConnection
32
+ field.number :viewer_name_length
33
+ field.number :average_rating
34
+
35
+ # just to test context:
36
+ def viewer_name_length
37
+ context.person_name.length
38
+ end
39
+
40
+ def average_rating
41
+ total_rating = items.map(&:rating).inject(&:+).to_f
42
+ total_rating / items.size
43
+ end
44
+ end
45
+
46
+ class LetterSelectionField < GraphQL::Types::StringField
47
+ call :from, -> (prev_value, chars) { prev_value[(chars.to_i)..-1] }
48
+ call :for, -> (prev_value, chars) { prev_value[0, (chars.to_i)] }
49
+ call :select, -> (prev_value, from_chars, for_chars) { prev_value[from_chars.to_i, for_chars.to_i] }
50
+ def raw_value
51
+ owner.content
52
+ end
53
+ end
54
+
55
+ class ApplicationConnectionField < GraphQL::Types::ConnectionField
56
+ type :connection
57
+ call :first, -> (prev_items, first) { prev_items.first(first.to_i) }
58
+ call :after, -> (prev_items, after) { prev_items.select {|i| i.id > after.to_i } }
59
+ end
60
+
61
+ class DateField < GraphQL::Types::ObjectField
62
+ type :date
63
+ call :minus_days, -> (prev_value, minus_days) { prev_value - minus_days.to_i }
64
+ end
65
+
66
+ class DateNode < GraphQL::Node
67
+ exposes "Date"
68
+ field.number(:year)
69
+ field.number(:month)
70
+ end
71
+
72
+ class PostNode < ApplicationNode
73
+ node_for Post
74
+ exposes "Post"
75
+ desc "A blog post entry"
23
76
 
24
- def self.call(argument)
25
- obj = Comment.find(argument)
26
- self.new(obj)
77
+ field.string(:title)
78
+ field.letter_selection(:content)
79
+ field.number(:length)
80
+ field.connection(:comments)
81
+ field.date(:published_at)
82
+ field.connection(:likes)
83
+
84
+ def length
85
+ target.content.length
27
86
  end
28
87
  end
29
88
 
30
- class ViewerNode < GraphQL::Node
31
- def name
32
- "It's you again"
89
+ class CommentNode < ApplicationNode
90
+ node_for Comment
91
+ exposes "Comment"
92
+ field.string :content
93
+ field.letter_selection(:letters)
94
+ field.object(:post)
95
+ end
96
+
97
+ # wraps a Like, for testing explicit name
98
+ class ThumbUpNode < ApplicationNode
99
+ node_for(Like)
100
+ exposes "Like"
101
+ type "upvote"
102
+ field.number :post_id
103
+ def id
104
+ target.id.to_s + target.id.to_s
33
105
  end
106
+ end
107
+
108
+ class ContextNode < GraphQL::Node
109
+ exposes "Context"
110
+ field.string(:person_name)
34
111
 
35
112
  def cursor
36
- "viewer"
113
+ "context"
37
114
  end
115
+ end
38
116
 
39
- def self.call(argument)
40
- self.new
117
+
118
+ class FindCall < GraphQL::RootCall
119
+ abstract!
120
+ argument.number("ids", any_number: true)
121
+ def execute!(*ids)
122
+ model_class = model_type
123
+ items = ids.map { |id| model_class.find(id.to_i) }
41
124
  end
42
125
  end
43
126
 
44
- class ApplicationCollectionEdge < GraphQL::CollectionEdge
45
- def apply_calls(items, calls)
46
- filtered_items = items
127
+ class PostCall < FindCall
128
+ returns :post
129
+ def model_type
130
+ Post
131
+ end
132
+ end
47
133
 
48
- if calls["after"].present?
49
- filtered_items = filtered_items.select {|i| i.id > calls["after"].to_i }
50
- end
134
+ class CommentCall < FindCall
135
+ returns :comment
136
+ def model_type
137
+ Comment
138
+ end
139
+ end
140
+
141
+ class ThumbUpCall < FindCall
142
+ returns :thumb_up
143
+ def model_type
144
+ Like
145
+ end
146
+ end
147
+
148
+ class ContextCall < GraphQL::RootCall
149
+ returns :context
150
+ def execute!
151
+ context
152
+ end
153
+ end
154
+
155
+ class LikePostCall < GraphQL::RootCall
156
+ indentifier "upvote_post"
157
+ returns :post, :upvote
158
+
159
+ argument.object("post_data")
160
+ argument.number("person_id")
51
161
 
52
- if calls["first"].present?
53
- filtered_items = filtered_items.first(calls["first"].to_i)
54
- end
55
162
 
56
- filtered_items
163
+ def execute!(post_data, person_id)
164
+ post_id = post_data["id"]
165
+ like = Like.create(post_id: post_id)
166
+ {
167
+ post: Post.find(post_id),
168
+ upvote: like
169
+ }
57
170
  end
58
171
  end
59
172
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: graphql
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Robert Mosolgo
@@ -38,90 +38,118 @@ dependencies:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: 1.6.2
41
+ - !ruby/object:Gem::Dependency
42
+ name: pry
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0.10'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0.10'
41
55
  - !ruby/object:Gem::Dependency
42
56
  name: guard
43
57
  requirement: !ruby/object:Gem::Requirement
44
58
  requirements:
45
59
  - - ">="
46
60
  - !ruby/object:Gem::Version
47
- version: '0'
61
+ version: '2.11'
48
62
  type: :development
49
63
  prerelease: false
50
64
  version_requirements: !ruby/object:Gem::Requirement
51
65
  requirements:
52
66
  - - ">="
53
67
  - !ruby/object:Gem::Version
54
- version: '0'
68
+ version: '2.11'
55
69
  - !ruby/object:Gem::Dependency
56
70
  name: guard-bundler
57
71
  requirement: !ruby/object:Gem::Requirement
58
72
  requirements:
59
73
  - - ">="
60
74
  - !ruby/object:Gem::Version
61
- version: '0'
75
+ version: '2.1'
62
76
  type: :development
63
77
  prerelease: false
64
78
  version_requirements: !ruby/object:Gem::Requirement
65
79
  requirements:
66
80
  - - ">="
67
81
  - !ruby/object:Gem::Version
68
- version: '0'
82
+ version: '2.1'
69
83
  - !ruby/object:Gem::Dependency
70
84
  name: guard-minitest
71
85
  requirement: !ruby/object:Gem::Requirement
72
86
  requirements:
73
87
  - - ">="
74
88
  - !ruby/object:Gem::Version
75
- version: '0'
89
+ version: '2.1'
76
90
  type: :development
77
91
  prerelease: false
78
92
  version_requirements: !ruby/object:Gem::Requirement
79
93
  requirements:
80
94
  - - ">="
81
95
  - !ruby/object:Gem::Version
82
- version: '0'
96
+ version: '2.1'
83
97
  - !ruby/object:Gem::Dependency
84
98
  name: minitest
85
99
  requirement: !ruby/object:Gem::Requirement
86
100
  requirements:
87
101
  - - ">="
88
102
  - !ruby/object:Gem::Version
89
- version: '0'
103
+ version: '5.5'
90
104
  type: :development
91
105
  prerelease: false
92
106
  version_requirements: !ruby/object:Gem::Requirement
93
107
  requirements:
94
108
  - - ">="
95
109
  - !ruby/object:Gem::Version
96
- version: '0'
110
+ version: '5.5'
97
111
  - !ruby/object:Gem::Dependency
98
112
  name: minitest-focus
99
113
  requirement: !ruby/object:Gem::Requirement
100
114
  requirements:
101
115
  - - ">="
102
116
  - !ruby/object:Gem::Version
103
- version: '0'
117
+ version: '1.1'
104
118
  type: :development
105
119
  prerelease: false
106
120
  version_requirements: !ruby/object:Gem::Requirement
107
121
  requirements:
108
122
  - - ">="
109
123
  - !ruby/object:Gem::Version
110
- version: '0'
124
+ version: '1.1'
111
125
  - !ruby/object:Gem::Dependency
112
126
  name: minitest-reporters
113
127
  requirement: !ruby/object:Gem::Requirement
114
128
  requirements:
115
129
  - - ">="
116
130
  - !ruby/object:Gem::Version
117
- version: '0'
131
+ version: '1.0'
118
132
  type: :development
119
133
  prerelease: false
120
134
  version_requirements: !ruby/object:Gem::Requirement
121
135
  requirements:
122
136
  - - ">="
123
137
  - !ruby/object:Gem::Version
124
- version: '0'
138
+ version: '1.0'
139
+ - !ruby/object:Gem::Dependency
140
+ name: rake
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ">="
144
+ - !ruby/object:Gem::Version
145
+ version: '10.4'
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: '10.4'
125
153
  description: A GraphQL adapter for Ruby
126
154
  email:
127
155
  - rdmosolgo@gmail.com
@@ -131,18 +159,47 @@ extra_rdoc_files: []
131
159
  files:
132
160
  - MIT-LICENSE
133
161
  - lib/graphql.rb
134
- - lib/graphql/collection_edge.rb
162
+ - lib/graphql/call.rb
163
+ - lib/graphql/connection.rb
164
+ - lib/graphql/field.rb
165
+ - lib/graphql/field_definer.rb
166
+ - lib/graphql/introspection/call_node.rb
167
+ - lib/graphql/introspection/connection.rb
168
+ - lib/graphql/introspection/field_node.rb
169
+ - lib/graphql/introspection/root_call_argument_node.rb
170
+ - lib/graphql/introspection/root_call_node.rb
171
+ - lib/graphql/introspection/schema_call.rb
172
+ - lib/graphql/introspection/schema_node.rb
173
+ - lib/graphql/introspection/type_call.rb
174
+ - lib/graphql/introspection/type_node.rb
135
175
  - lib/graphql/node.rb
136
176
  - lib/graphql/parser.rb
137
177
  - lib/graphql/query.rb
178
+ - lib/graphql/root_call.rb
179
+ - lib/graphql/root_call_argument.rb
180
+ - lib/graphql/root_call_argument_definer.rb
181
+ - lib/graphql/schema.rb
138
182
  - lib/graphql/syntax/call.rb
139
- - lib/graphql/syntax/edge.rb
140
183
  - lib/graphql/syntax/field.rb
141
184
  - lib/graphql/syntax/node.rb
185
+ - lib/graphql/syntax/query.rb
186
+ - lib/graphql/syntax/variable.rb
142
187
  - lib/graphql/transform.rb
188
+ - lib/graphql/types/boolean_field.rb
189
+ - lib/graphql/types/connection_field.rb
190
+ - lib/graphql/types/cursor_field.rb
191
+ - lib/graphql/types/number_field.rb
192
+ - lib/graphql/types/object_field.rb
193
+ - lib/graphql/types/string_field.rb
194
+ - lib/graphql/types/type_field.rb
195
+ - lib/graphql/version.rb
143
196
  - readme.md
197
+ - spec/graphql/field_spec.rb
198
+ - spec/graphql/node_spec.rb
144
199
  - spec/graphql/parser_spec.rb
145
200
  - spec/graphql/query_spec.rb
201
+ - spec/graphql/root_call_spec.rb
202
+ - spec/graphql/schema_spec.rb
146
203
  - spec/graphql/transform_spec.rb
147
204
  - spec/spec_helper.rb
148
205
  - spec/support/dummy_app.rb
@@ -159,7 +216,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
159
216
  requirements:
160
217
  - - ">="
161
218
  - !ruby/object:Gem::Version
162
- version: '0'
219
+ version: 2.1.0
163
220
  required_rubygems_version: !ruby/object:Gem::Requirement
164
221
  requirements:
165
222
  - - ">="
@@ -172,9 +229,14 @@ signing_key:
172
229
  specification_version: 4
173
230
  summary: GraphQL
174
231
  test_files:
232
+ - spec/graphql/field_spec.rb
233
+ - spec/graphql/node_spec.rb
175
234
  - spec/graphql/parser_spec.rb
176
235
  - spec/graphql/query_spec.rb
236
+ - spec/graphql/root_call_spec.rb
237
+ - spec/graphql/schema_spec.rb
177
238
  - spec/graphql/transform_spec.rb
178
239
  - spec/spec_helper.rb
179
240
  - spec/support/dummy_app.rb
180
241
  - spec/support/nodes.rb
242
+ has_rdoc:
@@ -1,62 +0,0 @@
1
- class GraphQL::CollectionEdge
2
- attr_accessor :fields, :edge_class, :calls, :fields
3
-
4
- def initialize(items:, edge_class:)
5
- @items = items
6
- @edge_class = edge_class
7
- end
8
-
9
- def to_json
10
- json = {}
11
- fields.each do |field|
12
- name = field.identifier
13
- if name == "edges"
14
- json["edges"] = edges(fields: field.fields)
15
- else
16
- json[name] = safe_send(name)
17
- end
18
- end
19
- json
20
- end
21
-
22
- def count
23
- @items.count
24
- end
25
-
26
- def apply_calls(unfiltered_items, call_hash)
27
- # override this to apply calls to your items
28
- unfiltered_items
29
- end
30
-
31
- def edges(fields:)
32
- filtered_items = apply_calls(items, calls)
33
- filtered_items.map do |item|
34
- node = edge_class.new(item)
35
- json = {}
36
- fields.each do |field|
37
- name = field.identifier
38
- if name == "node" # it's magic
39
- node.fields = field.fields
40
- json[name] = node.to_json
41
- else
42
- json[name] = node.safe_send(name)
43
- end
44
- end
45
- json
46
- end
47
- end
48
-
49
- def safe_send(identifier)
50
- if respond_to?(identifier)
51
- public_send(identifier)
52
- else
53
- raise GraphQL::FieldNotDefinedError, "#{self.class.name}##{identifier} was requested, but it isn't defined."
54
- end
55
- end
56
-
57
- private
58
-
59
- def items
60
- @items
61
- end
62
- end