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.
- checksums.yaml +4 -4
- data/lib/graphql.rb +31 -41
- data/lib/graphql/argument.rb +23 -21
- data/lib/graphql/base_type.rb +5 -8
- data/lib/graphql/define/assign_argument.rb +5 -2
- data/lib/graphql/define/type_definer.rb +2 -1
- data/lib/graphql/directive.rb +34 -36
- data/lib/graphql/directive/include_directive.rb +3 -7
- data/lib/graphql/directive/skip_directive.rb +3 -7
- data/lib/graphql/enum_type.rb +78 -76
- data/lib/graphql/execution_error.rb +1 -3
- data/lib/graphql/field.rb +99 -95
- data/lib/graphql/input_object_type.rb +49 -47
- data/lib/graphql/interface_type.rb +31 -34
- data/lib/graphql/introspection.rb +19 -18
- data/lib/graphql/introspection/directive_location_enum.rb +8 -0
- data/lib/graphql/introspection/directive_type.rb +1 -3
- data/lib/graphql/introspection/field_type.rb +1 -1
- data/lib/graphql/introspection/fields_field.rb +1 -1
- data/lib/graphql/introspection/introspection_query.rb +1 -3
- data/lib/graphql/introspection/possible_types_field.rb +7 -1
- data/lib/graphql/introspection/schema_field.rb +13 -9
- data/lib/graphql/introspection/type_by_name_field.rb +13 -17
- data/lib/graphql/introspection/typename_field.rb +12 -8
- data/lib/graphql/language.rb +5 -9
- data/lib/graphql/language/lexer.rb +668 -0
- data/lib/graphql/language/lexer.rl +149 -0
- data/lib/graphql/language/parser.rb +842 -116
- data/lib/graphql/language/parser.y +264 -0
- data/lib/graphql/language/token.rb +21 -0
- data/lib/graphql/list_type.rb +33 -31
- data/lib/graphql/non_null_type.rb +33 -31
- data/lib/graphql/object_type.rb +52 -55
- data/lib/graphql/query.rb +83 -80
- data/lib/graphql/query/context.rb +5 -1
- data/lib/graphql/query/directive_resolution.rb +16 -0
- data/lib/graphql/query/executor.rb +3 -3
- data/lib/graphql/query/input_validation_result.rb +17 -15
- data/lib/graphql/query/serial_execution.rb +5 -5
- data/lib/graphql/query/serial_execution/execution_context.rb +4 -3
- data/lib/graphql/query/serial_execution/selection_resolution.rb +19 -21
- data/lib/graphql/query/serial_execution/value_resolution.rb +1 -1
- data/lib/graphql/query/type_resolver.rb +22 -18
- data/lib/graphql/query/variable_validation_error.rb +14 -12
- data/lib/graphql/schema.rb +87 -77
- data/lib/graphql/schema/each_item_validator.rb +16 -12
- data/lib/graphql/schema/field_validator.rb +14 -10
- data/lib/graphql/schema/implementation_validator.rb +26 -22
- data/lib/graphql/schema/middleware_chain.rb +2 -1
- data/lib/graphql/schema/possible_types.rb +34 -0
- data/lib/graphql/schema/printer.rb +122 -120
- data/lib/graphql/schema/type_expression.rb +1 -0
- data/lib/graphql/schema/type_map.rb +3 -10
- data/lib/graphql/schema/type_reducer.rb +65 -81
- data/lib/graphql/schema/type_validator.rb +45 -41
- data/lib/graphql/static_validation.rb +7 -9
- data/lib/graphql/static_validation/all_rules.rb +29 -24
- data/lib/graphql/static_validation/arguments_validator.rb +39 -35
- data/lib/graphql/static_validation/literal_validator.rb +44 -40
- data/lib/graphql/static_validation/message.rb +30 -26
- data/lib/graphql/static_validation/rules/argument_literals_are_compatible.rb +15 -11
- data/lib/graphql/static_validation/rules/arguments_are_defined.rb +14 -10
- data/lib/graphql/static_validation/rules/directives_are_defined.rb +16 -12
- data/lib/graphql/static_validation/rules/directives_are_in_valid_locations.rb +59 -0
- data/lib/graphql/static_validation/rules/fields_are_defined_on_type.rb +25 -21
- data/lib/graphql/static_validation/rules/fields_have_appropriate_selections.rb +28 -24
- data/lib/graphql/static_validation/rules/fields_will_merge.rb +84 -80
- data/lib/graphql/static_validation/rules/fragment_spreads_are_possible.rb +49 -43
- data/lib/graphql/static_validation/rules/fragment_types_exist.rb +22 -17
- data/lib/graphql/static_validation/rules/fragments_are_finite.rb +19 -15
- data/lib/graphql/static_validation/rules/fragments_are_on_composite_types.rb +25 -20
- data/lib/graphql/static_validation/rules/fragments_are_used.rb +36 -23
- data/lib/graphql/static_validation/rules/required_arguments_are_present.rb +29 -25
- data/lib/graphql/static_validation/rules/variable_default_values_are_correctly_typed.rb +21 -17
- data/lib/graphql/static_validation/rules/variable_usages_are_allowed.rb +79 -70
- data/lib/graphql/static_validation/rules/variables_are_input_types.rb +24 -20
- data/lib/graphql/static_validation/rules/variables_are_used_and_defined.rb +122 -119
- data/lib/graphql/static_validation/type_stack.rb +138 -129
- data/lib/graphql/static_validation/validator.rb +29 -25
- data/lib/graphql/type_kinds.rb +42 -40
- data/lib/graphql/union_type.rb +22 -16
- data/lib/graphql/version.rb +1 -1
- data/readme.md +12 -27
- data/spec/graphql/base_type_spec.rb +3 -3
- data/spec/graphql/directive_spec.rb +10 -18
- data/spec/graphql/enum_type_spec.rb +7 -7
- data/spec/graphql/execution_error_spec.rb +1 -1
- data/spec/graphql/field_spec.rb +14 -13
- data/spec/graphql/id_type_spec.rb +6 -6
- data/spec/graphql/input_object_type_spec.rb +39 -39
- data/spec/graphql/interface_type_spec.rb +16 -32
- data/spec/graphql/introspection/directive_type_spec.rb +5 -9
- data/spec/graphql/introspection/input_value_type_spec.rb +10 -4
- data/spec/graphql/introspection/introspection_query_spec.rb +2 -2
- data/spec/graphql/introspection/schema_type_spec.rb +2 -2
- data/spec/graphql/introspection/type_type_spec.rb +34 -6
- data/spec/graphql/language/parser_spec.rb +299 -105
- data/spec/graphql/language/visitor_spec.rb +4 -4
- data/spec/graphql/list_type_spec.rb +11 -11
- data/spec/graphql/object_type_spec.rb +10 -10
- data/spec/graphql/query/arguments_spec.rb +7 -7
- data/spec/graphql/query/context_spec.rb +11 -3
- data/spec/graphql/query/executor_spec.rb +26 -19
- data/spec/graphql/query/serial_execution/execution_context_spec.rb +6 -6
- data/spec/graphql/query/serial_execution/value_resolution_spec.rb +2 -2
- data/spec/graphql/query/type_resolver_spec.rb +3 -3
- data/spec/graphql/query_spec.rb +6 -38
- data/spec/graphql/scalar_type_spec.rb +28 -19
- data/spec/graphql/schema/field_validator_spec.rb +1 -1
- data/spec/graphql/schema/middleware_chain_spec.rb +12 -1
- data/spec/graphql/schema/printer_spec.rb +12 -4
- data/spec/graphql/schema/rescue_middleware_spec.rb +1 -1
- data/spec/graphql/schema/type_expression_spec.rb +2 -2
- data/spec/graphql/schema/type_reducer_spec.rb +21 -36
- data/spec/graphql/schema/type_validator_spec.rb +9 -9
- data/spec/graphql/schema_spec.rb +1 -1
- data/spec/graphql/static_validation/rules/argument_literals_are_compatible_spec.rb +4 -4
- data/spec/graphql/static_validation/rules/arguments_are_defined_spec.rb +4 -4
- data/spec/graphql/static_validation/rules/directives_are_defined_spec.rb +5 -5
- data/spec/graphql/static_validation/rules/directives_are_in_valid_locations_spec.rb +39 -0
- data/spec/graphql/static_validation/rules/fields_are_defined_on_type_spec.rb +5 -5
- data/spec/graphql/static_validation/rules/fields_have_appropriate_selections_spec.rb +4 -4
- data/spec/graphql/static_validation/rules/fields_will_merge_spec.rb +2 -2
- data/spec/graphql/static_validation/rules/fragment_spreads_are_possible_spec.rb +1 -1
- data/spec/graphql/static_validation/rules/fragment_types_exist_spec.rb +2 -2
- data/spec/graphql/static_validation/rules/fragments_are_finite_spec.rb +2 -2
- data/spec/graphql/static_validation/rules/fragments_are_on_composite_types_spec.rb +2 -2
- data/spec/graphql/static_validation/rules/fragments_are_used_spec.rb +3 -3
- data/spec/graphql/static_validation/rules/required_arguments_are_present_spec.rb +3 -3
- data/spec/graphql/static_validation/rules/variable_default_values_are_correctly_typed_spec.rb +5 -5
- data/spec/graphql/static_validation/rules/variable_usages_are_allowed_spec.rb +3 -1
- data/spec/graphql/static_validation/rules/variables_are_input_types_spec.rb +4 -4
- data/spec/graphql/static_validation/rules/variables_are_used_and_defined_spec.rb +3 -3
- data/spec/graphql/static_validation/type_stack_spec.rb +3 -2
- data/spec/graphql/static_validation/validator_spec.rb +26 -6
- data/spec/graphql/union_type_spec.rb +5 -4
- data/spec/spec_helper.rb +2 -5
- data/spec/support/dairy_app.rb +30 -9
- data/spec/support/dairy_data.rb +1 -1
- data/spec/support/star_wars_data.rb +26 -26
- data/spec/support/star_wars_schema.rb +1 -1
- metadata +40 -21
- data/lib/graphql/language/transform.rb +0 -113
- data/lib/graphql/query/directive_chain.rb +0 -44
- data/lib/graphql/repl.rb +0 -27
- data/spec/graphql/language/transform_spec.rb +0 -156
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require "spec_helper"
|
2
2
|
|
3
3
|
describe GraphQL::StaticValidation::FieldsWillMerge do
|
4
4
|
let(:query_string) {"
|
@@ -34,7 +34,7 @@ describe GraphQL::StaticValidation::FieldsWillMerge do
|
|
34
34
|
let(:errors) { validator.validate(query) }
|
35
35
|
let(:error_messages) { errors.map { |e| e["message" ] }}
|
36
36
|
|
37
|
-
it
|
37
|
+
it "finds field naming conflicts" do
|
38
38
|
expected_errors = [
|
39
39
|
"Field 'id' has a directive conflict: [] or [someFlag]?", # different directives
|
40
40
|
"Field 'id' has a directive argument conflict: [] or [{}]?", # not sure this is a great way to handle it but here we are!
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require "spec_helper"
|
2
2
|
|
3
3
|
describe GraphQL::StaticValidation::FragmentTypesExist do
|
4
4
|
let(:query_string) {"
|
@@ -23,7 +23,7 @@ describe GraphQL::StaticValidation::FragmentTypesExist do
|
|
23
23
|
let(:query) { GraphQL::Query.new(DummySchema, query_string) }
|
24
24
|
let(:errors) { validator.validate(query) }
|
25
25
|
|
26
|
-
it
|
26
|
+
it "finds non-existent types on fragments" do
|
27
27
|
assert_equal(2, errors.length)
|
28
28
|
inline_fragment_error = {
|
29
29
|
"message"=>"No such type Something, so it can't be a fragment condition",
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require "spec_helper"
|
2
2
|
|
3
3
|
describe GraphQL::StaticValidation::FragmentsAreFinite do
|
4
4
|
let(:query_string) {%|
|
@@ -28,7 +28,7 @@ describe GraphQL::StaticValidation::FragmentsAreFinite do
|
|
28
28
|
let(:query) { GraphQL::Query.new(DummySchema, query_string) }
|
29
29
|
let(:errors) { validator.validate(query) }
|
30
30
|
|
31
|
-
it
|
31
|
+
it "doesnt allow infinite loops" do
|
32
32
|
expected = [
|
33
33
|
{
|
34
34
|
"message"=>"Fragment sourceField contains an infinite loop",
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require "spec_helper"
|
2
2
|
|
3
3
|
describe GraphQL::StaticValidation::FragmentsAreOnCompositeTypes do
|
4
4
|
let(:query_string) {%|
|
@@ -29,7 +29,7 @@ describe GraphQL::StaticValidation::FragmentsAreOnCompositeTypes do
|
|
29
29
|
let(:query) { GraphQL::Query.new(DummySchema, query_string) }
|
30
30
|
let(:errors) { validator.validate(query) }
|
31
31
|
|
32
|
-
it
|
32
|
+
it "requires Object/Union/Interface fragment types" do
|
33
33
|
expected = [
|
34
34
|
{
|
35
35
|
"message"=>"Invalid fragment on type Boolean (must be Union, Interface or Object)",
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require "spec_helper"
|
2
2
|
|
3
3
|
describe GraphQL::StaticValidation::FragmentsAreUsed do
|
4
4
|
let(:query_string) {"
|
@@ -15,11 +15,11 @@ describe GraphQL::StaticValidation::FragmentsAreUsed do
|
|
15
15
|
let(:query) { GraphQL::Query.new(DummySchema, query_string) }
|
16
16
|
let(:errors) { validator.validate(query) }
|
17
17
|
|
18
|
-
it
|
18
|
+
it "adds errors for unused fragment definitions" do
|
19
19
|
assert_includes(errors, {"message"=>"Fragment unusedFields was defined, but not used", "locations"=>[{"line"=>8, "column"=>5}]})
|
20
20
|
end
|
21
21
|
|
22
|
-
it
|
22
|
+
it "adds errors for undefined fragment spreads" do
|
23
23
|
assert_includes(errors, {"message"=>"Fragment undefinedFields was used, but not defined", "locations"=>[{"line"=>5, "column"=>7}]})
|
24
24
|
end
|
25
25
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require "spec_helper"
|
2
2
|
|
3
3
|
describe GraphQL::StaticValidation::RequiredArgumentsArePresent do
|
4
4
|
let(:query_string) {"
|
@@ -18,7 +18,7 @@ describe GraphQL::StaticValidation::RequiredArgumentsArePresent do
|
|
18
18
|
let(:query) { GraphQL::Query.new(DummySchema, query_string) }
|
19
19
|
let(:errors) { validator.validate(query) }
|
20
20
|
|
21
|
-
it
|
21
|
+
it "finds undefined arguments to fields and directives" do
|
22
22
|
assert_equal(3, errors.length)
|
23
23
|
|
24
24
|
query_root_error = {
|
@@ -35,7 +35,7 @@ describe GraphQL::StaticValidation::RequiredArgumentsArePresent do
|
|
35
35
|
|
36
36
|
directive_error = {
|
37
37
|
"message"=>"Directive 'skip' is missing required arguments: if",
|
38
|
-
"locations"=>[{"line"=>10, "column"=>
|
38
|
+
"locations"=>[{"line"=>10, "column"=>10}]
|
39
39
|
}
|
40
40
|
assert_includes(errors, directive_error)
|
41
41
|
end
|
data/spec/graphql/static_validation/rules/variable_default_values_are_correctly_typed_spec.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require "spec_helper"
|
2
2
|
|
3
3
|
describe GraphQL::StaticValidation::VariableDefaultValuesAreCorrectlyTyped do
|
4
4
|
let(:query_string) {%|
|
@@ -24,19 +24,19 @@ describe GraphQL::StaticValidation::VariableDefaultValuesAreCorrectlyTyped do
|
|
24
24
|
expected = [
|
25
25
|
{
|
26
26
|
"message"=>"Default value for $badFloat doesn't match type Float",
|
27
|
-
"locations"=>[{"line"=>6, "column"=>
|
27
|
+
"locations"=>[{"line"=>6, "column"=>7}]
|
28
28
|
},
|
29
29
|
{
|
30
30
|
"message"=>"Default value for $badInt doesn't match type Int",
|
31
|
-
"locations"=>[{"line"=>7, "column"=>
|
31
|
+
"locations"=>[{"line"=>7, "column"=>7}]
|
32
32
|
},
|
33
33
|
{
|
34
34
|
"message"=>"Default value for $badInput doesn't match type DairyProductInput",
|
35
|
-
"locations"=>[{"line"=>9, "column"=>
|
35
|
+
"locations"=>[{"line"=>9, "column"=>7}]
|
36
36
|
},
|
37
37
|
{
|
38
38
|
"message"=>"Non-null variable $nonNull can't have a default value",
|
39
|
-
"locations"=>[{"line"=>10, "column"=>
|
39
|
+
"locations"=>[{"line"=>10, "column"=>7}]
|
40
40
|
}
|
41
41
|
]
|
42
42
|
assert_equal(expected, errors)
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require "spec_helper"
|
2
2
|
|
3
3
|
describe GraphQL::StaticValidation::VariableUsagesAreAllowed do
|
4
4
|
let(:query_string) {'
|
@@ -20,6 +20,8 @@ describe GraphQL::StaticValidation::VariableUsagesAreAllowed do
|
|
20
20
|
similarCheese(source: $goodAnimals)
|
21
21
|
other: similarCheese(source: $badAnimals)
|
22
22
|
tooDeep: similarCheese(source: $deepAnimals)
|
23
|
+
nullableCheese(source: $goodAnimals)
|
24
|
+
deeplyNullableCheese(source: $deepAnimals)
|
23
25
|
}
|
24
26
|
|
25
27
|
milk(id: 1) {
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require "spec_helper"
|
2
2
|
|
3
3
|
describe GraphQL::StaticValidation::VariablesAreInputTypes do
|
4
4
|
let(:query_string) {'
|
@@ -21,15 +21,15 @@ describe GraphQL::StaticValidation::VariablesAreInputTypes do
|
|
21
21
|
expected = [
|
22
22
|
{
|
23
23
|
"message"=>"AnimalProduct isn't a valid input type (on $interface)",
|
24
|
-
"locations"=>[{"line"=>5, "column"=>
|
24
|
+
"locations"=>[{"line"=>5, "column"=>7}]
|
25
25
|
},
|
26
26
|
{
|
27
27
|
"message"=>"Milk isn't a valid input type (on $object)",
|
28
|
-
"locations"=>[{"line"=>6, "column"=>
|
28
|
+
"locations"=>[{"line"=>6, "column"=>7}]
|
29
29
|
},
|
30
30
|
{
|
31
31
|
"message"=>"Cheese isn't a valid input type (on $objects)",
|
32
|
-
"locations"=>[{"line"=>7, "column"=>
|
32
|
+
"locations"=>[{"line"=>7, "column"=>7}]
|
33
33
|
}
|
34
34
|
]
|
35
35
|
assert_equal(expected, errors)
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require "spec_helper"
|
2
2
|
|
3
3
|
describe GraphQL::StaticValidation::VariablesAreUsedAndDefined do
|
4
4
|
let(:query_string) {'
|
@@ -41,11 +41,11 @@ describe GraphQL::StaticValidation::VariablesAreUsedAndDefined do
|
|
41
41
|
},
|
42
42
|
{
|
43
43
|
"message"=>"Variable $undefinedVar is used by getCheese but not declared",
|
44
|
-
"locations"=>[{"line"=>11, "column"=>
|
44
|
+
"locations"=>[{"line"=>11, "column"=>29}]
|
45
45
|
},
|
46
46
|
{
|
47
47
|
"message"=>"Variable $undefinedFragmentVar is used by innerCheeseFields but not declared",
|
48
|
-
"locations"=>[{"line"=>24, "column"=>
|
48
|
+
"locations"=>[{"line"=>24, "column"=>26}]
|
49
49
|
},
|
50
50
|
]
|
51
51
|
assert_equal(expected, errors)
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require "spec_helper"
|
2
2
|
|
3
3
|
class TypeCheckValidator
|
4
4
|
def self.checks
|
@@ -24,7 +24,8 @@ describe GraphQL::StaticValidation::TypeStack do
|
|
24
24
|
let(:validator) { GraphQL::StaticValidation::Validator.new(schema: DummySchema, rules: [TypeCheckValidator]) }
|
25
25
|
let(:query) { GraphQL::Query.new(DummySchema, query_string) }
|
26
26
|
|
27
|
-
|
27
|
+
|
28
|
+
it "stores up types" do
|
28
29
|
validator.validate(query)
|
29
30
|
expected = [
|
30
31
|
["Query", "Cheese"],
|
@@ -1,13 +1,15 @@
|
|
1
|
-
require
|
1
|
+
require "spec_helper"
|
2
2
|
|
3
3
|
describe GraphQL::StaticValidation::Validator do
|
4
4
|
let(:validator) { GraphQL::StaticValidation::Validator.new(schema: DummySchema) }
|
5
5
|
let(:query) { GraphQL::Query.new(DummySchema, query_string) }
|
6
6
|
let(:errors) { validator.validate(query) }
|
7
7
|
|
8
|
-
describe 'validation order' do
|
9
8
|
|
10
|
-
|
9
|
+
describe "validation order" do
|
10
|
+
let(:document) { GraphQL.parse(query_string)}
|
11
|
+
|
12
|
+
describe "fields & arguments" do
|
11
13
|
let(:query_string) { %|
|
12
14
|
query getCheese($id: Int!) {
|
13
15
|
cheese(id: $undefinedVar, bogusArg: true) {
|
@@ -23,13 +25,13 @@ describe GraphQL::StaticValidation::Validator do
|
|
23
25
|
}
|
24
26
|
|}
|
25
27
|
|
26
|
-
it
|
28
|
+
it "handles args on invalid fields" do
|
27
29
|
# nonsenseField, nonsenseArg, bogusField, bogusArg, undefinedVar
|
28
30
|
assert_equal(5, errors.length)
|
29
31
|
end
|
30
32
|
end
|
31
33
|
|
32
|
-
describe
|
34
|
+
describe "infinite fragments" do
|
33
35
|
let(:query_string) { %|
|
34
36
|
query getCheese {
|
35
37
|
cheese(id: 1) {
|
@@ -41,7 +43,25 @@ describe GraphQL::StaticValidation::Validator do
|
|
41
43
|
}
|
42
44
|
|}
|
43
45
|
|
44
|
-
it
|
46
|
+
it "handles infinite fragment spreads" do
|
47
|
+
assert_equal(1, errors.length)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
describe "fragment spreads with no selections" do
|
52
|
+
let(:query_string) {%|
|
53
|
+
query SimpleQuery {
|
54
|
+
cheese(id: 1) {
|
55
|
+
# OK:
|
56
|
+
... {
|
57
|
+
id
|
58
|
+
}
|
59
|
+
# NOT OK:
|
60
|
+
...cheeseFields
|
61
|
+
}
|
62
|
+
}
|
63
|
+
|}
|
64
|
+
it "marks an error" do
|
45
65
|
assert_equal(1, errors.length)
|
46
66
|
end
|
47
67
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require "spec_helper"
|
2
2
|
|
3
3
|
describe GraphQL::UnionType do
|
4
4
|
let(:type_1) { OpenStruct.new(kind: GraphQL::TypeKinds::OBJECT)}
|
@@ -12,12 +12,13 @@ describe GraphQL::UnionType do
|
|
12
12
|
possible_types(types)
|
13
13
|
}
|
14
14
|
}
|
15
|
-
it
|
15
|
+
it "has a name" do
|
16
16
|
assert_equal("MyUnion", union.name)
|
17
17
|
end
|
18
18
|
|
19
|
-
|
20
|
-
|
19
|
+
|
20
|
+
it "infers type from an object" do
|
21
|
+
assert_equal(CheeseType, DairyProductUnion.resolve_type(CHEESES[1], OpenStruct.new(schema: DummySchema)))
|
21
22
|
end
|
22
23
|
|
23
24
|
it '#include? returns true if type in in possible_types' do
|
data/spec/spec_helper.rb
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
require "codeclimate-test-reporter"
|
2
2
|
CodeClimate::TestReporter.start
|
3
|
-
require
|
3
|
+
require "graphql"
|
4
4
|
require "benchmark"
|
5
5
|
require "minitest/autorun"
|
6
6
|
require "minitest/focus"
|
7
7
|
require "minitest/reporters"
|
8
|
-
require
|
8
|
+
require "pry"
|
9
9
|
Minitest::Reporters.use! Minitest::Reporters::SpecReporter.new
|
10
10
|
|
11
11
|
Minitest::Spec.make_my_diffs_pretty!
|
@@ -16,6 +16,3 @@ Minitest.backtrace_filter = Minitest::BacktraceFilter.new
|
|
16
16
|
|
17
17
|
# # Load support files
|
18
18
|
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
|
19
|
-
|
20
|
-
require 'parslet'
|
21
|
-
require 'parslet/convenience'
|
data/spec/support/dairy_app.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
require_relative
|
1
|
+
require_relative "./dairy_data"
|
2
2
|
|
3
3
|
class NoSuchDairyError < StandardError; end
|
4
4
|
|
@@ -51,6 +51,16 @@ CheeseType = GraphQL::ObjectType.define do
|
|
51
51
|
}
|
52
52
|
end
|
53
53
|
|
54
|
+
field :nullableCheese, -> { CheeseType }, "Cheeses like this one" do
|
55
|
+
argument :source, types[!DairyAnimalEnum]
|
56
|
+
resolve -> (t, a, c) { raise("NotImplemented") }
|
57
|
+
end
|
58
|
+
|
59
|
+
field :deeplyNullableCheese, -> { CheeseType }, "Cheeses like this one" do
|
60
|
+
argument :source, types[types[DairyAnimalEnum]]
|
61
|
+
resolve -> (t, a, c) { raise("NotImplemented") }
|
62
|
+
end
|
63
|
+
|
54
64
|
field :fatContent, property: :fat_content do
|
55
65
|
type(!GraphQL::FLOAT_TYPE)
|
56
66
|
description("Percentage which is milkfat")
|
@@ -59,7 +69,7 @@ CheeseType = GraphQL::ObjectType.define do
|
|
59
69
|
end
|
60
70
|
|
61
71
|
MilkType = GraphQL::ObjectType.define do
|
62
|
-
name
|
72
|
+
name "Milk"
|
63
73
|
description "Dairy beverage"
|
64
74
|
interfaces [EdibleInterface, AnimalProductInterface]
|
65
75
|
field :id, !types.ID
|
@@ -75,14 +85,14 @@ end
|
|
75
85
|
|
76
86
|
# No actual data; This type is an "orphan", only accessible through Interfaces
|
77
87
|
HoneyType = GraphQL::ObjectType.define do
|
78
|
-
name
|
88
|
+
name "Honey"
|
79
89
|
description "Sweet, dehydrated bee barf"
|
80
90
|
interfaces [EdibleInterface, AnimalProductInterface]
|
81
91
|
end
|
82
92
|
|
83
93
|
DairyType = GraphQL::ObjectType.define do
|
84
|
-
name
|
85
|
-
description
|
94
|
+
name "Dairy"
|
95
|
+
description "A farm where milk is harvested and cheese is produced"
|
86
96
|
field :id, !types.ID
|
87
97
|
field :cheese, CheeseType
|
88
98
|
field :milks, types[MilkType]
|
@@ -101,8 +111,8 @@ DairyProductUnion = GraphQL::UnionType.define do
|
|
101
111
|
end
|
102
112
|
|
103
113
|
CowType = GraphQL::ObjectType.define do
|
104
|
-
name
|
105
|
-
description
|
114
|
+
name "Cow"
|
115
|
+
description "A farm where milk is harvested and cheese is produced"
|
106
116
|
field :id, !types.ID
|
107
117
|
field :name, types.String
|
108
118
|
field :last_produced_dairy, DairyProductUnion
|
@@ -122,12 +132,22 @@ DairyProductInputType = GraphQL::InputObjectType.define {
|
|
122
132
|
name "DairyProductInput"
|
123
133
|
description "Properties for finding a dairy product"
|
124
134
|
input_field :source, !DairyAnimalEnum do
|
135
|
+
# ensure we can define description in block
|
125
136
|
description "Where it came from"
|
126
137
|
end
|
127
138
|
|
128
|
-
input_field :originDairy, types.String, "Dairy which produced it", default_value: "Sugar Hollow Dairy"
|
139
|
+
input_field :originDairy, types.String, "Dairy which produced it", default_value: "Sugar Hollow Dairy" do
|
140
|
+
description "Ignored because arg takes precedence"
|
141
|
+
default_value "Ignored because keyword arg takes precedence"
|
142
|
+
end
|
143
|
+
|
144
|
+
input_field :fatContent, types.Float, "How much fat it has" do
|
145
|
+
# ensure we can define default in block
|
146
|
+
default_value 0.3
|
147
|
+
end
|
129
148
|
|
130
|
-
|
149
|
+
# ensure default can be false
|
150
|
+
input_field :organic, types.Boolean, default_value: false
|
131
151
|
}
|
132
152
|
|
133
153
|
|
@@ -260,5 +280,6 @@ DummySchema = GraphQL::Schema.new(
|
|
260
280
|
mutation: MutationType,
|
261
281
|
subscription: SubscriptionType,
|
262
282
|
max_depth: 5,
|
283
|
+
types: [HoneyType],
|
263
284
|
)
|
264
285
|
DummySchema.rescue_from(NoSuchDairyError) { |err| err.message }
|
data/spec/support/dairy_data.rb
CHANGED
@@ -1,38 +1,38 @@
|
|
1
1
|
luke = OpenStruct.new({
|
2
|
-
id:
|
3
|
-
name:
|
4
|
-
friends: [
|
2
|
+
id: "1000",
|
3
|
+
name: "Luke Skywalker",
|
4
|
+
friends: ["1002", "1003", "2000", "2001"],
|
5
5
|
appearsIn: [4, 5, 6],
|
6
|
-
homePlanet:
|
6
|
+
homePlanet: "Tatooine",
|
7
7
|
})
|
8
8
|
|
9
9
|
vader = OpenStruct.new({
|
10
|
-
id:
|
11
|
-
name:
|
12
|
-
friends: [
|
10
|
+
id: "1001",
|
11
|
+
name: "Darth Vader",
|
12
|
+
friends: ["1004"],
|
13
13
|
appearsIn: [4, 5, 6],
|
14
|
-
homePlanet:
|
14
|
+
homePlanet: "Tatooine",
|
15
15
|
})
|
16
16
|
|
17
17
|
han = OpenStruct.new({
|
18
|
-
id:
|
19
|
-
name:
|
20
|
-
friends: [
|
18
|
+
id: "1002",
|
19
|
+
name: "Han Solo",
|
20
|
+
friends: ["1000", "1003", "2001"],
|
21
21
|
appearsIn: [4, 5, 6],
|
22
22
|
})
|
23
23
|
|
24
24
|
leia = OpenStruct.new({
|
25
|
-
id:
|
26
|
-
name:
|
27
|
-
friends: [
|
25
|
+
id: "1003",
|
26
|
+
name: "Leia Organa",
|
27
|
+
friends: ["1000", "1002", "2000", "2001"],
|
28
28
|
appearsIn: [4, 5, 6],
|
29
|
-
homePlanet:
|
29
|
+
homePlanet: "Alderaan",
|
30
30
|
})
|
31
31
|
|
32
32
|
tarkin = OpenStruct.new({
|
33
|
-
id:
|
34
|
-
name:
|
35
|
-
friends: [
|
33
|
+
id: "1004",
|
34
|
+
name: "Wilhuff Tarkin",
|
35
|
+
friends: ["1001"],
|
36
36
|
appearsIn: [4],
|
37
37
|
})
|
38
38
|
|
@@ -45,19 +45,19 @@ HUMAN_DATA = {
|
|
45
45
|
}
|
46
46
|
|
47
47
|
threepio = OpenStruct.new({
|
48
|
-
id:
|
49
|
-
name:
|
50
|
-
friends: [
|
48
|
+
id: "2000",
|
49
|
+
name: "C-3PO",
|
50
|
+
friends: ["1000", "1002", "1003", "2001"],
|
51
51
|
appearsIn: [4, 5, 6],
|
52
|
-
primaryFunction:
|
52
|
+
primaryFunction: "Protocol",
|
53
53
|
})
|
54
54
|
|
55
55
|
artoo = OpenStruct.new({
|
56
|
-
id:
|
57
|
-
name:
|
58
|
-
friends: [
|
56
|
+
id: "2001",
|
57
|
+
name: "R2-D2",
|
58
|
+
friends: ["1000", "1002", "1003"],
|
59
59
|
appearsIn: [4, 5, 6],
|
60
|
-
primaryFunction:
|
60
|
+
primaryFunction: "Astromech",
|
61
61
|
})
|
62
62
|
|
63
63
|
DROID_DATA = {
|