graphql 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (89) hide show
  1. checksums.yaml +4 -4
  2. data/lib/graph_ql/{types → definition_helpers}/argument_definer.rb +0 -0
  3. data/lib/graph_ql/definition_helpers/definable.rb +18 -0
  4. data/lib/graph_ql/{types → definition_helpers}/field_definer.rb +0 -0
  5. data/lib/graph_ql/definition_helpers/forwardable.rb +10 -0
  6. data/lib/graph_ql/definition_helpers/non_null_with_bang.rb +9 -0
  7. data/lib/graph_ql/definition_helpers/string_named_hash.rb +12 -0
  8. data/lib/graph_ql/{types → definition_helpers}/type_definer.rb +1 -0
  9. data/lib/graph_ql/directive.rb +9 -5
  10. data/lib/graph_ql/directives/directive_chain.rb +1 -1
  11. data/lib/graph_ql/field.rb +1 -5
  12. data/lib/graph_ql/parser/transform.rb +1 -3
  13. data/lib/graph_ql/query.rb +14 -3
  14. data/lib/graph_ql/query/arguments.rb +6 -5
  15. data/lib/graph_ql/query/field_resolution_strategy.rb +3 -3
  16. data/lib/graph_ql/{types → scalars}/boolean_type.rb +0 -0
  17. data/lib/graph_ql/{types → scalars}/float_type.rb +1 -1
  18. data/lib/graph_ql/scalars/id_type.rb +6 -0
  19. data/lib/graph_ql/{types → scalars}/int_type.rb +0 -0
  20. data/lib/graph_ql/{types → scalars}/scalar_type.rb +0 -4
  21. data/lib/graph_ql/{types → scalars}/string_type.rb +0 -0
  22. data/lib/graph_ql/static_validation.rb +7 -10
  23. data/lib/graph_ql/static_validation/all_rules.rb +23 -0
  24. data/lib/graph_ql/static_validation/literal_validator.rb +0 -3
  25. data/lib/graph_ql/static_validation/{argument_literals_are_compatible.rb → rules/argument_literals_are_compatible.rb} +0 -0
  26. data/lib/graph_ql/static_validation/{arguments_are_defined.rb → rules/arguments_are_defined.rb} +5 -0
  27. data/lib/graph_ql/static_validation/{directives_are_defined.rb → rules/directives_are_defined.rb} +0 -0
  28. data/lib/graph_ql/static_validation/{fields_are_defined_on_type.rb → rules/fields_are_defined_on_type.rb} +0 -0
  29. data/lib/graph_ql/static_validation/{fields_have_appropriate_selections.rb → rules/fields_have_appropriate_selections.rb} +0 -0
  30. data/lib/graph_ql/static_validation/{fields_will_merge.rb → rules/fields_will_merge.rb} +13 -5
  31. data/lib/graph_ql/static_validation/rules/fragment_spreads_are_possible.rb +50 -0
  32. data/lib/graph_ql/static_validation/{fragment_types_exist.rb → rules/fragment_types_exist.rb} +0 -0
  33. data/lib/graph_ql/static_validation/rules/fragments_are_finite.rb +23 -0
  34. data/lib/graph_ql/static_validation/rules/fragments_are_on_composite_types.rb +27 -0
  35. data/lib/graph_ql/static_validation/{fragments_are_used.rb → rules/fragments_are_used.rb} +0 -0
  36. data/lib/graph_ql/static_validation/{required_arguments_are_present.rb → rules/required_arguments_are_present.rb} +0 -0
  37. data/lib/graph_ql/static_validation/rules/variable_default_values_are_correctly_typed.rb +24 -0
  38. data/lib/graph_ql/static_validation/rules/variable_usages_are_allowed.rb +47 -0
  39. data/lib/graph_ql/static_validation/rules/variables_are_input_types.rb +27 -0
  40. data/lib/graph_ql/static_validation/rules/variables_are_used_and_defined.rb +31 -0
  41. data/lib/graph_ql/static_validation/type_stack.rb +13 -1
  42. data/lib/graph_ql/static_validation/validator.rb +14 -18
  43. data/lib/graph_ql/type_kinds.rb +8 -4
  44. data/lib/graph_ql/{enum.rb → types/enum.rb} +7 -6
  45. data/lib/graph_ql/types/input_object_type.rb +3 -10
  46. data/lib/graph_ql/{interface.rb → types/interface.rb} +0 -4
  47. data/lib/graph_ql/types/list_type.rb +0 -4
  48. data/lib/graph_ql/types/non_null_type.rb +0 -4
  49. data/lib/graph_ql/types/object_type.rb +28 -13
  50. data/lib/graph_ql/{union.rb → types/union.rb} +0 -4
  51. data/lib/graph_ql/version.rb +1 -1
  52. data/lib/graphql.rb +9 -40
  53. data/readme.md +26 -20
  54. data/spec/graph_ql/directive_spec.rb +4 -4
  55. data/spec/graph_ql/introspection/directive_type_spec.rb +2 -2
  56. data/spec/graph_ql/introspection/schema_type_spec.rb +3 -2
  57. data/spec/graph_ql/introspection/type_type_spec.rb +7 -7
  58. data/spec/graph_ql/parser/parser_spec.rb +6 -2
  59. data/spec/graph_ql/query_spec.rb +26 -8
  60. data/spec/graph_ql/scalars/id_type_spec.rb +24 -0
  61. data/spec/graph_ql/schema/type_reducer_spec.rb +1 -0
  62. data/spec/graph_ql/schema/type_validator_spec.rb +1 -1
  63. data/spec/graph_ql/static_validation/{argument_literals_are_compatible_spec.rb → rules/argument_literals_are_compatible_spec.rb} +1 -1
  64. data/spec/graph_ql/static_validation/{arguments_are_defined_spec.rb → rules/arguments_are_defined_spec.rb} +1 -1
  65. data/spec/graph_ql/static_validation/{directives_are_defined_spec.rb → rules/directives_are_defined_spec.rb} +1 -1
  66. data/spec/graph_ql/static_validation/{fields_are_defined_on_type_spec.rb → rules/fields_are_defined_on_type_spec.rb} +1 -1
  67. data/spec/graph_ql/static_validation/{fields_have_appropriate_selections_spec.rb → rules/fields_have_appropriate_selections_spec.rb} +1 -1
  68. data/spec/graph_ql/static_validation/{fields_will_merge_spec.rb → rules/fields_will_merge_spec.rb} +1 -1
  69. data/spec/graph_ql/static_validation/rules/fragment_spreads_are_possible_spec.rb +46 -0
  70. data/spec/graph_ql/static_validation/{fragment_types_exist_spec.rb → rules/fragment_types_exist_spec.rb} +1 -1
  71. data/spec/graph_ql/static_validation/rules/fragments_are_finite_spec.rb +43 -0
  72. data/spec/graph_ql/static_validation/rules/fragments_are_on_composite_types_spec.rb +48 -0
  73. data/spec/graph_ql/static_validation/{fragments_are_used_spec.rb → rules/fragments_are_used_spec.rb} +1 -1
  74. data/spec/graph_ql/static_validation/{required_arguments_are_present_spec.rb → rules/required_arguments_are_present_spec.rb} +1 -1
  75. data/spec/graph_ql/static_validation/rules/variable_default_values_are_correctly_typed_spec.rb +43 -0
  76. data/spec/graph_ql/static_validation/rules/variable_usages_are_allowed_spec.rb +45 -0
  77. data/spec/graph_ql/static_validation/rules/variables_are_input_types_spec.rb +36 -0
  78. data/spec/graph_ql/static_validation/rules/variables_are_used_and_defined_spec.rb +44 -0
  79. data/spec/graph_ql/static_validation/type_stack_spec.rb +2 -2
  80. data/spec/graph_ql/static_validation/validator_spec.rb +44 -5
  81. data/spec/graph_ql/types/enum_spec.rb +10 -0
  82. data/spec/graph_ql/{interface_spec.rb → types/interface_spec.rb} +1 -1
  83. data/spec/graph_ql/types/object_type_spec.rb +13 -0
  84. data/spec/graph_ql/{union_spec.rb → types/union_spec.rb} +0 -0
  85. data/spec/support/dummy_app.rb +7 -6
  86. data/spec/support/dummy_data.rb +3 -3
  87. metadata +74 -46
  88. data/lib/graph_ql/types/non_null_with_bang.rb +0 -5
  89. data/spec/graph_ql/enum_spec.rb +0 -5
