graphql 0.10.6 → 0.10.7

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1781d6bb2fe71c08f2e82984d9b47cf7ebd7ee5e
4
- data.tar.gz: ad4895dc6c53f7e5873c8fbad8affea55632c711
3
+ metadata.gz: 6f94bf39aba9a98caa4bf69c263eacb820d41b08
4
+ data.tar.gz: 4a11eb3ee5d554345942bab98098a623d33f0aad
5
5
  SHA512:
6
- metadata.gz: 8134095601316e72a2ce226e08466452fc98a1474ba8b398e6298e9342d4a039ede9b960afdc7073ac298009673d9d6961b69c2f13b8095b121f549fa1ab22d1
7
- data.tar.gz: 56ab2e53c131e7976532d33d35d009d693653ca5f4f60cd31efbbf3ba26236d814549c7778495c2bc9808b38acadba920518d4f61048b287908f2b28f7e9890f
6
+ metadata.gz: 33a339144c49cc616818d398248f8b6f75c507efde44975f8e03e758c7f3783887bddeadb8c094551bad3444f9c1eaa8ecf8966ef19c58fae8f6a23e95a226e0
7
+ data.tar.gz: b1d227ca3c1981e22a2b8be23e30c7d7eee78f3e8a13f8b6702ea29a842d4198eb929a38b01ae19e44c39e2cef81e2b322565035d7ecf7832c80ddecc4e5aac2
@@ -1,31 +1,25 @@
1
1
  module GraphQL
2
2
  module Language
3
- # Extend `Parslet::Context` with a convenience method
4
- # for building AST nodes
5
- module ParsletContextCreateNode
6
- refine Parslet::Context do
7
- # @param [Symbol] name of a node constant
8
- # @param [Hash] attributes to initialize the {Node} with
9
- # @return [GraphQL::Language::Node] a node of type `name` with attributes `attributes`
10
- def create_node(name, attributes)
11
- node_class = GraphQL::Language::Nodes.const_get(name)
12
- node_class.new(attributes)
13
- end
14
- end
15
- end
16
-
17
- using ParsletContextCreateNode
18
3
 
19
4
  # {Transform} is a [parslet](http://kschiess.github.io/parslet/) transform for for turning the AST into objects in {GraphQL::Language::Nodes} objects.
20
5
  class Transform < Parslet::Transform
6
+
7
+ # @param [Symbol] name of a node constant
8
+ # @param [Hash] attributes to initialize the {Node} with
9
+ # @return [GraphQL::Language::Node] a node of type `name` with attributes `attributes`
10
+ CREATE_NODE = Proc.new do |name, attributes|
11
+ node_class = GraphQL::Language::Nodes.const_get(name)
12
+ node_class.new(attributes)
13
+ end
14
+
21
15
  def self.optional_sequence(name)
22
16
  rule(name => simple(:val)) { [] }
23
17
  rule(name => sequence(:val)) { val }
24
18
  end
25
19
 
26
20
  # Document
27
- rule(document_parts: sequence(:p)) { create_node(:Document, parts: p, line: (p.first ? p.first.line : 1), col: (p.first ? p.first.col : 1))}
28
- rule(document_parts: simple(:p)) { create_node(:Document, parts: [], line: 1, col: 1)}
21
+ rule(document_parts: sequence(:p)) { CREATE_NODE[:Document, parts: p, line: (p.first ? p.first.line : 1), col: (p.first ? p.first.col : 1)]}
22
+ rule(document_parts: simple(:p)) { CREATE_NODE[:Document, parts: [], line: 1, col: 1]}
29
23
 
30
24
  # Fragment Definition
31
25
  rule(
@@ -34,20 +28,20 @@ module GraphQL
34
28
  type_condition: simple(:type),
35
29
  directives: sequence(:directives),
36
30
  selections: sequence(:selections)
37
- ) { create_node(:FragmentDefinition, name: name.to_s, type: type.to_s, directives: directives, selections: selections, position_source: kw)}
31
+ ) { CREATE_NODE[:FragmentDefinition, name: name.to_s, type: type.to_s, directives: directives, selections: selections, position_source: kw]}
38
32
 
39
33
  rule(
40
34
  fragment_spread_keyword: simple(:kw),
41
35
  fragment_spread_name: simple(:n),
42
36
  directives: sequence(:d)
43
- ) { create_node(:FragmentSpread, name: n.to_s, directives: d, position_source: kw)}
37
+ ) { CREATE_NODE[:FragmentSpread, name: n.to_s, directives: d, position_source: kw]}
44
38
 
