graphql 1.0.0 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/graphql.rb +10 -0
- data/lib/graphql/base_type.rb +8 -5
- data/lib/graphql/compatibility.rb +3 -0
- data/lib/graphql/compatibility/execution_specification.rb +414 -0
- data/lib/graphql/compatibility/query_parser_specification.rb +117 -0
- data/lib/graphql/compatibility/query_parser_specification/parse_error_specification.rb +81 -0
- data/lib/graphql/compatibility/query_parser_specification/query_assertions.rb +78 -0
- data/lib/graphql/compatibility/schema_parser_specification.rb +239 -0
- data/lib/graphql/define/instance_definable.rb +53 -21
- data/lib/graphql/directive.rb +1 -1
- data/lib/graphql/enum_type.rb +31 -8
- data/lib/graphql/execution/directive_checks.rb +0 -6
- data/lib/graphql/input_object_type.rb +6 -4
- data/lib/graphql/introspection/arguments_field.rb +3 -1
- data/lib/graphql/introspection/enum_values_field.rb +10 -5
- data/lib/graphql/introspection/fields_field.rb +1 -1
- data/lib/graphql/introspection/input_fields_field.rb +2 -2
- data/lib/graphql/introspection/interfaces_field.rb +7 -1
- data/lib/graphql/introspection/possible_types_field.rb +1 -1
- data/lib/graphql/introspection/schema_type.rb +1 -1
- data/lib/graphql/introspection/type_by_name_field.rb +4 -2
- data/lib/graphql/introspection/type_type.rb +7 -6
- data/lib/graphql/language/lexer.rl +0 -4
- data/lib/graphql/language/parser.rb +1 -1
- data/lib/graphql/language/parser.y +1 -1
- data/lib/graphql/list_type.rb +3 -4
- data/lib/graphql/non_null_type.rb +4 -8
- data/lib/graphql/object_type.rb +5 -3
- data/lib/graphql/query.rb +48 -12
- data/lib/graphql/query/context.rb +7 -1
- data/lib/graphql/query/serial_execution/execution_context.rb +8 -3
- data/lib/graphql/query/serial_execution/field_resolution.rb +8 -5
- data/lib/graphql/query/serial_execution/operation_resolution.rb +2 -2
- data/lib/graphql/query/serial_execution/selection_resolution.rb +4 -21
- data/lib/graphql/query/serial_execution/value_resolution.rb +59 -99
- data/lib/graphql/query/variables.rb +7 -2
- data/lib/graphql/scalar_type.rb +1 -1
- data/lib/graphql/schema.rb +49 -18
- data/lib/graphql/schema/build_from_definition.rb +248 -0
- data/lib/graphql/schema/instrumented_field_map.rb +23 -0
- data/lib/graphql/schema/loader.rb +4 -11
- data/lib/graphql/schema/possible_types.rb +4 -2
- data/lib/graphql/schema/printer.rb +1 -1
- data/lib/graphql/schema/type_expression.rb +4 -4
- data/lib/graphql/schema/type_map.rb +1 -1
- data/lib/graphql/schema/validation.rb +4 -0
- data/lib/graphql/schema/warden.rb +114 -0
- data/lib/graphql/static_validation/literal_validator.rb +10 -7
- data/lib/graphql/static_validation/rules/argument_literals_are_compatible.rb +1 -3
- data/lib/graphql/static_validation/rules/arguments_are_defined.rb +1 -1
- data/lib/graphql/static_validation/rules/fields_are_defined_on_type.rb +1 -1
- data/lib/graphql/static_validation/rules/fragment_spreads_are_possible.rb +3 -14
- data/lib/graphql/static_validation/rules/fragment_types_exist.rb +1 -1
- data/lib/graphql/static_validation/rules/fragments_are_on_composite_types.rb +1 -1
- data/lib/graphql/static_validation/rules/variable_default_values_are_correctly_typed.rb +3 -4
- data/lib/graphql/static_validation/rules/variables_are_input_types.rb +2 -1
- data/lib/graphql/static_validation/validation_context.rb +7 -1
- data/lib/graphql/union_type.rb +6 -3
- data/lib/graphql/unresolved_type_error.rb +1 -2
- data/lib/graphql/version.rb +1 -1
- data/readme.md +1 -5
- data/spec/graphql/compatibility/execution_specification_spec.rb +3 -0
- data/spec/graphql/compatibility/query_parser_specification_spec.rb +5 -0
- data/spec/graphql/compatibility/schema_parser_specification_spec.rb +5 -0
- data/spec/graphql/define/instance_definable_spec.rb +20 -0
- data/spec/graphql/directive_spec.rb +11 -0
- data/spec/graphql/enum_type_spec.rb +20 -1
- data/spec/graphql/input_object_type_spec.rb +9 -9
- data/spec/graphql/introspection/directive_type_spec.rb +4 -4
- data/spec/graphql/introspection/input_value_type_spec.rb +6 -6
- data/spec/graphql/introspection/type_type_spec.rb +28 -26
- data/spec/graphql/language/parser_spec.rb +27 -17
- data/spec/graphql/list_type_spec.rb +2 -2
- data/spec/graphql/query/variables_spec.rb +1 -0
- data/spec/graphql/scalar_type_spec.rb +3 -3
- data/spec/graphql/schema/build_from_definition_spec.rb +693 -0
- data/spec/graphql/schema/type_expression_spec.rb +3 -3
- data/spec/graphql/schema/validation_spec.rb +7 -3
- data/spec/graphql/schema/warden_spec.rb +510 -0
- data/spec/graphql/schema_spec.rb +129 -0
- data/spec/graphql/static_validation/rules/argument_literals_are_compatible_spec.rb +1 -1
- data/spec/graphql/static_validation/type_stack_spec.rb +3 -3
- data/spec/spec_helper.rb +27 -1
- data/spec/support/dairy_app.rb +8 -5
- metadata +21 -3
- data/lib/graphql/language/parser_tests.rb +0 -809
@@ -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"=>{"
|
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"=>{"
|
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" =>
|
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"=>{
|
33
|
+
{"name"=>"fatContent", "type"=>{"kind"=>"SCALAR", "name" => "Float"}, "defaultValue"=>"0.3",
|
34
34
|
"description" => "How much fat it has"},
|
35
|
-
{"name"=>"organic", "type"=>{
|
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'] == '
|
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" => { "
|
18
|
-
{"name"=>"id", "isDeprecated" => false, "type" => { "
|
19
|
-
{"name"=>"nullableCheese", "isDeprecated"=>false, "type"=>{"name"=>"Cheese", "ofType"=>nil}},
|
20
|
-
{"name"=>"origin", "isDeprecated" => false, "type" => { "
|
21
|
-
{"name"=>"similarCheese", "isDeprecated"=>false, "type"=>{"name"=>"Cheese", "ofType"=>nil}},
|
22
|
-
{"name"=>"source", "isDeprecated" => false, "type" => { "
|
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",
|
27
|
-
{"name"=>"
|
28
|
-
{"name"=>"
|
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"=>{"
|
45
|
-
{"type"=>{"name"=>"String", "ofType"=>nil}},
|
46
|
-
{"type"=>{"
|
47
|
-
{"type"=>{"
|
48
|
-
{"type"=>{"
|
49
|
-
{"type"=>{"
|
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"=>{"
|
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"=>{
|
117
|
-
{"name"=>"originDairy", "type"=>{"name"=>"String"}, "defaultValue"=>"\"Sugar Hollow Dairy\""},
|
118
|
-
{"name"=>"fatContent", "type"=>{
|
119
|
-
{"name"=>"organic", "type"=>{
|
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
|
-
|
17
|
-
it "parses queries" do
|
18
|
-
assert document
|
19
|
-
end
|
14
|
+
let(:fragment) { document.definitions.first }
|
20
15
|
|
21
|
-
|
22
|
-
|
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
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
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?)
|