graphql 1.1.0 → 1.2.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.
Files changed (79) hide show
  1. checksums.yaml +4 -4
  2. data/lib/graphql/analysis/analyze_query.rb +4 -2
  3. data/lib/graphql/analysis/field_usage.rb +4 -4
  4. data/lib/graphql/analysis/query_complexity.rb +16 -21
  5. data/lib/graphql/argument.rb +13 -6
  6. data/lib/graphql/base_type.rb +2 -1
  7. data/lib/graphql/compatibility/execution_specification.rb +76 -0
  8. data/lib/graphql/compatibility/query_parser_specification.rb +16 -2
  9. data/lib/graphql/compatibility/query_parser_specification/parse_error_specification.rb +0 -5
  10. data/lib/graphql/compatibility/schema_parser_specification.rb +6 -0
  11. data/lib/graphql/define/assign_argument.rb +8 -2
  12. data/lib/graphql/define/instance_definable.rb +12 -15
  13. data/lib/graphql/directive.rb +2 -1
  14. data/lib/graphql/enum_type.rb +5 -7
  15. data/lib/graphql/field.rb +6 -11
  16. data/lib/graphql/field/resolve.rb +1 -0
  17. data/lib/graphql/input_object_type.rb +9 -9
  18. data/lib/graphql/interface_type.rb +2 -1
  19. data/lib/graphql/internal_representation.rb +1 -0
  20. data/lib/graphql/internal_representation/node.rb +31 -9
  21. data/lib/graphql/internal_representation/rewrite.rb +26 -26
  22. data/lib/graphql/internal_representation/selections.rb +41 -0
  23. data/lib/graphql/introspection/input_value_type.rb +6 -2
  24. data/lib/graphql/language/generation.rb +2 -0
  25. data/lib/graphql/language/lexer.rl +4 -0
  26. data/lib/graphql/language/nodes.rb +3 -0
  27. data/lib/graphql/language/parser.rb +525 -509
  28. data/lib/graphql/language/parser.y +2 -0
  29. data/lib/graphql/object_type.rb +2 -2
  30. data/lib/graphql/query.rb +21 -0
  31. data/lib/graphql/query/context.rb +52 -4
  32. data/lib/graphql/query/serial_execution.rb +3 -4
  33. data/lib/graphql/query/serial_execution/field_resolution.rb +35 -36
  34. data/lib/graphql/query/serial_execution/operation_resolution.rb +9 -15
  35. data/lib/graphql/query/serial_execution/selection_resolution.rb +14 -11
  36. data/lib/graphql/query/serial_execution/value_resolution.rb +18 -17
  37. data/lib/graphql/query/variables.rb +1 -1
  38. data/lib/graphql/relay/mutation.rb +5 -8
  39. data/lib/graphql/scalar_type.rb +1 -2
  40. data/lib/graphql/schema.rb +2 -13
  41. data/lib/graphql/schema/build_from_definition.rb +28 -13
  42. data/lib/graphql/schema/loader.rb +4 -1
  43. data/lib/graphql/schema/printer.rb +10 -3
  44. data/lib/graphql/schema/timeout_middleware.rb +18 -2
  45. data/lib/graphql/schema/unique_within_type.rb +6 -3
  46. data/lib/graphql/static_validation/literal_validator.rb +3 -1
  47. data/lib/graphql/union_type.rb +1 -2
  48. data/lib/graphql/version.rb +1 -1
  49. data/readme.md +1 -0
  50. data/spec/graphql/analysis/analyze_query_spec.rb +6 -8
  51. data/spec/graphql/argument_spec.rb +18 -0
  52. data/spec/graphql/define/assign_argument_spec.rb +48 -0
  53. data/spec/graphql/define/instance_definable_spec.rb +4 -2
  54. data/spec/graphql/execution_error_spec.rb +66 -0
  55. data/spec/graphql/input_object_type_spec.rb +81 -0
  56. data/spec/graphql/internal_representation/rewrite_spec.rb +104 -21
  57. data/spec/graphql/introspection/input_value_type_spec.rb +43 -6
  58. data/spec/graphql/introspection/schema_type_spec.rb +1 -0
  59. data/spec/graphql/introspection/type_type_spec.rb +2 -0
  60. data/spec/graphql/language/generation_spec.rb +3 -2
  61. data/spec/graphql/query/arguments_spec.rb +17 -4
  62. data/spec/graphql/query/context_spec.rb +23 -0
  63. data/spec/graphql/query/variables_spec.rb +15 -1
  64. data/spec/graphql/relay/mutation_spec.rb +42 -2
  65. data/spec/graphql/schema/build_from_definition_spec.rb +4 -2
  66. data/spec/graphql/schema/loader_spec.rb +59 -1
  67. data/spec/graphql/schema/printer_spec.rb +2 -0
  68. data/spec/graphql/schema/reduce_types_spec.rb +1 -1
  69. data/spec/graphql/schema/timeout_middleware_spec.rb +2 -2
  70. data/spec/graphql/schema/unique_within_type_spec.rb +9 -0
  71. data/spec/graphql/schema/validation_spec.rb +15 -3
  72. data/spec/graphql/static_validation/rules/argument_literals_are_compatible_spec.rb +122 -0
  73. data/spec/graphql/static_validation/rules/variable_default_values_are_correctly_typed_spec.rb +78 -0
  74. data/spec/support/dairy_app.rb +9 -0
  75. data/spec/support/minimum_input_object.rb +4 -0
  76. data/spec/support/star_wars_schema.rb +1 -1
  77. metadata +5 -5
  78. data/lib/graphql/query/serial_execution/execution_context.rb +0 -37
  79. data/spec/graphql/query/serial_execution/execution_context_spec.rb +0 -54
