Skip to content

Commit 0739c11

Browse files
author
Robert Mosolgo
authored
Merge pull request rmosolgo#211 from rmosolgo/check-typecasting
fix(Typecast) add end-to-end test for interface-to-interface casting
2 parents 769ea49 + 69442f0 commit 0739c11

File tree

6 files changed

+72
-6
lines changed

6 files changed

+72
-6
lines changed

spec/graphql/interface_type_spec.rb

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,4 +53,29 @@
5353
assert_equal(interface.resolve_type(123, nil), :custom_resolve)
5454
end
5555
end
56+
57+
describe "fragments" do
58+
let(:query_string) {%|
59+
{
60+
favoriteEdible {
61+
fatContent
62+
... on LocalProduct {
63+
origin
64+
}
65+
}
66+
}
67+
|}
68+
let(:result) { DummySchema.execute(query_string) }
69+
70+
it "can apply interface fragments to an interface" do
71+
expected_result = { "data" => {
72+
"favoriteEdible" => {
73+
"fatContent" => 0.04,
74+
"origin" => "Antiquity",
75+
}
76+
} }
77+
78+
assert_equal(expected_result, result)
79+
end
80+
end
5681
end

spec/graphql/introspection/type_type_spec.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,8 @@
3636
"milkType"=>{
3737
"interfaces"=>[
3838
{"name"=>"Edible"},
39-
{"name"=>"AnimalProduct"}
39+
{"name"=>"AnimalProduct"},
40+
{"name"=>"LocalProduct"},
4041
],
4142
"fields"=>[
4243
{"type"=>{"name"=>"Non-Null", "ofType"=>{"name"=>"Float"}}},

spec/graphql/object_type_spec.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
end
1616

1717
it "may have interfaces" do
18-
assert_equal([EdibleInterface, AnimalProductInterface], type.interfaces)
18+
assert_equal([EdibleInterface, AnimalProductInterface, LocalProductInterface], type.interfaces)
1919
end
2020

2121
describe '#get_field ' do

spec/graphql/schema/reduce_types_spec.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ def reduce_types(types)
1414
"Int" => GraphQL::INT_TYPE,
1515
"Edible" => EdibleInterface,
1616
"AnimalProduct" => AnimalProductInterface,
17+
"LocalProduct" => LocalProductInterface,
1718
}
1819
result = reduce_types([CheeseType])
1920
assert_equal(expected.keys, result.keys)

spec/graphql/union_type_spec.rb

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,11 @@
1212
possible_types(types)
1313
}
1414
}
15+
1516
it "has a name" do
1617
assert_equal("MyUnion", union.name)
1718
end
1819

19-
2020
it "infers type from an object" do
2121
assert_equal(CheeseType, DairyProductUnion.resolve_type(CHEESES[1], OpenStruct.new(schema: DummySchema)))
2222
end
@@ -29,6 +29,33 @@
2929
assert_equal(false, union.include?(type_3))
3030
end
3131

32+
describe "typecasting from union to union" do
33+
let(:result) { DummySchema.execute(query_string) }
34+
let(:query_string) {%|
35+
{
36+
allDairy {
37+
dairyName: __typename
38+
... on Beverage {
39+
bevName: __typename
40+
... on Milk {
41+
flavors
42+
}
43+
}
44+
}
45+
}
46+
|}
47+
48+
it "casts if the object belongs to both unions" do
49+
expected_result = [
50+
{"dairyName"=>"Cheese"},
51+
{"dairyName"=>"Cheese"},
52+
{"dairyName"=>"Cheese"},
53+
{"dairyName"=>"Milk", "bevName"=>"Milk", "flavors"=>["Natural", "Chocolate", "Strawberry"]},
54+
]
55+
assert_equal expected_result, result["data"]["allDairy"]
56+
end
57+
end
58+
3259
describe "list of union type" do
3360
describe "fragment spreads" do
3461
let(:result) { DummySchema.execute(query_string) }

spec/support/dairy_app.rb

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,12 @@ class NoSuchDairyError < StandardError; end
55
GraphQL::Field.accepts_definitions(joins: GraphQL::Define.assign_metadata_key(:joins))
66
GraphQL::BaseType.accepts_definitions(class_names: GraphQL::Define.assign_metadata_key(:class_names))
77

8+
LocalProductInterface = GraphQL::InterfaceType.define do
9+
name "LocalProduct"
10+
description "Something that comes from somewhere"
11+
field :origin, !types.String, "Place the thing comes from"
12+
end
13+
814
EdibleInterface = GraphQL::InterfaceType.define do
915
name "Edible"
1016
description "Something you can eat, yum"
@@ -18,6 +24,12 @@ class NoSuchDairyError < StandardError; end
1824
field :source, !types.String, "Animal which produced this product"
1925
end
2026

27+
BeverageUnion = GraphQL::UnionType.define do
28+
name "Beverage"
29+
description "Something you can drink"
30+
possible_types [MilkType]
31+
end
32+
2133
DairyAnimalEnum = GraphQL::EnumType.define do
2234
name "DairyAnimal"
2335
description "An animal which can yield milk"
@@ -31,7 +43,7 @@ class NoSuchDairyError < StandardError; end
3143
name "Cheese"
3244
class_names ["Cheese"]
3345
description "Cultured dairy product"
34-
interfaces [EdibleInterface, AnimalProductInterface]
46+
interfaces [EdibleInterface, AnimalProductInterface, LocalProductInterface]
3547

3648
# Can have (name, type, desc)
3749
field :id, !types.Int, "Unique identifier"
@@ -78,7 +90,7 @@ class NoSuchDairyError < StandardError; end
7890
MilkType = GraphQL::ObjectType.define do
7991
name "Milk"
8092
description "Dairy beverage"
81-
interfaces [EdibleInterface, AnimalProductInterface]
93+
interfaces [EdibleInterface, AnimalProductInterface, LocalProductInterface]
8294
field :id, !types.ID
8395
field :source, DairyAnimalEnum, "Animal which produced this milk", hash_key: :source
8496
field :origin, !types.String, "Place the milk comes from"
@@ -317,6 +329,6 @@ def self.create(type:, data:)
317329
mutation: DairyAppMutationType,
318330
subscription: SubscriptionType,
319331
max_depth: 5,
320-
types: [HoneyType],
332+
types: [HoneyType, BeverageUnion],
321333
)
322334
DummySchema.rescue_from(NoSuchDairyError) { |err| err.message }

0 commit comments

Comments
 (0)