graphql 0.18.15 → 0.19.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/graphql/define/assign_global_id_field.rb +1 -2
  3. data/lib/graphql/directive.rb +41 -7
  4. data/lib/graphql/directive/deprecated_directive.rb +11 -0
  5. data/lib/graphql/directive/include_directive.rb +2 -2
  6. data/lib/graphql/directive/skip_directive.rb +2 -2
  7. data/lib/graphql/input_object_type.rb +14 -0
  8. data/lib/graphql/internal_representation/node.rb +8 -4
  9. data/lib/graphql/introspection/arguments_field.rb +0 -1
  10. data/lib/graphql/introspection/directive_location_enum.rb +3 -2
  11. data/lib/graphql/introspection/directive_type.rb +12 -7
  12. data/lib/graphql/introspection/enum_value_type.rb +4 -2
  13. data/lib/graphql/introspection/enum_values_field.rb +0 -1
  14. data/lib/graphql/introspection/field_type.rb +8 -7
  15. data/lib/graphql/introspection/fields_field.rb +0 -1
  16. data/lib/graphql/introspection/input_fields_field.rb +0 -1
  17. data/lib/graphql/introspection/input_value_type.rb +8 -10
  18. data/lib/graphql/introspection/interfaces_field.rb +0 -1
  19. data/lib/graphql/introspection/of_type_field.rb +0 -1
  20. data/lib/graphql/introspection/possible_types_field.rb +0 -1
  21. data/lib/graphql/introspection/schema_type.rb +11 -9
  22. data/lib/graphql/introspection/type_kind_enum.rb +3 -3
  23. data/lib/graphql/introspection/type_type.rb +9 -6
  24. data/lib/graphql/language/generation.rb +4 -1
  25. data/lib/graphql/language/lexer.rb +353 -316
  26. data/lib/graphql/language/lexer.rl +8 -6
  27. data/lib/graphql/language/nodes.rb +12 -0
  28. data/lib/graphql/language/parser.rb +553 -501
  29. data/lib/graphql/language/parser.y +26 -16
  30. data/lib/graphql/language/parser_tests.rb +20 -1
  31. data/lib/graphql/list_type.rb +5 -1
  32. data/lib/graphql/non_null_type.rb +4 -0
  33. data/lib/graphql/object_type.rb +1 -1
  34. data/lib/graphql/query/literal_input.rb +1 -1
  35. data/lib/graphql/relay.rb +1 -1
  36. data/lib/graphql/relay/global_id_resolve.rb +3 -5
  37. data/lib/graphql/relay/node.rb +34 -0
  38. data/lib/graphql/scalar_type.rb +1 -1
  39. data/lib/graphql/schema.rb +43 -15
  40. data/lib/graphql/schema/loader.rb +2 -2
  41. data/lib/graphql/schema/printer.rb +50 -8
  42. data/lib/graphql/schema/unique_within_type.rb +28 -0
  43. data/lib/graphql/schema/validation.rb +10 -3
  44. data/lib/graphql/static_validation/rules/fields_will_merge.rb +9 -1
  45. data/lib/graphql/static_validation/rules/fragment_spreads_are_possible.rb +8 -2
  46. data/lib/graphql/type_kinds.rb +12 -12
  47. data/lib/graphql/version.rb +1 -1
  48. data/readme.md +6 -5
  49. data/spec/graphql/argument_spec.rb +1 -1
  50. data/spec/graphql/execution_error_spec.rb +53 -0
  51. data/spec/graphql/introspection/directive_type_spec.rb +10 -0
  52. data/spec/graphql/introspection/input_value_type_spec.rb +23 -0
  53. data/spec/graphql/language/generation_spec.rb +4 -0
  54. data/spec/graphql/query/executor_spec.rb +2 -2
  55. data/spec/graphql/relay/mutation_spec.rb +1 -1
  56. data/spec/graphql/relay/node_spec.rb +87 -0
  57. data/spec/graphql/schema/catchall_middleware_spec.rb +1 -1
  58. data/spec/graphql/schema/loader_spec.rb +37 -4
  59. data/spec/graphql/schema/printer_spec.rb +30 -7
  60. data/spec/graphql/schema/unique_within_type_spec.rb +27 -0
  61. data/spec/graphql/schema/validation_spec.rb +7 -11
  62. data/spec/graphql/schema_spec.rb +32 -2
  63. data/spec/graphql/static_validation/rules/argument_literals_are_compatible_spec.rb +14 -15
  64. data/spec/graphql/static_validation/rules/arguments_are_defined_spec.rb +10 -10
  65. data/spec/graphql/static_validation/rules/directives_are_defined_spec.rb +1 -5
  66. data/spec/graphql/static_validation/rules/directives_are_in_valid_locations_spec.rb +3 -5
  67. data/spec/graphql/static_validation/rules/fields_are_defined_on_type_spec.rb +7 -11
  68. data/spec/graphql/static_validation/rules/fields_have_appropriate_selections_spec.rb +1 -4
  69. data/spec/graphql/static_validation/rules/fields_will_merge_spec.rb +10 -13
  70. data/spec/graphql/static_validation/rules/fragment_spreads_are_possible_spec.rb +3 -5
  71. data/spec/graphql/static_validation/rules/fragment_types_exist_spec.rb +2 -4
  72. data/spec/graphql/static_validation/rules/fragments_are_finite_spec.rb +4 -6
  73. data/spec/graphql/static_validation/rules/fragments_are_named_spec.rb +2 -4
  74. data/spec/graphql/static_validation/rules/fragments_are_on_composite_types_spec.rb +7 -7
  75. data/spec/graphql/static_validation/rules/fragments_are_used_spec.rb +1 -4
  76. data/spec/graphql/static_validation/rules/mutation_root_exists_spec.rb +2 -4
  77. data/spec/graphql/static_validation/rules/required_arguments_are_present_spec.rb +3 -6
  78. data/spec/graphql/static_validation/rules/subscription_root_exists_spec.rb +2 -4
  79. data/spec/graphql/static_validation/rules/variable_default_values_are_correctly_typed_spec.rb +12 -14
  80. data/spec/graphql/static_validation/rules/variable_usages_are_allowed_spec.rb +7 -9
  81. data/spec/graphql/static_validation/rules/variables_are_input_types_spec.rb +20 -22
  82. data/spec/graphql/static_validation/rules/variables_are_used_and_defined_spec.rb +27 -23
  83. data/spec/spec_helper.rb +1 -0
  84. data/spec/support/dairy_app.rb +2 -2
  85. data/spec/support/star_wars_schema.rb +15 -18
  86. data/spec/support/static_validation_helpers.rb +27 -0
  87. metadata +25 -5
  88. data/lib/graphql/relay/global_node_identification.rb +0 -138
  89. data/spec/graphql/relay/global_node_identification_spec.rb +0 -153
