graphql 1.0.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (87) hide show
  1. checksums.yaml +4 -4
  2. data/lib/graphql.rb +10 -0
  3. data/lib/graphql/base_type.rb +8 -5
  4. data/lib/graphql/compatibility.rb +3 -0
  5. data/lib/graphql/compatibility/execution_specification.rb +414 -0
  6. data/lib/graphql/compatibility/query_parser_specification.rb +117 -0
  7. data/lib/graphql/compatibility/query_parser_specification/parse_error_specification.rb +81 -0
  8. data/lib/graphql/compatibility/query_parser_specification/query_assertions.rb +78 -0
  9. data/lib/graphql/compatibility/schema_parser_specification.rb +239 -0
  10. data/lib/graphql/define/instance_definable.rb +53 -21
  11. data/lib/graphql/directive.rb +1 -1
  12. data/lib/graphql/enum_type.rb +31 -8
  13. data/lib/graphql/execution/directive_checks.rb +0 -6
  14. data/lib/graphql/input_object_type.rb +6 -4
  15. data/lib/graphql/introspection/arguments_field.rb +3 -1
  16. data/lib/graphql/introspection/enum_values_field.rb +10 -5
  17. data/lib/graphql/introspection/fields_field.rb +1 -1
  18. data/lib/graphql/introspection/input_fields_field.rb +2 -2
  19. data/lib/graphql/introspection/interfaces_field.rb +7 -1
  20. data/lib/graphql/introspection/possible_types_field.rb +1 -1
  21. data/lib/graphql/introspection/schema_type.rb +1 -1
  22. data/lib/graphql/introspection/type_by_name_field.rb +4 -2
  23. data/lib/graphql/introspection/type_type.rb +7 -6
  24. data/lib/graphql/language/lexer.rl +0 -4
  25. data/lib/graphql/language/parser.rb +1 -1
  26. data/lib/graphql/language/parser.y +1 -1
  27. data/lib/graphql/list_type.rb +3 -4
  28. data/lib/graphql/non_null_type.rb +4 -8
  29. data/lib/graphql/object_type.rb +5 -3
  30. data/lib/graphql/query.rb +48 -12
  31. data/lib/graphql/query/context.rb +7 -1
  32. data/lib/graphql/query/serial_execution/execution_context.rb +8 -3
  33. data/lib/graphql/query/serial_execution/field_resolution.rb +8 -5
  34. data/lib/graphql/query/serial_execution/operation_resolution.rb +2 -2
  35. data/lib/graphql/query/serial_execution/selection_resolution.rb +4 -21
  36. data/lib/graphql/query/serial_execution/value_resolution.rb +59 -99
  37. data/lib/graphql/query/variables.rb +7 -2
  38. data/lib/graphql/scalar_type.rb +1 -1
  39. data/lib/graphql/schema.rb +49 -18
  40. data/lib/graphql/schema/build_from_definition.rb +248 -0
  41. data/lib/graphql/schema/instrumented_field_map.rb +23 -0
  42. data/lib/graphql/schema/loader.rb +4 -11
  43. data/lib/graphql/schema/possible_types.rb +4 -2
  44. data/lib/graphql/schema/printer.rb +1 -1
  45. data/lib/graphql/schema/type_expression.rb +4 -4
  46. data/lib/graphql/schema/type_map.rb +1 -1
  47. data/lib/graphql/schema/validation.rb +4 -0
  48. data/lib/graphql/schema/warden.rb +114 -0
  49. data/lib/graphql/static_validation/literal_validator.rb +10 -7
  50. data/lib/graphql/static_validation/rules/argument_literals_are_compatible.rb +1 -3
  51. data/lib/graphql/static_validation/rules/arguments_are_defined.rb +1 -1
  52. data/lib/graphql/static_validation/rules/fields_are_defined_on_type.rb +1 -1
  53. data/lib/graphql/static_validation/rules/fragment_spreads_are_possible.rb +3 -14
  54. data/lib/graphql/static_validation/rules/fragment_types_exist.rb +1 -1
  55. data/lib/graphql/static_validation/rules/fragments_are_on_composite_types.rb +1 -1
  56. data/lib/graphql/static_validation/rules/variable_default_values_are_correctly_typed.rb +3 -4
  57. data/lib/graphql/static_validation/rules/variables_are_input_types.rb +2 -1
  58. data/lib/graphql/static_validation/validation_context.rb +7 -1
  59. data/lib/graphql/union_type.rb +6 -3
  60. data/lib/graphql/unresolved_type_error.rb +1 -2
  61. data/lib/graphql/version.rb +1 -1
  62. data/readme.md +1 -5
  63. data/spec/graphql/compatibility/execution_specification_spec.rb +3 -0
  64. data/spec/graphql/compatibility/query_parser_specification_spec.rb +5 -0
  65. data/spec/graphql/compatibility/schema_parser_specification_spec.rb +5 -0
  66. data/spec/graphql/define/instance_definable_spec.rb +20 -0
  67. data/spec/graphql/directive_spec.rb +11 -0
  68. data/spec/graphql/enum_type_spec.rb +20 -1
  69. data/spec/graphql/input_object_type_spec.rb +9 -9
  70. data/spec/graphql/introspection/directive_type_spec.rb +4 -4
  71. data/spec/graphql/introspection/input_value_type_spec.rb +6 -6
  72. data/spec/graphql/introspection/type_type_spec.rb +28 -26
  73. data/spec/graphql/language/parser_spec.rb +27 -17
  74. data/spec/graphql/list_type_spec.rb +2 -2
  75. data/spec/graphql/query/variables_spec.rb +1 -0
  76. data/spec/graphql/scalar_type_spec.rb +3 -3
  77. data/spec/graphql/schema/build_from_definition_spec.rb +693 -0
  78. data/spec/graphql/schema/type_expression_spec.rb +3 -3
  79. data/spec/graphql/schema/validation_spec.rb +7 -3
  80. data/spec/graphql/schema/warden_spec.rb +510 -0
  81. data/spec/graphql/schema_spec.rb +129 -0
  82. data/spec/graphql/static_validation/rules/argument_literals_are_compatible_spec.rb +1 -1
  83. data/spec/graphql/static_validation/type_stack_spec.rb +3 -3
  84. data/spec/spec_helper.rb +27 -1
  85. data/spec/support/dairy_app.rb +8 -5
  86. metadata +21 -3
  87. data/lib/graphql/language/parser_tests.rb +0 -809