45
39
  rule(
46
40
  fragment_spread_keyword: simple(:kw),
47
41
  inline_fragment_type: simple(:n),
48
42
  directives: sequence(:d),
49
43
  selections: sequence(:s),
50
- ) { create_node(:InlineFragment, type: n.to_s, directives: d, selections: s, position_source: kw)}
44
+ ) { CREATE_NODE[:InlineFragment, type: n.to_s, directives: d, selections: s, position_source: kw]}
51
45
 
52
46
  # Operation Definition
53
47
  rule(
@@ -56,14 +50,14 @@ module GraphQL
56
50
  variables: sequence(:v),
57
51
  directives: sequence(:d),
58
52
  selections: sequence(:s),
59
- ) { create_node(:OperationDefinition, operation_type: ot.to_s, name: n.to_s, variables: v, directives: d, selections: s, position_source: ot) }
53
+ ) { CREATE_NODE[:OperationDefinition, operation_type: ot.to_s, name: n.to_s, variables: v, directives: d, selections: s, position_source: ot] }
60
54
  optional_sequence(:optional_variables)
61
- rule(variable_name: simple(:n), variable_type: simple(:t), variable_optional_default_value: simple(:v)) { create_node(:Variable, name: n.name, type: t, default_value: v, line: n.line, col: n.col)}
62
- rule(variable_name: simple(:n), variable_type: simple(:t), variable_optional_default_value: sequence(:v)) { create_node(:Variable, name: n.name, type: t, default_value: v, line: n.line, col: n.col)}
55
+ rule(variable_name: simple(:n), variable_type: simple(:t), variable_optional_default_value: simple(:v)) { CREATE_NODE.(:Variable, name: n.name, type: t, default_value: v, line: n.line, col: n.col)}
56
+ rule(variable_name: simple(:n), variable_type: simple(:t), variable_optional_default_value: sequence(:v)) { CREATE_NODE.(:Variable, name: n.name, type: t, default_value: v, line: n.line, col: n.col)}
63
57
  rule(variable_default_value: simple(:v) ) { v }
64
58
  rule(variable_default_value: sequence(:v) ) { v }
65
59
  # Query short-hand
66
- rule(unnamed_selections: sequence(:s)) { create_node(:OperationDefinition, selections: s, operation_type: "query", name: nil, variables: [], directives: [], line: s.first.line, col: s.first.col)}
60
+ rule(unnamed_selections: sequence(:s)) { CREATE_NODE[:OperationDefinition, selections: s, operation_type: "query", name: nil, variables: [], directives: [], line: s.first.line, col: s.first.col]}
67
61
 
68
62
  # Field
69
63
  rule(
@@ -72,32 +66,32 @@ module GraphQL
72
66
  field_arguments: sequence(:args),
73
67
  directives: sequence(:dir),
74
68
  selections: sequence(:sel)
75
- ) { create_node(:Field, alias: a && a.to_s, name: name.to_s, arguments: args, directives: dir, selections: sel, position_source: [a, name].find { |part| !part.nil? }) }
69
+ ) { CREATE_NODE[:Field, alias: a && a.to_s, name: name.to_s, arguments: args, directives: dir, selections: sel, position_source: [a, name].find { |part| !part.nil? }] }
76
70
 
77
71
  rule(alias_name: simple(:a)) { a }
78
72
  optional_sequence(:optional_field_arguments)
79
- rule(field_argument_name: simple(:n), field_argument_value: simple(:v)) { create_node(:Argument, name: n.to_s, value: v, position_source: n)}
80
- rule(field_argument_name: simple(:n), field_argument_value: sequence(:v)) { create_node(:Argument, name: n.to_s, value: v, position_source: n)}
73
+ rule(field_argument_name: simple(:n), field_argument_value: simple(:v)) { CREATE_NODE[:Argument, name: n.to_s, value: v, position_source: n]}
74
+ rule(field_argument_name: simple(:n), field_argument_value: sequence(:v)) { CREATE_NODE[:Argument, name: n.to_s, value: v, position_source: n]}
81
75
  optional_sequence(:optional_selections)
82
76
  optional_sequence(:optional_directives)
83
77
 
84
78
  # Directive
85
- rule(directive_name: simple(:name), directive_arguments: sequence(:args)) { create_node(:Directive, name: name.to_s, arguments: args, position_source: name ) }
86
- rule(directive_argument_name: simple(:n), directive_argument_value: simple(:v)) { create_node(:Argument, name: n.to_s, value: v, position_source: n)}
79
+ rule(directive_name: simple(:name), directive_arguments: sequence(:args)) { CREATE_NODE[:Directive, name: name.to_s, arguments: args, position_source: name ] }
80
+ rule(directive_argument_name: simple(:n), directive_argument_value: simple(:v)) { CREATE_NODE[:Argument, name: n.to_s, value: v, position_source: n]}
87
81
  optional_sequence(:optional_directive_arguments)