@@ -13,7 +13,7 @@ describe GraphQL::StaticValidation::ArgumentsAreDefined do
13
13
  }
14
14
  ")}
15
15
 
16
- let(:validator) { GraphQL::StaticValidation::Validator.new(schema: DummySchema, validators: [GraphQL::StaticValidation::ArgumentsAreDefined]) }
16
+ let(:validator) { GraphQL::StaticValidation::Validator.new(schema: DummySchema, rules: [GraphQL::StaticValidation::ArgumentsAreDefined]) }
17
17
  let(:errors) { validator.validate(document) }
18
18
 
19
19
  it 'finds undefined arguments to fields and directives' do
@@ -13,7 +13,7 @@ describe GraphQL::StaticValidation::DirectivesAreDefined do
13
13
  }
14
14
  ")}
15
15
 
16
- let(:validator) { GraphQL::StaticValidation::Validator.new(schema: DummySchema, validators: [GraphQL::StaticValidation::DirectivesAreDefined]) }
16
+ let(:validator) { GraphQL::StaticValidation::Validator.new(schema: DummySchema, rules: [GraphQL::StaticValidation::DirectivesAreDefined]) }
17
17
  let(:errors) { validator.validate(document) }
18
18
 
19
19
  describe 'non-existent directives' do
@@ -11,7 +11,7 @@ describe GraphQL::StaticValidation::FieldsAreDefinedOnType do
11
11
  fragment cheeseFields on Cheese { fatContent, hogwashField }