@@ -43,4 +43,82 @@ describe GraphQL::StaticValidation::VariableDefaultValuesAreCorrectlyTyped do
43
43
  ]
44
44
  assert_equal(expected, errors)
45
45
  end
46
+
47
+ describe "null default values" do
48
+ describe "variables with valid default null values" do
49
+ let(:schema) {
50
+ GraphQL::Schema.from_definition(%|
51
+ type Query {
52
+ field(a: Int, b: String, c: ComplexInput): Int
53
+ }
54
+
55
+ input ComplexInput {
56
+ requiredField: Boolean!
57
+ intField: Int
58
+ }
59
+ |)
60
+ }
61
+
62
+ let(:query_string) {%|
63
+ query getCheese(
64
+ $a: Int = null,
65
+ $b: String = null,
66
+ $c: ComplexInput = { requiredField: true, intField: null }
67
+ ) {
68
+ field(a: $a, b: $b, c: $c)
69
+ }
70
+ |}
71
+
72
+ it "finds no errors" do
73
+ assert_equal [], errors
74
+ end
75
+ end
76
+
77
+ describe "variables with invalid default null values" do
78
+ let(:schema) {
79
+ GraphQL::Schema.from_definition(%|
80
+ type Query {
81
+ field(a: Int!, b: String!, c: ComplexInput): Int
82
+ }
83
+
84
+ input ComplexInput {
85
+ requiredField: Boolean!
86
+ intField: Int
87
+ }
88
+ |)
89
+ }
90
+
91
+ let(:query_string) {%|
92
+ query getCheese(
93
+ $a: Int! = null,
94
+ $b: String! = null,
95
+ $c: ComplexInput = { requiredField: null, intField: null }
96
+ ) {
97
+ field(a: $a, b: $b, c: $c)
98
+ }
99
+ |}
100
+
101
+ it "finds errors" do
102
+ expected = [
103
+ {
104
+ "message"=>"Non-null variable $a can't have a default value",
105
+ "locations"=>[{"line"=>3, "column"=>11}],
106
+ "fields"=>["query getCheese"]
107
+ },
108
+ {
109
+ "message"=>"Non-null variable $b can't have a default value",
110
+ "locations"=>[{"line"=>4, "column"=>11}],
111
+ "fields"=>["query getCheese"]
112
+ },
113
+ {
114
+ "message"=>"Default value for $c doesn't match type ComplexInput",
115
+ "locations"=>[{"line"=>5, "column"=>11}],
116
+ "fields"=>["query getCheese"]
117
+ }
118
+ ]
119
+
120
+ assert_equal expected, errors
121
+ end
122
+ end
123
+ end
46
124
  end