88
82
 
89
83
  # Type Defs
90
- rule(type_name: simple(:n)) { create_node(:TypeName, name: n.to_s, position_source: n) }
91
- rule(list_type: simple(:t)) { create_node(:ListType, of_type: t, line: t.line, col: t.col)}
92
- rule(non_null_type: simple(:t)) { create_node(:NonNullType, of_type: t, line: t.line, col: t.col)}
84
+ rule(type_name: simple(:n)) { CREATE_NODE[:TypeName, name: n.to_s, position_source: n] }
85
+ rule(list_type: simple(:t)) { CREATE_NODE[:ListType, of_type: t, line: t.line, col: t.col] }
86
+ rule(non_null_type: simple(:t)) { CREATE_NODE[:NonNullType, of_type: t, line: t.line, col: t.col] }
93
87
 
94
88
  # Values
95
89
  rule(array: sequence(:v)) { v }
96
90
  rule(array: simple(:v)) { [] } # just `nil`
97
91
  rule(boolean: simple(:v)) { v == "true" ? true : false }
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
- rule(input_object_name: simple(:n), input_object_value: simple(:v)) { create_node(:Argument, name: n.to_s, value: v, position_source: n)}
100
- rule(input_object_name: simple(:n), input_object_value: sequence(:v)) { create_node(:Argument, name: n.to_s, value: v, position_source: n)}
92
+ rule(input_object: sequence(:v)) { CREATE_NODE[:InputObject, pairs: v, line: (v.first ? v.first.line : 1), col: (v.first ? v.first.col : 1)] }
93
+ rule(input_object_name: simple(:n), input_object_value: simple(:v)) { CREATE_NODE[:Argument, name: n.to_s, value: v, position_source: n]}
94
+ rule(input_object_name: simple(:n), input_object_value: sequence(:v)) { CREATE_NODE[:Argument, name: n.to_s, value: v, position_source: n]}
101
95
  rule(int: simple(:v)) { v.to_i }
102
96
  rule(float: simple(:v)) { v.to_f }
103
97
 
@@ -112,8 +106,8 @@ module GraphQL
112
106
  string
113
107
  }
114
108
  rule(optional_string_content: simple(:v)) { v.to_s }
115
- rule(variable: simple(:v)) { create_node(:VariableIdentifier, name: v.to_s, position_source: v) }
116
- rule(enum: simple(:v)) { create_node(:Enum, name: v.to_s, position_source: v)}
109
+ rule(variable: simple(:v)) { CREATE_NODE[:VariableIdentifier, name: v.to_s, position_source: v] }
110
+ rule(enum: simple(:v)) { CREATE_NODE[:Enum, name: v.to_s, position_source: v] }
117
111
  end
118
112
  end
119
113
  end
@@ -18,11 +18,17 @@ class GraphQL::ListType < GraphQL::BaseType
18
18
  end
19
19
 
20
20
  def valid_non_null_input?(value)
21
- return false unless value.is_a?(Array)
22
- value.all?{ |item| of_type.valid_input?(item) }
21
+ ensure_array(value).all?{ |item| of_type.valid_input?(item) }
23
22
  end
24
23
 
25
24
  def coerce_non_null_input(value)
26
- value.map{ |item| of_type.coerce_input(item) }
25
+ ensure_array(value).map{ |item| of_type.coerce_input(item) }
26
+ end
27
+
28
+
29
+ private
30
+
31
+ def ensure_array(value)
32
+ value.is_a?(Array) ? value : [value]
27
33
  end
28
34
  end
@@ -3,9 +3,9 @@ class GraphQL::StaticValidation::LiteralValidator
3
3
  def validate(ast_value, type)
4
4
  if type.kind.non_null?
5
5
  (!ast_value.nil?) && validate(ast_value, type.of_type)
6
- elsif type.kind.list? && ast_value.is_a?(Array)
6
+ elsif type.kind.list?
7
7
  item_type = type.of_type
8
- ast_value.all? { |val| validate(val, item_type) }
8
+ ensure_array(ast_value).all? { |val| validate(val, item_type) }
9
9
  elsif type.kind.scalar? && !ast_value.is_a?(GraphQL::Language::Nodes::AbstractNode) && !ast_value.is_a?(Array)
10
10
  type.valid_input?(ast_value)
11
11
  elsif type.kind.enum? && ast_value.is_a?(GraphQL::Language::Nodes::Enum)