@@ -0,0 +1,5 @@
1
+ require "spec_helper"
2
+
3
+ BuiltInQueryParserSuite = GraphQL::Compatibility::QueryParserSpecification.build_suite do |query_string|
4
+ GraphQL::Language::Parser.parse(query_string)
5
+ end
@@ -0,0 +1,5 @@
1
+ require "spec_helper"
2
+
3
+ BuiltInSchemaParserSuite = GraphQL::Compatibility::SchemaParserSpecification.build_suite do |query_string|
4
+ GraphQL::Language::Parser.parse(query_string)
5
+ end
@@ -73,6 +73,26 @@ describe GraphQL::Define::InstanceDefinable do
73
73
  end
74
74
  end
75
75
 
76
+ describe "#redefine" do
77
+ it "re-runs definitions without modifying the original object" do
78
+ arugula = Garden::Vegetable.define(name: "Arugula", color: :green)
79
+
80
+ red_arugula = arugula.redefine(color: :red)
81
+ renamed_red_arugula = red_arugula.redefine do
82
+ name "Renamed Red Arugula"
83
+ end
84
+
85
+ assert_equal :green, arugula.metadata[:color]
86
+ assert_equal "Arugula", arugula.name
87
+
88
+ assert_equal :red, red_arugula.metadata[:color]
89
+ assert_equal "Arugula", red_arugula.name
90
+
91
+ assert_equal :red, renamed_red_arugula.metadata[:color]
92
+ assert_equal "Renamed Red Arugula", renamed_red_arugula.name
93
+ end
94
+ end
95
+
76
96
  describe "#metadata" do
77
97
  it "gets values from definitions" do
78
98
  arugula = Garden::Vegetable.define(name: "Arugula", color: :green)
@@ -212,4 +212,15 @@ describe GraphQL::Directive do
212
212
  end
213
213
  end
214
214
  end
