graphql 1.4.5 → 1.5.3
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.
- 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")
|