@@ -39,6 +39,10 @@ class GraphQL::StaticValidation::LiteralValidator
39
39
  ast_node.pairs.all? do |value|
40
40
  field_type = fields[value.name].type
41
41
  validate(value.value, field_type)
42
- end
43
- end
42
+ end
43
+ end
44
+
45
+ def ensure_array(value)
46
+ value.is_a?(Array) ? value : [value]
47
+ end
44
48
  end
@@ -1,3 +1,3 @@
1
1
  module GraphQL
2
- VERSION = "0.10.6"
2
+ VERSION = "0.10.7"
3
3
  end
@@ -28,7 +28,7 @@ describe GraphQL::InterfaceType do
28
28
  let(:interface) {
29
29
  GraphQL::InterfaceType.define do
30
30
  resolve_type -> (object) {
31
- return :custom_resolve
31
+ :custom_resolve
32
32
  }
33
33
  end
34
34
  }
@@ -0,0 +1,28 @@
1
+ require "spec_helper"
2
+
3
+ describe GraphQL::Query::Variables do
4
+ let(:query_string) {%|
5
+ query getCheese($animals: [DairyAnimal]) {
6
+ cheese(id: 1) {
7
+ similarCheese(source: $animals)
8
+ }
9
+ }
10
+ |}
11
+ let(:ast_variables) { GraphQL.parse(query_string).parts.first.variables }
12
+ let(:variables) { GraphQL::Query::Variables.new(
13
+ DummySchema,
14
+ ast_variables,
15
+ provided_variables)
16
+ }
17
+
18
+ describe "#initialize" do
19
+ describe "coercing inputs" do
20
+ let(:provided_variables) {
21
+ {"animals" => "YAK"}
22
+ }
23
+ it "coerces single items into one-element lists" do
24
+ assert_equal ["YAK"], variables["animals"]
25
+ end
26
+ end
27
+ end
28
+ end
@@ -8,6 +8,7 @@ describe GraphQL::StaticValidation::ArgumentLiteralsAreCompatible do
8
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
+ listCoerce: cheese(id: 1) { similarCheese(source: YAK) }
11
12
  }
12
13
 
13
14
  fragment cheeseFields on Cheese {
@@ -53,7 +54,7 @@ describe GraphQL::StaticValidation::ArgumentLiteralsAreCompatible do
53
54
 
54
55
  fragment_error = {
55
56
  "message"=>"Argument 'source' on Field 'similarCheese' has an invalid value",
56
- "locations"=>[{"line"=>11, "column"=>7}]
57
+ "locations"=>[{"line"=>12, "column"=>7}]
57
58
  }
58
59
  assert_includes(errors, fragment_error)
59
60
  end
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.6
4
+ version: 0.10.7
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-12-20 00:00:00.000000000 Z
11
+ date: 2015-12-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: parslet
@@ -150,8 +150,8 @@ dependencies:
150
150
  - - "~>"
151
151
  - !ruby/object:Gem::Version
152
152
  version: '10.4'
153
- description: Full-fledged implementation of the GraphQL spec. Includes query parsing,
154
- static validation, type definition, and query execution.
153
+ description: A GraphQL server implementation for Ruby. Includes schema definition,
154
+ query parsing, static validation, type definition, and query execution.
155
155
  email:
156
156
  - rdmosolgo@gmail.com
157
157
  executables: []
@@ -283,6 +283,7 @@ files:
283
283
  - spec/graphql/query/context_spec.rb
284
284
  - spec/graphql/query/executor_spec.rb
285
285
  - spec/graphql/query/type_resolver_spec.rb
286
+ - spec/graphql/query/variables_spec.rb
286
287
  - spec/graphql/query_spec.rb
287
288
  - spec/graphql/scalar_type_spec.rb
288
289
  - spec/graphql/schema/field_validator_spec.rb
@@ -341,7 +342,7 @@ rubyforge_project:
341
342
  rubygems_version: 2.4.5
342
343
  signing_key:
343
344
  specification_version: 4
344
- summary: A GraphQL implementation for Ruby
345
+ summary: A GraphQL server implementation for Ruby
345
346
  test_files:
346
347
  - spec/graphql/base_type_spec.rb
347
348
  - spec/graphql/directive_spec.rb
@@ -365,6 +366,7 @@ test_files:
365
366
  - spec/graphql/query/context_spec.rb
366
367
  - spec/graphql/query/executor_spec.rb
367
368
  - spec/graphql/query/type_resolver_spec.rb
369
+ - spec/graphql/query/variables_spec.rb
368
370
  - spec/graphql/query_spec.rb
369
371
  - spec/graphql/scalar_type_spec.rb
370
372
  - spec/graphql/schema/field_validator_spec.rb