12
12
  "}
13
13
 
14
- let(:validator) { GraphQL::StaticValidation::Validator.new(schema: DummySchema, validators: [GraphQL::StaticValidation::FieldsAreDefinedOnType]) }
14
+ let(:validator) { GraphQL::StaticValidation::Validator.new(schema: DummySchema, rules: [GraphQL::StaticValidation::FieldsAreDefinedOnType]) }
15
15
  let(:errors) { validator.validate(GraphQL.parse(query_string)) }
16
16
  let(:error_messages) { errors.map { |e| e["message" ] }}
17
17
 
@@ -9,7 +9,7 @@ describe GraphQL::StaticValidation::FieldsHaveAppropriateSelections do
9
9
  }
10
10
  ")}
11
11
 
12
- let(:validator) { GraphQL::StaticValidation::Validator.new(schema: DummySchema, validators: [GraphQL::StaticValidation::FieldsHaveAppropriateSelections]) }
12
+ let(:validator) { GraphQL::StaticValidation::Validator.new(schema: DummySchema, rules: [GraphQL::StaticValidation::FieldsHaveAppropriateSelections]) }
13
13
  let(:errors) { validator.validate(document) }
14
14
 
15
15
  it 'adds errors for selections on scalars' do
@@ -29,7 +29,7 @@ describe GraphQL::StaticValidation::FieldsWillMerge do
29
29
  }
30
30
  ")}
31
31
 
32
- let(:validator) { GraphQL::StaticValidation::Validator.new(schema: DummySchema, validators: [GraphQL::StaticValidation::FieldsWillMerge]) }
32
+ let(:validator) { GraphQL::StaticValidation::Validator.new(schema: DummySchema, rules: [GraphQL::StaticValidation::FieldsWillMerge]) }
33
33
  let(:errors) { validator.validate(document) }
34
34
  let(:error_messages) { errors.map { |e| e["message" ] }}
35
35
 
