Skip to content

Commit 0ea61fa

Browse files
committed
Add interface and union tests
1 parent c555241 commit 0ea61fa

File tree

3 files changed

+235
-0
lines changed

3 files changed

+235
-0
lines changed
Lines changed: 221 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,221 @@
1+
mod interface {
2+
use value::Value;
3+
use schema::model::RootNode;
4+
5+
trait Pet {
6+
fn name(&self) -> &str;
7+
8+
fn as_dog(&self) -> Option<&Dog> { None }
9+
fn as_cat(&self) -> Option<&Cat> { None }
10+
}
11+
12+
graphql_interface!(<'a> &'a Pet: () as "Pet" |&self| {
13+
field name() -> &str { self.name() }
14+
15+
instance_resolvers: |&_| {
16+
&Dog => self.as_dog(),
17+
&Cat => self.as_cat(),
18+
}
19+
});
20+
21+
struct Dog {
22+
name: String,
23+
woofs: bool,
24+
}
25+
26+
impl Pet for Dog {
27+
fn name(&self) -> &str { &self.name }
28+
fn as_dog(&self) -> Option<&Dog> { Some(self) }
29+
}
30+
31+
graphql_object!(Dog: () |&self| {
32+
field name() -> &str { &self.name }
33+
field woofs() -> bool { self.woofs }
34+
35+
interfaces: [&Pet]
36+
});
37+
38+
struct Cat {
39+
name: String,
40+
meows: bool,
41+
}
42+
43+
impl Pet for Cat {
44+
fn name(&self) -> &str { &self.name }
45+
fn as_cat(&self) -> Option<&Cat> { Some(self) }
46+
}
47+
48+
graphql_object!(Cat: () |&self| {
49+
field name() -> &str { &self.name }
50+
field meows() -> bool { self.meows }
51+
52+
interfaces: [&Pet]
53+
});
54+
55+
struct Schema {
56+
pets: Vec<Box<Pet>>,
57+
}
58+
59+
graphql_object!(Schema: () |&self| {
60+
field pets() -> Vec<&Pet> {
61+
self.pets.iter().map(|p| p.as_ref()).collect()
62+
}
63+
});
64+
65+
#[test]
66+
fn test() {
67+
let schema = RootNode::new(
68+
Schema {
69+
pets: vec![
70+
Box::new(Dog { name: "Odie".to_owned(), woofs: true }),
71+
Box::new(Cat { name: "Garfield".to_owned(), meows: false }),
72+
],
73+
},
74+
());
75+
let doc = r"
76+
{
77+
pets {
78+
name
79+
... on Dog {
80+
woofs
81+
}
82+
... on Cat {
83+
meows
84+
}
85+
}
86+
}";
87+
88+
let vars = vec![
89+
].into_iter().collect();
90+
91+
let (result, errs) = ::execute(doc, None, &schema, &vars, &())
92+
.expect("Execution failed");
93+
94+
assert_eq!(errs, []);
95+
96+
println!("Result: {:?}", result);
97+
98+
assert_eq!(
99+
result,
100+
Value::object(vec![
101+
("pets", Value::list(vec![
102+
Value::object(vec![
103+
("name", Value::string("Odie")),
104+
("woofs", Value::boolean(true)),
105+
].into_iter().collect()),
106+
Value::object(vec![
107+
("name", Value::string("Garfield")),
108+
("meows", Value::boolean(false)),
109+
].into_iter().collect()),
110+
])),
111+
].into_iter().collect()));
112+
}
113+
}
114+
115+
116+
117+
118+
mod union {
119+
use value::Value;
120+
use schema::model::RootNode;
121+
122+
trait Pet {
123+
fn as_dog(&self) -> Option<&Dog> { None }
124+
fn as_cat(&self) -> Option<&Cat> { None }
125+
}
126+
127+
graphql_union!(<'a> &'a Pet: () as "Pet" |&self| {
128+
instance_resolvers: |&_| {
129+
&Dog => self.as_dog(),
130+
&Cat => self.as_cat(),
131+
}
132+
});
133+
134+
struct Dog {
135+
name: String,
136+
woofs: bool,
137+
}
138+
139+
impl Pet for Dog {
140+
fn as_dog(&self) -> Option<&Dog> { Some(self) }
141+
}
142+
143+
graphql_object!(Dog: () |&self| {
144+
field name() -> &str { &self.name }
145+
field woofs() -> bool { self.woofs }
146+
});
147+
148+
struct Cat {
149+
name: String,
150+
meows: bool,
151+
}
152+
153+
impl Pet for Cat {
154+
fn as_cat(&self) -> Option<&Cat> { Some(self) }
155+
}
156+
157+
graphql_object!(Cat: () |&self| {
158+
field name() -> &str { &self.name }
159+
field meows() -> bool { self.meows }
160+
});
161+
162+
struct Schema {
163+
pets: Vec<Box<Pet>>,
164+
}
165+
166+
graphql_object!(Schema: () |&self| {
167+
field pets() -> Vec<&Pet> {
168+
self.pets.iter().map(|p| p.as_ref()).collect()
169+
}
170+
});
171+
172+
#[test]
173+
fn test() {
174+
let schema = RootNode::new(
175+
Schema {
176+
pets: vec![
177+
Box::new(Dog { name: "Odie".to_owned(), woofs: true }),
178+
Box::new(Cat { name: "Garfield".to_owned(), meows: false }),
179+
],
180+
},
181+
());
182+
let doc = r"
183+
{
184+
pets {
185+
... on Dog {
186+
name
187+
woofs
188+
}
189+
... on Cat {
190+
name
191+
meows
192+
}
193+
}
194+
}";
195+
196+
let vars = vec![
197+
].into_iter().collect();
198+
199+
let (result, errs) = ::execute(doc, None, &schema, &vars, &())
200+
.expect("Execution failed");
201+
202+
assert_eq!(errs, []);
203+
204+
println!("Result: {:?}", result);
205+
206+
assert_eq!(
207+
result,
208+
Value::object(vec![
209+
("pets", Value::list(vec![
210+
Value::object(vec![
211+
("name", Value::string("Odie")),
212+
("woofs", Value::boolean(true)),
213+
].into_iter().collect()),
214+
Value::object(vec![
215+
("name", Value::string("Garfield")),
216+
("meows", Value::boolean(false)),
217+
].into_iter().collect()),
218+
])),
219+
].into_iter().collect()));
220+
}
221+
}

src/executor_tests/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@ mod variables;
33
mod enums;
44
mod directives;
55
mod executor;
6+
mod interfaces_unions;

src/macros/interface.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,19 @@ macro_rules! graphql_interface {
169169
graphql_interface!(@gather_meta, ($reg, $acc, $descr), $( $rest )*)
170170
};
171171

172+
// instance_resolvers: | <ctxtvar> | [...]
173+
(
174+
@ gather_meta,
175+
($reg:expr, $acc:expr, $descr:expr),
176+
instance_resolvers : | $ctxtvar:pat | { $( $srctype:ty => $resolver:expr ),* $(,)* } $( $rest:tt )*
177+
) => {
178+
$(
179+
let _ = $reg.get_type::<$srctype>();
180+
)*
181+
182+
graphql_interface!(@gather_meta, ($reg, $acc, $descr), $( $rest )*)
183+
};
184+
172185
// instance_resolvers: | <ctxtvar> | [...]
173186
(
174187
@ concrete_type_name,

0 commit comments

Comments
 (0)