graphql 0.10.4 → 0.10.5

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 47e57c2465fd5d01d22c69ddfc1e964dc0b93239
4
- data.tar.gz: c759b0a07b75f19ac51f31c77c89be361c5ab897
3
+ metadata.gz: 6cd1237e5dde15c5cfa1dbd20213f6c2dcadd533
4
+ data.tar.gz: e45738645ee04b67b211f66b3f7f56b84bd195da
5
5
  SHA512:
6
- metadata.gz: e16ebf74d11acb3deece7cab048c89b99a1d564b2daba526bc0234609c56fded00beb8fa38066aa8c0330dc29c5aef532e4231cfd485ff615547ee6eb60ae538
7
- data.tar.gz: 84c3ec086585193859acc914e29cf74f62473360994394125e12b83a0ee67d3e5382fc0c4c1f537a706f5a4d0c6c9f07ad8f6c3b6cb762f8de4cb9cbd02d7dd5
6
+ metadata.gz: bc1b9ee393c15f7e9424a144ed6dbf6b3f724e6041236f995668a18cfb7d328d380624441921a16cd50d22cb6a87d8423a75772a9d28d06e0e4610a303c8b4df
7
+ data.tar.gz: 32205354a511517f5fac3d83b431d633035edc5799b73dc5fbb660f091dbe1de06e582779245a00d8bf11cb8e38164af252205852c990c111f289b20ba8aca9c
@@ -66,7 +66,7 @@ module GraphQL::DefinitionHelpers::DefinedByConfig
66
66
 
67
67
  # For EnumType
68
68
  def value(name, desc = nil, deprecation_reason: nil, value: name)
69
- values << GraphQL::EnumType::EnumValue.new(name: name, description: description, deprecation_reason: deprecation_reason, value: value)
69
+ values << GraphQL::EnumType::EnumValue.new(name: name, description: desc, deprecation_reason: deprecation_reason, value: value)
70
70
  end
71
71
 
72
72
  # For InputObjectType
@@ -10,6 +10,7 @@
10
10
  class GraphQL::InputObjectType < GraphQL::BaseType
11
11
  attr_accessor :name, :description, :input_fields
12
12
  defined_by_config :name, :description, :input_fields
13
+ alias :arguments :input_fields
13
14
 
14
15
  def input_fields=(new_fields)
15
16
  @input_fields = GraphQL::DefinitionHelpers::StringNamedHash.new(new_fields).to_h
@@ -64,7 +64,7 @@ module GraphQL
64
64
  }
65
65
 
66
66
  rule(:field_alias) { name.as(:alias_name) >> space? >> str(":") >> space? }
67
- rule(:field_arguments) { str("(") >> field_argument.repeat(1) >> str(")") }
67
+ rule(:field_arguments) { str("(") >> space? >> field_argument.repeat(1) >> space? >> str(")") }
68
68
  rule(:field_argument) { name.as(:field_argument_name) >> str(":") >> space? >> value.as(:field_argument_value) >> separator? }
69
69
 
70
70
  rule(:directives) { (directive >> separator?).repeat(1) }
@@ -94,7 +94,7 @@ module GraphQL
94
94
  rule(:value_array) { (str("[") >> space? >> (value >> separator?).repeat(0) >> str("]")).as(:array) }
95
95
  rule(:value_boolean) { (str("true") | str("false")).as(:boolean) }
96
96
  rule(:value_float) { (value_sign? >> match('\d').repeat(1) >> str(".") >> match('\d').repeat(1) >> (match("[eE]") >> value_sign? >> match('\d').repeat(1)).maybe).as(:float) }
97
- rule(:value_input_object) { str("{") >> space? >> value_input_object_pair.repeat(1).as(:input_object) >> space? >> str("}") }
97
+ rule(:value_input_object) { str("{") >> space? >> value_input_object_pair.repeat(0).as(:input_object) >> space? >> str("}") }
98
98
  rule(:value_input_object_pair) { space? >> name.as(:input_object_name) >> space? >> str(":") >> space? >> value.as(:input_object_value) >> separator? }
