graphql 0.12.1 → 0.13.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.
Files changed (146) hide show
  1. checksums.yaml +4 -4
  2. data/lib/graphql.rb +31 -41
  3. data/lib/graphql/argument.rb +23 -21
  4. data/lib/graphql/base_type.rb +5 -8
  5. data/lib/graphql/define/assign_argument.rb +5 -2
  6. data/lib/graphql/define/type_definer.rb +2 -1
  7. data/lib/graphql/directive.rb +34 -36
  8. data/lib/graphql/directive/include_directive.rb +3 -7
  9. data/lib/graphql/directive/skip_directive.rb +3 -7
  10. data/lib/graphql/enum_type.rb +78 -76
  11. data/lib/graphql/execution_error.rb +1 -3
  12. data/lib/graphql/field.rb +99 -95
  13. data/lib/graphql/input_object_type.rb +49 -47
  14. data/lib/graphql/interface_type.rb +31 -34
  15. data/lib/graphql/introspection.rb +19 -18
  16. data/lib/graphql/introspection/directive_location_enum.rb +8 -0
  17. data/lib/graphql/introspection/directive_type.rb +1 -3
  18. data/lib/graphql/introspection/field_type.rb +1 -1
  19. data/lib/graphql/introspection/fields_field.rb +1 -1
  20. data/lib/graphql/introspection/introspection_query.rb +1 -3
  21. data/lib/graphql/introspection/possible_types_field.rb +7 -1
  22. data/lib/graphql/introspection/schema_field.rb +13 -9
  23. data/lib/graphql/introspection/type_by_name_field.rb +13 -17
  24. data/lib/graphql/introspection/typename_field.rb +12 -8
  25. data/lib/graphql/language.rb +5 -9
  26. data/lib/graphql/language/lexer.rb +668 -0
  27. data/lib/graphql/language/lexer.rl +149 -0
  28. data/lib/graphql/language/parser.rb +842 -116
  29. data/lib/graphql/language/parser.y +264 -0
  30. data/lib/graphql/language/token.rb +21 -0
  31. data/lib/graphql/list_type.rb +33 -31
  32. data/lib/graphql/non_null_type.rb +33 -31
  33. data/lib/graphql/object_type.rb +52 -55
  34. data/lib/graphql/query.rb +83 -80
  35. data/lib/graphql/query/context.rb +5 -1
  36. data/lib/graphql/query/directive_resolution.rb +16 -0
  37. data/lib/graphql/query/executor.rb +3 -3
  38. data/lib/graphql/query/input_validation_result.rb +17 -15
  39. data/lib/graphql/query/serial_execution.rb +5 -5
  40. data/lib/graphql/query/serial_execution/execution_context.rb +4 -3
  41. data/lib/graphql/query/serial_execution/selection_resolution.rb +19 -21
  42. data/lib/graphql/query/serial_execution/value_resolution.rb +1 -1
  43. data/lib/graphql/query/type_resolver.rb +22 -18
  44. data/lib/graphql/query/variable_validation_error.rb +14 -12
  45. data/lib/graphql/schema.rb +87 -77
  46. data/lib/graphql/schema/each_item_validator.rb +16 -12
  47. data/lib/graphql/schema/field_validator.rb +14 -10
  48. data/lib/graphql/schema/implementation_validator.rb +26 -22
  49. data/lib/graphql/schema/middleware_chain.rb +2 -1
  50. data/lib/graphql/schema/possible_types.rb +34 -0
  51. data/lib/graphql/schema/printer.rb +122 -120
  52. data/lib/graphql/schema/type_expression.rb +1 -0
  53. data/lib/graphql/schema/type_map.rb +3 -10
  54. data/lib/graphql/schema/type_reducer.rb +65 -81
  55. data/lib/graphql/schema/type_validator.rb +45 -41
  56. data/lib/graphql/static_validation.rb +7 -9
  57. data/lib/graphql/static_validation/all_rules.rb +29 -24
  58. data/lib/graphql/static_validation/arguments_validator.rb +39 -35
  59. data/lib/graphql/static_validation/literal_validator.rb +44 -40
  60. data/lib/graphql/static_validation/message.rb +30 -26
  61. data/lib/graphql/static_validation/rules/argument_literals_are_compatible.rb +15 -11
  62. data/lib/graphql/static_validation/rules/arguments_are_defined.rb +14 -10
  63. data/lib/graphql/static_validation/rules/directives_are_defined.rb +16 -12
  64. data/lib/graphql/static_validation/rules/directives_are_in_valid_locations.rb +59 -0
  65. data/lib/graphql/static_validation/rules/fields_are_defined_on_type.rb +25 -21
  66. data/lib/graphql/static_validation/rules/fields_have_appropriate_selections.rb +28 -24
  67. data/lib/graphql/static_validation/rules/fields_will_merge.rb +84 -80
  68. data/lib/graphql/static_validation/rules/fragment_spreads_are_possible.rb +49 -43
  69. data/lib/graphql/static_validation/rules/fragment_types_exist.rb +22 -17
  70. data/lib/graphql/static_validation/rules/fragments_are_finite.rb +19 -15
  71. data/lib/graphql/static_validation/rules/fragments_are_on_composite_types.rb +25 -20
  72. data/lib/graphql/static_validation/rules/fragments_are_used.rb +36 -23
  73. data/lib/graphql/static_validation/rules/required_arguments_are_present.rb +29 -25
  74. data/lib/graphql/static_validation/rules/variable_default_values_are_correctly_typed.rb +21 -17
  75. data/lib/graphql/static_validation/rules/variable_usages_are_allowed.rb +79 -70
  76. data/lib/graphql/static_validation/rules/variables_are_input_types.rb +24 -20
  77. data/lib/graphql/static_validation/rules/variables_are_used_and_defined.rb +122 -119
  78. data/lib/graphql/static_validation/type_stack.rb +138 -129
  79. data/lib/graphql/static_validation/validator.rb +29 -25
  80. data/lib/graphql/type_kinds.rb +42 -40
  81. data/lib/graphql/union_type.rb +22 -16
  82. data/lib/graphql/version.rb +1 -1
  83. data/readme.md +12 -27
  84. data/spec/graphql/base_type_spec.rb +3 -3
  85. data/spec/graphql/directive_spec.rb +10 -18
  86. data/spec/graphql/enum_type_spec.rb +7 -7
  87. data/spec/graphql/execution_error_spec.rb +1 -1
  88. data/spec/graphql/field_spec.rb +14 -13
  89. data/spec/graphql/id_type_spec.rb +6 -6
  90. data/spec/graphql/input_object_type_spec.rb +39 -39
  91. data/spec/graphql/interface_type_spec.rb +16 -32
  92. data/spec/graphql/introspection/directive_type_spec.rb +5 -9
  93. data/spec/graphql/introspection/input_value_type_spec.rb +10 -4
  94. data/spec/graphql/introspection/introspection_query_spec.rb +2 -2
  95. data/spec/graphql/introspection/schema_type_spec.rb +2 -2
  96. data/spec/graphql/introspection/type_type_spec.rb +34 -6
  97. data/spec/graphql/language/parser_spec.rb +299 -105
  98. data/spec/graphql/language/visitor_spec.rb +4 -4
  99. data/spec/graphql/list_type_spec.rb +11 -11
  100. data/spec/graphql/object_type_spec.rb +10 -10
  101. data/spec/graphql/query/arguments_spec.rb +7 -7
  102. data/spec/graphql/query/context_spec.rb +11 -3
  103. data/spec/graphql/query/executor_spec.rb +26 -19
  104. data/spec/graphql/query/serial_execution/execution_context_spec.rb +6 -6
  105. data/spec/graphql/query/serial_execution/value_resolution_spec.rb +2 -2
  106. data/spec/graphql/query/type_resolver_spec.rb +3 -3
  107. data/spec/graphql/query_spec.rb +6 -38
  108. data/spec/graphql/scalar_type_spec.rb +28 -19
  109. data/spec/graphql/schema/field_validator_spec.rb +1 -1
  110. data/spec/graphql/schema/middleware_chain_spec.rb +12 -1
  111. data/spec/graphql/schema/printer_spec.rb +12 -4
  112. data/spec/graphql/schema/rescue_middleware_spec.rb +1 -1
  113. data/spec/graphql/schema/type_expression_spec.rb +2 -2
  114. data/spec/graphql/schema/type_reducer_spec.rb +21 -36
  115. data/spec/graphql/schema/type_validator_spec.rb +9 -9
  116. data/spec/graphql/schema_spec.rb +1 -1
  117. data/spec/graphql/static_validation/rules/argument_literals_are_compatible_spec.rb +4 -4
  118. data/spec/graphql/static_validation/rules/arguments_are_defined_spec.rb +4 -4
  119. data/spec/graphql/static_validation/rules/directives_are_defined_spec.rb +5 -5
  120. data/spec/graphql/static_validation/rules/directives_are_in_valid_locations_spec.rb +39 -0
  121. data/spec/graphql/static_validation/rules/fields_are_defined_on_type_spec.rb +5 -5
  122. data/spec/graphql/static_validation/rules/fields_have_appropriate_selections_spec.rb +4 -4
  123. data/spec/graphql/static_validation/rules/fields_will_merge_spec.rb +2 -2
  124. data/spec/graphql/static_validation/rules/fragment_spreads_are_possible_spec.rb +1 -1
  125. data/spec/graphql/static_validation/rules/fragment_types_exist_spec.rb +2 -2
  126. data/spec/graphql/static_validation/rules/fragments_are_finite_spec.rb +2 -2
  127. data/spec/graphql/static_validation/rules/fragments_are_on_composite_types_spec.rb +2 -2
  128. data/spec/graphql/static_validation/rules/fragments_are_used_spec.rb +3 -3
  129. data/spec/graphql/static_validation/rules/required_arguments_are_present_spec.rb +3 -3
  130. data/spec/graphql/static_validation/rules/variable_default_values_are_correctly_typed_spec.rb +5 -5
  131. data/spec/graphql/static_validation/rules/variable_usages_are_allowed_spec.rb +3 -1
  132. data/spec/graphql/static_validation/rules/variables_are_input_types_spec.rb +4 -4
  133. data/spec/graphql/static_validation/rules/variables_are_used_and_defined_spec.rb +3 -3
  134. data/spec/graphql/static_validation/type_stack_spec.rb +3 -2
  135. data/spec/graphql/static_validation/validator_spec.rb +26 -6
  136. data/spec/graphql/union_type_spec.rb +5 -4
  137. data/spec/spec_helper.rb +2 -5
  138. data/spec/support/dairy_app.rb +30 -9
  139. data/spec/support/dairy_data.rb +1 -1
  140. data/spec/support/star_wars_data.rb +26 -26
  141. data/spec/support/star_wars_schema.rb +1 -1
  142. metadata +40 -21
  143. data/lib/graphql/language/transform.rb +0 -113
  144. data/lib/graphql/query/directive_chain.rb +0 -44
  145. data/lib/graphql/repl.rb +0 -27
  146. data/spec/graphql/language/transform_spec.rb +0 -156