@@ -16,6 +16,7 @@ EdibleInterface = GraphQL::InterfaceType.define do
16
16
  description "Something you can eat, yum"
17
17
  field :fatContent, !types.Float, "Percentage which is fat"
18
18
  field :origin, !types.String, "Place the edible comes from"
19
+ field :selfAsEdible, EdibleInterface, resolve: ->(o, a, c) { o }
19
20
  end
20
21
 
21
22
  AnimalProductInterface = GraphQL::InterfaceType.define do
@@ -297,6 +298,14 @@ DairyAppQueryType = GraphQL::ObjectType.define do
297
298
  resolve ->(t, a, c) { raise(GraphQL::ExecutionError, "There was an execution error") }
298
299
  end
299
300
 
301
+ field :valueWithExecutionError do
302
+ type !GraphQL::INT_TYPE
303
+ resolve ->(t, a, c) {
304
+ c.add_error(GraphQL::ExecutionError.new("Could not fetch latest value"))
305
+ return 0
306
+ }
307
+ end
308
+
300
309
  # To test possibly-null fields
301
310
  field :maybeNull, MaybeNullType do
302
311
  resolve ->(t, a, c) { OpenStruct.new(cheese: nil) }
@@ -13,4 +13,8 @@ class MinimumInputObject
13
13
  def [](key)
14
14
  @values[key]
15
15
  end
16
+
17
+ def key?(key)
18
+ @values.key?(key)
19
+ end
16
20
  end
@@ -147,7 +147,7 @@ IntroduceShipMutation = GraphQL::Relay::Mutation.define do
147
147
  description "Add a ship to this faction"
148
148
 
149
149
  # Nested under `input` in the query:
150
- input_field :shipName, !types.String
150
+ input_field :shipName, types.String
151
151
  input_field :factionId, !types.ID
152
152
 
153
153
  # Result may have access to these fields:
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: graphql
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Robert Mosolgo
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-11-01 00:00:00.000000000 Z
11
+ date: 2016-11-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: codeclimate-test-reporter
@@ -306,6 +306,7 @@ files:
306
306
  - lib/graphql/internal_representation.rb
307
307
  - lib/graphql/internal_representation/node.rb
308
308
  - lib/graphql/internal_representation/rewrite.rb
309
+ - lib/graphql/internal_representation/selections.rb
309
310
  - lib/graphql/introspection.rb
310
311
  - lib/graphql/introspection/arguments_field.rb
311
312
  - lib/graphql/introspection/directive_location_enum.rb
@@ -348,7 +349,6 @@ files:
348
349
  - lib/graphql/query/input_validation_result.rb
349
350
  - lib/graphql/query/literal_input.rb
350
351
  - lib/graphql/query/serial_execution.rb
351
- - lib/graphql/query/serial_execution/execution_context.rb
352
352
  - lib/graphql/query/serial_execution/field_resolution.rb
353
353
  - lib/graphql/query/serial_execution/operation_resolution.rb
354
354
  - lib/graphql/query/serial_execution/selection_resolution.rb
@@ -432,6 +432,7 @@ files:
432
432
  - spec/graphql/compatibility/execution_specification_spec.rb
433
433
  - spec/graphql/compatibility/query_parser_specification_spec.rb
434
434
  - spec/graphql/compatibility/schema_parser_specification_spec.rb
435
+ - spec/graphql/define/assign_argument_spec.rb
435
436
  - spec/graphql/define/instance_definable_spec.rb
436
437
  - spec/graphql/directive_spec.rb
437
438
  - spec/graphql/enum_type_spec.rb
@@ -462,7 +463,6 @@ files:
462
463
  - spec/graphql/query/arguments_spec.rb
463
464
  - spec/graphql/query/context_spec.rb
464
465
  - spec/graphql/query/executor_spec.rb
465
- - spec/graphql/query/serial_execution/execution_context_spec.rb
466
466
  - spec/graphql/query/serial_execution/value_resolution_spec.rb
467
467
  - spec/graphql/query/variables_spec.rb
