graphql 0.0.4 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/graph_ql/directive.rb +36 -0
- data/lib/graph_ql/directives/directive_chain.rb +33 -0
- data/lib/graph_ql/directives/include_directive.rb +15 -0
- data/lib/graph_ql/directives/skip_directive.rb +15 -0
- data/lib/graph_ql/enum.rb +34 -0
- data/lib/graph_ql/fields/abstract_field.rb +37 -0
- data/lib/graph_ql/fields/access_field.rb +24 -0
- data/lib/graph_ql/fields/field.rb +34 -0
- data/lib/graph_ql/interface.rb +14 -0
- data/lib/graph_ql/introspection/arguments_field.rb +5 -0
- data/lib/graph_ql/introspection/directive_type.rb +12 -0
- data/lib/graph_ql/introspection/enum_value_type.rb +10 -0
- data/lib/graph_ql/introspection/enum_values_field.rb +15 -0
- data/lib/graph_ql/introspection/field_type.rb +11 -0
- data/lib/graph_ql/introspection/fields_field.rb +14 -0
- data/lib/graph_ql/introspection/input_fields_field.rb +12 -0
- data/lib/graph_ql/introspection/input_value_type.rb +10 -0
- data/lib/graph_ql/introspection/of_type_field.rb +12 -0
- data/lib/graph_ql/introspection/possible_types_field.rb +12 -0
- data/lib/graph_ql/introspection/schema_type.rb +32 -0
- data/lib/graph_ql/introspection/type_kind_enum.rb +7 -0
- data/lib/graph_ql/introspection/type_type.rb +22 -0
- data/lib/graph_ql/parser/nodes.rb +72 -0
- data/lib/graph_ql/parser/parser.rb +108 -0
- data/lib/graph_ql/parser/transform.rb +86 -0
- data/lib/graph_ql/parser/visitor.rb +47 -0
- data/lib/graph_ql/query.rb +50 -0
- data/lib/graph_ql/query/arguments.rb +25 -0
- data/lib/graph_ql/query/field_resolution_strategy.rb +83 -0
- data/lib/graph_ql/query/fragment_spread_resolution_strategy.rb +16 -0
- data/lib/graph_ql/query/inline_fragment_resolution_strategy.rb +14 -0
- data/lib/graph_ql/query/operation_resolver.rb +28 -0
- data/lib/graph_ql/query/selection_resolver.rb +20 -0
- data/lib/graph_ql/query/type_resolver.rb +19 -0
- data/lib/graph_ql/repl.rb +27 -0
- data/lib/graph_ql/schema.rb +30 -0
- data/lib/graph_ql/schema/type_reducer.rb +44 -0
- data/lib/graph_ql/type_kinds.rb +15 -0
- data/lib/graph_ql/types/abstract_type.rb +14 -0
- data/lib/graph_ql/types/boolean_type.rb +6 -0
- data/lib/graph_ql/types/float_type.rb +6 -0
- data/lib/graph_ql/types/input_object_type.rb +17 -0
- data/lib/graph_ql/types/input_value.rb +10 -0
- data/lib/graph_ql/types/int_type.rb +6 -0
- data/lib/graph_ql/types/list_type.rb +10 -0
- data/lib/graph_ql/types/non_null_type.rb +18 -0
- data/lib/graph_ql/types/non_null_with_bang.rb +5 -0
- data/lib/graph_ql/types/object_type.rb +62 -0
- data/lib/graph_ql/types/scalar_type.rb +5 -0
- data/lib/graph_ql/types/string_type.rb +6 -0
- data/lib/graph_ql/types/type_definer.rb +16 -0
- data/lib/graph_ql/union.rb +35 -0
- data/lib/graph_ql/validations/fields_are_defined_on_type.rb +44 -0
- data/lib/graph_ql/validations/fields_will_merge.rb +80 -0
- data/lib/graph_ql/validations/fragments_are_used.rb +24 -0
- data/lib/graph_ql/validator.rb +29 -0
- data/lib/graph_ql/version.rb +3 -0
- data/lib/graphql.rb +92 -99
- data/readme.md +17 -177
- data/spec/graph_ql/directive_spec.rb +81 -0
- data/spec/graph_ql/enum_spec.rb +5 -0
- data/spec/graph_ql/fields/field_spec.rb +10 -0
- data/spec/graph_ql/interface_spec.rb +13 -0
- data/spec/graph_ql/introspection/directive_type_spec.rb +40 -0
- data/spec/graph_ql/introspection/schema_type_spec.rb +39 -0
- data/spec/graph_ql/introspection/type_type_spec.rb +104 -0
- data/spec/graph_ql/parser/parser_spec.rb +120 -0
- data/spec/graph_ql/parser/transform_spec.rb +109 -0
- data/spec/graph_ql/parser/visitor_spec.rb +31 -0
- data/spec/graph_ql/query/operation_resolver_spec.rb +14 -0
- data/spec/graph_ql/query_spec.rb +82 -0
- data/spec/graph_ql/schema/type_reducer_spec.rb +24 -0
- data/spec/graph_ql/types/input_object_type_spec.rb +12 -0
- data/spec/graph_ql/types/object_type_spec.rb +35 -0
- data/spec/graph_ql/union_spec.rb +27 -0
- data/spec/graph_ql/validations/fields_are_defined_on_type_spec.rb +28 -0
- data/spec/graph_ql/validations/fields_will_merge_spec.rb +40 -0
- data/spec/graph_ql/validations/fragments_are_used_spec.rb +28 -0
- data/spec/graph_ql/validator_spec.rb +24 -0
- data/spec/spec_helper.rb +2 -2
- data/spec/support/dummy_app.rb +123 -63
- data/spec/support/dummy_data.rb +11 -0
- metadata +107 -59
- data/lib/graphql/call.rb +0 -8
- data/lib/graphql/connection.rb +0 -65
- data/lib/graphql/field.rb +0 -12
- data/lib/graphql/field_definer.rb +0 -25
- data/lib/graphql/introspection/call_type.rb +0 -13
- data/lib/graphql/introspection/connection.rb +0 -9
- data/lib/graphql/introspection/field_type.rb +0 -10
- data/lib/graphql/introspection/root_call_argument_node.rb +0 -5
- data/lib/graphql/introspection/root_call_type.rb +0 -20
- data/lib/graphql/introspection/schema_call.rb +0 -8
- data/lib/graphql/introspection/schema_type.rb +0 -17
- data/lib/graphql/introspection/type_call.rb +0 -8
- data/lib/graphql/introspection/type_type.rb +0 -18
- data/lib/graphql/node.rb +0 -244
- data/lib/graphql/parser/parser.rb +0 -39
- data/lib/graphql/parser/transform.rb +0 -22
- data/lib/graphql/query.rb +0 -109
- data/lib/graphql/root_call.rb +0 -202
- data/lib/graphql/root_call_argument.rb +0 -11
- data/lib/graphql/root_call_argument_definer.rb +0 -17
- data/lib/graphql/schema/all.rb +0 -46
- data/lib/graphql/schema/schema.rb +0 -87
- data/lib/graphql/schema/schema_validation.rb +0 -32
- data/lib/graphql/syntax/call.rb +0 -8
- data/lib/graphql/syntax/field.rb +0 -9
- data/lib/graphql/syntax/fragment.rb +0 -7
- data/lib/graphql/syntax/node.rb +0 -8
- data/lib/graphql/syntax/query.rb +0 -8
- data/lib/graphql/syntax/variable.rb +0 -7
- data/lib/graphql/types/boolean_type.rb +0 -3
- data/lib/graphql/types/number_type.rb +0 -3
- data/lib/graphql/types/object_type.rb +0 -6
- data/lib/graphql/types/string_type.rb +0 -3
- data/lib/graphql/version.rb +0 -3
- data/spec/graphql/node_spec.rb +0 -69
- data/spec/graphql/parser/parser_spec.rb +0 -168
- data/spec/graphql/parser/transform_spec.rb +0 -157
- data/spec/graphql/query_spec.rb +0 -274
- data/spec/graphql/root_call_spec.rb +0 -69
- data/spec/graphql/schema/schema_spec.rb +0 -93
- data/spec/graphql/schema/schema_validation_spec.rb +0 -48
- data/spec/support/nodes.rb +0 -175
@@ -1,157 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe GraphQL::Parser::Transform do
|
4
|
-
let(:transform) { GraphQL::TRANSFORM }
|
5
|
-
let(:parser) { GraphQL::PARSER }
|
6
|
-
|
7
|
-
describe '#apply' do
|
8
|
-
describe 'query' do
|
9
|
-
it 'parses node and variables' do
|
10
|
-
tree = parser.query.parse(%{
|
11
|
-
like_page(<page_info>) { page { $fragment, likes } }
|
12
|
-
|
13
|
-
<page_info>: {
|
14
|
-
"page" : { "id": 4},
|
15
|
-
"person" : {"id": 4}
|
16
|
-
}
|
17
|
-
<other>: {
|
18
|
-
"page" : { "id": 4},
|
19
|
-
"person" : {"id": 4}
|
20
|
-
}
|
21
|
-
|
22
|
-
$fragment: {
|
23
|
-
id, name
|
24
|
-
}
|
25
|
-
})
|
26
|
-
res = transform.apply(tree)
|
27
|
-
assert_equal 1, res.nodes.length
|
28
|
-
assert_equal "like_page", res.nodes[0].identifier
|
29
|
-
assert_equal ["<page_info>"], res.nodes[0].arguments
|
30
|
-
assert_equal ["<page_info>", "<other>"], res.variables.map(&:identifier)
|
31
|
-
assert_equal ["$fragment"], res.fragments.map(&:identifier)
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
describe 'nodes' do
|
36
|
-
it 'turns a simple node into a Node' do
|
37
|
-
tree = parser.node.parse("post(123) { name }")
|
38
|
-
res = transform.apply(tree)
|
39
|
-
assert(res.is_a?(GraphQL::Syntax::Node), 'it gets a node')
|
40
|
-
end
|
41
|
-
|
42
|
-
it 'turns a node into a Node' do
|
43
|
-
tree = parser.node.parse("person(1) { name, check_ins.last(4) { count, edges { node { id } } } }")
|
44
|
-
res = transform.apply(tree)
|
45
|
-
assert(res.is_a?(GraphQL::Syntax::Node), 'it gets a node')
|
46
|
-
assert(res.identifier == "person")
|
47
|
-
assert(res.fields.length == 2)
|
48
|
-
assert(res.fields[0].is_a?(GraphQL::Syntax::Field), 'it gets a field')
|
49
|
-
assert(res.fields[1].is_a?(GraphQL::Syntax::Field), 'it gets an field with fields')
|
50
|
-
assert(res.fields[1].calls.first.is_a?(GraphQL::Syntax::Call), 'it gets a call')
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
describe 'fields' do
|
55
|
-
it 'turns a field into a Field' do
|
56
|
-
tree = parser.field.parse("friends")
|
57
|
-
res = transform.apply(tree)
|
58
|
-
assert(res.is_a?(GraphQL::Syntax::Field))
|
59
|
-
assert(res.identifier == "friends")
|
60
|
-
end
|
61
|
-
|
62
|
-
it 'gets aliases' do
|
63
|
-
tree = parser.field.parse("friends as pals")
|
64
|
-
res = transform.apply(tree)
|
65
|
-
assert(res.is_a?(GraphQL::Syntax::Field))
|
66
|
-
assert(res.identifier == "friends")
|
67
|
-
assert(res.alias_name == "pals")
|
68
|
-
end
|
69
|
-
|
70
|
-
it 'gets calls' do
|
71
|
-
tree = parser.field.parse("friends.orderby(name, birthdate).first(3)")
|
72
|
-
res = transform.apply(tree)
|
73
|
-
assert_equal "orderby", res.calls[0].identifier
|
74
|
-
assert_equal ["name", "birthdate"], res.calls[0].arguments
|
75
|
-
assert_equal "first", res.calls[1].identifier
|
76
|
-
assert_equal ["3"], res.calls[1].arguments
|
77
|
-
end
|
78
|
-
|
79
|
-
describe 'fields that return objects' do
|
80
|
-
it 'gets them' do
|
81
|
-
tree = parser.field.parse("friends { count }")
|
82
|
-
res = transform.apply(tree)
|
83
|
-
assert_equal "friends", res.identifier
|
84
|
-
assert_equal 1, res.fields.length
|
85
|
-
end
|
86
|
-
it 'gets them with aliases' do
|
87
|
-
tree = parser.field.parse("friends as pals { count }")
|
88
|
-
res = transform.apply(tree)
|
89
|
-
assert_equal "friends", res.identifier
|
90
|
-
assert_equal "pals", res.alias_name
|
91
|
-
assert_equal 1, res.fields.length
|
92
|
-
end
|
93
|
-
it 'gets them with calls' do
|
94
|
-
tree = parser.field.parse("friends.orderby(name, birthdate).last(1) { count }")
|
95
|
-
res = transform.apply(tree)
|
96
|
-
assert_equal "friends", res.identifier
|
97
|
-
assert_equal 1, res.fields.length
|
98
|
-
assert_equal 2, res.calls.length
|
99
|
-
end
|
100
|
-
it 'gets them with calls and aliases' do
|
101
|
-
tree = parser.field.parse("friends.orderby(name, birthdate).last(1) as pals { count }")
|
102
|
-
res = transform.apply(tree)
|
103
|
-
assert_equal "friends", res.identifier
|
104
|
-
assert_equal "pals", res.alias_name
|
105
|
-
assert_equal 1, res.fields.length
|
106
|
-
assert_equal 2, res.calls.length
|
107
|
-
end
|
108
|
-
end
|
109
|
-
end
|
110
|
-
|
111
|
-
describe 'calls' do
|
112
|
-
it 'turns call into a Call' do
|
113
|
-
tree = parser.call.parse("node(4, 6, tree)")
|
114
|
-
res = transform.apply(tree)
|
115
|
-
assert(res.is_a?(GraphQL::Syntax::Call))
|
116
|
-
assert(res.identifier == "node")
|
117
|
-
assert(res.arguments == ["4", "6", "tree"])
|
118
|
-
end
|
119
|
-
|
120
|
-
it 'turns a call without an argument into a Call' do
|
121
|
-
tree = parser.call.parse("viewer()")
|
122
|
-
res = transform.apply(tree)
|
123
|
-
assert(res.is_a?(GraphQL::Syntax::Call))
|
124
|
-
assert(res.identifier == "viewer")
|
125
|
-
assert(res.arguments.length == 0)
|
126
|
-
end
|
127
|
-
|
128
|
-
it 'gets calls with variable identifiers' do
|
129
|
-
tree = parser.call.parse("like_page(<page_info>)")
|
130
|
-
res = transform.apply(tree)
|
131
|
-
assert_equal "<page_info>", res.arguments[0]
|
132
|
-
end
|
133
|
-
end
|
134
|
-
|
135
|
-
describe 'variables' do
|
136
|
-
it 'gets variables' do
|
137
|
-
tree = parser.variable.parse(%{
|
138
|
-
<page_info>: {
|
139
|
-
"page" : { "id": 4},
|
140
|
-
"person" : {"id": 4}
|
141
|
-
}
|
142
|
-
})
|
143
|
-
res = transform.apply(tree)
|
144
|
-
assert_equal "<page_info>", res.identifier
|
145
|
-
end
|
146
|
-
end
|
147
|
-
|
148
|
-
describe 'fragments' do
|
149
|
-
it 'gets fragments' do
|
150
|
-
tree = parser.fragment.parse(%{$frag: { id, name, $otherFrag }})
|
151
|
-
res = transform.apply(tree)
|
152
|
-
assert_equal "$frag", res.identifier
|
153
|
-
assert_equal ["id", "name", "$otherFrag"], res.fields.map(&:identifier)
|
154
|
-
end
|
155
|
-
end
|
156
|
-
end
|
157
|
-
end
|
data/spec/graphql/query_spec.rb
DELETED
@@ -1,274 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe GraphQL::Query do
|
4
|
-
let(:query_string) { "post(123) { title, content } "}
|
5
|
-
let(:context) { Context.new(person_name: "Han Solo") }
|
6
|
-
let(:query) { GraphQL::Query.new(query_string, context: context) }
|
7
|
-
let(:result) { query.as_result }
|
8
|
-
|
9
|
-
before do
|
10
|
-
@post = Post.create(id: 123, content: "So many great things", title: "My great post", published_at: Date.new(2010,1,4))
|
11
|
-
@comment1 = Comment.create(id: 444, post_id: 123, content: "I agree", rating: 5)
|
12
|
-
@comment2 = Comment.create(id: 445, post_id: 123, content: "I disagree", rating: 1)
|
13
|
-
@like1 = Like.create(id: 991, post_id: 123)
|
14
|
-
@like2 = Like.create(id: 992, post_id: 123)
|
15
|
-
end
|
16
|
-
|
17
|
-
after do
|
18
|
-
@post.destroy
|
19
|
-
@comment1.destroy
|
20
|
-
@comment2.destroy
|
21
|
-
@like1.destroy
|
22
|
-
@like2.destroy
|
23
|
-
end
|
24
|
-
|
25
|
-
describe '#as_result' do
|
26
|
-
it 'finds fields that delegate to a target' do
|
27
|
-
assert_equal result, {"123" => {"title" => "My great post", "content" => "So many great things"}}
|
28
|
-
end
|
29
|
-
|
30
|
-
describe 'with multiple roots' do
|
31
|
-
let(:query_string) { "comment(444, 445) { content } "}
|
32
|
-
it 'adds each as a key-value of the response' do
|
33
|
-
assert_equal ["444", "445"], result.keys
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
describe 'when accessing fields that return objects' do
|
38
|
-
describe 'when making calls on the field' do
|
39
|
-
let(:query_string) { "post(123) { published_at.minus_days(200) { year } }"}
|
40
|
-
it 'returns the modified value' do
|
41
|
-
assert_equal 2009, result["123"]["published_at"]["year"]
|
42
|
-
end
|
43
|
-
end
|
44
|
-
describe 'when requesting more fields' do
|
45
|
-
let(:query_string) { "post(123) { published_at { month, year } }"}
|
46
|
-
it 'returns those fields' do
|
47
|
-
assert_equal({"month" => 1, "year" => 2010}, result["123"]["published_at"])
|
48
|
-
end
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
describe 'when using query fragments' do
|
53
|
-
let(:query_string) { "post(123) { id, $publishedData } $publishedData: { published_at { month, year } }"}
|
54
|
-
|
55
|
-
it 'can yield the fragment' do
|
56
|
-
fragment = query.fragments["$publishedData"]
|
57
|
-
assert_equal "$publishedData", fragment.identifier
|
58
|
-
assert_equal 1, fragment.fields.length
|
59
|
-
end
|
60
|
-
|
61
|
-
it 'returns literal fields and fragment fields' do
|
62
|
-
assert_equal(123, result["123"]['id'])
|
63
|
-
assert_equal({"month" => 1, "year" => 2010}, result["123"]["published_at"])
|
64
|
-
end
|
65
|
-
end
|
66
|
-
describe 'when aliasing things' do
|
67
|
-
let(:query_string) { "post(123) { title as headline, content as what_it_says }"}
|
68
|
-
|
69
|
-
it 'applies aliases to fields' do
|
70
|
-
assert_equal @post.title, result["123"]["headline"]
|
71
|
-
assert_equal @post.content, result["123"]["what_it_says"]
|
72
|
-
end
|
73
|
-
|
74
|
-
it 'applies aliases to edges' # dunno the syntax yet
|
75
|
-
end
|
76
|
-
|
77
|
-
describe 'when requesting fields defined on the node' do
|
78
|
-
let(:query_string) { "post(123) { length } "}
|
79
|
-
it 'finds fields defined on the node' do
|
80
|
-
assert_equal 20, result["123"]["length"]
|
81
|
-
end
|
82
|
-
end
|
83
|
-
|
84
|
-
describe 'when accessing custom fields' do
|
85
|
-
let(:query_string) { "comment(444) { letters }"}
|
86
|
-
|
87
|
-
it 'uses the custom field' do
|
88
|
-
assert_equal "I agree", result["444"]["letters"]
|
89
|
-
end
|
90
|
-
|
91
|
-
describe 'when making calls on fields' do
|
92
|
-
let(:query_string) { "comment(444) {
|
93
|
-
letters.select(4, 3),
|
94
|
-
letters.from(3).for(2) as snippet
|
95
|
-
}"}
|
96
|
-
|
97
|
-
it 'works with aliases' do
|
98
|
-
assert result["444"]["snippet"].present?
|
99
|
-
end
|
100
|
-
|
101
|
-
it 'applies calls' do
|
102
|
-
assert_equal "gr", result["444"]["snippet"]
|
103
|
-
end
|
104
|
-
|
105
|
-
it 'applies calls with multiple arguments' do
|
106
|
-
assert_equal "ree", result["444"]["letters"]
|
107
|
-
end
|
108
|
-
end
|
109
|
-
|
110
|
-
describe 'when requesting fields overriden on a child class' do
|
111
|
-
let(:query_string) { 'thumb_up(991) { id }'}
|
112
|
-
it 'uses the child implementation' do
|
113
|
-
assert_equal '991991', result["991991"]["id"]
|
114
|
-
end
|
115
|
-
end
|
116
|
-
end
|
117
|
-
|
118
|
-
describe 'when requesting an undefined field' do
|
119
|
-
let(:query_string) { "post(123) { destroy } "}
|
120
|
-
it 'raises a FieldNotDefined error' do
|
121
|
-
assert_raises(GraphQL::FieldNotDefinedError) { query.as_result }
|
122
|
-
assert(Post.find(123).present?)
|
123
|
-
end
|
124
|
-
end
|
125
|
-
|
126
|
-
describe 'when the root call doesnt have an argument' do
|
127
|
-
let(:query_string) { "context() { person_name, present }"}
|
128
|
-
it 'calls the node with no arguments' do
|
129
|
-
assert_equal true, result["context"]["present"]
|
130
|
-
assert_equal "Han Solo", result["context"]["person_name"]
|
131
|
-
end
|
132
|
-
end
|
133
|
-
|
134
|
-
describe 'when requesting a collection' do
|
135
|
-
let(:query_string) { "post(123) {
|
136
|
-
title,
|
137
|
-
comments { count, edges { cursor, node { content } } }
|
138
|
-
}"}
|
139
|
-
|
140
|
-
it 'returns collection data' do
|
141
|
-
assert_equal result, {
|
142
|
-
"123" => {
|
143
|
-
"title" => "My great post",
|
144
|
-
"comments" => {
|
145
|
-
"count" => 2,
|
146
|
-
"edges" => [
|
147
|
-
{ "cursor" => "444", "node" => {"content" => "I agree"} },
|
148
|
-
{ "cursor" => "445", "node" => {"content" => "I disagree"}}
|
149
|
-
]
|
150
|
-
}}}
|
151
|
-
end
|
152
|
-
end
|
153
|
-
|
154
|
-
describe 'when making calls on a collection' do
|
155
|
-
let(:query_string) { "post(123) { comments.first(1) { edges { cursor, node { content } } } }"}
|
156
|
-
|
157
|
-
it 'executes those calls' do
|
158
|
-
expected_result = { "123" => {
|
159
|
-
"comments" => {
|
160
|
-
"edges" => [
|
161
|
-
{ "cursor" => "444", "node" => { "content" => "I agree"} }
|
162
|
-
]
|
163
|
-
}}}
|
164
|
-
assert_equal(expected_result, result)
|
165
|
-
end
|
166
|
-
end
|
167
|
-
|
168
|
-
describe 'when making DEEP calls on a collection' do
|
169
|
-
let(:query_string) { "post(123) { comments.after(444).first(1) {
|
170
|
-
edges { cursor, node { content } }
|
171
|
-
}}"}
|
172
|
-
|
173
|
-
it 'executes those calls' do
|
174
|
-
assert_equal result, {
|
175
|
-
"123" => {
|
176
|
-
"comments" => {
|
177
|
-
"edges" => [
|
178
|
-
{
|
179
|
-
"cursor" => "445",
|
180
|
-
"node" => { "content" => "I disagree"}
|
181
|
-
}
|
182
|
-
]
|
183
|
-
}}}
|
184
|
-
end
|
185
|
-
end
|
186
|
-
|
187
|
-
describe 'when requesting fields at collection-level' do
|
188
|
-
let(:query_string) { "post(123) { comments { average_rating } }"}
|
189
|
-
|
190
|
-
it 'executes those calls' do
|
191
|
-
assert_equal result, { "123" => { "comments" => { "average_rating" => 3 } } }
|
192
|
-
end
|
193
|
-
end
|
194
|
-
|
195
|
-
describe 'when making calls on node fields' do
|
196
|
-
let(:query_string) { "post(123) { comments { edges { node { letters.from(3).for(3) }} } }"}
|
197
|
-
|
198
|
-
it 'makes calls on the fields' do
|
199
|
-
assert_equal ["gre", "isa"], result["123"]["comments"]["edges"].map {|e| e["node"]["letters"] }
|
200
|
-
end
|
201
|
-
end
|
202
|
-
|
203
|
-
describe 'when requesting collection-level fields that dont exist' do
|
204
|
-
let(:query_string) { "post(123) { comments { bogus_field } }"}
|
205
|
-
|
206
|
-
it 'raises FieldNotDefined' do
|
207
|
-
assert_raises(GraphQL::FieldNotDefinedError) { query.as_result }
|
208
|
-
end
|
209
|
-
end
|
210
|
-
end
|
211
|
-
|
212
|
-
describe 'when requesting fields on a related object' do
|
213
|
-
let(:query_string) { "comment(444) { post { title } }"}
|
214
|
-
|
215
|
-
it 'finds fields on that object' do
|
216
|
-
assert_equal "My great post", result["444"]["post"]["title"]
|
217
|
-
end
|
218
|
-
|
219
|
-
describe 'when the object doesnt exist' do
|
220
|
-
before do
|
221
|
-
Post.all.map(&:destroy)
|
222
|
-
end
|
223
|
-
|
224
|
-
it 'blows_up' do # what _should_ this do?
|
225
|
-
assert_raises(NoMethodError) { result }
|
226
|
-
end
|
227
|
-
end
|
228
|
-
end
|
229
|
-
|
230
|
-
describe 'when edge classes were named explicitly' do
|
231
|
-
let(:query_string) { "post(123) { likes { any, edges { node { id } } } }"}
|
232
|
-
|
233
|
-
it 'gets node values' do
|
234
|
-
assert_equal ["991991","992992"], result["123"]["likes"]["edges"].map {|e| e["node"]["id"] }
|
235
|
-
end
|
236
|
-
|
237
|
-
it 'gets edge values' do
|
238
|
-
assert_equal true, result["123"]["likes"]["any"]
|
239
|
-
end
|
240
|
-
end
|
241
|
-
|
242
|
-
describe '#context' do
|
243
|
-
let(:query_string) { "context() { person_name }"}
|
244
|
-
|
245
|
-
it 'is accessible inside nodes' do
|
246
|
-
assert_equal({"context" => {"person_name" => "Han Solo"}}, result)
|
247
|
-
end
|
248
|
-
|
249
|
-
describe 'inside edges' do
|
250
|
-
let(:query_string) { "post(123) { comments { viewer_name_length } }"}
|
251
|
-
it 'is accessible' do
|
252
|
-
assert_equal 8, result["123"]["comments"]["viewer_name_length"]
|
253
|
-
end
|
254
|
-
end
|
255
|
-
end
|
256
|
-
|
257
|
-
describe 'parsing error' do
|
258
|
-
let(:query_string) { "\n\n<< bogus >>"}
|
259
|
-
|
260
|
-
it 'raises SyntaxError' do
|
261
|
-
assert_raises(GraphQL::SyntaxError) { result }
|
262
|
-
end
|
263
|
-
|
264
|
-
it 'contains line an character number' do
|
265
|
-
err = assert_raises(GraphQL::SyntaxError) { result }
|
266
|
-
assert_match(/1, 1/, err.to_s)
|
267
|
-
end
|
268
|
-
|
269
|
-
it 'contains sample of text' do
|
270
|
-
err = assert_raises(GraphQL::SyntaxError) { result }
|
271
|
-
assert_includes(err.to_s, "<< bogus >>")
|
272
|
-
end
|
273
|
-
end
|
274
|
-
end
|
@@ -1,69 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe GraphQL::RootCall do
|
4
|
-
let(:query_string) { %{
|
5
|
-
upvote_post(<post_data>, <person_id>) {
|
6
|
-
post {
|
7
|
-
likes { count, any }
|
8
|
-
}
|
9
|
-
upvote {
|
10
|
-
post_id
|
11
|
-
}
|
12
|
-
}
|
13
|
-
<post_data>: { "id" : #{@post_id} }
|
14
|
-
<person_id>: 888
|
15
|
-
}}
|
16
|
-
let(:result) { GraphQL::Query.new(query_string).as_result }
|
17
|
-
|
18
|
-
before do
|
19
|
-
# make sure tests don't conflict :(
|
20
|
-
@post_id = "#{Time.now.to_i}#{[1,2,3].sample}".to_i
|
21
|
-
@post = Post.create(id: @post_id, content: "My great post")
|
22
|
-
@like = Like.create(post_id: @post_id)
|
23
|
-
end
|
24
|
-
|
25
|
-
after do
|
26
|
-
@post.likes.map(&:destroy)
|
27
|
-
@post.destroy
|
28
|
-
end
|
29
|
-
|
30
|
-
describe '#as_result' do
|
31
|
-
it 'operates on the application' do
|
32
|
-
assert_equal 1, @post.likes.count
|
33
|
-
result
|
34
|
-
assert_equal 2, @post.likes.count
|
35
|
-
end
|
36
|
-
|
37
|
-
it 'returns fields for the node' do
|
38
|
-
assert_equal @post_id, result["upvote"]["post_id"]
|
39
|
-
assert_equal 2, result["post"]["likes"]["count"]
|
40
|
-
assert_equal true, result["post"]["likes"]["any"]
|
41
|
-
end
|
42
|
-
|
43
|
-
describe 'when the input is the wrong type' do
|
44
|
-
let(:query_string) { %{upvote_post(bogus_arg, 888) { post { id } } } }
|
45
|
-
it 'validates the input' do
|
46
|
-
assert_raises(GraphQL::RootCallArgumentError) { result }
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
describe '.argument' do
|
52
|
-
it 'is reload-safe' do
|
53
|
-
assert_equal 2, Nodes::LikePostCall.arguments.length, "it starts with 1"
|
54
|
-
assert_equal "person_id", Nodes::LikePostCall.argument_at_index(1).name
|
55
|
-
assert_raises(RuntimeError, 'it raises before') { Nodes::LikePostCall.argument_at_index(2) }
|
56
|
-
|
57
|
-
Nodes::LikePostCall.argument.number("person_id")
|
58
|
-
|
59
|
-
assert_equal 2, Nodes::LikePostCall.arguments.length, "it stays at 1"
|
60
|
-
assert_equal "person_id", Nodes::LikePostCall.argument_at_index(1).name
|
61
|
-
assert_raises(RuntimeError, 'it raises after') { Nodes::LikePostCall.argument_at_index(2) }
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
65
|
-
describe '#__type__' do
|
66
|
-
it 'describes the arguments'
|
67
|
-
it 'describes the response'
|
68
|
-
end
|
69
|
-
end
|