graphql 1.1.0 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
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