468
468
  - spec/graphql/query_spec.rb
@@ -556,6 +556,7 @@ test_files:
556
556
  - spec/graphql/compatibility/execution_specification_spec.rb
557
557
  - spec/graphql/compatibility/query_parser_specification_spec.rb
558
558
  - spec/graphql/compatibility/schema_parser_specification_spec.rb
559
+ - spec/graphql/define/assign_argument_spec.rb
559
560
  - spec/graphql/define/instance_definable_spec.rb
560
561
  - spec/graphql/directive_spec.rb
561
562
  - spec/graphql/enum_type_spec.rb
@@ -586,7 +587,6 @@ test_files:
586
587
  - spec/graphql/query/arguments_spec.rb
587
588
  - spec/graphql/query/context_spec.rb
588
589
  - spec/graphql/query/executor_spec.rb
589
- - spec/graphql/query/serial_execution/execution_context_spec.rb
590
590
  - spec/graphql/query/serial_execution/value_resolution_spec.rb
591
591
  - spec/graphql/query/variables_spec.rb
592
592
  - spec/graphql/query_spec.rb
@@ -1,37 +0,0 @@
1
- module GraphQL
2
- class Query
3
- class SerialExecution
4
- class ExecutionContext
5
- attr_reader :query, :schema, :strategy
6
-
7
- def initialize(query, strategy)
8
- @query = query
9
- @schema = query.schema
10
- @strategy = strategy
11
- @warden = query.warden
12
- end
13
-
14
- def get_type(type_name)
15
- @warden.get_type(type_name)
16
- end
17
-
18
- def get_fragment(name)
19
- @query.fragments[name]
20
- end
21
-
22
- def get_field(type, irep_node)
23
- # fall back for dynamic fields (eg __typename)
24
- irep_node.definitions[type] || @warden.get_field(type, irep_node.definition_name) || raise("No field found on #{type.name} for '#{irep_node.definition_name}' (#{irep_node.ast_node.name})")
25
- end
26
-
27
- def possible_types(type)
28
- @warden.possible_types(type)
29
- end
30
-
31
- def add_error(err)
32
- @query.context.errors << err
33
- end
34
- end
35
- end
36
- end
37
- end
@@ -1,54 +0,0 @@
1
- require "spec_helper"
2
-
3
- describe GraphQL::Query::SerialExecution::ExecutionContext do
4
- let(:query_string) { %|
5
- query getFlavor($cheeseId: Int!) {
6
- brie: cheese(id: 1) { ...cheeseFields, taste: flavor }
7
- }
8
- fragment cheeseFields on Cheese { flavor }
9
- |}
10
- let(:operation_name) { nil }
11
- let(:query_variables) { {"cheeseId" => 2} }
12
- let(:schema) { DummySchema }
13
- let(:query) { GraphQL::Query.new(
14
- schema,
15
- query_string,
16
- variables: query_variables,
17
- operation_name: operation_name,
18
- )}
19
- let(:execution_context) {
20
- GraphQL::Query::SerialExecution::ExecutionContext.new(query, nil)
21
- }
22
-
23
- describe "add_error" do
24
- let(:err) { StandardError.new("test") }
25
- let(:expected) { [err] }
26
-
27
- it "adds an error on the query context" do
28
- execution_context.add_error(err)
29
- assert_equal(expected, query.context.errors)
30
- end
31
- end
32
-
33
- describe "get_type" do
34
- it "returns the respective type from the schema" do
35
- type = execution_context.get_type("Dairy")
36
- assert_equal(DairyType, type)
37
- end
38
- end
39
-
40
- describe "get_field" do
41
- it "returns the respective field from the schema" do
42
- irep_node = OpenStruct.new(definition_name: "cheese", definitions: {DairyType => DairyType.fields["cheese"]})
43
- field = execution_context.get_field(DairyType, irep_node)
44
- assert_equal("cheese", field.name)
45
- end
46
- end
47
-
48
- describe "get_fragment" do
49
- it "returns a fragment on the query by name" do
50
- fragment = execution_context.get_fragment("cheeseFields")
51
- assert_equal("cheeseFields", fragment.name)
52
- end
53
- end
54
- end