99
99
  rule(:value_int) { (value_sign? >> match('\d').repeat(1)).as(:int) }
100
100
  rule(:value_string) { str('"') >> value_string_char.repeat.maybe.as(:optional_string_content).as(:string) >> str('"')}
@@ -95,7 +95,7 @@ module GraphQL
95
95
  rule(array: sequence(:v)) { v }
96
96
  rule(array: simple(:v)) { [] } # just `nil`
97
97
  rule(boolean: simple(:v)) { v == "true" ? true : false }
98
- rule(input_object: sequence(:v)) { create_node(:InputObject, pairs: v, line: v.first.line, col: v.first.col) }
98
+ rule(input_object: sequence(:v)) { create_node(:InputObject, pairs: v, line: (v.first ? v.first.line : 1), col: (v.first ? v.first.col : 1)) }
99
99
  rule(input_object_name: simple(:n), input_object_value: simple(:v)) { create_node(:Argument, name: n.to_s, value: v, position_source: n)}
100
100
  rule(input_object_name: simple(:n), input_object_value: sequence(:v)) { create_node(:Argument, name: n.to_s, value: v, position_source: n)}
101
101
  rule(int: simple(:v)) { v.to_i }
@@ -5,8 +5,21 @@ class GraphQL::StaticValidation::ArgumentsValidator
5
5
  def validate(context)
6
6
  visitor = context.visitor
7
7
  visitor[GraphQL::Language::Nodes::Argument] << -> (node, parent) {
8
- return if parent.is_a?(GraphQL::Language::Nodes::InputObject) || context.skip_field?(parent.name)
9
- if parent.is_a?(GraphQL::Language::Nodes::Directive)
8
+ if parent.is_a?(GraphQL::Language::Nodes::InputObject)
9
+ arg_defn = context.argument_definition
10
+ if arg_defn.nil?
11
+ return
12
+ else
13
+ parent_defn = arg_defn.type.unwrap
14
+ puts "#{node}"
15
+ puts "#{parent_defn}"
16
+ if parent_defn.is_a?(GraphQL::ScalarType)
17
+ return
18
+ end
19
+ end
20
+ elsif context.skip_field?(parent.name)
21
+ return
22
+ elsif parent.is_a?(GraphQL::Language::Nodes::Directive)
10
23
  parent_defn = context.schema.directives[parent.name]
11
24
  else
12
25
  parent_defn = context.field_definition
@@ -14,4 +27,20 @@ class GraphQL::StaticValidation::ArgumentsValidator
14
27
  validate_node(parent, node, parent_defn, context)
15
28
  }
16
29
  end
30
+
31
+ private
32
+
33
+ def parent_name(parent, type_defn)
34
+ field_name = if parent.is_a?(GraphQL::Language::Nodes::Field)
35
+ parent.alias || parent.name
36
+ elsif parent.is_a?(GraphQL::Language::Nodes::InputObject)
37
+ type_defn.name
38
+ else
39
+ parent.name
40
+ end
41
+ end
42
+
43
+ def node_type(parent)
44
+ parent.class.name.split("::").last
45
+ end
17
46
  end
@@ -5,12 +5,9 @@ class GraphQL::StaticValidation::ArgumentLiteralsAreCompatible < GraphQL::Static
5
5
  arg_defn = defn.arguments[node.name]
6
6
  valid = validator.validate(node.value, arg_defn.type)
7
7
  if !valid
8
- field_name = if parent.respond_to?(:alias)
9
- parent.alias || parent.name
10
- else
11
- parent.name
12
- end
13
- context.errors << message("Argument #{node.name} on #{parent.class.name.split("::").last} '#{field_name}' has an invalid value", parent)
8
+ kind_of_node = node_type(parent)
9
+ error_arg_name = parent_name(parent, defn)
10
+ context.errors << message("Argument '#{node.name}' on #{kind_of_node} '#{error_arg_name}' has an invalid value", parent)
14
11
  end