215
+
216
+ describe "defining a directive" do
217
+ it "can accept an array of arguments" do
218
+ directive = GraphQL::Directive.define do
219
+ arguments [GraphQL::Argument.define(name: 'skip')]
220
+ end
221
+
222
+ assert_equal 1, directive.arguments.length
223
+ assert_equal 'skip', directive.arguments.first.name
224
+ end
225
+ end
215
226
  end
@@ -15,6 +15,25 @@ describe GraphQL::EnumType do
15
15
  it "coerces result values to value's value" do
16
16
  assert_equal("YAK", enum.coerce_result("YAK"))
17
17
  assert_equal("COW", enum.coerce_result(1))
18
+ assert_equal("REINDEER", enum.coerce_result('reindeer'))
19
+ assert_equal("DONKEY", enum.coerce_result(:donkey))
20
+ end
21
+
22
+ it "raises when a result value can't be coerced" do
23
+ assert_raises(GraphQL::EnumType::UnresolvedValueError) {
24
+ enum.coerce_result(:nonsense)
25
+ }
26
+ end
27
+
28
+ describe "resolving with a warden" do
29
+ it "gets values from the warden" do
30
+ # OK
31
+ assert_equal("YAK", enum.coerce_result("YAK"))
32
+ # NOT OK
33
+ assert_raises(GraphQL::EnumType::UnresolvedValueError) {
34
+ enum.coerce_result("YAK", NothingWarden)
35
+ }
36
+ end
18
37
  end
19
38
 
20
39
  it "has value description" do
@@ -22,7 +41,7 @@ describe GraphQL::EnumType do
22
41
  end
23
42
 
24
43
  describe "validate_input with bad input" do
25
- let(:result) { DairyAnimalEnum.validate_input("bad enum") }
44
+ let(:result) { DairyAnimalEnum.validate_input("bad enum", PermissiveWarden) }
26
45
 
27
46
  it "returns an invalid result" do
28
47
  assert(!result.valid?)
@@ -13,18 +13,18 @@ describe GraphQL::InputObjectType do
13
13
  describe "input validation" do
14
14
  it "Accepts anything that yields key-value pairs to #all?" do
15
15
  values_obj = MinimumInputObject.new({"source" => "COW", "fatContent" => 0.4})
16
- assert DairyProductInputType.valid_input?(values_obj)
16
+ assert DairyProductInputType.valid_input?(values_obj, PermissiveWarden)
17
17
  end
18
18
 
19
19
  describe "validate_input with non-enumerable input" do
20
20
  it "returns a valid result for MinimumInputObject" do
21
- result = DairyProductInputType.validate_input(MinimumInputObject.new({"source" => "COW", "fatContent" => 0.4}))
21
+ result = DairyProductInputType.validate_input(MinimumInputObject.new({"source" => "COW", "fatContent" => 0.4}), PermissiveWarden)
22
22
  assert(result.valid?)
23
23
  end
24
24
 
25
25
  it "returns an invalid result for MinimumInvalidInputObject" do
26
26
  invalid_input = MinimumInputObject.new({"source" => "KOALA", "fatContent" => 0.4})
27
- result = DairyProductInputType.validate_input(invalid_input)
27
+ result = DairyProductInputType.validate_input(invalid_input, PermissiveWarden)
28
28
  assert(!result.valid?)
29
29
  end
30
30
  end
@@ -37,7 +37,7 @@ describe GraphQL::InputObjectType do
37
37
  "fatContent" => 0.4
38
38
  }
39
39
  end
40
- let(:result) { DairyProductInputType.validate_input(input) }
40
+ let(:result) { DairyProductInputType.validate_input(input, PermissiveWarden) }
41
41
 
42
42
  it "returns a valid result" do
43
43
  assert(result.valid?)
@@ -45,7 +45,7 @@ describe GraphQL::InputObjectType do
45
45
  end
46
46
 
47
47
  describe "with bad enum and float" do
48
- let(:result) { DairyProductInputType.validate_input("source" => "KOALA", "fatContent" => "bad_num") }
48
+ let(:result) { DairyProductInputType.validate_input({"source" => "KOALA", "fatContent" => "bad_num"}, PermissiveWarden) }
49
49
 
50
50
  it "returns an invalid result" do
51
51
  assert(!result.valid?)