@@ -1,4 +1,4 @@
1
- require 'spec_helper'
1
+ require "spec_helper"
2
2
 
3
3
  describe GraphQL::Schema::FieldValidator do
4
4
  let(:field_defn) {{
@@ -1,4 +1,4 @@
1
- require 'spec_helper'
1
+ require "spec_helper"
2
2
 
3
3
  describe GraphQL::Schema::MiddlewareChain do
4
4
  let(:step_1) { -> (step_values, next_step) { step_values << 1; next_step.call } }
@@ -27,5 +27,16 @@ describe GraphQL::Schema::MiddlewareChain do
27
27
  assert_equal([1,2], step_values)
28
28
  end
29
29
  end
30
+
31
+ describe "when a step provides alternate arguments" do
32
+ it "passes the new arguments to the next step" do
33
+ step_1 = -> (test_arg, next_step) { assert_equal(test_arg, 'HELLO'); next_step.call(['WORLD']) }
34
+ step_2 = -> (test_arg, next_step) { assert_equal(test_arg, 'WORLD'); test_arg }
35
+
36
+ chain = GraphQL::Schema::MiddlewareChain.new(steps: [step_1, step_2], arguments: ['HELLO'])
37
+ result = chain.call
38
+ assert_equal(result, 'WORLD')
39
+ end
40
+ end
30
41
  end
31
42
  end
@@ -1,4 +1,4 @@
1
- require 'spec_helper'
1
+ require "spec_helper"
2
2
 
3
3
  describe GraphQL::Schema::Printer do
4
4
  let(:schema) {
@@ -70,9 +70,17 @@ type __Directive {
70
70
  name: String!
71
71
  description: String
72
72
  args: [__InputValue!]!
73
- onOperation: Boolean!
74
- onFragment: Boolean!
75
- onField: Boolean!
73
+ locations: [__DirectiveLocation!]!
74
+ }
75
+
76
+ enum __DirectiveLocation {
77
+ QUERY
78
+ MUTATION
79
+ SUBSCRIPTION
80
+ FIELD
81
+ FRAGMENT_DEFINITION
82
+ FRAGMENT_SPREAD
83
+ INLINE_FRAGMENT
76
84
  }
77
85
 
78
86
  type __EnumValue {
@@ -1,4 +1,4 @@
1
- require 'spec_helper'
1
+ require "spec_helper"
2
2
 
3
3
  class SpecExampleError < StandardError; end
4
4
 
@@ -3,8 +3,8 @@ require "spec_helper"
3
3
  describe GraphQL::Schema::TypeExpression do
4
4
  let(:schema) { DummySchema }
5
5
  let(:ast_node) {
6
- ast = GraphQL::PARSER.type.parse(type_name)
7
- GraphQL::TRANSFORM.apply(ast)
6
+ document = GraphQL.parse("query dostuff($var: #{type_name}) { id } ")
7
+ document.definitions.first.variables.first.type
8
8
  }
9
9
  let(:type_expression) { GraphQL::Schema::TypeExpression.new(schema, ast_node) }
10
10
 
@@ -1,9 +1,8 @@
1
- require 'spec_helper'
1
+ require "spec_helper"
2
2
 
3
3
  describe GraphQL::Schema::TypeReducer do
4
- let(:type_map) { GraphQL::Schema::TypeMap.new }
5
- it 'finds types from a single type and its fields' do
6
- reducer = GraphQL::Schema::TypeReducer.new(CheeseType, type_map)
4
+ it "finds types from a single type and its fields" do
5
+ reducer = GraphQL::Schema::TypeReducer.new(CheeseType, {})
7
6
  expected = {
8
7
  "Cheese" => CheeseType,
9
8
  "Float" => GraphQL::FLOAT_TYPE,
@@ -11,21 +10,18 @@ describe GraphQL::Schema::TypeReducer do
11
10
  "DairyAnimal" => DairyAnimalEnum,
12
11
  "Int" => GraphQL::INT_TYPE,
13
12
  "Edible" => EdibleInterface,
14
- "Milk" => MilkType,
15
- "ID" => GraphQL::ID_TYPE,
16
13
  "AnimalProduct" => AnimalProductInterface,
17
- "Honey" => HoneyType,
18
14
  }
19
15
  assert_equal(expected.keys, reducer.result.keys)
20
- assert_equal(expected, reducer.result.to_h)
16
+ assert_equal(expected, reducer.result)
21
17
  end
22
18
 
23
- it 'finds type from arguments' do
24
- reducer = GraphQL::Schema::TypeReducer.new(QueryType, type_map)
19
+ it "finds type from arguments" do
20
+ reducer = GraphQL::Schema::TypeReducer.new(QueryType, {})
25
21
  assert_equal(DairyProductInputType, reducer.result["DairyProductInput"])
26
22
  end
27
23
 
28
- it 'finds types from nested InputObjectTypes' do
24
+ it "finds types from nested InputObjectTypes" do
29
25
  type_child = GraphQL::InputObjectType.define do
30
26
  name "InputTypeChild"
31
27
  input_field :someField, GraphQL::STRING_TYPE
@@ -36,16 +32,16 @@ describe GraphQL::Schema::TypeReducer do
36
32
  input_field :child, type_child
37
33
  end
38
34
 
39
- reducer = GraphQL::Schema::TypeReducer.new(type_parent, type_map)
35
+ reducer = GraphQL::Schema::TypeReducer.new(type_parent, {})
40
36
  expected = {
41
37
  "InputTypeParent" => type_parent,
42
38
  "InputTypeChild" => type_child,
43
39
  "String" => GraphQL::STRING_TYPE
44
40
  }
45
- assert_equal(expected, reducer.result.to_h)
41
+ assert_equal(expected, reducer.result)
46
42
  end
47
43
 
48
- describe 'when a type is invalid' do
44
+ describe "when a type is invalid" do
49
45
  let(:invalid_type) {
50
46
  GraphQL::ObjectType.define do
51
47
  name "InvalidType"
@@ -60,18 +56,18 @@ describe GraphQL::Schema::TypeReducer do
60
56
  end
61
57
  }
62
58
 
63
- it 'raises an InvalidTypeError when passed nil' do
64
- reducer = GraphQL::Schema::TypeReducer.new(invalid_type, type_map)
59
+ it "raises an InvalidTypeError when passed nil" do
60
+ reducer = GraphQL::Schema::TypeReducer.new(invalid_type, {})
65
61
  assert_raises(GraphQL::Schema::InvalidTypeError) { reducer.result }
66
62
  end
67
63
 
68
- it 'raises an InvalidTypeError when passed an object that isnt a GraphQL::BaseType' do
69
- reducer = GraphQL::Schema::TypeReducer.new(another_invalid_type, type_map)
64
+ it "raises an InvalidTypeError when passed an object that isnt a GraphQL::BaseType" do
65
+ reducer = GraphQL::Schema::TypeReducer.new(another_invalid_type, {})
70
66
  assert_raises(GraphQL::Schema::InvalidTypeError) { reducer.result }
71
67
  end
72
68
  end
73
69
 
74
- describe 'when a schema has multiple types with the same name' do
70
+ describe "when a schema has multiple types with the same name" do
75
71
  let(:type_1) {
76
72
  GraphQL::ObjectType.define do
77
73
  name "MyType"
@@ -82,34 +78,23 @@ describe GraphQL::Schema::TypeReducer do
82
78
  name "MyType"
83
79
  end
84
80
  }
85
- it 'raises an error' do
81
+ it "raises an error" do
86
82
  assert_raises(RuntimeError) {
87
83
  GraphQL::Schema::TypeReducer.find_all([type_1, type_2])
88
84
  }
89
85
  end
90
86
  end
91
87
 
92
- describe 'when getting a type which doesnt exist' do
93
- it 'raises an error' do
88
+ describe "when getting a type which doesnt exist" do
89
+ it "raises an error" do
94
90
  type_map = GraphQL::Schema::TypeReducer.find_all([])
95
91
  assert_raises(RuntimeError) { type_map["SomeType"] }
96
92
  end
97
93
  end
98
94
 
99
- describe "when a type can only be inferred through an interface" do
100
- it "logs a warning" do
101
- out, err = capture_io do
102
- GraphQL::Schema::TypeReducer.find_all([EdibleInterface])
103
- end
104
- assert_match /Type "Milk" was inferred from an interface/, err
105
- assert_match /Type "Honey" was inferred from an interface/, err
106
- end
107
-
108
- it "is ok if the types are passed in explicitly" do
109
- out, err = capture_io do
110
- GraphQL::Schema::TypeReducer.find_all([EdibleInterface, HoneyType, MilkType])
111
- end
112
- assert_equal "", err
95
+ describe "when a field is only accessible through an interface" do
96
+ it "is found through Schema.new(types:)" do
97
+ assert_equal HoneyType, DummySchema.types["Honey"]
113
98
  end
114
99
  end
115
100
  end
@@ -1,4 +1,4 @@
1
- require 'spec_helper'
1
+ require "spec_helper"
2
2
 
3
3
  describe GraphQL::Schema::TypeValidator do
4
4
  let(:base_type_defn) {
@@ -18,9 +18,9 @@ describe GraphQL::Schema::TypeValidator do
18
18
  }
19
19
  let(:validator) { GraphQL::Schema::TypeValidator.new }
20
20
  let(:errors) { e = []; validator.validate(object, e); e;}
21
- describe 'when name isnt defined' do
21
+ describe "when name isnt defined" do
22
22
  let(:type_defn) { base_type_defn.delete_if {|k,v| k == :name }}
23
- it 'requires name' do
23
+ it "requires name" do
24
24
  assert_equal(
25
25
  ["InvalidType must respond to #name() to be a Type"],
26
26
  errors
@@ -28,9 +28,9 @@ describe GraphQL::Schema::TypeValidator do
28
28
  end
29
29
  end
30
30
 
31
- describe 'when a method returns nil' do
31
+ describe "when a method returns nil" do
32
32
  let(:type_defn) { base_type_defn.merge(interfaces: nil)}
33
- it 'requires name' do
33
+ it "requires name" do
34
34
  assert_equal(
35
35
  ["InvalidType must return a value for #interfaces() to be a OBJECT"],
36
36
  errors
@@ -59,18 +59,18 @@ describe GraphQL::Schema::TypeValidator do
59
59
  }
60
60
  let(:errors) { e = []; GraphQL::Schema::TypeValidator.new.validate(object, e); e;}
61
61
 
62
- describe 'when non-object types' do
62
+ describe "when non-object types" do
63
63
  let(:types) { [DairyProductInputType] }
64
- it 'must be must be only object types' do
64
+ it "must be must be only object types" do
65
65
  expected = [
66
66
  "Something.possible_types must be objects, but some aren't: DairyProductInput"
67
67
  ]
68
68
  assert_equal(expected, errors)
69
69
  end
70
70
  end
71
- describe 'when no types' do
71
+ describe "when no types" do
72
72
  let(:types) { [] }
73
- it 'must have a type' do
73
+ it "must have a type" do
74
74
  expected = [
75
75
  "Union Something must be defined with 1 or more types, not 0!"
76
76
  ]
@@ -1,4 +1,4 @@
1
- require 'spec_helper'
1
+ require "spec_helper"
2
2
 
3
3
  describe GraphQL::Schema do
4
4
  let(:schema) { DummySchema }
@@ -1,4 +1,4 @@
1
- require 'spec_helper'
1
+ require "spec_helper"
2
2
 
3
3
  describe GraphQL::StaticValidation::ArgumentLiteralsAreCompatible do
4
4
  let(:query_string) {%|
@@ -21,7 +21,7 @@ describe GraphQL::StaticValidation::ArgumentLiteralsAreCompatible do
21
21
  let(:query) { GraphQL::Query.new(DummySchema, query_string) }
22
22
  let(:errors) { validator.validate(query) }
23
23
 
24
- it 'finds undefined or missing-required arguments to fields and directives' do
24
+ it "finds undefined or missing-required arguments to fields and directives" do
25
25
  assert_equal(6, errors.length)
26
26
 
27
27
  query_root_error = {
@@ -32,7 +32,7 @@ describe GraphQL::StaticValidation::ArgumentLiteralsAreCompatible do
32
32
 
33
33
  directive_error = {
34
34
  "message"=>"Argument 'if' on Directive 'skip' has an invalid value",
35
- "locations"=>[{"line"=>4, "column"=>31}]
35
+ "locations"=>[{"line"=>4, "column"=>30}]
36
36
  }
37
37
  assert_includes(errors, directive_error)
38
38
 
@@ -44,7 +44,7 @@ describe GraphQL::StaticValidation::ArgumentLiteralsAreCompatible do
44
44
 
45
45
  input_object_field_error = {
46
46
  "message"=>"Argument 'source' on InputObject 'DairyProductInput' has an invalid value",
47
- "locations"=>[{"line"=>6, "column"=>41}]
47
+ "locations"=>[{"line"=>6, "column"=>40}]
48
48
  }
49
49
  assert_includes(errors, input_object_field_error)
50
50
 
@@ -1,4 +1,4 @@
1
- require 'spec_helper'
1
+ require "spec_helper"
2
2
 
3
3
  describe GraphQL::StaticValidation::ArgumentsAreDefined do
4
4
  let(:query_string) {"
@@ -18,7 +18,7 @@ describe GraphQL::StaticValidation::ArgumentsAreDefined do
18
18
  let(:query) { GraphQL::Query.new(DummySchema, query_string) }
19
19
  let(:errors) { validator.validate(query) }
20
20
 
21
- it 'finds undefined arguments to fields and directives' do
21
+ it "finds undefined arguments to fields and directives" do
22
22
  assert_equal(4, errors.length)
23
23
 
24
24
  query_root_error = {
@@ -29,7 +29,7 @@ describe GraphQL::StaticValidation::ArgumentsAreDefined do
29
29
 
30
30
  input_obj_record = {
31
31
  "message"=>"InputObject 'DairyProductInput' doesn't accept argument 'wacky'",
32
- "locations"=>[{"line"=>5, "column"=>30}]
32
+ "locations"=>[{"line"=>5, "column"=>29}]
33
33
  }
34
34
  assert_includes(errors, input_obj_record)
35
35
 
@@ -41,7 +41,7 @@ describe GraphQL::StaticValidation::ArgumentsAreDefined do
41
41
 
42
42
  directive_error = {
43
43
  "message"=>"Directive 'skip' doesn't accept argument 'something'",
44
- "locations"=>[{"line"=>10, "column"=>11}]
44
+ "locations"=>[{"line"=>10, "column"=>10}]
45
45
  }
46
46
  assert_includes(errors, directive_error)
47
47
  end
@@ -1,4 +1,4 @@
1
- require 'spec_helper'
1
+ require "spec_helper"
2
2
 
3
3
  describe GraphQL::StaticValidation::DirectivesAreDefined do
4
4
  let(:query_string) {"
@@ -17,15 +17,15 @@ describe GraphQL::StaticValidation::DirectivesAreDefined do
17
17
  let(:query) { GraphQL::Query.new(DummySchema, query_string) }
18
18
  let(:errors) { validator.validate(query) }
19
19
 
20
- describe 'non-existent directives' do
21
- it 'makes errors for them' do
20
+ describe "non-existent directives" do
21
+ it "makes errors for them" do
22
22
  expected = [
23
23
  {
24
24
  "message"=>"Directive @nonsense is not defined",
25
- "locations"=>[{"line"=>5, "column"=>17}]
25
+ "locations"=>[{"line"=>5, "column"=>16}]
26
26
  }, {
27
27
  "message"=>"Directive @moreNonsense is not defined",
28
- "locations"=>[{"line"=>7, "column"=>19}]
28
+ "locations"=>[{"line"=>7, "column"=>18}]
29
29
  }
30
30
  ]
31
31
  assert_equal(expected, errors)
@@ -0,0 +1,39 @@
1
+ require "spec_helper"
2
+
3
+ describe GraphQL::StaticValidation::DirectivesAreInValidLocations do
4
+ let(:query_string) {"
5
+ query getCheese @skip(if: true) {
6
+ okCheese: cheese(id: 1) {
7
+ id @skip(if: true),
8
+ source
9
+ ... on Cheese @skip(if: true) {
10
+ flavor
11
+ }
12
+ }
13
+ }
14
+
15
+ fragment whatever on Cheese @skip(if: true) {
16
+ id
17
+ }
18
+ "}
19
+
20
+ let(:validator) { GraphQL::StaticValidation::Validator.new(schema: DummySchema, rules: [GraphQL::StaticValidation::DirectivesAreInValidLocations]) }
21
+ let(:query) { GraphQL::Query.new(DummySchema, query_string) }
22
+ let(:errors) { validator.validate(query) }
23
+
24
+ describe "invalid directive locations" do
25
+ it "makes errors for them" do
26
+ expected = [
27
+ {
28
+ "message"=> "'@skip' can't be applied to queries (allowed: fields, fragment spreads, inline fragments)",
29
+ "locations"=>[{"line"=>2, "column"=>21}]
30
+ },
31
+ {
32
+ "message"=>"'@skip' can't be applied to fragment definitions (allowed: fields, fragment spreads, inline fragments)",
33
+ "locations"=>[{"line"=>12, "column"=>33}]
34
+ },
35
+ ]
36
+ assert_equal(expected, errors)
37
+ end
38
+ end
39
+ end
@@ -1,4 +1,4 @@
1
- require 'spec_helper'
1
+ require "spec_helper"
2
2
 
3
3
  describe GraphQL::StaticValidation::FieldsAreDefinedOnType do
4
4
  let(:query_string) { "
@@ -26,10 +26,10 @@ describe GraphQL::StaticValidation::FieldsAreDefinedOnType do
26
26
  assert_equal(expected_errors, error_messages)
27
27
  end
28
28
 
29
- describe 'on interfaces' do
29
+ describe "on interfaces" do
30
30
  let(:query_string) { "query getStuff { favoriteEdible { amountThatILikeIt } }"}
31
31
 
32
- it 'finds invalid fields' do
32
+ it "finds invalid fields" do
33
33
  expected_errors = [
34
34
  {"message"=>"Field 'amountThatILikeIt' doesn't exist on type 'Edible'", "locations"=>[{"line"=>1, "column"=>18}]}
35
35
  ]
@@ -37,7 +37,7 @@ describe GraphQL::StaticValidation::FieldsAreDefinedOnType do
37
37
  end
38
38
  end
39
39
 
40
- describe 'on unions' do
40
+ describe "on unions" do
41
41
  let(:query_string) { "
42
42
  query notOnUnion { favoriteEdible { ...dpFields } }
43
43
  fragment dbFields on DairyProduct { source }
@@ -45,7 +45,7 @@ describe GraphQL::StaticValidation::FieldsAreDefinedOnType do
45
45
  "}
46
46
 
47
47
 
48
- it 'doesnt allow selections on unions' do
48
+ it "doesnt allow selections on unions" do
49
49
  expected_errors = [
50
50
  {
51
51
  "message"=>"Selections can't be made directly on unions (see selections on DairyProduct)",
@@ -1,4 +1,4 @@
1
- require 'spec_helper'
1
+ require "spec_helper"
2
2
 
3
3
  describe GraphQL::StaticValidation::FieldsHaveAppropriateSelections do
4
4
  let(:query_string) {"
@@ -13,19 +13,19 @@ describe GraphQL::StaticValidation::FieldsHaveAppropriateSelections do
13
13
  let(:query) { GraphQL::Query.new(DummySchema, query_string) }
14
14
  let(:errors) { validator.validate(query) }
15
15
 
16
- it 'adds errors for selections on scalars' do
16
+ it "adds errors for selections on scalars" do
17
17
  assert_equal(2, errors.length)
18
18
 
19
19
  illegal_selection_error = {
20
20
  "message"=>"Selections can't be made on scalars (field 'id' returns Int but has selections [something, someFields])",
21
21
  "locations"=>[{"line"=>5, "column"=>47}]
22
22
  }
23
- assert_includes(errors, illegal_selection_error, 'finds illegal selections on scalarss')
23
+ assert_includes(errors, illegal_selection_error, "finds illegal selections on scalarss")
24
24
 
25
25
  selection_required_error = {
26
26
  "message"=>"Objects must have selections (field 'cheese' returns Cheese but has no selections)",
27
27
  "locations"=>[{"line"=>4, "column"=>7}]
28
28
  }
29
- assert_includes(errors, selection_required_error, 'finds objects without selections')
29
+ assert_includes(errors, selection_required_error, "finds objects without selections")
30
30
  end
31
31
  end