15
12
  end
16
13
  end
@@ -2,7 +2,9 @@ class GraphQL::StaticValidation::ArgumentsAreDefined < GraphQL::StaticValidation
2
2
  def validate_node(parent, node, defn, context)
3
3
  argument_defn = defn.arguments[node.name]
4
4
  if argument_defn.nil?
5
- context.errors << message("#{parent.class.name.split("::").last} '#{parent.name}' doesn't accept argument #{node.name}", parent)
5
+ kind_of_node = node_type(parent)
6
+ error_arg_name = parent_name(parent, defn)
7
+ context.errors << message("#{kind_of_node} '#{error_arg_name}' doesn't accept argument '#{node.name}'", parent)
6
8
  GraphQL::Language::Visitor::SKIP
7
9
  else
8
10
  nil
@@ -15,6 +15,10 @@ class GraphQL::StaticValidation::VariableUsagesAreAllowed
15
15
  arguments = context.field_definition.arguments
16
16
  elsif parent.is_a?(GraphQL::Language::Nodes::Directive)
17
17
  arguments = context.directive_definition.arguments
18
+ elsif parent.is_a?(GraphQL::Language::Nodes::InputObject)
19
+ arguments = context.argument_definition.type.unwrap.input_fields
20
+ else
21
+ raise("Unexpected argument parent: #{parent}")
18
22
  end
19
23
  var_defn_ast = declared_variables[node.value.name]
20
24
  # Might be undefined :(
@@ -24,6 +24,9 @@ class GraphQL::StaticValidation::TypeStack
24
24
  # @return [Array<GraphQL::Node::Directive>] directives which have been entered
25
25
  attr_reader :directive_definitions
26
26
 
27
+ # @return [Array<GraphQL::Node::Argument>] arguments which have been entered
28
+ attr_reader :argument_definitions
29
+
27
30
  # @param schema [GraphQL::Schema] the schema whose types to use when climbing this document
28
31
  # @param visitor [GraphQL::Language::Visitor] a visitor to follow & watch the types
29
32
  def initialize(schema, visitor)
@@ -31,6 +34,7 @@ class GraphQL::StaticValidation::TypeStack
31
34
  @object_types = []
32
35
  @field_definitions = []
33
36
  @directive_definitions = []
37
+ @argument_definitions = []
34
38
  visitor.enter << -> (node, parent) { PUSH_STRATEGIES[node.class].push(self, node) }
35
39
  visitor.leave << -> (node, parent) { PUSH_STRATEGIES[node.class].pop(self, node) }
36
40
  end
@@ -65,7 +69,7 @@ class GraphQL::StaticValidation::TypeStack
65
69
 
66
70
  class OperationDefinitionStrategy
67
71
  def push(stack, node)
68
- # query or mutation
72
+ # eg, QueryType, MutationType
69
73
  object_type = stack.schema.public_send(node.operation_type)
70
74
  stack.object_types.push(object_type)
71
75
  end
@@ -110,6 +114,33 @@ class GraphQL::StaticValidation::TypeStack
110
114
  end
111
115
  end
112
116
 
117
+ class ArgumentStrategy
118
+ # Push `argument_defn` onto the stack.
119
+ # It's possible that `argument_defn` will be nil.
120
+ # Push it anyways so `pop` has something to pop.
121
+ def push(stack, node)
122
+ if stack.argument_definitions.last
123
+ arg_type = stack.argument_definitions.last.type.unwrap
124
+ if arg_type.kind.input_object?
125
+ argument_defn = arg_type.input_fields[node.name]
126
+ else
127
+ argument_defn = nil
128
+ end
129
+ elsif stack.directive_definitions.last
130
+ argument_defn = stack.directive_definitions.last.arguments[node.name]
131
+ elsif stack.field_definitions.last
132
+ argument_defn = stack.field_definitions.last.arguments[node.name]
133
+ else
134
+ argument_defn = nil
135
+ end
136
+ stack.argument_definitions.push(argument_defn)
137
+ end
138
+
139
+ def pop(stack, node)
140
+ stack.argument_definitions.pop
141
+ end
142
+ end
143
+
113
144
  # A no-op strategy (don't handle this node)
