graphql 1.4.5 → 1.5.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/generators/graphql/enum_generator.rb +33 -0
- data/lib/generators/graphql/function_generator.rb +15 -0
- data/lib/generators/graphql/install_generator.rb +118 -0
- data/lib/generators/graphql/interface_generator.rb +27 -0
- data/lib/generators/graphql/loader_generator.rb +17 -0
- data/lib/generators/graphql/mutation_generator.rb +19 -0
- data/lib/generators/graphql/object_generator.rb +34 -0
- data/lib/generators/graphql/templates/enum.erb +4 -0
- data/lib/generators/graphql/templates/function.erb +17 -0
- data/lib/generators/graphql/templates/graphql_controller.erb +32 -0
- data/lib/generators/graphql/templates/interface.erb +4 -0
- data/lib/generators/graphql/templates/loader.erb +15 -0
- data/lib/generators/graphql/templates/mutation.erb +12 -0
- data/lib/generators/graphql/templates/object.erb +5 -0
- data/lib/generators/graphql/templates/query_type.erb +15 -0
- data/lib/generators/graphql/templates/schema.erb +34 -0
- data/lib/generators/graphql/templates/union.erb +4 -0
- data/lib/generators/graphql/type_generator.rb +78 -0
- data/lib/generators/graphql/union_generator.rb +33 -0
- data/lib/graphql.rb +10 -0
- data/lib/graphql/analysis/analyze_query.rb +1 -1
- data/lib/graphql/analysis/query_complexity.rb +6 -50
- data/lib/graphql/analysis/query_depth.rb +1 -1
- data/lib/graphql/argument.rb +21 -0
- data/lib/graphql/compatibility/execution_specification/counter_schema.rb +3 -3
- data/lib/graphql/define.rb +1 -0
- data/lib/graphql/define/assign_argument.rb +3 -19
- data/lib/graphql/define/assign_mutation_function.rb +34 -0
- data/lib/graphql/define/assign_object_field.rb +26 -14
- data/lib/graphql/define/defined_object_proxy.rb +21 -0
- data/lib/graphql/define/instance_definable.rb +61 -11
- data/lib/graphql/directive.rb +6 -1
- data/lib/graphql/execution/directive_checks.rb +1 -0
- data/lib/graphql/execution/execute.rb +14 -9
- data/lib/graphql/execution/field_result.rb +1 -0
- data/lib/graphql/execution/lazy.rb +8 -17
- data/lib/graphql/execution/lazy/lazy_method_map.rb +2 -0
- data/lib/graphql/execution/lazy/resolve.rb +1 -0
- data/lib/graphql/execution/selection_result.rb +1 -0
- data/lib/graphql/execution/typecast.rb +39 -26
- data/lib/graphql/field.rb +15 -3
- data/lib/graphql/field/resolve.rb +3 -3
- data/lib/graphql/function.rb +134 -0
- data/lib/graphql/id_type.rb +1 -1
- data/lib/graphql/input_object_type.rb +1 -1
- data/lib/graphql/internal_representation.rb +1 -1
- data/lib/graphql/internal_representation/node.rb +35 -107
- data/lib/graphql/internal_representation/rewrite.rb +189 -183
- data/lib/graphql/internal_representation/visit.rb +38 -0
- data/lib/graphql/introspection/input_value_type.rb +10 -1
- data/lib/graphql/introspection/schema_type.rb +1 -1
- data/lib/graphql/language/lexer.rb +6 -3
- data/lib/graphql/language/lexer.rl +6 -3
- data/lib/graphql/object_type.rb +53 -13
- data/lib/graphql/query.rb +30 -14
- data/lib/graphql/query/arguments.rb +2 -0
- data/lib/graphql/query/context.rb +2 -2
- data/lib/graphql/query/literal_input.rb +9 -0
- data/lib/graphql/query/serial_execution/field_resolution.rb +2 -2
- data/lib/graphql/query/serial_execution/selection_resolution.rb +1 -1
- data/lib/graphql/relay.rb +1 -0
- data/lib/graphql/relay/array_connection.rb +1 -1
- data/lib/graphql/relay/base_connection.rb +34 -15
- data/lib/graphql/relay/connection_resolve.rb +7 -2
- data/lib/graphql/relay/mutation.rb +45 -4
- data/lib/graphql/relay/node.rb +18 -6
- data/lib/graphql/relay/range_add.rb +45 -0
- data/lib/graphql/relay/relation_connection.rb +17 -2
- data/lib/graphql/runtime_type_error.rb +1 -0
- data/lib/graphql/schema.rb +40 -5
- data/lib/graphql/schema/base_64_encoder.rb +1 -0
- data/lib/graphql/schema/build_from_definition.rb +56 -21
- data/lib/graphql/schema/default_parse_error.rb +10 -0
- data/lib/graphql/schema/loader.rb +8 -1
- data/lib/graphql/schema/null_mask.rb +1 -0
- data/lib/graphql/schema/validation.rb +35 -0
- data/lib/graphql/static_validation.rb +1 -0
- data/lib/graphql/static_validation/all_rules.rb +1 -0
- data/lib/graphql/static_validation/arguments_validator.rb +7 -4
- data/lib/graphql/static_validation/definition_dependencies.rb +183 -0
- data/lib/graphql/static_validation/rules/fields_will_merge.rb +28 -96
- data/lib/graphql/static_validation/rules/fragment_names_are_unique.rb +23 -0
- data/lib/graphql/static_validation/rules/fragment_spreads_are_possible.rb +8 -5
- data/lib/graphql/static_validation/rules/fragments_are_finite.rb +6 -31
- data/lib/graphql/static_validation/rules/fragments_are_used.rb +11 -41
- data/lib/graphql/static_validation/rules/operation_names_are_valid.rb +2 -2
- data/lib/graphql/static_validation/rules/variable_usages_are_allowed.rb +19 -7
- data/lib/graphql/static_validation/validation_context.rb +22 -1
- data/lib/graphql/static_validation/validator.rb +4 -1
- data/lib/graphql/string_type.rb +5 -1
- data/lib/graphql/version.rb +1 -1
- data/readme.md +12 -3
- data/spec/generators/graphql/enum_generator_spec.rb +29 -0
- data/spec/generators/graphql/function_generator_spec.rb +33 -0
- data/spec/generators/graphql/install_generator_spec.rb +185 -0
- data/spec/generators/graphql/interface_generator_spec.rb +32 -0
- data/spec/generators/graphql/loader_generator_spec.rb +31 -0
- data/spec/generators/graphql/mutation_generator_spec.rb +28 -0
- data/spec/generators/graphql/object_generator_spec.rb +42 -0
- data/spec/generators/graphql/union_generator_spec.rb +50 -0
- data/spec/graphql/analysis/query_complexity_spec.rb +2 -1
- data/spec/graphql/define/instance_definable_spec.rb +38 -0
- data/spec/graphql/directive/skip_directive_spec.rb +1 -0
- data/spec/graphql/directive_spec.rb +18 -0
- data/spec/graphql/execution/typecast_spec.rb +41 -46
- data/spec/graphql/field_spec.rb +1 -1
- data/spec/graphql/function_spec.rb +128 -0
- data/spec/graphql/internal_representation/rewrite_spec.rb +166 -129
- data/spec/graphql/introspection/type_type_spec.rb +1 -1
- data/spec/graphql/language/lexer_spec.rb +6 -0
- data/spec/graphql/object_type_spec.rb +73 -2
- data/spec/graphql/query/arguments_spec.rb +28 -0
- data/spec/graphql/query/variables_spec.rb +7 -1
- data/spec/graphql/query_spec.rb +30 -0
- data/spec/graphql/relay/base_connection_spec.rb +26 -8
- data/spec/graphql/relay/connection_resolve_spec.rb +45 -0
- data/spec/graphql/relay/connection_type_spec.rb +21 -0
- data/spec/graphql/relay/node_spec.rb +30 -2
- data/spec/graphql/relay/range_add_spec.rb +113 -0
- data/spec/graphql/schema/build_from_definition_spec.rb +114 -0
- data/spec/graphql/schema/loader_spec.rb +1 -0
- data/spec/graphql/schema/printer_spec.rb +2 -2
- data/spec/graphql/schema/validation_spec.rb +80 -11
- data/spec/graphql/schema/warden_spec.rb +10 -10
- data/spec/graphql/schema_spec.rb +18 -1
- data/spec/graphql/static_validation/rules/argument_literals_are_compatible_spec.rb +16 -0
- data/spec/graphql/static_validation/rules/fields_will_merge_spec.rb +50 -3
- data/spec/graphql/static_validation/rules/fragment_names_are_unique_spec.rb +27 -0
- data/spec/graphql/static_validation/rules/fragments_are_finite_spec.rb +57 -0
- data/spec/graphql/static_validation/rules/fragments_are_used_spec.rb +1 -1
- data/spec/graphql/static_validation/rules/variables_are_input_types_spec.rb +14 -0
- data/spec/graphql/string_type_spec.rb +7 -0
- data/spec/spec_helper.rb +3 -3
- data/spec/support/base_generator_test.rb +7 -0
- data/spec/support/dummy/schema.rb +32 -30
- data/spec/support/star_wars/schema.rb +81 -23
- metadata +98 -20
- data/lib/graphql/internal_representation/selection.rb +0 -85
@@ -2,162 +2,196 @@
|
|
2
2
|
require "spec_helper"
|
3
3
|
|
4
4
|
describe GraphQL::InternalRepresentation::Rewrite do
|
5
|
-
let(:
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
}
|
10
|
-
describe "plain queries" do
|
11
|
-
let(:query_string) {%|
|
12
|
-
query getCheeses {
|
13
|
-
cheese1: cheese(id: 1) {
|
14
|
-
id1: id
|
15
|
-
id2: id
|
16
|
-
id3: id
|
17
|
-
}
|
18
|
-
cheese2: cheese(id: 2) {
|
19
|
-
id
|
20
|
-
}
|
5
|
+
let(:schema) {
|
6
|
+
GraphQL::Schema.from_definition <<-GRAPHQL
|
7
|
+
type Query {
|
8
|
+
plant(id: ID!): Plant
|
21
9
|
}
|
22
|
-
|}
|
23
10
|
|
24
|
-
|
25
|
-
op_node = rewrite_result["getCheeses"]
|
26
|
-
|
27
|
-
root_children = op_node.typed_children[Dummy::DairyAppQueryType]
|
28
|
-
assert_equal 2, root_children.length
|
29
|
-
assert_equal Dummy::DairyAppQueryType, op_node.return_type
|
30
|
-
first_field = root_children.values.first
|
31
|
-
assert_equal 3, first_field.typed_children[Dummy::CheeseType].length
|
32
|
-
assert_equal Dummy::DairyAppQueryType, first_field.owner_type
|
33
|
-
assert_equal Dummy::CheeseType, first_field.return_type
|
34
|
-
|
35
|
-
second_field = root_children.values.last
|
36
|
-
assert_equal 1, second_field.typed_children[Dummy::CheeseType].length
|
37
|
-
assert_equal Dummy::DairyAppQueryType.get_field("cheese"), second_field.definition
|
38
|
-
assert_equal Dummy::CheeseType, second_field.return_type
|
39
|
-
assert second_field.inspect.is_a?(String)
|
40
|
-
end
|
41
|
-
end
|
11
|
+
union Plant = Grain | Fruit | Vegetable | Nut
|
42
12
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
}
|
49
|
-
}
|
50
|
-
|}
|
13
|
+
interface Tree {
|
14
|
+
name: String!
|
15
|
+
leafType: LeafType
|
16
|
+
habitats: [Habitat]
|
17
|
+
}
|
51
18
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
assert_equal "__typename", typename_field.definition_name
|
57
|
-
end
|
58
|
-
end
|
19
|
+
enum LeafType {
|
20
|
+
NEEDLE
|
21
|
+
LEAF
|
22
|
+
}
|
59
23
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
id2: id
|
67
|
-
}
|
24
|
+
type Fruit implements Tree {
|
25
|
+
name: String!
|
26
|
+
color: [Int!]!
|
27
|
+
leafType: LeafType
|
28
|
+
habitats: [Habitat]
|
29
|
+
}
|
68
30
|
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
}
|
31
|
+
type Vegetable {
|
32
|
+
name: String!
|
33
|
+
edibleParts: [String!]!
|
34
|
+
}
|
74
35
|
|
75
|
-
|
36
|
+
type Grain {
|
37
|
+
name: String!
|
38
|
+
}
|
76
39
|
|
77
|
-
|
78
|
-
|
40
|
+
type Nut implements Tree {
|
41
|
+
name: String!
|
42
|
+
diameter: Int!
|
43
|
+
leafType: LeafType
|
44
|
+
habitats: [Habitat]
|
45
|
+
}
|
79
46
|
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
... cheese2Fields
|
85
|
-
}
|
47
|
+
type Habitat {
|
48
|
+
residentName: String!
|
49
|
+
averageWeight: Int!
|
50
|
+
seasons: [String]
|
86
51
|
}
|
52
|
+
GRAPHQL
|
87
53
|
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
54
|
+
}
|
55
|
+
let(:validator) { GraphQL::StaticValidation::Validator.new(schema: schema) }
|
56
|
+
let(:query) { GraphQL::Query.new(schema, query_string) }
|
57
|
+
let(:rewrite_result) {
|
58
|
+
res = validator.validate(query)
|
59
|
+
res[:errors].any? && raise(res[:errors].map(&:message).join("; "))
|
60
|
+
res[:irep]
|
61
|
+
}
|
62
|
+
# TODO: make sure all rewrite specs are covered
|
63
|
+
|
64
|
+
describe "building a tree over concrete types with fragments" do
|
65
|
+
let(:query_string) {
|
66
|
+
<<-GRAPHQL
|
67
|
+
query getPlant($id: ID!) {
|
68
|
+
plant(id: $id) {
|
69
|
+
__typename
|
70
|
+
... on Tree {
|
71
|
+
leafType
|
72
|
+
habitats {
|
73
|
+
averageWeight
|
74
|
+
}
|
75
|
+
}
|
76
|
+
... on Fruit {
|
77
|
+
name
|
78
|
+
color
|
79
|
+
... on Tree {
|
80
|
+
leafType
|
81
|
+
}
|
82
|
+
}
|
83
|
+
... on Nut {
|
84
|
+
leafType
|
85
|
+
...NutFields
|
86
|
+
}
|
87
|
+
}
|
95
88
|
}
|
96
|
-
}
|
97
89
|
|
98
|
-
|
99
|
-
|
100
|
-
|
90
|
+
fragment NutFields on Nut {
|
91
|
+
leafType
|
92
|
+
... TreeFields
|
101
93
|
}
|
102
|
-
}
|
103
94
|
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
similarCowSource: source,
|
108
|
-
fatContent
|
109
|
-
similarCheese(source: SHEEP) {
|
110
|
-
flavor
|
95
|
+
fragment TreeFields on Tree {
|
96
|
+
habitats {
|
97
|
+
... HabitatFields
|
111
98
|
}
|
112
99
|
}
|
113
|
-
}
|
114
|
-
|
115
|
-
fragment cheese2InnerFields on Cheese {
|
116
|
-
id
|
117
|
-
fatContent
|
118
|
-
}
|
119
100
|
|
120
|
-
|
121
|
-
|
122
|
-
... cheese2InnerFields
|
101
|
+
fragment HabitatFields on Habitat {
|
102
|
+
seasons
|
123
103
|
}
|
104
|
+
GRAPHQL
|
124
105
|
}
|
125
106
|
|
126
|
-
|
107
|
+
it "groups selections by object types which they apply to" do
|
108
|
+
doc = rewrite_result["getPlant"]
|
109
|
+
|
110
|
+
plant_selection = doc.typed_children[schema.types["Query"]]["plant"]
|
111
|
+
assert_equal ["Fruit", "Grain", "Nut", "Vegetable"], plant_selection.typed_children.keys.map(&:name).sort
|
112
|
+
|
113
|
+
fruit_selections = plant_selection.typed_children[schema.types["Fruit"]]
|
114
|
+
assert_equal ["__typename", "color", "habitats", "leafType", "name"], fruit_selections.keys.sort
|
115
|
+
assert_equal 2, fruit_selections["leafType"].ast_nodes.size
|
116
|
+
|
117
|
+
nut_selections = plant_selection.typed_children[schema.types["Nut"]]
|
118
|
+
# `... on Tree`, `... on Nut`, and `NutFields`, but not `... on Fruit { ... on Tree }`
|
119
|
+
assert_equal 3, nut_selections["leafType"].ast_nodes.size
|
120
|
+
# Multi-level merging when including fragments:
|
121
|
+
habitats_selections = nut_selections["habitats"].typed_children[schema.types["Habitat"]]
|
122
|
+
assert_equal ["averageWeight", "seasons"], habitats_selections.keys
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
describe "tracking directives on fragment spreads" do
|
127
|
+
let(:query_string) { <<-GRAPHQL
|
128
|
+
query getPlant($id: ID!) {
|
129
|
+
plant(id: $id) {
|
130
|
+
... on Nut @skip(if: true) {
|
131
|
+
leafType
|
132
|
+
}
|
133
|
+
|
134
|
+
... on Tree {
|
135
|
+
leafType @include(if: true)
|
136
|
+
}
|
127
137
|
|
128
|
-
|
129
|
-
|
138
|
+
... on Nut {
|
139
|
+
leafType # no directives
|
140
|
+
}
|
130
141
|
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
assert_equal ["flavor", "source"], similar_sheep_field.typed_children[Dummy::CheeseType].keys
|
142
|
+
... NutFields @include(if: false)
|
143
|
+
}
|
144
|
+
}
|
145
|
+
fragment NutFields on Nut {
|
146
|
+
leafType @skip(if: false)
|
147
|
+
}
|
148
|
+
GRAPHQL
|
149
|
+
}
|
140
150
|
|
141
|
-
|
142
|
-
|
143
|
-
|
151
|
+
it "applies directives from all contexts" do
|
152
|
+
doc = rewrite_result["getPlant"]
|
153
|
+
plant_selection = doc.typed_children[schema.types["Query"]]["plant"]
|
154
|
+
leaf_type_selection = plant_selection.typed_children[schema.types["Nut"]]["leafType"]
|
155
|
+
# Only unskipped occurrences in the AST
|
156
|
+
assert_equal 2, leaf_type_selection.ast_nodes.size
|
157
|
+
end
|
158
|
+
end
|
144
159
|
|
145
|
-
|
146
|
-
|
147
|
-
|
160
|
+
describe "deep fragment merging" do
|
161
|
+
let(:query_string) { <<-GRAPHQL
|
162
|
+
{
|
163
|
+
plant(id: 1) {
|
164
|
+
...TreeFields
|
165
|
+
...NutFields
|
166
|
+
}
|
167
|
+
}
|
148
168
|
|
149
|
-
|
150
|
-
|
151
|
-
|
169
|
+
fragment TreeFields on Tree {
|
170
|
+
habitats {
|
171
|
+
seasons
|
172
|
+
}
|
173
|
+
}
|
152
174
|
|
153
|
-
|
154
|
-
|
155
|
-
|
175
|
+
fragment NutFields on Nut {
|
176
|
+
habitats {
|
177
|
+
residentName
|
178
|
+
... HabitatFields
|
179
|
+
}
|
180
|
+
}
|
156
181
|
|
182
|
+
fragment HabitatFields on Habitat {
|
183
|
+
averageWeight
|
184
|
+
}
|
185
|
+
GRAPHQL
|
186
|
+
}
|
157
187
|
|
158
|
-
|
159
|
-
|
160
|
-
|
188
|
+
it "applies spreads to their parents only" do
|
189
|
+
doc = rewrite_result[nil]
|
190
|
+
plant_selection = doc.typed_children[schema.types["Query"]]["plant"]
|
191
|
+
nut_habitat_selections = plant_selection.typed_children[schema.types["Nut"]]["habitats"].typed_children[schema.types["Habitat"]]
|
192
|
+
assert_equal ["averageWeight", "residentName", "seasons"], nut_habitat_selections.keys.sort
|
193
|
+
fruit_habitat_selections = plant_selection.typed_children[schema.types["Fruit"]]["habitats"].typed_children[schema.types["Habitat"]]
|
194
|
+
assert_equal ["seasons"], fruit_habitat_selections.keys
|
161
195
|
end
|
162
196
|
end
|
163
197
|
|
@@ -219,11 +253,14 @@ describe GraphQL::InternalRepresentation::Rewrite do
|
|
219
253
|
assert_equal 3, cheeses.length
|
220
254
|
assert_equal 1, milks.length
|
221
255
|
|
256
|
+
expected_cheese_fields = ["cheeseInlineOrigin", "edibleInlineOrigin", "untypedInlineOrigin", "cheeseFragmentOrigin"]
|
222
257
|
cheeses.each do |cheese|
|
223
|
-
assert_equal
|
258
|
+
assert_equal expected_cheese_fields, cheese["selfAsEdible"].keys
|
224
259
|
end
|
260
|
+
|
261
|
+
expected_milk_fields = ["milkInlineOrigin", "edibleInlineOrigin", "untypedInlineOrigin", "milkFragmentOrigin"]
|
225
262
|
milks.each do |milk|
|
226
|
-
assert_equal
|
263
|
+
assert_equal expected_milk_fields, milk["selfAsEdible"].keys
|
227
264
|
end
|
228
265
|
end
|
229
266
|
end
|
@@ -52,7 +52,7 @@ describe GraphQL::Introspection::TypeType do
|
|
52
52
|
{"type"=>{"kind"=>"NON_NULL","name"=>nil, "ofType"=>{"name"=>"ID"}}},
|
53
53
|
{"type"=>{"kind"=>"NON_NULL","name"=>nil, "ofType"=>{"name"=>"String"}}},
|
54
54
|
{"type"=>{"kind"=>"INTERFACE", "name"=>"Edible", "ofType"=>nil}},
|
55
|
-
{"type"=>{"kind"=>"
|
55
|
+
{"type"=>{"kind"=>"NON_NULL","name"=>nil,"ofType"=>{"name"=>"DairyAnimal"}}},
|
56
56
|
]
|
57
57
|
},
|
58
58
|
"dairyAnimal"=>{
|
@@ -16,6 +16,12 @@ describe GraphQL::Language::Lexer do
|
|
16
16
|
|}
|
17
17
|
let(:tokens) { subject.tokenize(query_string) }
|
18
18
|
|
19
|
+
it "makes utf-8 comments" do
|
20
|
+
tokens = subject.tokenize("# 不要!\n{")
|
21
|
+
comment_token = tokens.first.prev_token
|
22
|
+
assert_equal "# 不要!", comment_token.to_s
|
23
|
+
end
|
24
|
+
|
19
25
|
it "keeps track of previous_token" do
|
20
26
|
assert_equal tokens[0], tokens[1].prev_token
|
21
27
|
end
|
@@ -15,8 +15,19 @@ describe GraphQL::ObjectType do
|
|
15
15
|
assert_equal(22, type.description.length)
|
16
16
|
end
|
17
17
|
|
18
|
-
|
19
|
-
|
18
|
+
describe "interfaces" do
|
19
|
+
it "may have interfaces" do
|
20
|
+
assert_equal([Dummy::EdibleInterface, Dummy::AnimalProductInterface, Dummy::LocalProductInterface], type.interfaces)
|
21
|
+
end
|
22
|
+
|
23
|
+
it "raises if the interfaces arent an array" do
|
24
|
+
type = GraphQL::ObjectType.define do
|
25
|
+
name "InvalidInterfaces"
|
26
|
+
interfaces(55)
|
27
|
+
end
|
28
|
+
|
29
|
+
assert_raises(ArgumentError) { type.name }
|
30
|
+
end
|
20
31
|
end
|
21
32
|
|
22
33
|
it "accepts fields definition" do
|
@@ -25,6 +36,66 @@ describe GraphQL::ObjectType do
|
|
25
36
|
assert_equal([last_produced_dairy], cow_type.fields)
|
26
37
|
end
|
27
38
|
|
39
|
+
describe "#implements" do
|
40
|
+
it "adds an interface" do
|
41
|
+
type = GraphQL::ObjectType.define do
|
42
|
+
name 'Hello'
|
43
|
+
implements Dummy::EdibleInterface
|
44
|
+
implements Dummy::AnimalProductInterface
|
45
|
+
|
46
|
+
field :hello, types.String
|
47
|
+
end
|
48
|
+
|
49
|
+
assert_equal([Dummy::EdibleInterface, Dummy::AnimalProductInterface], type.interfaces)
|
50
|
+
end
|
51
|
+
|
52
|
+
it "adds many interfaces" do
|
53
|
+
type = GraphQL::ObjectType.define do
|
54
|
+
name 'Hello'
|
55
|
+
implements Dummy::EdibleInterface, Dummy::AnimalProductInterface
|
56
|
+
|
57
|
+
field :hello, types.String
|
58
|
+
end
|
59
|
+
|
60
|
+
assert_equal([Dummy::EdibleInterface, Dummy::AnimalProductInterface], type.interfaces)
|
61
|
+
end
|
62
|
+
|
63
|
+
it "preserves existing interfaces and appends a new one" do
|
64
|
+
type = GraphQL::ObjectType.define do
|
65
|
+
name 'Hello'
|
66
|
+
interfaces [Dummy::EdibleInterface]
|
67
|
+
implements Dummy::AnimalProductInterface
|
68
|
+
|
69
|
+
field :hello, types.String
|
70
|
+
end
|
71
|
+
|
72
|
+
assert_equal([Dummy::EdibleInterface, Dummy::AnimalProductInterface], type.interfaces)
|
73
|
+
end
|
74
|
+
|
75
|
+
it "can be used to inherit fields from the interface" do
|
76
|
+
type_1 = GraphQL::ObjectType.define do
|
77
|
+
name 'Hello'
|
78
|
+
implements Dummy::EdibleInterface
|
79
|
+
implements Dummy::AnimalProductInterface
|
80
|
+
end
|
81
|
+
|
82
|
+
type_2 = GraphQL::ObjectType.define do
|
83
|
+
name 'Hello'
|
84
|
+
implements Dummy::EdibleInterface
|
85
|
+
implements Dummy::AnimalProductInterface, inherit: true
|
86
|
+
end
|
87
|
+
|
88
|
+
type_3 = GraphQL::ObjectType.define do
|
89
|
+
name 'Hello'
|
90
|
+
implements Dummy::EdibleInterface, Dummy::AnimalProductInterface, inherit: true
|
91
|
+
end
|
92
|
+
|
93
|
+
assert_equal [], type_1.all_fields.map(&:name)
|
94
|
+
assert_equal ["source"], type_2.all_fields.map(&:name)
|
95
|
+
assert_equal ["fatContent", "origin", "selfAsEdible", "source"], type_3.all_fields.map(&:name)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
28
99
|
describe '#get_field' do
|
29
100
|
it "exposes fields" do
|
30
101
|
field = type.get_field("id")
|