@@ -58,7 +58,7 @@ describe GraphQL::InputObjectType do
58
58
  end
59
59
 
60
60
  it "has correct problem explanation" do
61
- expected = DairyAnimalEnum.validate_input("KOALA").problems[0]["explanation"]
61
+ expected = DairyAnimalEnum.validate_input("KOALA", PermissiveWarden).problems[0]["explanation"]
62
62
 
63
63
  source_problem = result.problems.detect { |p| p["path"] == ["source"] }
64
64
  actual = source_problem["explanation"]
@@ -68,7 +68,7 @@ describe GraphQL::InputObjectType do
68
68
  end
69
69
 
70
70
  describe "with extra argument" do
71
- let(:result) { DairyProductInputType.validate_input("source" => "COW", "fatContent" => 0.4, "isDelicious" => false) }
71
+ let(:result) { DairyProductInputType.validate_input({"source" => "COW", "fatContent" => 0.4, "isDelicious" => false}, PermissiveWarden) }
72
72
 
73
73
  it "returns an invalid result" do
74
74
  assert(!result.valid?)
@@ -90,7 +90,7 @@ describe GraphQL::InputObjectType do
90
90
  list_type.validate_input([
91
91
  { "source" => "COW", "fatContent" => 0.4 },
92
92
  { "source" => "KOALA", "fatContent" => 0.4 }
93
- ])
93
+ ], PermissiveWarden)
94
94
  end
95
95
 
96
96
  it "returns an invalid result" do
@@ -107,7 +107,7 @@ describe GraphQL::InputObjectType do
107
107
  end
108
108
 
109
109
  it "has problem with correct explanation" do
110
- expected = DairyAnimalEnum.validate_input("KOALA").problems[0]["explanation"]
110
+ expected = DairyAnimalEnum.validate_input("KOALA", PermissiveWarden).problems[0]["explanation"]
111
111
  actual = result.problems[0]["explanation"]
112
112
  assert_equal(expected, actual)
113
113
  end