@@ -1,15 +1,17 @@
1
1
  require "spec_helper"
2
2
 
3
3
  describe GraphQL::StaticValidation::FieldsWillMerge do
4
+ include StaticValidationHelpers
5
+
4
6
  let(:query_string) {"
5
- query getCheese($sourceVar: DairyAnimal!) {
7
+ query getCheese($sourceVar: [DairyAnimal!] = [YAK]) {
6
8
  cheese(id: 1) {
7
9
  id,
8
- nickname: name,
10
+ nickname: flavor,
9
11
  nickname: fatContent,
10
12
  fatContent
11
13
  differentLevel: fatContent
12
- similarCheese(source: $sourceVar)
14
+ similarCheese(source: $sourceVar) { __typename }
13
15
 
14
16
  similarCow: similarCheese(source: COW) {
15
17
  similarCowSource: source,
@@ -17,27 +19,22 @@ describe GraphQL::StaticValidation::FieldsWillMerge do
17
19
  }
18
20
  ...cheeseFields
19
21
  ... on Cheese {
20
- fatContent: name
21
- similarCheese(source: SHEEP)
22
+ fatContent: flavor
23
+ similarCheese(source: SHEEP) { __typename }
22
24
  }
23
25
  }
24
26
  }
25
27
  fragment cheeseFields on Cheese {
26
28
  fatContent,
27
29
  similarCow: similarCheese(source: COW) { similarCowSource: id, id }
28
- id @someFlag
30
+ id @skip(if: true)
29
31
  }
30
32
  "}
31
33
 
32
- let(:validator) { GraphQL::StaticValidation::Validator.new(schema: DummySchema, rules: [GraphQL::StaticValidation::FieldsWillMerge]) }
33
- let(:query) { GraphQL::Query.new(DummySchema, query_string) }
34
- let(:errors) { validator.validate(query)[:errors] }
35
- let(:error_messages) { errors.map { |e| e["message" ] }}
36
-
37
34
  it "finds field naming conflicts" do
38
35
  expected_errors = [
39
- "Field 'nickname' has a field conflict: name or fatContent?", # alias conflict in query
40
- "Field 'fatContent' has a field conflict: fatContent or name?", # alias/name conflict in query and fragment
36
+ "Field 'nickname' has a field conflict: flavor or fatContent?", # alias conflict in query
37
+ "Field 'fatContent' has a field conflict: fatContent or flavor?", # alias/name conflict in query and fragment
41
38
  "Field 'similarCheese' has an argument conflict: {\"source\":\"sourceVar\"} or {\"source\":\"SHEEP\"}?", # different arguments
42
39
  "Field 'similarCowSource' has a field conflict: source or id?", # nested conflict
43
40
  ]
@@ -1,6 +1,8 @@
1
1
  require "spec_helper"
2
2
 
3
3
  describe GraphQL::StaticValidation::FragmentSpreadsArePossible do
4
+ include StaticValidationHelpers
5
+
4
6
  let(:query_string) {%|
5
7
  query getCheese {
6
8
  cheese(id: 1) {
@@ -9,7 +11,7 @@ describe GraphQL::StaticValidation::FragmentSpreadsArePossible do
9
11
  ... on Milk { fatContent }
10
12
  ... on AnimalProduct { source }
11
13
  ... on DairyProduct {
12
- fatContent
14
+ ... on Cheese { fatContent }
13
15
  ... on Edible { fatContent }
14
16
  }
15
17
  }
@@ -22,10 +24,6 @@ describe GraphQL::StaticValidation::FragmentSpreadsArePossible do
22
24
  }
23
25
  |}
24
26
 
25
- let(:validator) { GraphQL::StaticValidation::Validator.new(schema: DummySchema, rules: [GraphQL::StaticValidation::FragmentSpreadsArePossible]) }
26
- let(:query) { GraphQL::Query.new(DummySchema, query_string) }
27
- let(:errors) { validator.validate(query)[:errors] }
28
-
29
27
  it "doesnt allow spreads where they'll never apply" do
30
28
  # TODO: more negative, abstract examples here, add stuff to the schema
31
29
  expected = [
@@ -1,6 +1,8 @@
1
1
  require "spec_helper"
2
2
 
3
3
  describe GraphQL::StaticValidation::FragmentTypesExist do
4
+ include StaticValidationHelpers
5
+
4
6
  let(:query_string) {"
5
7
  query getCheese {
6
8
  cheese(id: 1) {
@@ -19,10 +21,6 @@ describe GraphQL::StaticValidation::FragmentTypesExist do
19
21
  }
20
22
  "}
21
23
 
22
- let(:validator) { GraphQL::StaticValidation::Validator.new(schema: DummySchema, rules: [GraphQL::StaticValidation::FragmentTypesExist]) }
23
- let(:query) { GraphQL::Query.new(DummySchema, query_string) }
24
- let(:errors) { validator.validate(query)[:errors] }
25
-
26
24
  it "finds non-existent types on fragments" do
27
25
  assert_equal(2, errors.length)
28
26
  inline_fragment_error = {
@@ -1,12 +1,14 @@
1
1
  require "spec_helper"
2
2
 
3
3
  describe GraphQL::StaticValidation::FragmentsAreFinite do
4
+ include StaticValidationHelpers
5
+
4
6
  let(:query_string) {%|
5
7
  query getCheese {
6
8
  cheese(id: 1) {
7
9
  ... idField
8
10
  ... sourceField
9
- similarCheese {
11
+ similarCheese(source: SHEEP) {
10
12
  ... flavorField
11
13
  }
12
14
  }
@@ -19,7 +21,7 @@ describe GraphQL::StaticValidation::FragmentsAreFinite do
19
21
  }
20
22
  fragment flavorField on Cheese {
21
23
  flavor,
22
- similarCheese {
24
+ similarCheese(source: SHEEP) {
23
25
  ... on Cheese {
24
26
  ... sourceField
25
27
  }
@@ -30,10 +32,6 @@ describe GraphQL::StaticValidation::FragmentsAreFinite do
30
32
  }
31
33
  |}
32
34
 
33
- let(:validator) { GraphQL::StaticValidation::Validator.new(schema: DummySchema, rules: [GraphQL::StaticValidation::FragmentsAreFinite]) }
34
- let(:query) { GraphQL::Query.new(DummySchema, query_string) }
35
- let(:errors) { validator.validate(query)[:errors] }
36
-
37
35
  it "doesnt allow infinite loops" do
38
36
  expected = [
39
37
  {
@@ -1,6 +1,8 @@
1
1
  require "spec_helper"
2
2
 
3
3
  describe GraphQL::StaticValidation::FragmentTypesExist do
4
+ include StaticValidationHelpers
5
+
4
6
  let(:query_string) {"
5
7
  fragment on Cheese {
6
8
  id
@@ -8,10 +10,6 @@ describe GraphQL::StaticValidation::FragmentTypesExist do
8
10
  }
9
11
  "}
10
12
 
11
- let(:validator) { GraphQL::StaticValidation::Validator.new(schema: DummySchema, rules: [GraphQL::StaticValidation::FragmentsAreNamed]) }
12
- let(:query) { GraphQL::Query.new(DummySchema, query_string) }
13
- let(:errors) { validator.validate(query)[:errors] }
14
-
15
13
  it "finds non-existent types on fragments" do
16
14
  assert_equal(1, errors.length)
17
15
  fragment_def_error = {
@@ -1,6 +1,8 @@
1
1
  require "spec_helper"
2
2
 
3
3
  describe GraphQL::StaticValidation::FragmentsAreOnCompositeTypes do
4
+ include StaticValidationHelpers
5
+
4
6
  let(:query_string) {%|
5
7
  query getCheese {
6
8
  cheese(id: 1) {
@@ -12,7 +14,9 @@ describe GraphQL::StaticValidation::FragmentsAreOnCompositeTypes do
12
14
  }
13
15
  ... intFields
14
16
  ... on DairyProduct {
15
- name
17
+ ... on Cheese {
18
+ flavor
19
+ }
16
20
  }
17
21
  ... on DairyProductInput {
18
22
  something
@@ -25,10 +29,6 @@ describe GraphQL::StaticValidation::FragmentsAreOnCompositeTypes do
25
29
  }
26
30
  |}
27
31
 
28
- let(:validator) { GraphQL::StaticValidation::Validator.new(schema: DummySchema, rules: [GraphQL::StaticValidation::FragmentsAreOnCompositeTypes]) }
29
- let(:query) { GraphQL::Query.new(DummySchema, query_string) }
30
- let(:errors) { validator.validate(query)[:errors] }
31
-
32
32
  it "requires Object/Union/Interface fragment types" do
33
33
  expected = [
34
34
  {
@@ -38,12 +38,12 @@ describe GraphQL::StaticValidation::FragmentsAreOnCompositeTypes do
38
38
  },
39
39
  {
40
40
  "message"=>"Invalid fragment on type DairyProductInput (must be Union, Interface or Object)",
41
- "locations"=>[{"line"=>14, "column"=>9}],
41
+ "locations"=>[{"line"=>16, "column"=>9}],
42
42
  "fields"=>["query getCheese", "cheese", "... on DairyProductInput"],
43
43
  },
44
44
  {
45
45
  "message"=>"Invalid fragment on type Int (must be Union, Interface or Object)",
46
- "locations"=>[{"line"=>20, "column"=>5}],
46
+ "locations"=>[{"line"=>22, "column"=>5}],
47
47
  "fields"=>["fragment intFields"],
48
48
  },
49
49
  ]
@@ -1,6 +1,7 @@
1
1
  require "spec_helper"
2
2
 
3
3
  describe GraphQL::StaticValidation::FragmentsAreUsed do
4
+ include StaticValidationHelpers
4
5
  let(:query_string) {"
5
6
  query getCheese {
6
7
  name,
@@ -11,10 +12,6 @@ describe GraphQL::StaticValidation::FragmentsAreUsed do
11
12
  fragment unusedFields on Cheese { is, not, used }
12
13
  "}
13
14
 
14
- let(:validator) { GraphQL::StaticValidation::Validator.new(schema: DummySchema, rules: [GraphQL::StaticValidation::FragmentsAreUsed]) }
15
- let(:query) { GraphQL::Query.new(DummySchema, query_string) }
16
- let(:errors) { validator.validate(query)[:errors] }
17
-
18
15
  it "adds errors for unused fragment definitions" do
19
16
  assert_includes(errors, {
20
17
  "message"=>"Fragment unusedFields was defined, but not used",
@@ -1,6 +1,8 @@
1
1
  require "spec_helper"
2
2
 
3
3
  describe GraphQL::StaticValidation::MutationRootExists do
4
+ include StaticValidationHelpers
5
+
4
6
  let(:query_string) {%|
5
7
  mutation addBagel {
6
8
  introduceShip(input: {shipName: "Bagel"}) {
@@ -23,10 +25,6 @@ describe GraphQL::StaticValidation::MutationRootExists do
23
25
  end
24
26
  }
25
27
 
26
- let(:validator) { GraphQL::StaticValidation::Validator.new(schema: schema, rules: [GraphQL::StaticValidation::MutationRootExists]) }
27
- let(:query) { GraphQL::Query.new(schema, query_string) }
28
- let(:errors) { validator.validate(query)[:errors] }
29
-
30
28
  it "errors when a mutation is performed on a schema without a mutation root" do
31
29
  assert_equal(1, errors.length)
32
30
  missing_mutation_root_error = {
@@ -1,23 +1,20 @@
1
1
  require "spec_helper"
2
2
 
3
3
  describe GraphQL::StaticValidation::RequiredArgumentsArePresent do
4
+ include StaticValidationHelpers
4
5
  let(:query_string) {"
5
6
  query getCheese {
6
- cheese(id: 1) { source }
7
+ okCheese: cheese(id: 1) { ...cheeseFields }
7
8
  cheese { source }
8
9
  }
9
10
 
10
11
  fragment cheeseFields on Cheese {
11
- similarCheese(id: 1)
12
+ similarCheese() { __typename }
12
13
  flavor @include(if: true)
13
14
  id @skip
14
15
  }
15
16
  "}
16
17
 
17
- let(:validator) { GraphQL::StaticValidation::Validator.new(schema: DummySchema, rules: [GraphQL::StaticValidation::RequiredArgumentsArePresent]) }
18
- let(:query) { GraphQL::Query.new(DummySchema, query_string) }
19
- let(:errors) { validator.validate(query)[:errors] }
20
-
21
18
  it "finds undefined arguments to fields and directives" do
22
19
  assert_equal(3, errors.length)
23
20
 
@@ -1,6 +1,8 @@
1
1
  require "spec_helper"
2
2
 
3
3
  describe GraphQL::StaticValidation::SubscriptionRootExists do
4
+ include StaticValidationHelpers
5
+
4
6
  let(:query_string) {%|
5
7
  subscription {
6
8
  test
@@ -18,10 +20,6 @@ describe GraphQL::StaticValidation::SubscriptionRootExists do
18
20
  end
19
21
  }
20
22
 
21
- let(:validator) { GraphQL::StaticValidation::Validator.new(schema: schema, rules: [GraphQL::StaticValidation::SubscriptionRootExists]) }
22
- let(:query) { GraphQL::Query.new(schema, query_string) }
23
- let(:errors) { validator.validate(query)[:errors] }
24
-
25
23
  it "errors when a subscription is performed on a schema without a subscription root" do
26
24
  assert_equal(1, errors.length)
27
25
  missing_subscription_root_error = {
@@ -1,45 +1,43 @@
1
1
  require "spec_helper"
2
2
 
3
3
  describe GraphQL::StaticValidation::VariableDefaultValuesAreCorrectlyTyped do
4
+ include StaticValidationHelpers
5
+
4
6
  let(:query_string) {%|
5
7
  query getCheese(
6
8
  $id: Int = 1,
7
9
  $int: Int = 3.4e24, # can be coerced
8
10
  $str: String!,
9
- $badFloat: Float = true,
10
11
  $badInt: Int = "abc",
11
12
  $input: DairyProductInput = {source: YAK, fatContent: 1},
12
13
  $badInput: DairyProductInput = {source: YAK, fatContent: true},
13
14
  $nonNull: Int! = 1,
14
15
  ) {
15
- cheese(id: $id) { source }
16
+ cheese1: cheese(id: $id) { source }
17
+ cheese4: cheese(id: $int) { source }
18
+ cheese2: cheese(id: $badInt) { source }
19
+ cheese3: cheese(id: $nonNull) { source }
20
+ search1: searchDairy(product: [$input]) { __typename }
21
+ search2: searchDairy(product: [$badInput]) { __typename }
22
+ __type(name: $str) { name }
16
23
  }
17
24
  |}
18
25
 
19
- let(:validator) { GraphQL::StaticValidation::Validator.new(schema: DummySchema, rules: [GraphQL::StaticValidation::VariableDefaultValuesAreCorrectlyTyped]) }
20
- let(:query) { GraphQL::Query.new(DummySchema, query_string) }
21
- let(:errors) { validator.validate(query)[:errors] }
22
-
23
26
  it "finds default values that don't match their types" do
24
27
  expected = [
25
- {
26
- "message"=>"Default value for $badFloat doesn't match type Float",
27
- "locations"=>[{"line"=>6, "column"=>7}],
28
- "fields"=>["query getCheese"],
29
- },
30
28
  {
31
29
  "message"=>"Default value for $badInt doesn't match type Int",
32
- "locations"=>[{"line"=>7, "column"=>7}],
30
+ "locations"=>[{"line"=>6, "column"=>7}],
33
31
  "fields"=>["query getCheese"],
34
32
  },
35
33
  {
36
34
  "message"=>"Default value for $badInput doesn't match type DairyProductInput",
37
- "locations"=>[{"line"=>9, "column"=>7}],
35
+ "locations"=>[{"line"=>8, "column"=>7}],
38
36
  "fields"=>["query getCheese"],
39
37
  },
40
38
  {
41
39
  "message"=>"Non-null variable $nonNull can't have a default value",
42
- "locations"=>[{"line"=>10, "column"=>7}],
40
+ "locations"=>[{"line"=>9, "column"=>7}],
43
41
  "fields"=>["query getCheese"],
44
42
  }
45
43
  ]
@@ -1,6 +1,8 @@
1
1
  require "spec_helper"
2
2
 
3
3
  describe GraphQL::StaticValidation::VariableUsagesAreAllowed do
4
+ include StaticValidationHelpers
5
+
4
6
  let(:query_string) {'
5
7
  query getCheese(
6
8
  $goodInt: Int = 1,
@@ -17,11 +19,11 @@ describe GraphQL::StaticValidation::VariableUsagesAreAllowed do
17
19
  badCheese: cheese(id: $badInt) { source }
18
20
  badStrCheese: cheese(id: $badStr) { source }
19
21
  cheese(id: 1) {
20
- similarCheese(source: $goodAnimals)
21
- other: similarCheese(source: $badAnimals)
22
- tooDeep: similarCheese(source: $deepAnimals)
23
- nullableCheese(source: $goodAnimals)
24
- deeplyNullableCheese(source: $deepAnimals)
22
+ similarCheese(source: $goodAnimals) { source }
23
+ other: similarCheese(source: $badAnimals) { source }
24
+ tooDeep: similarCheese(source: $deepAnimals) { source }
25
+ nullableCheese(source: $goodAnimals) { source }
26
+ deeplyNullableCheese(source: $deepAnimals) { source }
25
27
  }
26
28
 
27
29
  milk(id: 1) {
@@ -34,10 +36,6 @@ describe GraphQL::StaticValidation::VariableUsagesAreAllowed do
34
36
  }
35
37
  '}
36
38
 
37
- let(:validator) { GraphQL::StaticValidation::Validator.new(schema: DummySchema, rules: [GraphQL::StaticValidation::VariableUsagesAreAllowed]) }
38
- let(:query) { GraphQL::Query.new(DummySchema, query_string) }
39
- let(:errors) { validator.validate(query)[:errors] }
40
-
41
39
  it "finds variables used as arguments but don't match the argument's type" do
42
40
  assert_equal(4, errors.length)
43
41
  expected = [
@@ -1,6 +1,8 @@
1
1
  require "spec_helper"
2
2
 
3
3
  describe GraphQL::StaticValidation::VariablesAreInputTypes do
4
+ include StaticValidationHelpers
5
+
4
6
  let(:query_string) {'
5
7
  query getCheese(
6
8
  $id: Int = 1,
@@ -10,31 +12,27 @@ describe GraphQL::StaticValidation::VariablesAreInputTypes do
10
12
  $objects: [Cheese]!,
11
13
  ) {
12
14
  cheese(id: $id) { source }
15
+ __type(name: $str) { name }
13
16
  }
14
17
  '}
15
18
 
16
- let(:validator) { GraphQL::StaticValidation::Validator.new(schema: DummySchema, rules: [GraphQL::StaticValidation::VariablesAreInputTypes]) }
17
- let(:query) { GraphQL::Query.new(DummySchema, query_string) }
18
- let(:errors) { validator.validate(query)[:errors] }
19
-
20
19
  it "finds variables whose types are invalid" do
21
- expected = [
22
- {
23
- "message"=>"AnimalProduct isn't a valid input type (on $interface)",
24
- "locations"=>[{"line"=>5, "column"=>7}],
25
- "fields"=>["query getCheese"],
26
- },
27
- {
28
- "message"=>"Milk isn't a valid input type (on $object)",
29
- "locations"=>[{"line"=>6, "column"=>7}],
30
- "fields"=>["query getCheese"],
31
- },
32
- {
33
- "message"=>"Cheese isn't a valid input type (on $objects)",
34
- "locations"=>[{"line"=>7, "column"=>7}],
35
- "fields"=>["query getCheese"],
36
- }
37
- ]
38
- assert_equal(expected, errors)
20
+ assert_includes(errors, {
21
+ "message"=>"AnimalProduct isn't a valid input type (on $interface)",
22
+ "locations"=>[{"line"=>5, "column"=>7}],
23
+ "fields"=>["query getCheese"],
24
+ })
25
+
26
+ assert_includes(errors, {
27
+ "message"=>"Milk isn't a valid input type (on $object)",
28
+ "locations"=>[{"line"=>6, "column"=>7}],
29
+ "fields"=>["query getCheese"],
30
+ })
31
+
32
+ assert_includes(errors, {
33
+ "message"=>"Cheese isn't a valid input type (on $objects)",
34
+ "locations"=>[{"line"=>7, "column"=>7}],
35
+ "fields"=>["query getCheese"],
36
+ })
39
37
  end
40
38
  end
@@ -1,38 +1,41 @@
1
1
  require "spec_helper"
2
2
 
3
3
  describe GraphQL::StaticValidation::VariablesAreUsedAndDefined do
4
+ include StaticValidationHelpers
5
+
4
6
  let(:query_string) {'
5
7
  query getCheese(
6
- $usedVar: Int,
7
- $usedInnerVar: String,
8
- $usedInlineFragmentVar: Boolean,
9
- $usedFragmentVar: Int,
10
- $notUsedVar: Float,
8
+ $usedVar: Int!,
9
+ $usedInnerVar: [DairyAnimal!]!,
10
+ $usedInlineFragmentVar: Int!,
11
+ $usedFragmentVar: Int!,
12
+ $notUsedVar: Int!,
11
13
  ) {
12
- cheese(id: $usedVar) {
13
- source(str: $usedInnerVar)
14
- whatever(undefined: $undefinedVar)
15
- ... on Cheese {
16
- something(bool: $usedInlineFragmentVar)
14
+ c1: cheese(id: $usedVar) {
15
+ __typename
16
+ }
17
+ ... on Query {
18
+ c2: cheese(id: $usedInlineFragmentVar) {
19
+ similarCheese(source: $usedInnerVar) { __typename }
17
20
  }
18
- ... outerCheeseFields
21
+
19
22
  }
23
+
24
+ c3: cheese(id: $undefinedVar) { __typename }
25
+
26
+ ... outerCheeseFields
20
27
  }
21
28
 
22
- fragment outerCheeseFields on Cheese {
29
+ fragment outerCheeseFields on Query {
23
30
  ... innerCheeseFields
24
31
  }
25
32
 
26
- fragment innerCheeseFields on Cheese {
27
- source(notDefined: $undefinedFragmentVar)
28
- someField(someArg: $usedFragmentVar)
33
+ fragment innerCheeseFields on Query {
34
+ c4: cheese(id: $undefinedFragmentVar) { __typename }
35
+ c5: cheese(id: $usedFragmentVar) { __typename }
29
36
  }
30
37
  '}
31
38
 
32
- let(:validator) { GraphQL::StaticValidation::Validator.new(schema: DummySchema, rules: [GraphQL::StaticValidation::VariablesAreUsedAndDefined]) }
33
- let(:query) { GraphQL::Query.new(DummySchema, query_string) }
34
- let(:errors) { validator.validate(query)[:errors] }
35
-
36
39
  it "finds variables which are used-but-not-defined or defined-but-not-used" do
37
40
  expected = [
38
41
  {
@@ -42,15 +45,16 @@ describe GraphQL::StaticValidation::VariablesAreUsedAndDefined do
42
45
  },
43
46
  {
44
47
  "message"=>"Variable $undefinedVar is used by getCheese but not declared",
45
- "locations"=>[{"line"=>11, "column"=>29}],
46
- "fields"=>["query getCheese", "cheese", "whatever", "undefined"],
48
+ "locations"=>[{"line"=>19, "column"=>22}],
49
+ "fields"=>["query getCheese", "c3", "id"],
47
50
  },
48
51
  {
49
52
  "message"=>"Variable $undefinedFragmentVar is used by innerCheeseFields but not declared",
50
- "locations"=>[{"line"=>24, "column"=>26}],
51
- "fields"=>["fragment innerCheeseFields", "source", "notDefined"],
53
+ "locations"=>[{"line"=>29, "column"=>22}],
54
+ "fields"=>["fragment innerCheeseFields", "c4", "id"],
52
55
  },
53
56
  ]
57
+
54
58
  assert_equal(expected, errors)
55
59
  end
56
60
  end