graphql 1.8.0.pre10 → 1.8.0.pre11
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/lib/generators/graphql/install_generator.rb +14 -8
- data/lib/graphql.rb +1 -24
- data/lib/graphql/backtrace.rb +1 -1
- data/lib/graphql/deprecated_dsl.rb +2 -2
- data/lib/graphql/execution/execute.rb +6 -0
- data/lib/graphql/execution/lazy/lazy_method_map.rb +1 -1
- data/lib/graphql/introspection/base_object.rb +1 -0
- data/lib/graphql/language/document_from_schema_definition.rb +4 -1
- data/lib/graphql/language/nodes.rb +5 -2
- data/lib/graphql/language/parser.rb +288 -288
- data/lib/graphql/language/parser.y +1 -1
- data/lib/graphql/language/printer.rb +12 -2
- data/lib/graphql/non_null_type.rb +1 -1
- data/lib/graphql/query.rb +1 -1
- data/lib/graphql/query/arguments.rb +1 -1
- data/lib/graphql/query/context.rb +2 -2
- data/lib/graphql/query/null_context.rb +1 -1
- data/lib/graphql/query/result.rb +1 -1
- data/lib/graphql/query/variables.rb +21 -3
- data/lib/graphql/relay.rb +1 -0
- data/lib/graphql/relay/mongo_relation_connection.rb +40 -0
- data/lib/graphql/scalar_type.rb +14 -2
- data/lib/graphql/schema.rb +17 -1
- data/lib/graphql/schema/argument.rb +39 -7
- data/lib/graphql/schema/enum.rb +7 -0
- data/lib/graphql/schema/field.rb +145 -39
- data/lib/graphql/schema/finder.rb +4 -4
- data/lib/graphql/schema/input_object.rb +13 -2
- data/lib/graphql/schema/interface.rb +50 -16
- data/lib/graphql/schema/list.rb +28 -0
- data/lib/graphql/schema/member.rb +8 -106
- data/lib/graphql/schema/member/accepts_definition.rb +58 -24
- data/lib/graphql/schema/member/base_dsl_methods.rb +96 -0
- data/lib/graphql/schema/member/build_type.rb +15 -9
- data/lib/graphql/schema/member/cached_graphql_definition.rb +26 -0
- data/lib/graphql/schema/member/graphql_type_names.rb +21 -0
- data/lib/graphql/schema/member/has_arguments.rb +1 -1
- data/lib/graphql/schema/member/has_fields.rb +91 -8
- data/lib/graphql/schema/member/type_system_helpers.rb +34 -0
- data/lib/graphql/schema/middleware_chain.rb +5 -1
- data/lib/graphql/schema/mutation.rb +24 -12
- data/lib/graphql/schema/non_null.rb +34 -0
- data/lib/graphql/schema/object.rb +24 -11
- data/lib/graphql/schema/relay_classic_mutation.rb +14 -11
- data/lib/graphql/schema/rescue_middleware.rb +8 -7
- data/lib/graphql/schema/scalar.rb +9 -2
- data/lib/graphql/schema/union.rb +4 -0
- data/lib/graphql/static_validation/definition_dependencies.rb +1 -1
- data/lib/graphql/static_validation/literal_validator.rb +16 -4
- data/lib/graphql/static_validation/validation_context.rb +1 -1
- data/lib/graphql/subscriptions.rb +90 -16
- data/lib/graphql/upgrader/member.rb +27 -89
- data/lib/graphql/version.rb +1 -1
- data/spec/dummy/app/channels/graphql_channel.rb +1 -1
- data/spec/dummy/log/test.log +206 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/-x/-xYZjAnuuzgR79fcznLTQtSdh6AARxu8FcQ_J6p7L3U.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/13/13HiV12xyoQvT-1L39ZzLwMZxjyaGMiENmfw7f-QTIc.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/3W/3Wtf5pCWdqq0AB-iB0Y9uUNrTkruRxIEf1XFn_BETU0.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/5i/5iguGafb4hOn8262Kn8Q37ogNN9MxxQKGKNzHAzUcvI.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/8m/8mj2T6yy847Mc2Z7k3Xzh8O91hhVJt3NrPe8ASNDlIA.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/DT/DTQyMpr4ABZYQetsdRJ5A7S4jf1r3ie4FGOR7GZBNSs.cache +3 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Dq/DqJ5_yJPrP5iLlOQyTQsjAVI5FE5LCVDkED0f7GgsSo.cache +3 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/F8/F8MUNRzORGFgr329fNM0xLaoWCXdv3BIalT7dsvLfjs.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/KB/KB07ZaKNC5uXJ7TjLi-WqnY6g7dq8wWp_8N3HNjBNxg.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Rw/RwDuCV-XpnCtjNkvhpJfBuxXMk0b5AD3L9eR6M-wcy0.cache +3 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/UL/ULdjhhb0bRuqmaG7XSZlFYzGYCXTDnqZuJBTWRlzqgw.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Up/UpPNgh0yYoUsyMDh5zWqe_U6qJIyTC6-dxMMAs1vvlM.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Wg/Wguh-szFGTI1gaL6npYwPekMXflugRei7F_mOyRucXg.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/X-/X-khLYMA9mqFRPg3zAi86mREDxpKl4bdKYp3uF6WHos.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/bi/BIkdhfxsezxM4q-HZ4oCNTq97WEJTigcq0tpX2cDvbY.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/ff/FfxmA4CMHQZT7exx0G7NS1Wpcnny0vzp-Jhc2H36bp8.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/gE/gEiiG4GZNy_djEjK2pHm_NgA-gyhLZhdQvo0Yt96GqE.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/gn/gnA9ZSqpjccNL2m8pe_jBvY6SinXlCzXDWyop83Od8s.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/lO/lOAan3cMwCE_Hli6gsDML88xFNfn0nxPmvrSkW7eEOw.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/m1/M1pv8MJEPLXGLvS8QxVh3DSO9cI4mRt5FHFWdrvUj6o.cache +2 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/m7/m77qH7ZqH0_0SmwJbiKGDd-aLau1Dav847DC6ge46zY.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/sj/sjRjnjRB37lH2vrgtkdJ8Cz84__IJ978IuKTM7HcztI.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/um/um1JrirR4hJhK-1rE-HywlyCi5ibgxHVrReiujZBWJM.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/v4/v4fwVytD7ITcE0_GDbslZEYud8a5Okm85fV1o7SDl6g.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/v_/v_0PAQt0iipQjFP5zjgkkk9Stnpf4VzvnMv67d1Keuw.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/wd/wdT9U4MKxe1PyqNjVuCKMpCl3dxGCIRJIlwUTfh2DQU.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/xI/xIaxut_fEIhKBDqljTNwYaADK9kj3gG0ESrfHs-5_og.cache +3 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/y0/y0SJOqIx2fn1SKqOkAihsQow0trRJrSIyAswufVuoA8.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/zg/zgpzeaX-KZErHyGJ1aBH3ZusweNXMneVZule88XsIJI.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/zy/zYFltDy-8VC-uKq2BVEiJJyYXNFvVzAKuMlR3ZIYZsk.cache +0 -0
- data/spec/dummy/tmp/screenshots/failures_test_it_handles_subscriptions.png +0 -0
- data/spec/fixtures/upgrader/photo.original.rb +10 -0
- data/spec/fixtures/upgrader/photo.transformed.rb +12 -0
- data/spec/fixtures/upgrader/starrable.original.rb +4 -1
- data/spec/fixtures/upgrader/starrable.transformed.rb +25 -22
- data/spec/fixtures/upgrader/subscribable.transformed.rb +32 -33
- data/spec/graphql/execution_error_spec.rb +18 -0
- data/spec/graphql/introspection/schema_type_spec.rb +1 -0
- data/spec/graphql/object_type_spec.rb +2 -1
- data/spec/graphql/query/variables_spec.rb +41 -0
- data/spec/graphql/relay/mongo_relation_connection_spec.rb +474 -0
- data/spec/graphql/schema/argument_spec.rb +65 -9
- data/spec/graphql/schema/build_from_definition_spec.rb +4 -2
- data/spec/graphql/schema/enum_spec.rb +1 -1
- data/spec/graphql/schema/field_spec.rb +79 -4
- data/spec/graphql/schema/input_object_spec.rb +56 -0
- data/spec/graphql/schema/instrumentation_spec.rb +4 -3
- data/spec/graphql/schema/interface_spec.rb +40 -25
- data/spec/graphql/schema/member/accepts_definition_spec.rb +38 -11
- data/spec/graphql/schema/member/has_fields_spec.rb +129 -0
- data/spec/graphql/schema/member/type_system_helpers_spec.rb +63 -0
- data/spec/graphql/schema/mutation_spec.rb +48 -0
- data/spec/graphql/schema/object_spec.rb +34 -8
- data/spec/graphql/schema/relay_classic_mutation_spec.rb +10 -0
- data/spec/graphql/schema/rescue_middleware_spec.rb +11 -0
- data/spec/graphql/schema/scalar_spec.rb +55 -0
- data/spec/graphql/subscriptions_spec.rb +31 -4
- data/spec/graphql/upgrader/member_spec.rb +14 -6
- data/spec/spec_helper.rb +7 -0
- data/spec/support/dummy/schema.rb +8 -0
- data/spec/support/jazz.rb +89 -19
- data/spec/support/star_trek/data.rb +109 -0
- data/spec/support/star_trek/schema.rb +388 -0
- metadata +80 -7
- data/lib/graphql/schema/field/dynamic_resolve.rb +0 -70
- data/lib/graphql/schema/field/unwrapped_resolve.rb +0 -20
- data/lib/graphql/schema/member/list_type_proxy.rb +0 -25
- data/lib/graphql/schema/member/non_null_type_proxy.rb +0 -25
@@ -2,30 +2,86 @@
|
|
2
2
|
require "spec_helper"
|
3
3
|
|
4
4
|
describe GraphQL::Schema::Argument do
|
5
|
-
|
6
|
-
|
7
|
-
|
5
|
+
module SchemaArgumentTest
|
6
|
+
class Query < GraphQL::Schema::Object
|
7
|
+
field :field, String, null: false do
|
8
|
+
argument :arg, String, description: "test", required: false
|
8
9
|
|
9
|
-
|
10
|
-
|
10
|
+
argument :arg_with_block, String, required: false do
|
11
|
+
description "test"
|
12
|
+
end
|
13
|
+
|
14
|
+
argument :aliased_arg, String, required: false, as: :renamed
|
15
|
+
argument :prepared_arg, Int, required: false, prepare: :multiply
|
16
|
+
end
|
17
|
+
|
18
|
+
def field(**args)
|
19
|
+
args.inspect
|
11
20
|
end
|
21
|
+
|
22
|
+
def multiply(val)
|
23
|
+
context[:multiply_by] * val
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
class Schema < GraphQL::Schema
|
28
|
+
query(Query)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
|
33
|
+
|
34
|
+
describe "#name" do
|
35
|
+
it "reflects camelization" do
|
36
|
+
assert_equal "argWithBlock", SchemaArgumentTest::Query.fields["field"].arguments["argWithBlock"].name
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
describe "#type" do
|
41
|
+
let(:argument) { SchemaArgumentTest::Query.fields["field"].arguments["arg"] }
|
42
|
+
it "returns the type" do
|
43
|
+
assert_equal GraphQL::STRING_TYPE, argument.type
|
12
44
|
end
|
13
45
|
end
|
14
46
|
|
15
47
|
describe "graphql definition" do
|
16
48
|
it "calls block" do
|
17
|
-
assert_equal "test", SchemaArgumentTest.fields["field"].arguments["argWithBlock"].description
|
49
|
+
assert_equal "test", SchemaArgumentTest::Query.fields["field"].arguments["argWithBlock"].description
|
18
50
|
end
|
19
51
|
end
|
20
52
|
|
21
53
|
describe "#description" do
|
22
54
|
it "sets description" do
|
23
|
-
SchemaArgumentTest.fields["field"].arguments["arg"].description "new description"
|
24
|
-
assert_equal "new description", SchemaArgumentTest.fields["field"].arguments["arg"].description
|
55
|
+
SchemaArgumentTest::Query.fields["field"].arguments["arg"].description "new description"
|
56
|
+
assert_equal "new description", SchemaArgumentTest::Query.fields["field"].arguments["arg"].description
|
25
57
|
end
|
26
58
|
|
27
59
|
it "returns description" do
|
28
|
-
assert_equal "test", SchemaArgumentTest.fields["field"].arguments["argWithBlock"].description
|
60
|
+
assert_equal "test", SchemaArgumentTest::Query.fields["field"].arguments["argWithBlock"].description
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
describe "as:" do
|
65
|
+
it "uses that Symbol for Ruby kwargs" do
|
66
|
+
query_str = <<-GRAPHQL
|
67
|
+
{ field(aliasedArg: "x") }
|
68
|
+
GRAPHQL
|
69
|
+
|
70
|
+
res = SchemaArgumentTest::Schema.execute(query_str)
|
71
|
+
# Make sure it's getting the renamed symbol:
|
72
|
+
assert_equal '{:renamed=>"x"}', res["data"]["field"]
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
describe "prepare:" do
|
77
|
+
it "calls the method on the field's owner" do
|
78
|
+
query_str = <<-GRAPHQL
|
79
|
+
{ field(preparedArg: 5) }
|
80
|
+
GRAPHQL
|
81
|
+
|
82
|
+
res = SchemaArgumentTest::Schema.execute(query_str, context: {multiply_by: 3})
|
83
|
+
# Make sure it's getting the renamed symbol:
|
84
|
+
assert_equal '{:prepared_arg=>15}', res["data"]["field"]
|
29
85
|
end
|
30
86
|
end
|
31
87
|
end
|
@@ -132,11 +132,12 @@ type Hello {
|
|
132
132
|
|
133
133
|
it 'supports adding directives while maintaining built-in directives' do
|
134
134
|
schema = <<-SCHEMA
|
135
|
-
schema {
|
135
|
+
schema @custom(thing: true) {
|
136
136
|
query: Hello
|
137
137
|
}
|
138
138
|
|
139
139
|
directive @foo(arg: Int) on FIELD
|
140
|
+
directive @custom(thing: Boolean) on SCHEMA
|
140
141
|
|
141
142
|
type Hello {
|
142
143
|
str: String
|
@@ -615,7 +616,7 @@ type Query {
|
|
615
616
|
|
616
617
|
it "tracks original AST node" do
|
617
618
|
schema_definition = <<-GRAPHQL
|
618
|
-
schema {
|
619
|
+
schema @custom(thing: true) {
|
619
620
|
query: Query
|
620
621
|
}
|
621
622
|
|
@@ -653,6 +654,7 @@ type Type implements Interface {
|
|
653
654
|
schema = GraphQL::Schema.from_definition(schema_definition)
|
654
655
|
|
655
656
|
assert_equal [1, 1], schema.ast_node.position
|
657
|
+
assert_equal [1, 8], schema.ast_node.directives.first.position
|
656
658
|
assert_equal [5, 1], schema.types["Enum"].ast_node.position
|
657
659
|
assert_equal [6, 3], schema.types["Enum"].values["VALUE"].ast_node.position
|
658
660
|
assert_equal [9, 1], schema.types["Query"].ast_node.position
|
@@ -67,7 +67,7 @@ describe GraphQL::Schema::Enum do
|
|
67
67
|
it "works as input" do
|
68
68
|
query_str = "query($family: Family!) { instruments(family: $family) { name } }"
|
69
69
|
expected_names = ["Piano", "Organ"]
|
70
|
-
result = Jazz::Schema.execute(query_str, variables: {
|
70
|
+
result = Jazz::Schema.execute(query_str, variables: { family: "KEYS" })
|
71
71
|
assert_equal expected_names, result["data"]["instruments"].map { |i| i["name"] }
|
72
72
|
end
|
73
73
|
end
|
@@ -4,15 +4,20 @@ require "spec_helper"
|
|
4
4
|
describe GraphQL::Schema::Field do
|
5
5
|
describe "graphql definition" do
|
6
6
|
let(:object_class) { Jazz::Query }
|
7
|
-
let(:field) { object_class.fields["
|
7
|
+
let(:field) { object_class.fields["inspectInput"] }
|
8
8
|
|
9
9
|
it "uses the argument class" do
|
10
10
|
arg_defn = field.graphql_definition.arguments.values.first
|
11
11
|
assert_equal :ok, arg_defn.metadata[:custom]
|
12
12
|
end
|
13
13
|
|
14
|
+
it "attaches itself to its graphql_definition as type_class" do
|
15
|
+
assert_equal field, field.graphql_definition.metadata[:type_class]
|
16
|
+
end
|
17
|
+
|
14
18
|
it "camelizes the field name, unless camelize: false" do
|
15
19
|
assert_equal 'inspectInput', field.graphql_definition.name
|
20
|
+
assert_equal 'inspectInput', field.name
|
16
21
|
|
17
22
|
underscored_field = GraphQL::Schema::Field.new(:underscored_field, String, null: false, camelize: false, owner: nil) do
|
18
23
|
argument :underscored_arg, String, required: true, camelize: false
|
@@ -25,11 +30,11 @@ describe GraphQL::Schema::Field do
|
|
25
30
|
end
|
26
31
|
|
27
32
|
it "exposes the method override" do
|
28
|
-
assert_nil field.method
|
29
33
|
object = Class.new(Jazz::BaseObject) do
|
30
34
|
field :t, String, method: :tt, null: true
|
31
35
|
end
|
32
|
-
assert_equal :tt, object.fields["t"].
|
36
|
+
assert_equal :tt, object.fields["t"].method_sym
|
37
|
+
assert_equal "tt", object.fields["t"].method_str
|
33
38
|
end
|
34
39
|
|
35
40
|
it "accepts a block for definition" do
|
@@ -84,6 +89,17 @@ describe GraphQL::Schema::Field do
|
|
84
89
|
assert_equal Jazz::Query, field.owner
|
85
90
|
end
|
86
91
|
|
92
|
+
describe "type" do
|
93
|
+
it "tells the return type" do
|
94
|
+
assert_equal "[String!]!", field.type.graphql_definition.to_s
|
95
|
+
end
|
96
|
+
|
97
|
+
it "returns the type class" do
|
98
|
+
field = Jazz::Query.fields["nowPlaying"]
|
99
|
+
assert_equal Jazz::PerformingAct, field.type.of_type
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
87
103
|
describe "complexity" do
|
88
104
|
it "accepts a keyword argument" do
|
89
105
|
object = Class.new(Jazz::BaseObject) do
|
@@ -158,10 +174,69 @@ describe GraphQL::Schema::Field do
|
|
158
174
|
end
|
159
175
|
|
160
176
|
err = assert_raises ArgumentError do
|
161
|
-
thing.fields["stuff"].
|
177
|
+
thing.fields["stuff"].type
|
178
|
+
end
|
179
|
+
|
180
|
+
assert_includes err.message, "Thing.stuff"
|
181
|
+
assert_includes err.message, "Unexpected class/module"
|
182
|
+
end
|
183
|
+
|
184
|
+
it "makes a suggestion when the type is false" do
|
185
|
+
thing = Class.new(GraphQL::Schema::Object) do
|
186
|
+
graphql_name "Thing"
|
187
|
+
# False might come from an invalid `!`
|
188
|
+
field :stuff, false, null: false
|
189
|
+
end
|
190
|
+
|
191
|
+
err = assert_raises ArgumentError do
|
192
|
+
thing.fields["stuff"].type
|
162
193
|
end
|
163
194
|
|
164
195
|
assert_includes err.message, "Thing.stuff"
|
196
|
+
assert_includes err.message, "Received `false` instead of a type, maybe a `!` should be replaced with `null: true` (for fields) or `required: true` (for arguments)"
|
197
|
+
end
|
198
|
+
|
199
|
+
it "makes a suggestion when the type is a GraphQL::Field" do
|
200
|
+
err = assert_raises ArgumentError do
|
201
|
+
Class.new(GraphQL::Schema::Object) do
|
202
|
+
graphql_name "Thing"
|
203
|
+
# Previously, field was a valid second argument
|
204
|
+
field :stuff, GraphQL::Relay::Node.field, null: false
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
208
|
+
assert_includes err.message, "use the `field:` keyword for this instead"
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
describe "mutation" do
|
213
|
+
let(:mutation) do
|
214
|
+
Class.new(GraphQL::Schema::Mutation) do
|
215
|
+
graphql_name "Thing"
|
216
|
+
|
217
|
+
field :stuff, String, null: false
|
218
|
+
end
|
219
|
+
end
|
220
|
+
let(:error_message) { "when keyword `mutation:` is present, all arguments are ignored, please remove them" }
|
221
|
+
|
222
|
+
it "fails when including null option as true" do
|
223
|
+
error = assert_raises(ArgumentError) do
|
224
|
+
GraphQL::Schema::Field.new(:my_field, mutation: mutation, null: true)
|
225
|
+
end
|
226
|
+
|
227
|
+
assert_equal error.message, error_message
|
228
|
+
end
|
229
|
+
|
230
|
+
it "fails when including null option as false" do
|
231
|
+
error = assert_raises(ArgumentError) do
|
232
|
+
GraphQL::Schema::Field.new(:my_field, mutation: mutation, null: false)
|
233
|
+
end
|
234
|
+
|
235
|
+
assert_equal error.message, error_message
|
236
|
+
end
|
237
|
+
|
238
|
+
it "passes when not including extra arguments" do
|
239
|
+
assert_equal GraphQL::Schema::Field.new(:my_field, mutation: mutation).mutation, mutation
|
165
240
|
end
|
166
241
|
end
|
167
242
|
end
|
@@ -14,6 +14,22 @@ describe GraphQL::Schema::InputObject do
|
|
14
14
|
argument = input_object.arguments["name"]
|
15
15
|
assert_equal input_object, argument.owner
|
16
16
|
end
|
17
|
+
|
18
|
+
it "inherits arguments" do
|
19
|
+
base_class = Class.new(GraphQL::Schema::InputObject) do
|
20
|
+
argument :arg1, String, required: true
|
21
|
+
argument :arg2, String, required: true
|
22
|
+
end
|
23
|
+
|
24
|
+
subclass = Class.new(base_class) do
|
25
|
+
argument :arg2, Integer, required: true
|
26
|
+
argument :arg3, Integer, required: true
|
27
|
+
end
|
28
|
+
|
29
|
+
assert_equal 3, subclass.arguments.size
|
30
|
+
assert_equal ["arg1", "arg2", "arg3"], subclass.arguments.keys
|
31
|
+
assert_equal ["String!", "Int!", "Int!"], subclass.arguments.values.map { |a| a.type.to_s }
|
32
|
+
end
|
17
33
|
end
|
18
34
|
|
19
35
|
describe ".to_graphql" do
|
@@ -28,6 +44,46 @@ describe GraphQL::Schema::InputObject do
|
|
28
44
|
end
|
29
45
|
end
|
30
46
|
|
47
|
+
describe "prepare: / as:" do
|
48
|
+
module InputObjectPrepareTest
|
49
|
+
class InputObj < GraphQL::Schema::InputObject
|
50
|
+
argument :a, Integer, required: true
|
51
|
+
argument :b, Integer, required: true, as: :b2
|
52
|
+
argument :c, Integer, required: true, prepare: :prep
|
53
|
+
argument :d, Integer, required: true, prepare: :prep, as: :d2
|
54
|
+
argument :e, Integer, required: true, prepare: ->(val, ctx) { val * ctx[:multiply_by] * 2 }, as: :e2
|
55
|
+
|
56
|
+
def prep(val)
|
57
|
+
val * context[:multiply_by]
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
class Query < GraphQL::Schema::Object
|
62
|
+
field :inputs, String, null: false do
|
63
|
+
argument :input, InputObj, required: true
|
64
|
+
end
|
65
|
+
|
66
|
+
def inputs(input:)
|
67
|
+
input.to_kwargs.inspect
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
class Schema < GraphQL::Schema
|
72
|
+
query(Query)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
it "calls methods on the input object" do
|
77
|
+
query_str = <<-GRAPHQL
|
78
|
+
{ inputs(input: { a: 1, b: 2, c: 3, d: 4, e: 5 }) }
|
79
|
+
GRAPHQL
|
80
|
+
|
81
|
+
res = InputObjectPrepareTest::Schema.execute(query_str, context: { multiply_by: 3 })
|
82
|
+
expected_obj = { a: 1, b2: 2, c: 9, d2: 12, e2: 30 }.inspect
|
83
|
+
assert_equal expected_obj, res["data"]["inputs"]
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
31
87
|
describe "in queries" do
|
32
88
|
it "is passed to the field method" do
|
33
89
|
query_str = <<-GRAPHQL
|
@@ -2,8 +2,9 @@
|
|
2
2
|
require "spec_helper"
|
3
3
|
|
4
4
|
module InstrumentationSpec
|
5
|
-
|
6
|
-
|
5
|
+
module SomeInterface
|
6
|
+
include GraphQL::Schema::Interface
|
7
|
+
field :never_called, String, null: false
|
7
8
|
|
8
9
|
def never_called
|
9
10
|
"should never be called"
|
@@ -15,7 +16,7 @@ module InstrumentationSpec
|
|
15
16
|
end
|
16
17
|
|
17
18
|
class Query < GraphQL::Schema::Object
|
18
|
-
field :
|
19
|
+
field :some_field, [SomeInterface], null: true
|
19
20
|
|
20
21
|
def some_field
|
21
22
|
nil
|
@@ -10,21 +10,17 @@ describe GraphQL::Schema::Interface do
|
|
10
10
|
assert_equal 2, interface.fields.size
|
11
11
|
end
|
12
12
|
|
13
|
-
|
14
|
-
|
15
|
-
module Implementation
|
16
|
-
include Jazz::GloballyIdentifiableType::Implementation
|
17
|
-
end
|
13
|
+
module NewInterface1
|
14
|
+
include Jazz::GloballyIdentifiableType
|
18
15
|
end
|
19
16
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
end
|
17
|
+
module NewInterface2
|
18
|
+
include Jazz::GloballyIdentifiableType
|
19
|
+
def new_method
|
24
20
|
end
|
25
21
|
end
|
26
22
|
|
27
|
-
it "can override
|
23
|
+
it "can override methods" do
|
28
24
|
new_object_1 = Class.new(GraphQL::Schema::Object) do
|
29
25
|
implements NewInterface1
|
30
26
|
end
|
@@ -33,14 +29,19 @@ describe GraphQL::Schema::Interface do
|
|
33
29
|
assert new_object_1.method_defined?(:id)
|
34
30
|
|
35
31
|
new_object_2 = Class.new(GraphQL::Schema::Object) do
|
32
|
+
graphql_name "XYZ"
|
36
33
|
implements NewInterface2
|
34
|
+
field :id, "ID", null: false, description: "The ID !!!!!"
|
37
35
|
end
|
38
36
|
|
39
37
|
assert_equal 2, new_object_2.fields.size
|
40
38
|
# It got the new method
|
41
39
|
assert new_object_2.method_defined?(:new_method)
|
42
|
-
#
|
43
|
-
|
40
|
+
# And the inherited method
|
41
|
+
assert new_object_2.method_defined?(:id)
|
42
|
+
|
43
|
+
# It gets an overridden description:
|
44
|
+
assert_equal "The ID !!!!!", new_object_2.graphql_definition.fields["id"].description
|
44
45
|
end
|
45
46
|
end
|
46
47
|
|
@@ -57,25 +58,25 @@ describe GraphQL::Schema::Interface do
|
|
57
58
|
end
|
58
59
|
|
59
60
|
it "can specify a resolve_type method" do
|
60
|
-
interface =
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
61
|
+
interface = Module.new do
|
62
|
+
include GraphQL::Schema::Interface
|
63
|
+
graphql_name "MyInterface"
|
64
|
+
|
65
|
+
module self::DefinitionMethods # rubocop:disable Style/ClassAndModuleChildren
|
66
|
+
def resolve_type(_object, _context)
|
67
|
+
"MyType"
|
68
|
+
end
|
67
69
|
end
|
68
70
|
end
|
71
|
+
|
69
72
|
interface_type = interface.to_graphql
|
70
73
|
assert_equal "MyType", interface_type.resolve_type_proc.call(nil, nil)
|
71
74
|
end
|
72
75
|
|
73
76
|
it "can specify orphan types" do
|
74
|
-
interface =
|
75
|
-
|
76
|
-
|
77
|
-
end
|
78
|
-
|
77
|
+
interface = Module.new do
|
78
|
+
include GraphQL::Schema::Interface
|
79
|
+
graphql_name "MyInterface"
|
79
80
|
orphan_types Dummy::CheeseType, Dummy::HoneyType
|
80
81
|
end
|
81
82
|
|
@@ -85,10 +86,12 @@ describe GraphQL::Schema::Interface do
|
|
85
86
|
end
|
86
87
|
|
87
88
|
it 'supports global_id_field' do
|
88
|
-
object =
|
89
|
+
object = Module.new do
|
90
|
+
include GraphQL::Schema::Interface
|
89
91
|
graphql_name 'GlobalIdFieldTest'
|
90
92
|
global_id_field :uuid
|
91
93
|
end.to_graphql
|
94
|
+
|
92
95
|
uuid_field = object.fields["uuid"]
|
93
96
|
|
94
97
|
assert_equal GraphQL::NonNullType, uuid_field.type.class
|
@@ -99,6 +102,18 @@ describe GraphQL::Schema::Interface do
|
|
99
102
|
)
|
100
103
|
end
|
101
104
|
|
105
|
+
describe "using `include`" do
|
106
|
+
it "raises" do
|
107
|
+
err = assert_raises RuntimeError do
|
108
|
+
Class.new(GraphQL::Schema::Object) do
|
109
|
+
include(Jazz::GloballyIdentifiableType)
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
assert_includes err.message, "implements(Jazz::GloballyIdentifiableType)"
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
102
117
|
describe "in queries" do
|
103
118
|
it "works" do
|
104
119
|
query_str = <<-GRAPHQL
|