@@ -6,7 +6,7 @@ describe GraphQL::Introspection::DirectiveType do
6
6
  __schema {
7
7
  directives {
8
8
  name,
9
- args { name, type { name, ofType { name } } },
9
+ args { name, type { kind, name, ofType { name } } },
10
10
  locations
11
11
  # Deprecated fields:
12
12
  onField
@@ -25,7 +25,7 @@ describe GraphQL::Introspection::DirectiveType do
25
25
  {
26
26
  "name" => "include",
27
27
  "args" => [
28
- {"name"=>"if", "type"=>{"name"=>"Non-Null", "ofType"=>{"name"=>"Boolean"}}}
28
+ {"name"=>"if", "type"=>{"kind"=>"NON_NULL", "name"=>nil, "ofType"=>{"name"=>"Boolean"}}}
29
29
  ],
30
30
  "locations"=>["FIELD", "FRAGMENT_SPREAD", "INLINE_FRAGMENT"],
31
31
  "onField" => true,
@@ -35,7 +35,7 @@ describe GraphQL::Introspection::DirectiveType do
35
35
  {
36
36
  "name" => "skip",
37
37
  "args" => [
38
- {"name"=>"if", "type"=>{"name"=>"Non-Null", "ofType"=>{"name"=>"Boolean"}}}
38
+ {"name"=>"if", "type"=>{"kind"=>"NON_NULL", "name"=>nil, "ofType"=>{"name"=>"Boolean"}}}
39
39
  ],
40
40
  "locations"=>["FIELD", "FRAGMENT_SPREAD", "INLINE_FRAGMENT"],
41
41
  "onField" => true,
@@ -45,7 +45,7 @@ describe GraphQL::Introspection::DirectiveType do
45
45
  {
46
46
  "name" => "deprecated",
47
47
  "args" => [
48
- {"name"=>"reason", "type"=>{"name"=>"String", "ofType"=>nil}}
48
+ {"name"=>"reason", "type"=>{"kind"=>"SCALAR", "name"=>"String", "ofType"=>nil}}
49
49
  ],
50
50
  "locations"=>["FIELD_DEFINITION", "ENUM_VALUE"],
51
51
  "onField" => false,
@@ -10,7 +10,7 @@ describe GraphQL::Introspection::InputValueType do
10
10
  kind,
11
11
  inputFields {
12
12
  name,
13
- type { name },
13
+ type { kind, name },
14
14
  defaultValue
15
15
  description
16
16
  }
@@ -26,13 +26,13 @@ describe GraphQL::Introspection::InputValueType do
26
26
  "description"=>"Properties for finding a dairy product",
27
27
  "kind"=>"INPUT_OBJECT",
28
28
  "inputFields"=>[
29
- {"name"=>"source", "type"=>{ "name" => "Non-Null"}, "defaultValue"=>nil,
29
+ {"name"=>"source", "type"=>{"kind"=>"NON_NULL", "name" => nil}, "defaultValue"=>nil,
30
30
  "description" => "Where it came from"},
31
- {"name"=>"originDairy", "type"=>{ "name" => "String"}, "defaultValue"=>"\"Sugar Hollow Dairy\"",
31
+ {"name"=>"originDairy", "type"=>{"kind"=>"SCALAR", "name" => "String"}, "defaultValue"=>"\"Sugar Hollow Dairy\"",
32
32
  "description" => "Dairy which produced it"},
33
- {"name"=>"fatContent", "type"=>{ "name" => "Float"}, "defaultValue"=>"0.3",
33
+ {"name"=>"fatContent", "type"=>{"kind"=>"SCALAR", "name" => "Float"}, "defaultValue"=>"0.3",
34
34
  "description" => "How much fat it has"},
35
- {"name"=>"organic", "type"=>{ "name" => "Boolean"}, "defaultValue"=>"false",
35
+ {"name"=>"organic", "type"=>{"kind"=>"SCALAR", "name" => "Boolean"}, "defaultValue"=>"false",
36
36
  "description" => nil}
37
37
  ]
38
38
  }
@@ -58,7 +58,7 @@ describe GraphQL::Introspection::InputValueType do
58
58
 
59
59
  it "converts default values to GraphQL values" do
60
60
  field = cheese_type['data']['__type']['fields'].detect { |f| f['name'] == 'similarCheese' }
61
- arg = field['args'].detect { |a| a['name'] == 'source' }
61
+ arg = field['args'].detect { |a| a['name'] == 'nullableSource' }
62
62
 
63
63
  assert_equal('["COW"]', arg['defaultValue'])
64
64
  end
@@ -3,8 +3,8 @@ require "spec_helper"
3
3
  describe GraphQL::Introspection::TypeType do
4
4
  let(:query_string) {%|
5
5
  query introspectionQuery {
6
- cheeseType: __type(name: "Cheese") { name, kind, fields { name, isDeprecated, type { name, ofType { name } } } }
7
- milkType: __type(name: "Milk") { interfaces { name }, fields { type { name, ofType { name } } } }
6
+ cheeseType: __type(name: "Cheese") { name, kind, fields { name, isDeprecated, type { kind, name, ofType { name } } } }
7
+ milkType: __type(name: "Milk") { interfaces { name }, fields { type { kind, name, ofType { name } } } }
8
8
  dairyAnimal: __type(name: "DairyAnimal") { name, kind, enumValues(includeDeprecated: false) { name, isDeprecated } }
9
9
  dairyProduct: __type(name: "DairyProduct") { name, kind, possibleTypes { name } }
10
10
  animalProduct: __type(name: "AnimalProduct") { name, kind, possibleTypes { name }, fields { name } }
@@ -13,19 +13,21 @@ describe GraphQL::Introspection::TypeType do
13
13
  |}
14
14
  let(:result) { DummySchema.execute(query_string, context: {}, variables: {"cheeseId" => 2}) }
15
15
  let(:cheese_fields) {[
16
- {"name"=>"deeplyNullableCheese", "isDeprecated"=>false, "type"=>{"name"=>"Cheese", "ofType"=>nil}},
17
- {"name"=>"flavor", "isDeprecated" => false, "type" => { "name" => "Non-Null", "ofType" => { "name" => "String"}}},
18
- {"name"=>"id", "isDeprecated" => false, "type" => { "name" => "Non-Null", "ofType" => { "name" => "Int"}}},
19
- {"name"=>"nullableCheese", "isDeprecated"=>false, "type"=>{"name"=>"Cheese", "ofType"=>nil}},
20
- {"name"=>"origin", "isDeprecated" => false, "type" => { "name" => "Non-Null", "ofType" => { "name" => "String"}}},
21
- {"name"=>"similarCheese", "isDeprecated"=>false, "type"=>{"name"=>"Cheese", "ofType"=>nil}},
22
- {"name"=>"source", "isDeprecated" => false, "type" => { "name" => "Non-Null", "ofType" => { "name" => "DairyAnimal"}}},
16
+ {"name"=>"deeplyNullableCheese", "isDeprecated" => false, "type"=>{ "kind" => "OBJECT", "name" => "Cheese", "ofType" => nil}},
17
+ {"name"=>"flavor", "isDeprecated" => false, "type" => { "kind" => "NON_NULL", "name" => nil, "ofType" => { "name" => "String"}}},
18
+ {"name"=>"id", "isDeprecated" => false, "type" => { "kind" => "NON_NULL", "name" => nil, "ofType" => { "name" => "Int"}}},
19
+ {"name"=>"nullableCheese", "isDeprecated"=>false, "type"=>{ "kind" => "OBJECT", "name" => "Cheese", "ofType"=>nil}},
20
+ {"name"=>"origin", "isDeprecated" => false, "type" => { "kind" => "NON_NULL", "name" => nil, "ofType" => { "name" => "String"}}},
21
+ {"name"=>"similarCheese", "isDeprecated"=>false, "type"=>{ "kind" => "OBJECT", "name"=>"Cheese", "ofType"=>nil}},
22
+ {"name"=>"source", "isDeprecated" => false, "type" => { "kind" => "NON_NULL", "name" => nil, "ofType" => { "name" => "DairyAnimal"}}},
23
23
  ]}
24
24
 
25
25
  let(:dairy_animals) {[
26
- {"name"=>"COW", "isDeprecated"=> false },
27
- {"name"=>"GOAT", "isDeprecated"=> false },
28
- {"name"=>"SHEEP", "isDeprecated"=> false },
26
+ {"name"=>"COW", "isDeprecated"=> false },
27
+ {"name"=>"DONKEY", "isDeprecated"=> false },
28
+ {"name"=>"GOAT", "isDeprecated"=> false },
29
+ {"name"=>"REINDEER", "isDeprecated"=> false },
30
+ {"name"=>"SHEEP", "isDeprecated"=> false },
29
31
  ]}
30
32
  it "exposes metadata about types" do
31
33
  expected = {"data"=> {
@@ -41,13 +43,13 @@ describe GraphQL::Introspection::TypeType do
41
43
  {"name"=>"LocalProduct"},
42
44
  ],
43
45
  "fields"=>[
44
- {"type"=>{"name"=>"List", "ofType"=>{"name"=>"DairyProduct"}}},
45
- {"type"=>{"name"=>"String", "ofType"=>nil}},
46
- {"type"=>{"name"=>"Non-Null", "ofType"=>{"name"=>"Float"}}},
47
- {"type"=>{"name"=>"List", "ofType"=>{"name"=>"String"}}},
48
- {"type"=>{"name"=>"Non-Null", "ofType"=>{"name"=>"ID"}}},
49
- {"type"=>{"name"=>"Non-Null", "ofType"=>{"name"=>"String"}}},
50
- {"type"=>{"name"=>"DairyAnimal", "ofType"=>nil}},
46
+ {"type"=>{"kind"=>"LIST","name"=>nil, "ofType"=>{"name"=>"DairyProduct"}}},
47
+ {"type"=>{"kind"=>"SCALAR","name"=>"String", "ofType"=>nil}},
48
+ {"type"=>{"kind"=>"NON_NULL","name"=>nil, "ofType"=>{"name"=>"Float"}}},
49
+ {"type"=>{"kind"=>"LIST","name"=>nil, "ofType"=>{"name"=>"String"}}},
50
+ {"type"=>{"kind"=>"NON_NULL","name"=>nil, "ofType"=>{"name"=>"ID"}}},
51
+ {"type"=>{"kind"=>"NON_NULL","name"=>nil, "ofType"=>{"name"=>"String"}}},
52
+ {"type"=>{"kind"=>"ENUM","name"=>"DairyAnimal", "ofType"=>nil}},
51
53
  ]
52
54
  },
53
55
  "dairyAnimal"=>{
@@ -76,11 +78,11 @@ describe GraphQL::Introspection::TypeType do
76
78
  describe "deprecated fields" do
77
79
  let(:query_string) {%|
78
80
  query introspectionQuery {
79
- cheeseType: __type(name: "Cheese") { name, kind, fields(includeDeprecated: true) { name, isDeprecated, type { name, ofType { name } } } }
81
+ cheeseType: __type(name: "Cheese") { name, kind, fields(includeDeprecated: true) { name, isDeprecated, type { kind, name, ofType { name } } } }
80
82
  dairyAnimal: __type(name: "DairyAnimal") { name, kind, enumValues(includeDeprecated: true) { name, isDeprecated } }
81
83
  }
82
84
  |}
83
- let(:deprecated_fields) { {"name"=>"fatContent", "isDeprecated"=>true, "type"=>{"name"=>"Non-Null", "ofType"=>{"name"=>"Float"}}} }
85
+ let(:deprecated_fields) { {"name"=>"fatContent", "isDeprecated"=>true, "type"=>{"kind"=>"NON_NULL","name"=>nil, "ofType"=>{"name"=>"Float"}}} }
84
86
 
85
87
  it "can expose deprecated fields" do
86
88
  new_cheese_fields = ([deprecated_fields] + cheese_fields).sort_by { |f| f["name"] }
@@ -102,7 +104,7 @@ describe GraphQL::Introspection::TypeType do
102
104
  describe "input objects" do
103
105
  let(:query_string) {%|
104
106
  query introspectionQuery {
105
- __type(name: "DairyProductInput") { name, description, kind, inputFields { name, type { name }, defaultValue } }
107
+ __type(name: "DairyProductInput") { name, description, kind, inputFields { name, type { kind, name }, defaultValue } }
106
108
  }
107
109
  |}
108
110
 
@@ -113,10 +115,10 @@ describe GraphQL::Introspection::TypeType do
113
115
  "description"=>"Properties for finding a dairy product",
114
116
  "kind"=>"INPUT_OBJECT",
115
117
  "inputFields"=>[
116
- {"name"=>"source", "type"=>{ "name" => "Non-Null"}, "defaultValue"=>nil},
117
- {"name"=>"originDairy", "type"=>{"name"=>"String"}, "defaultValue"=>"\"Sugar Hollow Dairy\""},
118
- {"name"=>"fatContent", "type"=>{ "name" => "Float"}, "defaultValue"=>"0.3"},
119
- {"name"=>"organic", "type"=>{ "name" => "Boolean"}, "defaultValue"=>"false"},
118
+ {"name"=>"source", "type"=>{"kind"=>"NON_NULL","name"=>nil, }, "defaultValue"=>nil},
119
+ {"name"=>"originDairy", "type"=>{"kind"=>"SCALAR","name"=>"String"}, "defaultValue"=>"\"Sugar Hollow Dairy\""},
120
+ {"name"=>"fatContent", "type"=>{"kind"=>"SCALAR","name" => "Float"}, "defaultValue"=>"0.3"},
121
+ {"name"=>"organic", "type"=>{"kind"=>"SCALAR","name" => "Boolean"}, "defaultValue"=>"false"},
120
122
  ]
121
123
  }
122
124
  }}
@@ -1,8 +1,6 @@
1
1
  require "spec_helper"
2
- require 'graphql/language/parser_tests'
3
2
 
4
3
  describe GraphQL::Language::Parser do
5
- include GraphQL::Language::ParserTests
6
4
  subject { GraphQL::Language::Parser }
7
5
 
8
6
  describe "anonymous fragment extension" do
@@ -13,23 +11,35 @@ describe GraphQL::Language::Parser do
13
11
  }
14
12
  |}
15
13
 
16
- describe ".parse" do
17
- it "parses queries" do
18
- assert document
19
- end
14
+ let(:fragment) { document.definitions.first }
20
15
 
21
- describe "visited nodes" do
22
- let(:fragment) { document.definitions.first }
16
+ it "creates an anonymous fragment definition" do
17
+ assert fragment.is_a?(GraphQL::Language::Nodes::FragmentDefinition)
18
+ assert_equal nil, fragment.name
19
+ assert_equal 1, fragment.selections.length
20
+ assert_equal "NestedType", fragment.type.name
21
+ assert_equal 1, fragment.directives.length
22
+ assert_equal [2, 7], fragment.position
23
+ end
24
+ end
23
25
 
24
- it "creates an anonymous fragment definition" do
25
- assert fragment.is_a?(GraphQL::Language::Nodes::FragmentDefinition)
26
- assert_equal nil, fragment.name
27
- assert_equal 1, fragment.selections.length
28
- assert_equal "NestedType", fragment.type.name
29
- assert_equal 1, fragment.directives.length
30
- assert_equal [2, 7], fragment.position
31
- end
32
- end
26
+ it "parses empty arguments" do
27
+ strings = [
28
+ "{ field { inner } }",
29
+ "{ field() { inner }}",
30
+ ]
31
+ strings.each do |query_str|
32
+ doc = subject.parse(query_str)
33
+ field = doc.definitions.first.selections.first
34
+ assert_equal 0, field.arguments.length
35
+ assert_equal 1, field.selections.length
33
36
  end
34
37
  end
38
+
39
+ it "parses the test schema" do
40
+ schema = DummySchema
41
+ schema_string = GraphQL::Schema::Printer.print_schema(schema)
42
+ document = subject.parse(schema_string)
43
+ assert_equal schema_string, document.to_query_string
44
+ end
35
45
  end
@@ -9,7 +9,7 @@ describe GraphQL::ListType do
9
9
 
10
10
  describe "validate_input with bad input" do
11
11
  let(:bad_num) { "bad_num" }
12
- let(:result) { float_list.validate_input([bad_num, 2.0, 3.0]) }
12
+ let(:result) { float_list.validate_input([bad_num, 2.0, 3.0], PermissiveWarden) }
13
13
 
14
14
  it "returns an invalid result" do
15
15
  assert(!result.valid?)
@@ -24,7 +24,7 @@ describe GraphQL::ListType do
24
24
  end
25
25
 
26
26
  it "has the correct explanation" do
27
- expected = GraphQL::FLOAT_TYPE.validate_input(bad_num).problems[0]["explanation"]
27
+ expected = GraphQL::FLOAT_TYPE.validate_input(bad_num, PermissiveWarden).problems[0]["explanation"]
28
28
  actual = result.problems[0]["explanation"]
29
29
  assert_equal(actual, expected)
30
30
  end
@@ -11,6 +11,7 @@ describe GraphQL::Query::Variables do
11
11
  let(:ast_variables) { GraphQL.parse(query_string).definitions.first.variables }
12
12
  let(:variables) { GraphQL::Query::Variables.new(
13
13
  DummySchema,
14
+ GraphQL::Schema::Warden.new(DummySchema, GraphQL::Query::NullExcept),
14
15
  ast_variables,
15
16
  provided_variables)
16
17
  }
@@ -23,7 +23,7 @@ describe GraphQL::ScalarType do
23
23
  end
24
24
 
25
25
  describe "custom scalar errors" do
26
- let(:result) { custom_scalar.validate_input("xyz") }
26
+ let(:result) { custom_scalar.validate_input("xyz", PermissiveWarden) }
27
27
 
28
28
  it "returns an invalid result" do
29
29
  assert !result.valid?
@@ -32,7 +32,7 @@ describe GraphQL::ScalarType do
32
32
  end
33
33
 
34
34
  describe "validate_input with good input" do
35
- let(:result) { GraphQL::INT_TYPE.validate_input(150) }
35
+ let(:result) { GraphQL::INT_TYPE.validate_input(150, PermissiveWarden) }
36
36
 
37
37
  it "returns a valid result" do
38
38
  assert(result.valid?)
@@ -40,7 +40,7 @@ describe GraphQL::ScalarType do
40
40
  end
41
41
 
42
42
  describe "validate_input with bad input" do
43
- let(:result) { GraphQL::INT_TYPE.validate_input("bad num") }
43
+ let(:result) { GraphQL::INT_TYPE.validate_input("bad num", PermissiveWarden) }
44
44
 
45
45
  it "returns an invalid result for bad input" do
46
46
  assert(!result.valid?)