114
145
  class NullStrategy
115
146
  def self.new; self; end
@@ -54,14 +54,23 @@ class GraphQL::StaticValidation::Validator
54
54
  @type_stack.object_types
55
55
  end
56
56
 
57
+ # @return [GraphQL::Field, nil] The most-recently-entered GraphQL::Field, if currently inside one
57
58
  def field_definition
58
59
  @type_stack.field_definitions.last
59
60
  end
60
61
 
62
+ # @return [GraphQL::Directive, nil] The most-recently-entered GraphQL::Directive, if currently inside one
61
63
  def directive_definition
62
64
  @type_stack.directive_definitions.last
63
65
  end
64
66
 
67
+ # @return [GraphQL::Argument, nil] The most-recently-entered GraphQL::Argument, if currently inside one
68
+ def argument_definition
69
+ # Don't get the _last_ one because that's the current one.
70
+ # Get the second-to-last one, which is the parent of the current one.
71
+ @type_stack.argument_definitions[-2]
72
+ end
73
+
65
74
  # Don't try to validate dynamic fields
66
75
  # since they aren't defined by the type system
67
76
  def skip_field?(field_name)
@@ -1,3 +1,3 @@
1
1
  module GraphQL
2
- VERSION = "0.10.4"
2
+ VERSION = "0.10.5"
3
3
  end
data/readme.md CHANGED
@@ -96,8 +96,7 @@ If you're building a backend for [Relay](http://facebook.github.io/relay/), you'
96
96
  ## To Do
97
97
 
98
98
  - Code clean-up