@@ -0,0 +1,46 @@
1
+ require 'spec_helper'
2
+
3
+ describe GraphQL::StaticValidation::FragmentSpreadsArePossible do
4
+ let(:document) { GraphQL.parse(%|
5
+ query getCheese {
6
+ cheese(id: 1) {
7
+ ... milkFields
8
+ ... cheeseFields
9
+ ... on Milk { fatContent }
10
+ ... on AnimalProduct { source }
11
+ ... on DairyProduct {
12
+ fatContent
13
+ ... on Edible { fatContent }
14
+ }
15
+ }
16
+ }
17
+
18
+ fragment milkFields on Milk { fatContent }
19
+ fragment cheeseFields on Cheese {
20
+ fatContent
21
+ ... milkFields
22
+ }
23
+ |)}
24
+
25
+ let(:validator) { GraphQL::StaticValidation::Validator.new(schema: DummySchema, rules: [GraphQL::StaticValidation::FragmentSpreadsArePossible]) }
26
+ let(:errors) { validator.validate(document) }
27
+
28
+ it "doesnt allow spreads where they'll never apply" do
29
+ # TODO: more negative, abstract examples here, add stuff to the schema
30
+ expected = [
31
+ {
32
+ "message"=>"Fragment on Milk can't be spread inside Cheese",
33
+ "locations"=>[{"line"=>6, "column"=>9}]
34
+ },
35
+ {
36
+ "message"=>"Fragment milkFields on Milk can't be spread inside Cheese",
37
+ "locations"=>[{"line"=>4, "column"=>9}]
38
+ },
39
+ {
40
+ "message"=>"Fragment milkFields on Milk can't be spread inside Cheese",
41
+ "locations"=>[{"line"=>18, "column"=>7}]
42
+ }
43
+ ]
44
+ assert_equal(expected, errors)
45
+ end
46
+ end
@@ -19,7 +19,7 @@ describe GraphQL::StaticValidation::FragmentTypesExist do
19
19
  }
20
20
  ")}
21
21
 
22
- let(:validator) { GraphQL::StaticValidation::Validator.new(schema: DummySchema, validators: [GraphQL::StaticValidation::FragmentTypesExist]) }
22
+ let(:validator) { GraphQL::StaticValidation::Validator.new(schema: DummySchema, rules: [GraphQL::StaticValidation::FragmentTypesExist]) }
23
23
  let(:errors) { validator.validate(document) }
24
24
 
25
25
  it 'finds non-existent types on fragments' do
@@ -0,0 +1,43 @@
1
+ require 'spec_helper'
2
+
3
+ describe GraphQL::StaticValidation::FragmentsAreFinite do
4
+ let(:document) { GraphQL.parse(%|
5
+ query getCheese {
6
+ cheese(id: 1) {
7
+ ... idField
8
+ ... sourceField
9
+ ... flavorField
10
+ }
11
+ }
12
+
13
+ fragment sourceField on Cheese {
14
+ source,
15
+ ... flavorField
16
+ ... idField
17
+ }
18
+ fragment flavorField on Cheese {
19
+ flavor,
20
+ ... sourceField
21
+ }
22
+ fragment idField on Cheese {
23
+ id
24
+ }
25
+ |)}
26
+
27
+ let(:validator) { GraphQL::StaticValidation::Validator.new(schema: DummySchema, rules: [GraphQL::StaticValidation::FragmentsAreFinite]) }
28
+ let(:errors) { validator.validate(document) }
29
+
30
+ it 'doesnt allow infinite loops' do
31
+ expected = [
32
+ {
33
+ "message"=>"Fragment sourceField contains an infinite loop",
34
+ "locations"=>[{"line"=>10, "column"=>5}]
35
+ },
36
+ {
37
+ "message"=>"Fragment flavorField contains an infinite loop",
38
+ "locations"=>[{"line"=>15, "column"=>5}]
39
+ }
40
+ ]
41
+ assert_equal(expected, errors)
42
+ end
43
+ end
@@ -0,0 +1,48 @@
1
+ require 'spec_helper'
2
+
3
+ describe GraphQL::StaticValidation::FragmentsAreOnCompositeTypes do
4
+ let(:document) { GraphQL.parse(%|
5
+ query getCheese {
6
+ cheese(id: 1) {
7
+ ... on Cheese {
8
+ source
9
+ ... on Boolean {
10
+ something
11
+ }
12
+ }
13
+ ... intFields
14
+ ... on DairyProduct {
15
+ name
16
+ }
17
+ ... on DairyProductInput {
18
+ something
19
+ }
20
+ }
21
+ }
22
+
23
+ fragment intFields on Int {
24
+ something
25
+ }
26
+ |)}
27
+
28
+ let(:validator) { GraphQL::StaticValidation::Validator.new(schema: DummySchema, rules: [GraphQL::StaticValidation::FragmentsAreOnCompositeTypes]) }
29
+ let(:errors) { validator.validate(document) }
30
+
31
+ it 'requires Object/Union/Interface fragment types' do
32
+ expected = [
33
+ {
34
+ "message"=>"Invalid fragment on type Boolean (must be Union, Interface or Object)",
35
+ "locations"=>[{"line"=>6, "column"=>11}]
36
+ },
37
+ {
38
+ "message"=>"Invalid fragment on type DairyProductInput (must be Union, Interface or Object)",
39
+ "locations"=>[{"line"=>14, "column"=>9}],
40
+ },
41
+ {
42
+ "message"=>"Invalid fragment on type Int (must be Union, Interface or Object)",
43
+ "locations"=>[{"line"=>20, "column"=>5}]
44
+ },
45
+ ]
46
+ assert_equal(expected, errors)
47
+ end
48
+ end
@@ -11,7 +11,7 @@ describe GraphQL::StaticValidation::FragmentsAreUsed do
11
11
  fragment unusedFields on Cheese { is, not, used }
