graphql 0.2.0 → 0.3.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.
- checksums.yaml +4 -4
- data/lib/graph_ql/{types → definition_helpers}/argument_definer.rb +0 -0
- data/lib/graph_ql/definition_helpers/definable.rb +18 -0
- data/lib/graph_ql/{types → definition_helpers}/field_definer.rb +0 -0
- data/lib/graph_ql/definition_helpers/forwardable.rb +10 -0
- data/lib/graph_ql/definition_helpers/non_null_with_bang.rb +9 -0
- data/lib/graph_ql/definition_helpers/string_named_hash.rb +12 -0
- data/lib/graph_ql/{types → definition_helpers}/type_definer.rb +1 -0
- data/lib/graph_ql/directive.rb +9 -5
- data/lib/graph_ql/directives/directive_chain.rb +1 -1
- data/lib/graph_ql/field.rb +1 -5
- data/lib/graph_ql/parser/transform.rb +1 -3
- data/lib/graph_ql/query.rb +14 -3
- data/lib/graph_ql/query/arguments.rb +6 -5
- data/lib/graph_ql/query/field_resolution_strategy.rb +3 -3
- data/lib/graph_ql/{types → scalars}/boolean_type.rb +0 -0
- data/lib/graph_ql/{types → scalars}/float_type.rb +1 -1
- data/lib/graph_ql/scalars/id_type.rb +6 -0
- data/lib/graph_ql/{types → scalars}/int_type.rb +0 -0
- data/lib/graph_ql/{types → scalars}/scalar_type.rb +0 -4
- data/lib/graph_ql/{types → scalars}/string_type.rb +0 -0
- data/lib/graph_ql/static_validation.rb +7 -10
- data/lib/graph_ql/static_validation/all_rules.rb +23 -0
- data/lib/graph_ql/static_validation/literal_validator.rb +0 -3
- data/lib/graph_ql/static_validation/{argument_literals_are_compatible.rb → rules/argument_literals_are_compatible.rb} +0 -0
- data/lib/graph_ql/static_validation/{arguments_are_defined.rb → rules/arguments_are_defined.rb} +5 -0
- data/lib/graph_ql/static_validation/{directives_are_defined.rb → rules/directives_are_defined.rb} +0 -0
- data/lib/graph_ql/static_validation/{fields_are_defined_on_type.rb → rules/fields_are_defined_on_type.rb} +0 -0
- data/lib/graph_ql/static_validation/{fields_have_appropriate_selections.rb → rules/fields_have_appropriate_selections.rb} +0 -0
- data/lib/graph_ql/static_validation/{fields_will_merge.rb → rules/fields_will_merge.rb} +13 -5
- data/lib/graph_ql/static_validation/rules/fragment_spreads_are_possible.rb +50 -0
- data/lib/graph_ql/static_validation/{fragment_types_exist.rb → rules/fragment_types_exist.rb} +0 -0
- data/lib/graph_ql/static_validation/rules/fragments_are_finite.rb +23 -0
- data/lib/graph_ql/static_validation/rules/fragments_are_on_composite_types.rb +27 -0
- data/lib/graph_ql/static_validation/{fragments_are_used.rb → rules/fragments_are_used.rb} +0 -0
- data/lib/graph_ql/static_validation/{required_arguments_are_present.rb → rules/required_arguments_are_present.rb} +0 -0
- data/lib/graph_ql/static_validation/rules/variable_default_values_are_correctly_typed.rb +24 -0
- data/lib/graph_ql/static_validation/rules/variable_usages_are_allowed.rb +47 -0
- data/lib/graph_ql/static_validation/rules/variables_are_input_types.rb +27 -0
- data/lib/graph_ql/static_validation/rules/variables_are_used_and_defined.rb +31 -0
- data/lib/graph_ql/static_validation/type_stack.rb +13 -1
- data/lib/graph_ql/static_validation/validator.rb +14 -18
- data/lib/graph_ql/type_kinds.rb +8 -4
- data/lib/graph_ql/{enum.rb → types/enum.rb} +7 -6
- data/lib/graph_ql/types/input_object_type.rb +3 -10
- data/lib/graph_ql/{interface.rb → types/interface.rb} +0 -4
- data/lib/graph_ql/types/list_type.rb +0 -4
- data/lib/graph_ql/types/non_null_type.rb +0 -4
- data/lib/graph_ql/types/object_type.rb +28 -13
- data/lib/graph_ql/{union.rb → types/union.rb} +0 -4
- data/lib/graph_ql/version.rb +1 -1
- data/lib/graphql.rb +9 -40
- data/readme.md +26 -20
- data/spec/graph_ql/directive_spec.rb +4 -4
- data/spec/graph_ql/introspection/directive_type_spec.rb +2 -2
- data/spec/graph_ql/introspection/schema_type_spec.rb +3 -2
- data/spec/graph_ql/introspection/type_type_spec.rb +7 -7
- data/spec/graph_ql/parser/parser_spec.rb +6 -2
- data/spec/graph_ql/query_spec.rb +26 -8
- data/spec/graph_ql/scalars/id_type_spec.rb +24 -0
- data/spec/graph_ql/schema/type_reducer_spec.rb +1 -0
- data/spec/graph_ql/schema/type_validator_spec.rb +1 -1
- data/spec/graph_ql/static_validation/{argument_literals_are_compatible_spec.rb → rules/argument_literals_are_compatible_spec.rb} +1 -1
- data/spec/graph_ql/static_validation/{arguments_are_defined_spec.rb → rules/arguments_are_defined_spec.rb} +1 -1
- data/spec/graph_ql/static_validation/{directives_are_defined_spec.rb → rules/directives_are_defined_spec.rb} +1 -1
- data/spec/graph_ql/static_validation/{fields_are_defined_on_type_spec.rb → rules/fields_are_defined_on_type_spec.rb} +1 -1
- data/spec/graph_ql/static_validation/{fields_have_appropriate_selections_spec.rb → rules/fields_have_appropriate_selections_spec.rb} +1 -1
- data/spec/graph_ql/static_validation/{fields_will_merge_spec.rb → rules/fields_will_merge_spec.rb} +1 -1
- data/spec/graph_ql/static_validation/rules/fragment_spreads_are_possible_spec.rb +46 -0
- data/spec/graph_ql/static_validation/{fragment_types_exist_spec.rb → rules/fragment_types_exist_spec.rb} +1 -1
- data/spec/graph_ql/static_validation/rules/fragments_are_finite_spec.rb +43 -0
- data/spec/graph_ql/static_validation/rules/fragments_are_on_composite_types_spec.rb +48 -0
- data/spec/graph_ql/static_validation/{fragments_are_used_spec.rb → rules/fragments_are_used_spec.rb} +1 -1
- data/spec/graph_ql/static_validation/{required_arguments_are_present_spec.rb → rules/required_arguments_are_present_spec.rb} +1 -1
- data/spec/graph_ql/static_validation/rules/variable_default_values_are_correctly_typed_spec.rb +43 -0
- data/spec/graph_ql/static_validation/rules/variable_usages_are_allowed_spec.rb +45 -0
- data/spec/graph_ql/static_validation/rules/variables_are_input_types_spec.rb +36 -0
- data/spec/graph_ql/static_validation/rules/variables_are_used_and_defined_spec.rb +44 -0
- data/spec/graph_ql/static_validation/type_stack_spec.rb +2 -2
- data/spec/graph_ql/static_validation/validator_spec.rb +44 -5
- data/spec/graph_ql/types/enum_spec.rb +10 -0
- data/spec/graph_ql/{interface_spec.rb → types/interface_spec.rb} +1 -1
- data/spec/graph_ql/types/object_type_spec.rb +13 -0
- data/spec/graph_ql/{union_spec.rb → types/union_spec.rb} +0 -0
- data/spec/support/dummy_app.rb +7 -6
- data/spec/support/dummy_data.rb +3 -3
- metadata +74 -46
- data/lib/graph_ql/types/non_null_with_bang.rb +0 -5
- data/spec/graph_ql/enum_spec.rb +0 -5
data/lib/graph_ql/version.rb
CHANGED
data/lib/graphql.rb
CHANGED
@@ -12,56 +12,26 @@ module GraphQL
|
|
12
12
|
raise [line, col, string].join(", ")
|
13
13
|
end
|
14
14
|
|
15
|
-
module Definable
|
16
|
-
def attr_definable(*names)
|
17
|
-
attr_accessor(*names)
|
18
|
-
names.each do |name|
|
19
|
-
ivar_name = "@#{name}".to_sym
|
20
|
-
define_method(name) do |new_value=nil|
|
21
|
-
new_value && self.instance_variable_set(ivar_name, new_value)
|
22
|
-
instance_variable_get(ivar_name)
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
module Forwardable
|
29
|
-
def delegate(*methods, to:)
|
30
|
-
methods.each do |method_name|
|
31
|
-
define_method(method_name) do |*args|
|
32
|
-
self.public_send(to).public_send(method_name, *args)
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
15
|
module Introspection; end
|
39
16
|
end
|
40
17
|
|
18
|
+
def require_dir(dir)
|
19
|
+
Dir.glob(File.expand_path("../graph_ql/#{dir}/*.rb", __FILE__)).each do |file|
|
20
|
+
require file
|
21
|
+
end
|
22
|
+
end
|
41
23
|
# Order matters for these:
|
42
24
|
|
43
|
-
|
25
|
+
require_dir('definition_helpers')
|
44
26
|
require 'graph_ql/types/object_type'
|
45
|
-
|
46
|
-
require 'graph_ql/types/scalar_type'
|
47
|
-
require 'graph_ql/types/non_null_type'
|
48
|
-
require 'graph_ql/types/input_value'
|
49
|
-
require 'graph_ql/types/input_object_type'
|
50
|
-
|
51
|
-
require 'graph_ql/types/type_definer'
|
52
|
-
require 'graph_ql/types/field_definer'
|
53
|
-
require 'graph_ql/types/argument_definer'
|
27
|
+
require_dir('types')
|
54
28
|
|
55
|
-
require 'graph_ql/enum'
|
56
29
|
require 'graph_ql/field'
|
57
|
-
require 'graph_ql/union'
|
58
30
|
require 'graph_ql/type_kinds'
|
59
31
|
require 'graph_ql/introspection/typename_field'
|
60
32
|
|
61
|
-
require 'graph_ql/
|
62
|
-
|
63
|
-
require 'graph_ql/types/float_type'
|
64
|
-
require 'graph_ql/types/boolean_type'
|
33
|
+
require 'graph_ql/scalars/scalar_type'
|
34
|
+
require_dir('scalars')
|
65
35
|
|
66
36
|
require 'graph_ql/introspection/input_value_type'
|
67
37
|
require 'graph_ql/introspection/enum_value_type'
|
@@ -87,7 +57,6 @@ require 'graph_ql/schema'
|
|
87
57
|
|
88
58
|
# Order does not matter for these:
|
89
59
|
|
90
|
-
require 'graph_ql/interface'
|
91
60
|
require 'graph_ql/query'
|
92
61
|
require 'graph_ql/repl'
|
93
62
|
require 'graph_ql/static_validation'
|
data/readme.md
CHANGED
@@ -27,7 +27,7 @@
|
|
27
27
|
t.name "Post"
|
28
28
|
t.description "A blog post"
|
29
29
|
t.fields({
|
30
|
-
id: field.build(type: !types.Int)
|
30
|
+
id: field.build(type: !types.Int),
|
31
31
|
title: field.build(type: !types.String),
|
32
32
|
body: field.build(type: !types.String),
|
33
33
|
comments: field.build(type: types[!CommentType])
|
@@ -76,29 +76,35 @@
|
|
76
76
|
- [`queries_controller.rb`](https://github.com/rmosolgo/graphql-ruby-demo/blob/master/app/controllers/queries_controller.rb) for a Rails example
|
77
77
|
- Try it on [heroku](http://graphql-ruby-demo.herokuapp.com)
|
78
78
|
|
79
|
-
## To Do
|
80
|
-
|
81
|
-
-
|
82
|
-
-
|
83
|
-
-
|
84
|
-
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
- [In abstract scope, object-typed fragments fit that type](http://facebook.github.io/graphql/#sec-Object-Spreads-In-Abstract-Scope)
|
89
|
-
- [In abstract scope, abstract-typed fragments must share a type](http://facebook.github.io/graphql/#sec-Abstract-Spreads-in-Abstract-Scope)
|
90
|
-
- everything in [Variables](http://facebook.github.io/graphql/#sec-Validation.Operations.Variables)
|
91
|
-
- directives:
|
92
|
-
- `@skip` has precedence over `@include`
|
93
|
-
- directives on fragments: http://facebook.github.io/graphql/#sec-Fragment-Directives
|
94
|
-
- Support any "real" value for enum, not just stringified name (see `Character::EPISODES` in demo)
|
95
|
-
- field merging (https://github.com/graphql/graphql-js/issues/19#issuecomment-118515077)
|
79
|
+
## To Do
|
80
|
+
|
81
|
+
- To match spec:
|
82
|
+
- Directives:
|
83
|
+
- `@skip` has precedence over `@include`
|
84
|
+
- directives on fragments: http://facebook.github.io/graphql/#sec-Fragment-Directives
|
85
|
+
- Field merging
|
86
|
+
- if you were to request a field, then request it in a fragment, it would get looked up twice
|
87
|
+
- https://github.com/graphql/graphql-js/issues/19#issuecomment-118515077
|
96
88
|
- Code clean-up
|
97
89
|
- Unify unwrapping types (It's on `TypeKind` but it's still not right)
|
98
|
-
|
90
|
+
- Cook up some path other than "n+1s everywhere"
|
99
91
|
|
100
|
-
## Goals
|
92
|
+
## Goals
|
101
93
|
|
102
94
|
- Implement the GraphQL spec & support a Relay front end
|
103
95
|
- Provide idiomatic, plain-Ruby API with similarities to reference implementation where possible
|
104
96
|
- Support `graphql-rails`
|
97
|
+
|
98
|
+
## Getting Involved
|
99
|
+
|
100
|
+
- __Say hi & ask questions__ in the [#ruby channel on Slack](https://graphql-slack.herokuapp.com/) or [on Twitter](https://twitter.com/rmosolgo)!
|
101
|
+
- __Report bugs__ by posting a description, full stack trace, and all relevant code in a [GitHub issue](https://github.com/rmosolgo/graphql-ruby/issues).
|
102
|
+
- __Features & patches__ are welcome! Consider discussing it in an [issue](https://github.com/rmosolgo/graphql-ruby/issues) or in the [#ruby channel on Slack](https://graphql-slack.herokuapp.com/) to make sure we're on the same page.
|
103
|
+
- __Run the tests__ with `rake test` or start up guard with `bundle exec guard`.
|
104
|
+
|
105
|
+
## Other Resources
|
106
|
+
|
107
|
+
- [GraphQL Spec](http://facebook.github.io/graphql/)
|
108
|
+
- Other implementations: [graphql-links](https://github.com/emmenko/graphql-links)
|
109
|
+
- `graphql-ruby` + Rails demo ([src](https://github.com/rmosolgo/graphql-ruby-demo) / [heroku](http://graphql-ruby-demo.herokuapp.com))
|
110
|
+
- [GraphQL Slack](https://graphql-slack.herokuapp.com/)
|
@@ -23,14 +23,14 @@ describe GraphQL::Directive do
|
|
23
23
|
fragment dontSkipIdField on Cheese { dontSkipId: id @skip(if: false) }
|
24
24
|
|}
|
25
25
|
it 'intercepts fields' do
|
26
|
-
expected = { "data" =>
|
26
|
+
expected = { "data" =>{
|
27
27
|
"cheese" => {
|
28
28
|
"dontSkipFlavor" => "Brie",
|
29
29
|
"includeFlavor" => "Brie",
|
30
30
|
"includeId" => 1,
|
31
31
|
"dontSkipId" => 1,
|
32
32
|
},
|
33
|
-
}}
|
33
|
+
}}
|
34
34
|
assert_equal(expected, result)
|
35
35
|
end
|
36
36
|
end
|
@@ -65,7 +65,7 @@ describe GraphQL::Directive do
|
|
65
65
|
|}
|
66
66
|
|
67
67
|
it 'intercepts fragment spreads' do
|
68
|
-
expected = { "data" => {
|
68
|
+
expected = { "data" => {
|
69
69
|
"cheese" => {
|
70
70
|
"dontSkipFlavor" => "Brie",
|
71
71
|
"includeFlavor" => "Brie",
|
@@ -74,7 +74,7 @@ describe GraphQL::Directive do
|
|
74
74
|
"dontSkipInlineId" => 1,
|
75
75
|
"includeInlineId" => 1,
|
76
76
|
},
|
77
|
-
}}
|
77
|
+
}}
|
78
78
|
assert_equal(expected, result)
|
79
79
|
end
|
80
80
|
end
|
@@ -11,7 +11,7 @@ describe GraphQL::Introspection::DirectiveType do
|
|
11
11
|
let(:result) { GraphQL::Query.new(DummySchema, query_string).result }
|
12
12
|
|
13
13
|
it 'shows directive info ' do
|
14
|
-
expected = { "data" => {
|
14
|
+
expected = { "data" => {
|
15
15
|
"__schema" => {
|
16
16
|
"directives" => [
|
17
17
|
{
|
@@ -34,7 +34,7 @@ describe GraphQL::Introspection::DirectiveType do
|
|
34
34
|
},
|
35
35
|
]
|
36
36
|
}
|
37
|
-
}}
|
37
|
+
}}
|
38
38
|
assert_equal(expected, result)
|
39
39
|
end
|
40
40
|
end
|
@@ -12,12 +12,13 @@ describe GraphQL::Introspection::SchemaType do
|
|
12
12
|
|}
|
13
13
|
let(:result) { GraphQL::Query.new(DummySchema, query_string).result }
|
14
14
|
it 'exposes the schema' do
|
15
|
-
expected = { "data" => {
|
15
|
+
expected = { "data" => {
|
16
16
|
"__schema" => {
|
17
17
|
"types" => DummySchema.types.values.map { |t| t.name.nil? ? (p t; raise("no name for #{t}")) : {"name" => t.name} },
|
18
18
|
"queryType"=>{
|
19
19
|
"fields"=>[
|
20
20
|
{"name"=>"cheese"},
|
21
|
+
{"name"=>"milk"},
|
21
22
|
{"name"=>"fromSource"},
|
22
23
|
{"name"=>"favoriteEdible"},
|
23
24
|
{"name"=>"searchDairy"},
|
@@ -34,7 +35,7 @@ describe GraphQL::Introspection::SchemaType do
|
|
34
35
|
]
|
35
36
|
},
|
36
37
|
}
|
37
|
-
}}
|
38
|
+
}}
|
38
39
|
assert_equal(expected, result)
|
39
40
|
end
|
40
41
|
end
|
@@ -25,7 +25,7 @@ describe GraphQL::Introspection::TypeType do
|
|
25
25
|
{"name"=>"SHEEP", "isDeprecated"=> false },
|
26
26
|
]}
|
27
27
|
it 'exposes metadata about types' do
|
28
|
-
expected = {"data"=> {
|
28
|
+
expected = {"data"=> {
|
29
29
|
"cheeseType" => {
|
30
30
|
"name"=> "Cheese",
|
31
31
|
"kind" => "OBJECT",
|
@@ -37,7 +37,7 @@ describe GraphQL::Introspection::TypeType do
|
|
37
37
|
{"name"=>"AnimalProduct"}
|
38
38
|
],
|
39
39
|
"fields"=>[
|
40
|
-
{"type"=>{"name"=>"Non-Null", "ofType"=>{"name"=>"
|
40
|
+
{"type"=>{"name"=>"Non-Null", "ofType"=>{"name"=>"ID"}}},
|
41
41
|
{"type"=>{"name"=>"DairyAnimal", "ofType"=>nil}},
|
42
42
|
{"type"=>{"name"=>"Non-Null", "ofType"=>{"name"=>"Float"}}},
|
43
43
|
{"type"=>{"name"=>"List", "ofType"=>{"name"=>"String"}}},
|
@@ -63,7 +63,7 @@ describe GraphQL::Introspection::TypeType do
|
|
63
63
|
{"name"=>"__typename"},
|
64
64
|
]
|
65
65
|
}
|
66
|
-
}}
|
66
|
+
}}
|
67
67
|
assert_equal(expected, query.result)
|
68
68
|
end
|
69
69
|
|
@@ -78,7 +78,7 @@ describe GraphQL::Introspection::TypeType do
|
|
78
78
|
it 'can expose deprecated fields' do
|
79
79
|
typename = cheese_fields.pop
|
80
80
|
new_cheese_fields = cheese_fields + [deprecated_fields, typename]
|
81
|
-
expected = { "data" => {
|
81
|
+
expected = { "data" => {
|
82
82
|
"cheeseType" => {
|
83
83
|
"name"=> "Cheese",
|
84
84
|
"kind" => "OBJECT",
|
@@ -89,7 +89,7 @@ describe GraphQL::Introspection::TypeType do
|
|
89
89
|
"kind"=>"ENUM",
|
90
90
|
"enumValues"=> dairy_animals + [{"name" => "YAK", "isDeprecated" => true}],
|
91
91
|
},
|
92
|
-
}}
|
92
|
+
}}
|
93
93
|
assert_equal(expected, query.result)
|
94
94
|
end
|
95
95
|
|
@@ -101,7 +101,7 @@ describe GraphQL::Introspection::TypeType do
|
|
101
101
|
|}
|
102
102
|
|
103
103
|
it 'exposes metadata about input objects' do
|
104
|
-
expected = { "data" => {
|
104
|
+
expected = { "data" => {
|
105
105
|
"__type" => {
|
106
106
|
"name"=>"DairyProductInput",
|
107
107
|
"description"=>"Properties for finding a dairy product",
|
@@ -111,7 +111,7 @@ describe GraphQL::Introspection::TypeType do
|
|
111
111
|
{"name"=>"fatContent", "type"=>{ "name" => "Float"}, "defaultValue"=>nil}
|
112
112
|
]
|
113
113
|
}
|
114
|
-
}}
|
114
|
+
}}
|
115
115
|
assert_equal(expected, query.result)
|
116
116
|
end
|
117
117
|
end
|
@@ -9,7 +9,11 @@ describe GraphQL::Parser do
|
|
9
9
|
# a read-only:
|
10
10
|
query getStuff {id, name @skip(if: true)}
|
11
11
|
# a mutation:
|
12
|
-
mutation changeStuff(
|
12
|
+
mutation changeStuff(
|
13
|
+
$override: Boolean = true,
|
14
|
+
$cucumbers: [Vegetable]!,
|
15
|
+
$input: SomeInputType = {key: "value"},
|
16
|
+
) @veggie, @healthy(vitamins: true) {
|
13
17
|
# change the cucumber
|
14
18
|
changeStuff(thing: $cucumbers) {
|
15
19
|
id,
|
@@ -72,7 +76,7 @@ describe GraphQL::Parser do
|
|
72
76
|
assert(parser.operation_variable_definition.parse_with_debug("$myVar: [Int]"), "it gets list variables")
|
73
77
|
assert(parser.operation_variable_definition.parse_with_debug("$myVar: Elephant!"), "it gets non-null variables")
|
74
78
|
assert(parser.operation_variable_definition.parse_with_debug("$myVar: [Food]!"), "it gets non-null list variables")
|
75
|
-
assert(parser.operation_variable_definitions.parse_with_debug(%|($myVar: Elephant!, $myList: [Float], $myString: String="Cheese")|), "it gets a list of defns")
|
79
|
+
assert(parser.operation_variable_definitions.parse_with_debug(%|($myVar: Elephant!, $myList: [Float], $myString: String = "Cheese")|), "it gets a list of defns")
|
76
80
|
end
|
77
81
|
|
78
82
|
describe 'value' do
|
data/spec/graph_ql/query_spec.rb
CHANGED
@@ -4,17 +4,17 @@ describe GraphQL::Query do
|
|
4
4
|
describe '#execute' do
|
5
5
|
let(:query_string) { %|
|
6
6
|
query getFlavor($cheeseId: Int!) {
|
7
|
-
brie: cheese(id: 1) { ...cheeseFields,
|
7
|
+
brie: cheese(id: 1) { ...cheeseFields, taste: flavor },
|
8
8
|
cheese(id: $cheeseId) {
|
9
9
|
__typename,
|
10
10
|
id,
|
11
11
|
...cheeseFields,
|
12
12
|
... edibleFields,
|
13
13
|
... on Cheese { cheeseKind: flavor },
|
14
|
-
... on Milk { source }
|
15
14
|
}
|
16
15
|
fromSource(source: COW) { id }
|
17
|
-
|
16
|
+
fromSheep: fromSource(source: SHEEP) { id }
|
17
|
+
firstSheep: searchDairy(product: {source: SHEEP}) { ... dairyFields, ... milkFields }
|
18
18
|
favoriteEdible { __typename, fatContent }
|
19
19
|
}
|
20
20
|
fragment cheeseFields on Cheese { flavor }
|
@@ -26,11 +26,11 @@ describe GraphQL::Query do
|
|
26
26
|
}
|
27
27
|
|}
|
28
28
|
let(:debug) { false }
|
29
|
-
let(:query) { GraphQL::Query.new(DummySchema, query_string,
|
29
|
+
let(:query) { GraphQL::Query.new(DummySchema, query_string, params: {"cheeseId" => 2}, debug: debug)}
|
30
30
|
let(:result) { query.result }
|
31
31
|
|
32
32
|
it 'returns fields on objects' do
|
33
|
-
expected = {"data"=> {
|
33
|
+
expected = {"data"=> {
|
34
34
|
"brie" => { "flavor" => "Brie", "taste" => "Brie" },
|
35
35
|
"cheese" => {
|
36
36
|
"__typename" => "Cheese",
|
@@ -40,9 +40,10 @@ describe GraphQL::Query do
|
|
40
40
|
"cheeseKind" => "Gouda",
|
41
41
|
},
|
42
42
|
"fromSource" => [{ "id" => 1 }, {"id" => 2}],
|
43
|
+
"fromSheep"=>[{"id"=>3}],
|
43
44
|
"firstSheep" => { "flavor" => "Manchego" },
|
44
45
|
"favoriteEdible"=>{"__typename"=>"Milk", "fatContent"=>0.04},
|
45
|
-
}}
|
46
|
+
}}
|
46
47
|
assert_equal(expected, result)
|
47
48
|
end
|
48
49
|
|
@@ -81,14 +82,31 @@ describe GraphQL::Query do
|
|
81
82
|
|}
|
82
83
|
it 'executes mutations in order' do
|
83
84
|
expected = {"data"=>{
|
84
|
-
"setInOrder"=>{
|
85
85
|
"first"=> [1],
|
86
86
|
"second"=>[1, 5],
|
87
87
|
"third"=> [1, 5, 2],
|
88
|
-
}
|
89
88
|
}}
|
90
89
|
assert_equal(expected, result)
|
91
90
|
end
|
92
91
|
end
|
93
92
|
end
|
93
|
+
|
94
|
+
describe 'context' do
|
95
|
+
let(:context_field) { GraphQL::Field.new do |f, types, field, args|
|
96
|
+
f.type(GraphQL::STRING_TYPE)
|
97
|
+
f.arguments(key: args.build(type: types.String))
|
98
|
+
f.resolve -> (target, args, ctx) { ctx[args["key"]] }
|
99
|
+
end}
|
100
|
+
let(:query_type) { GraphQL::ObjectType.new {|t| t.fields({context: context_field})}}
|
101
|
+
let(:schema) { GraphQL::Schema.new(query: query_type, mutation: nil)}
|
102
|
+
let(:query) { GraphQL::Query.new(schema, query_string, context: {"some_key" => "some value"})}
|
103
|
+
let(:query_string) { %|
|
104
|
+
query getCtx { context(key: "some_key") }
|
105
|
+
|}
|
106
|
+
|
107
|
+
it 'passes context to fields' do
|
108
|
+
expected = {"data" => {"context" => "some value"}}
|
109
|
+
assert_equal(expected, query.result)
|
110
|
+
end
|
111
|
+
end
|
94
112
|
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe GraphQL::ID_TYPE do
|
4
|
+
let(:query) { GraphQL::Query.new(DummySchema, query_string)}
|
5
|
+
let(:result) { query.result }
|
6
|
+
|
7
|
+
describe 'coercion for int inputs' do
|
8
|
+
let(:query_string) { %|query getMilk { cow: milk(id: 1) { id } }| }
|
9
|
+
|
10
|
+
it 'coerces IDs from ints and serializes as strings' do
|
11
|
+
expected = {"data" => {"cow" => {"id" => "1"}}}
|
12
|
+
assert_equal(expected, result)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
describe 'coercion for string inputs' do
|
17
|
+
let(:query_string) { %|query getMilk { cow: milk(id: "1") { id } }| }
|
18
|
+
|
19
|
+
it 'coerces IDs from strings and serializes as strings' do
|
20
|
+
expected = {"data" => {"cow" => {"id" => "1"}}}
|
21
|
+
assert_equal(expected, result)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -11,6 +11,7 @@ describe GraphQL::Schema::TypeReducer do
|
|
11
11
|
"Float" => GraphQL::FLOAT_TYPE,
|
12
12
|
"Edible" => EdibleInterface,
|
13
13
|
"Milk" => MilkType,
|
14
|
+
"ID" => GraphQL::ID_TYPE,
|
14
15
|
"AnimalProduct" => AnimalProductInterface,
|
15
16
|
}
|
16
17
|
assert_equal(expected.keys, reducer.result.keys)
|
@@ -45,7 +45,7 @@ describe GraphQL::Schema::TypeValidator do
|
|
45
45
|
let(:errors) { e = []; GraphQL::Schema::TypeValidator.new.validate(object, e); e;}
|
46
46
|
it 'must be 2+ types, must be only object types' do
|
47
47
|
expected = [
|
48
|
-
"Something.possible_types must be objects, but some aren't:
|
48
|
+
"Something.possible_types must be objects, but some aren't: DairyProductInput",
|
49
49
|
"Union Something must be defined with 2 or more types, not 1",
|
50
50
|
]
|
51
51
|
assert_equal(expected, errors)
|
@@ -14,7 +14,7 @@ describe GraphQL::StaticValidation::ArgumentLiteralsAreCompatible do
|
|
14
14
|
}
|
15
15
|
|)}
|
16
16
|
|
17
|
-
let(:validator) { GraphQL::StaticValidation::Validator.new(schema: DummySchema,
|
17
|
+
let(:validator) { GraphQL::StaticValidation::Validator.new(schema: DummySchema, rules: [GraphQL::StaticValidation::ArgumentLiteralsAreCompatible]) }
|
18
18
|
let(:errors) { validator.validate(document) }
|
19
19
|
|
20
20
|
it 'finds undefined arguments to fields and directives' do
|