99
- - Raise if you try to configure an attribute which doesn't suit the type
100
- - ie, if you try to define `resolve` on an ObjectType, it should somehow raise
99
+ - Raise if you try to configure an attribute which doesn't suit the type (ie, if you try to define `resolve` on an ObjectType, it should somehow raise)
101
100
  - Clean up file structure in `lib/query` (don't need serial_execution namespace anymore)
102
101
  - Overriding `!` on types breaks ActiveSupport `.blank?`
103
102
 
@@ -109,17 +108,19 @@ If you're building a backend for [Relay](http://facebook.github.io/relay/), you'
109
108
  my_type.blank?
110
109
  # => MyType!
111
110
  ```
111
+
112
+ - Accept strings for circular type references
113
+ - Interface's possible types should be a property of the schema, not the interface
112
114
  - Statically validate type of variables (see early return in LiteralValidator)
113
115
  - Big ideas:
114
- - Use [graphql-parser](https://github.com/shopify/graphql-parser) (Ruby bindings for [libgraphqlparser](https://github.com/graphql/libgraphqlparser)) instead of Parslet
116
+ - Use [graphql-parser](https://github.com/shopify/graphql-parser) (Ruby bindings for [libgraphqlparser](https://github.com/graphql/libgraphqlparser)) instead of Parslet ([underway-ish](https://github.com/rmosolgo/graphql-libgraphqlparser-ruby))
115
117
  - Revamp the fixture Schema to be more useful (better names, more extensible)
116
118
  - __Subscriptions__
117
119
  - This is a good chance to make an `Operation` abstraction of which `query`, `mutation` and `subscription` are members
118
120
  - For a subscription, `graphql` would send an outbound message to the system (allow the host application to manage its own subscriptions via Pusher, ActionCable, whatever)
119
- - Pre-process query strings?
120
- - Remove `@skip`-ed things
121
- - Inline any fragments
122
- - Inline variables?
121
+ - Documentation
122
+ - Write a "Getting started with Rails"-type blog post
123
+ - Compile existing articles & slide decks and link to them from a guide
123
124
 
124
125
  ## Goals
125
126
 
@@ -8,8 +8,12 @@ describe GraphQL::EnumType do
8
8
  assert_equal(1, enum.coerce_input("COW"))
9
9
  end
10
10
 
11
- it 'coerces result values to value name' do
11
+ it "coerces result values to value's value" do
12
12
  assert_equal("YAK", enum.coerce_result("YAK"))
13
13
  assert_equal("COW", enum.coerce_result(1))
14
14
  end
15
+
16
+ it 'has value description' do
17
+ assert_equal("Animal with horns", enum.values['GOAT'].description)
18
+ end
15
19
  end
@@ -15,7 +15,9 @@ describe GraphQL::Language::Parser do
15
15
  $input: SomeInputType = {key: "value"},
16
16
  ) @veggie, @healthy(vitamins: true) {
17
17
  # change the cucumber
18
- changeStuff(thing: $cucumbers) {
18
+ changeStuff(
19
+ thing: $cucumbers
20
+ ) {
19
21
  id,
20
22
  name,
21
23
  ... on Species { color },
@@ -23,13 +25,13 @@ describe GraphQL::Language::Parser do
23
25
  }
24
26
  }
25
27
  subscription watchStuff {
26
- field, otherField
28
+ field(emptyObj: {}), otherField
27
29
  }
28
30
 
29
31
  # a fragment:
30
32
  fragment family on Species {
31
33
  family {
32
- name, # name of the family
34
+ name, # name of the family
33
35
  members(first: 3, query: {isPlant: true}) # some of the other examples
34
36
  }
35
37
  }
@@ -125,6 +127,8 @@ describe GraphQL::Language::Parser do
125
127
  assert(parser.value.parse_with_debug('{name: "tomato", calories: 50}'), 'gets scalar values')
126
128
  assert(parser.value.parse_with_debug('{listOfValues: [1, 2, [3]], nestedObject: {nestedKey: "nested{Value}"}}'), 'gets complex values')
127
129
  assert(parser.value.parse_with_debug('{variableKey: $variableValue}'), 'gets variables')
130
+ assert(parser.value.parse_with_debug('{}'), 'gets empty')
131
+ assert(parser.value.parse_with_debug('{ }'), 'gets empty')
128
132
  end
129
133
 
130
134
  it 'gets enums' do
@@ -23,6 +23,7 @@ describe GraphQL::Language::Transform do
23
23
  ...personInfo
24
24
  someStuff(vars: [1,2,3])
25
25
  someOtherStuff(input: {ints: [1,2,3]})
26
+ someEmptyStuff(emptyObj: {}, emptySpaceObj: { })
26
27
  }
27
28
  }
28
29
 
@@ -109,6 +110,24 @@ describe GraphQL::Language::Transform do
109
110
  assert_equal(2, res.selections.length)
110
111
  end
111
112
 
113
+ it 'transforms input objects' do
114
+ res_one_pair = get_result(%q|{one: 1}|, parse: :value_input_object)
115
+ res_two_pair = get_result(%q|{first: "Apple", second: "Banana"}|, parse: :value_input_object)
116
+ res_empty = get_result(%q|{}|, parse: :value_input_object)
117
+ res_empty_space = get_result(%q|{ }|, parse: :value_input_object)
118
+
119
+ assert_equal('one', res_one_pair.pairs[0].name)
120
+ assert_equal(1 , res_one_pair.pairs[0].value)
121
+
122
+ assert_equal('first' , res_two_pair.pairs[0].name)
123
+ assert_equal('Apple' , res_two_pair.pairs[0].value)
124
+ assert_equal('second', res_two_pair.pairs[1].name)
125
+ assert_equal('Banana', res_two_pair.pairs[1].value)
126
+
127
+ assert_equal([], res_empty.pairs)
128
+ assert_equal([], res_empty_space.pairs)
129
+ end
130
+
112
131
  it 'transforms directives' do
113
132
  res = get_result('@doSomething(vigorously: "\"true\u0025\"")', parse: :directive)
114
133
  assert_equal("doSomething", res.name, 'gets the name without @')
@@ -5,7 +5,7 @@ describe GraphQL::StaticValidation::ArgumentLiteralsAreCompatible do
5
5
  query getCheese {
6
6
  cheese(id: "aasdlkfj") { source }
7
7
  cheese(id: 1) { source @skip(if: {id: 1})}
8
- yakSource: searchDairy(product: [{source: YAK, fatContent: 1.1}]) { source }
8
+ yakSource: searchDairy(product: [{source: COW, fatContent: 1.1}]) { source }
9
9
  badSource: searchDairy(product: [{source: 1.1}]) { source }
10
10
  missingSource: searchDairy(product: [{fatContent: 1.1}]) { source }
11
11
  }
@@ -19,34 +19,40 @@ describe GraphQL::StaticValidation::ArgumentLiteralsAreCompatible do
19
19
  let(:errors) { validator.validate(document) }
20
20
 
21
21
  it 'finds undefined or missing-required arguments to fields and directives' do
22
- assert_equal(5, errors.length)
22
+ assert_equal(6, errors.length)
23
23
 
24
24
  query_root_error = {
25
- "message"=>"Argument id on Field 'cheese' has an invalid value",
25
+ "message"=>"Argument 'id' on Field 'cheese' has an invalid value",
26
26
  "locations"=>[{"line"=>3, "column"=>7}]
27
27
  }
28
28
  assert_includes(errors, query_root_error)
29
29
 
30
30
  directive_error = {
31
- "message"=>"Argument if on Directive 'skip' has an invalid value",
31
+ "message"=>"Argument 'if' on Directive 'skip' has an invalid value",
32
32
  "locations"=>[{"line"=>4, "column"=>31}]
33
33
  }
34
34
  assert_includes(errors, directive_error)
35
35
 
36
36
  input_object_error = {
37
- "message"=>"Argument product on Field 'badSource' has an invalid value",
37
+ "message"=>"Argument 'product' on Field 'badSource' has an invalid value",
38
38
  "locations"=>[{"line"=>6, "column"=>7}]
39
39
  }
40
40
  assert_includes(errors, input_object_error)
41
41
 
42
+ input_object_field_error = {
43
+ "message"=>"Argument 'source' on InputObject 'DairyProductInput' has an invalid value",
44
+ "locations"=>[{"line"=>6, "column"=>41}]
45
+ }
46
+ assert_includes(errors, input_object_field_error)
47
+
42
48
  missing_required_field_error = {
43
- "message"=>"Argument product on Field 'missingSource' has an invalid value",
49
+ "message"=>"Argument 'product' on Field 'missingSource' has an invalid value",
44
50
  "locations"=>[{"line"=>7, "column"=>7}]
45
51
  }
46
52
  assert_includes(errors, missing_required_field_error)
47
53
 
48
54
  fragment_error = {
49
- "message"=>"Argument source on Field 'similarCheese' has an invalid value",
55
+ "message"=>"Argument 'source' on Field 'similarCheese' has an invalid value",
50
56
  "locations"=>[{"line"=>11, "column"=>7}]
51
57
  }
52
58
  assert_includes(errors, fragment_error)
@@ -5,6 +5,7 @@ describe GraphQL::StaticValidation::ArgumentsAreDefined do
5
5
  query getCheese {
6
6
  cheese(id: 1) { source }
7
7
  cheese(silly: false) { source }
8
+ searchDairy(product: [{wacky: 1}])
8
9
  }
9
10
 
10
11
  fragment cheeseFields on Cheese {
@@ -17,23 +18,29 @@ describe GraphQL::StaticValidation::ArgumentsAreDefined do
17
18
  let(:errors) { validator.validate(document) }
18
19
 
19
20
  it 'finds undefined arguments to fields and directives' do
20
- assert_equal(3, errors.length)
21
+ assert_equal(4, errors.length)
21
22
 
22
23
  query_root_error = {
23
- "message"=>"Field 'cheese' doesn't accept argument silly",
24
+ "message"=>"Field 'cheese' doesn't accept argument 'silly'",
24
25
  "locations"=>[{"line"=>4, "column"=>7}]
25
26
  }
26
27
  assert_includes(errors, query_root_error)
27
28
 
29
+ input_obj_record = {
30
+ "message"=>"InputObject 'DairyProductInput' doesn't accept argument 'wacky'",
31
+ "locations"=>[{"line"=>5, "column"=>30}]
32
+ }
33
+ assert_includes(errors, input_obj_record)
34
+
28
35
  fragment_error = {
29
- "message"=>"Field 'similarCheese' doesn't accept argument nonsense",
30
- "locations"=>[{"line"=>8, "column"=>7}]
36
+ "message"=>"Field 'similarCheese' doesn't accept argument 'nonsense'",
37
+ "locations"=>[{"line"=>9, "column"=>7}]
31
38
  }
32
39
  assert_includes(errors, fragment_error)
33
40
 
34
41
  directive_error = {
35
- "message"=>"Directive 'skip' doesn't accept argument something",
36
- "locations"=>[{"line"=>9, "column"=>11}]
42
+ "message"=>"Directive 'skip' doesn't accept argument 'something'",
43
+ "locations"=>[{"line"=>10, "column"=>11}]
37
44
  }
38
45
  assert_includes(errors, directive_error)
39
46
  end
@@ -10,6 +10,7 @@ describe GraphQL::StaticValidation::VariableUsagesAreAllowed do
10
10
  $goodAnimals: [DairyAnimal!]!,
11
11
  $badAnimals: [DairyAnimal]!,
12
12
  $deepAnimals: [[DairyAnimal!]!]!,
13
+ $goodSource: DairyAnimal!,
13
14
  ) {
14
15
  goodCheese: cheese(id: $goodInt) { source }
15
16
  okCheese: cheese(id: $okInt) { source }
@@ -24,6 +25,10 @@ describe GraphQL::StaticValidation::VariableUsagesAreAllowed do
24
25
  milk(id: 1) {
25
26
  flavors(limit: $okInt)
26
27
  }
28
+
29
+ searchDairy(product: [{source: $goodSource}]) {
30
+ ... on Cheese { id }
31
+ }
27
32
  }
28
33
  ')}
29
34
 
@@ -35,19 +40,19 @@ describe GraphQL::StaticValidation::VariableUsagesAreAllowed do
35
40
  expected = [
36
41
  {
37
42
  "message"=>"Nullability mismatch on variable $badInt and argument id (Int / Int!)",
38
- "locations"=>[{"line"=>13, "column"=>28}]
43
+ "locations"=>[{"line"=>14, "column"=>28}]
39
44
  },
40
45
  {
41
46
  "message"=>"Type mismatch on variable $badStr and argument id (String! / Int!)",
42
- "locations"=>[{"line"=>14, "column"=>28}]
47
+ "locations"=>[{"line"=>15, "column"=>28}]
43
48
  },
44
49
  {
45
50
  "message"=>"Nullability mismatch on variable $badAnimals and argument source ([DairyAnimal]! / [DairyAnimal!]!)",
46
- "locations"=>[{"line"=>17, "column"=>30}]
51
+ "locations"=>[{"line"=>18, "column"=>30}]
47
52
  },
48
53
  {
49
54
  "message"=>"List dimension mismatch on variable $deepAnimals and argument source ([[DairyAnimal!]!]! / [DairyAnimal!]!)",
50
- "locations"=>[{"line"=>18, "column"=>32}]
55
+ "locations"=>[{"line"=>19, "column"=>32}]
51
56
  }
52
57
  ]
53
58
  assert_equal(expected, errors)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: graphql
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.10.4
4
+ version: 0.10.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Robert Mosolgo
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-11-24 00:00:00.000000000 Z
11
+ date: 2015-12-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: parslet