12
12
  ")}
13
13
 
14
- let(:validator) { GraphQL::StaticValidation::Validator.new(schema: DummySchema, validators: [GraphQL::StaticValidation::FragmentsAreUsed]) }
14
+ let(:validator) { GraphQL::StaticValidation::Validator.new(schema: DummySchema, rules: [GraphQL::StaticValidation::FragmentsAreUsed]) }
15
15
  let(:errors) { validator.validate(document) }
16
16
 
17
17
  it 'adds errors for unused fragment definitions' do
@@ -14,7 +14,7 @@ describe GraphQL::StaticValidation::RequiredArgumentsArePresent do
14
14
  }
15
15
  ")}
16
16
 
17
- let(:validator) { GraphQL::StaticValidation::Validator.new(schema: DummySchema, validators: [GraphQL::StaticValidation::RequiredArgumentsArePresent]) }
17
+ let(:validator) { GraphQL::StaticValidation::Validator.new(schema: DummySchema, rules: [GraphQL::StaticValidation::RequiredArgumentsArePresent]) }
18
18
  let(:errors) { validator.validate(document) }
19
19
 
20
20
  it 'finds undefined arguments to fields and directives' do
@@ -0,0 +1,43 @@
1
+ require 'spec_helper'
2
+
3
+ describe GraphQL::StaticValidation::VariableDefaultValuesAreCorrectlyTyped do
4
+ let(:document) { GraphQL.parse('
5
+ query getCheese(
6
+ $id: Int = 1,
7
+ $bool: Boolean = 3.4e24, # can be coerced
8
+ $str: String!,
9
+ $badFloat: Float = true,
10
+ $badInt: Int = "abc",
11
+ $input: DairyProductInput = {source: YAK, fatContent: 1},
12
+ $badInput: DairyProductInput = {source: YAK, fatContent: true},
13
+ $nonNull: Int! = 1,
14
+ ) {
15
+ cheese(id: $id) { source }
16
+ }
17
+ ')}
18
+
19
+ let(:validator) { GraphQL::StaticValidation::Validator.new(schema: DummySchema, rules: [GraphQL::StaticValidation::VariableDefaultValuesAreCorrectlyTyped]) }
20
+ let(:errors) { validator.validate(document) }
21
+
22
+ it "finds default values that don't match their types" do
23
+ expected = [
24
+ {
25
+ "message"=>"Default value for $badFloat doesn't match type Float",
26
+ "locations"=>[{"line"=>6, "column"=>8}]
27
+ },
28
+ {
29
+ "message"=>"Default value for $badInt doesn't match type Int",
30
+ "locations"=>[{"line"=>7, "column"=>8}]
31
+ },
32
+ {
33
+ "message"=>"Default value for $badInput doesn't match type DairyProductInput",
34
+ "locations"=>[{"line"=>9, "column"=>8}]
35
+ },
36
+ {
37
+ "message"=>"Non-null variable $nonNull can't have a default value",
38
+ "locations"=>[{"line"=>10, "column"=>8}]
39
+ }
40
+ ]
41
+ assert_equal(expected, errors)
42
+ end
43
+ end
@@ -0,0 +1,45 @@
1
+ require 'spec_helper'
2
+
3
+ describe GraphQL::StaticValidation::VariableUsagesAreAllowed do
4
+ let(:document) { GraphQL.parse('
5
+ query getCheese(
6
+ $goodInt: Int = 1,
7
+ $okInt: Int!,
8
+ $badInt: Int,
9
+ $badStr: String!,
10
+ $goodAnimals: [DairyAnimal!]!,
11
+ $badAnimals: [DairyAnimal]!,
12
+ ) {
13
+ goodCheese: cheese(id: $goodInt) { source }
14
+ okCheese: cheese(id: $okInt) { source }
15
+ badCheese: cheese(id: $badInt) { source }
16
+ badStrCheese: cheese(id: $badStr) { source }
17
+ cheese(id: 1) {
18
+ similarCheeses(source: $goodAnimals)
19
+ other: similarCheeses(source: $badAnimals)
20
+ }
21
+ }
22
+ ')}
23
+
24
+ let(:validator) { GraphQL::StaticValidation::Validator.new(schema: DummySchema, rules: [GraphQL::StaticValidation::VariableUsagesAreAllowed]) }
25
+ let(:errors) { validator.validate(document) }
26
+
27
+ it "finds variables used as arguments but don't match the argument's type" do
28
+ assert_equal(3, errors.length)
29
+ expected = [
30
+ {
31
+ "message"=>"Type mismatch on variable $badInt and argument id (Int / Int!)",
32
+ "locations"=>[{"line"=>12, "column"=>28}]
33
+ },
34
+ {
35
+ "message"=>"Type mismatch on variable $badStr and argument id (String! / Int!)",
36
+ "locations"=>[{"line"=>13, "column"=>28}]
37
+ },
38
+ {
39
+ "message"=>"Type mismatch on variable $badAnimals and argument source ([DairyAnimal]! / [DairyAnimal!]!)",
40
+ "locations"=>[{"line"=>16, "column"=>31}]
41
+ }
42
+ ]
43
+ assert_equal(expected, errors)
44
+ end
45
+ end
@@ -0,0 +1,36 @@
1
+ require 'spec_helper'
2
+
3
+ describe GraphQL::StaticValidation::VariablesAreInputTypes do
4
+ let(:document) { GraphQL.parse('
5
+ query getCheese(
6
+ $id: Int = 1,
7
+ $str: [String!],
8
+ $interface: AnimalProduct!,
9
+ $object: Milk = 1,
10
+ $objects: [Cheese]!,
11
+ ) {
12
+ cheese(id: $id) { source }
13
+ }
14
+ ')}
15
+
16
+ let(:validator) { GraphQL::StaticValidation::Validator.new(schema: DummySchema, rules: [GraphQL::StaticValidation::VariablesAreInputTypes]) }
17
+ let(:errors) { validator.validate(document) }
18
+
19
+ it "finds variables whose types are invalid" do
20
+ expected = [
21
+ {
22
+ "message"=>"AnimalProduct isn't a valid input type (on $interface)",
23
+ "locations"=>[{"line"=>5, "column"=>8}]
24
+ },
25
+ {
26
+ "message"=>"Milk isn't a valid input type (on $object)",
27
+ "locations"=>[{"line"=>6, "column"=>8}]
28
+ },
29
+ {
30
+ "message"=>"Cheese isn't a valid input type (on $objects)",
31
+ "locations"=>[{"line"=>7, "column"=>8}]
32
+ }
33
+ ]
34
+ assert_equal(expected, errors)
35
+ end
36
+ end
@@ -0,0 +1,44 @@
1
+ require 'spec_helper'
2
+
3
+ describe GraphQL::StaticValidation::VariablesAreUsedAndDefined do
4
+ let(:document) { GraphQL.parse('
5
+ query getCheese($id: Int, $str: String, $notUsedVar: Float, $bool: Boolean) {
6
+ cheese(id: $id) {
7
+ source(str: $str)
8
+ whatever(undefined: $undefinedVar)
9
+ ... on Cheese {
10
+ something(bool: $bool)
11
+ }
12
+ }
13
+ }
14
+
15
+ fragment outerCheeseFields on Cheese {
16
+ ... innerCheeseFields
17
+ }
18
+
19
+ fragment innerCheeseFields on Cheese {
20
+ source(notDefined: $notDefinedVar)
21
+ }
22
+ ')}
23
+
24
+ let(:validator) { GraphQL::StaticValidation::Validator.new(schema: DummySchema, rules: [GraphQL::StaticValidation::VariablesAreUsedAndDefined]) }
25
+ let(:errors) { validator.validate(document) }
26
+
27
+ it "finds variables which are used-but-not-defined or defined-but-not-used" do
28
+ expected = [
29
+ {
30
+ "message"=>"Variable $undefinedVar is used but not declared",
31
+ "locations"=>[{"line"=>5, "column"=>30}]
32
+ },
33
+ {
34
+ "message"=>"Variable $notUsedVar is declared but not used",
35
+ "locations"=>[{"line"=>2, "column"=>5}]
36
+ },
37
+ {
38
+ "message"=>"Variable $notDefinedVar is used but not declared",
39
+ "locations"=>[{"line"=>17, "column"=>27}]
40
+ },
41
+ ]
42
+ assert_equal(expected, errors)
43
+ end
44
+ end
@@ -18,10 +18,10 @@ describe GraphQL::StaticValidation::TypeStack do
18
18
  query getCheese {
19
19
  cheese(id: 1) { id, ... edibleFields }
20
20
  }
21
- fragment edibleFields on Edible { fatContent }
21
+ fragment edibleFields on Edible { fatContent @skip(if: false)}
22
22
  |}
23
23
  let(:document) { GraphQL.parse(query_string) }
24
- let(:validator) { GraphQL::StaticValidation::Validator.new(schema: DummySchema, validators: [TypeCheckValidator]) }
24
+ let(:validator) { GraphQL::StaticValidation::Validator.new(schema: DummySchema, rules: [TypeCheckValidator]) }
25
25
 
26
26
  it 'stores up types' do
27
27
  validator.validate(document)
@@ -14,15 +14,54 @@ class DocumentErrorValidator
14
14
  end
15
15
 
16
16
  describe GraphQL::StaticValidation::Validator do
17
- let(:document) { OpenStruct.new(name: "This is not a document", children: []) }
18
- let(:validator) { GraphQL::StaticValidation::Validator.new(schema: "This is not a schema", validators: [SchemaErrorValidator, DocumentErrorValidator]) }
19
-
20
- it 'uses validators' do
21
- errors = validator.validate(document)
17
+ let(:document) { OpenStruct.new(name: "This is not a document", children: [], parts: []) }
18
+ let(:validator) { GraphQL::StaticValidation::Validator.new(schema: "This is not a schema", rules: [SchemaErrorValidator, DocumentErrorValidator]) }
19
+ let(:errors) { validator.validate(document) }
20
+ it 'uses rules' do
22
21
  expected_errors = [
23
22
  {"message" => "Something is wrong: This is not a schema", "locations" => [{"line" => 100, "column" => 4}]},
24
23
  {"message" => "Something is wrong: This is not a document", "locations" => [{"line" => 1, "column" => 1}]}
25
24
  ]
26
25
  assert_equal(expected_errors, errors)
27
26
  end
27
+
28
+ describe 'validation order' do
29
+ let(:validator) { GraphQL::StaticValidation::Validator.new(schema: DummySchema) }
30
+ let(:document) { GraphQL.parse(query_string)}
31
+
32
+ describe 'fields & arguments' do
33
+ let(:query_string) { %|
34
+ query getCheese {
35
+ cheese(id: 1) {
36
+ source,
37
+ nonsenseField,
38
+ id(nonsenseArg: 1)
39
+ bogusField(bogusArg: true)
40
+ }
41
+ }
42
+ |}
43
+
44
+ it 'handles args on invalid fields' do
45
+ assert_equal(3, errors.length)
46
+ end
47
+ end
48
+
49
+ describe 'infinite fragments' do
50
+ let(:query_string) { %|
51
+ query getCheese {
52
+ cheese(id: 1) {
53
+ ... cheeseFields
54
+ }
55
+ }
56
+ fragment cheeseFields on Cheese {
57
+ id, ... cheeseFields
58
+ }
59
+ |}
60
+
61
+ it 'handles infinite fragment spreads' do
62
+ p errors
63
+ assert_equal(1, errors.length)
64
+ end
65
+ end
66
+ end
28
67
  end