Add interface and union tests
This commit is contained in:
parent
c555241978
commit
0ea61fa493
3 changed files with 235 additions and 0 deletions
221
src/executor_tests/interfaces_unions.rs
Normal file
221
src/executor_tests/interfaces_unions.rs
Normal file
|
@ -0,0 +1,221 @@
|
|||
mod interface {
|
||||
use value::Value;
|
||||
use schema::model::RootNode;
|
||||
|
||||
trait Pet {
|
||||
fn name(&self) -> &str;
|
||||
|
||||
fn as_dog(&self) -> Option<&Dog> { None }
|
||||
fn as_cat(&self) -> Option<&Cat> { None }
|
||||
}
|
||||
|
||||
graphql_interface!(<'a> &'a Pet: () as "Pet" |&self| {
|
||||
field name() -> &str { self.name() }
|
||||
|
||||
instance_resolvers: |&_| {
|
||||
&Dog => self.as_dog(),
|
||||
&Cat => self.as_cat(),
|
||||
}
|
||||
});
|
||||
|
||||
struct Dog {
|
||||
name: String,
|
||||
woofs: bool,
|
||||
}
|
||||
|
||||
impl Pet for Dog {
|
||||
fn name(&self) -> &str { &self.name }
|
||||
fn as_dog(&self) -> Option<&Dog> { Some(self) }
|
||||
}
|
||||
|
||||
graphql_object!(Dog: () |&self| {
|
||||
field name() -> &str { &self.name }
|
||||
field woofs() -> bool { self.woofs }
|
||||
|
||||
interfaces: [&Pet]
|
||||
});
|
||||
|
||||
struct Cat {
|
||||
name: String,
|
||||
meows: bool,
|
||||
}
|
||||
|
||||
impl Pet for Cat {
|
||||
fn name(&self) -> &str { &self.name }
|
||||
fn as_cat(&self) -> Option<&Cat> { Some(self) }
|
||||
}
|
||||
|
||||
graphql_object!(Cat: () |&self| {
|
||||
field name() -> &str { &self.name }
|
||||
field meows() -> bool { self.meows }
|
||||
|
||||
interfaces: [&Pet]
|
||||
});
|
||||
|
||||
struct Schema {
|
||||
pets: Vec<Box<Pet>>,
|
||||
}
|
||||
|
||||
graphql_object!(Schema: () |&self| {
|
||||
field pets() -> Vec<&Pet> {
|
||||
self.pets.iter().map(|p| p.as_ref()).collect()
|
||||
}
|
||||
});
|
||||
|
||||
#[test]
|
||||
fn test() {
|
||||
let schema = RootNode::new(
|
||||
Schema {
|
||||
pets: vec![
|
||||
Box::new(Dog { name: "Odie".to_owned(), woofs: true }),
|
||||
Box::new(Cat { name: "Garfield".to_owned(), meows: false }),
|
||||
],
|
||||
},
|
||||
());
|
||||
let doc = r"
|
||||
{
|
||||
pets {
|
||||
name
|
||||
... on Dog {
|
||||
woofs
|
||||
}
|
||||
... on Cat {
|
||||
meows
|
||||
}
|
||||
}
|
||||
}";
|
||||
|
||||
let vars = vec![
|
||||
].into_iter().collect();
|
||||
|
||||
let (result, errs) = ::execute(doc, None, &schema, &vars, &())
|
||||
.expect("Execution failed");
|
||||
|
||||
assert_eq!(errs, []);
|
||||
|
||||
println!("Result: {:?}", result);
|
||||
|
||||
assert_eq!(
|
||||
result,
|
||||
Value::object(vec![
|
||||
("pets", Value::list(vec![
|
||||
Value::object(vec![
|
||||
("name", Value::string("Odie")),
|
||||
("woofs", Value::boolean(true)),
|
||||
].into_iter().collect()),
|
||||
Value::object(vec![
|
||||
("name", Value::string("Garfield")),
|
||||
("meows", Value::boolean(false)),
|
||||
].into_iter().collect()),
|
||||
])),
|
||||
].into_iter().collect()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
mod union {
|
||||
use value::Value;
|
||||
use schema::model::RootNode;
|
||||
|
||||
trait Pet {
|
||||
fn as_dog(&self) -> Option<&Dog> { None }
|
||||
fn as_cat(&self) -> Option<&Cat> { None }
|
||||
}
|
||||
|
||||
graphql_union!(<'a> &'a Pet: () as "Pet" |&self| {
|
||||
instance_resolvers: |&_| {
|
||||
&Dog => self.as_dog(),
|
||||
&Cat => self.as_cat(),
|
||||
}
|
||||
});
|
||||
|
||||
struct Dog {
|
||||
name: String,
|
||||
woofs: bool,
|
||||
}
|
||||
|
||||
impl Pet for Dog {
|
||||
fn as_dog(&self) -> Option<&Dog> { Some(self) }
|
||||
}
|
||||
|
||||
graphql_object!(Dog: () |&self| {
|
||||
field name() -> &str { &self.name }
|
||||
field woofs() -> bool { self.woofs }
|
||||
});
|
||||
|
||||
struct Cat {
|
||||
name: String,
|
||||
meows: bool,
|
||||
}
|
||||
|
||||
impl Pet for Cat {
|
||||
fn as_cat(&self) -> Option<&Cat> { Some(self) }
|
||||
}
|
||||
|
||||
graphql_object!(Cat: () |&self| {
|
||||
field name() -> &str { &self.name }
|
||||
field meows() -> bool { self.meows }
|
||||
});
|
||||
|
||||
struct Schema {
|
||||
pets: Vec<Box<Pet>>,
|
||||
}
|
||||
|
||||
graphql_object!(Schema: () |&self| {
|
||||
field pets() -> Vec<&Pet> {
|
||||
self.pets.iter().map(|p| p.as_ref()).collect()
|
||||
}
|
||||
});
|
||||
|
||||
#[test]
|
||||
fn test() {
|
||||
let schema = RootNode::new(
|
||||
Schema {
|
||||
pets: vec![
|
||||
Box::new(Dog { name: "Odie".to_owned(), woofs: true }),
|
||||
Box::new(Cat { name: "Garfield".to_owned(), meows: false }),
|
||||
],
|
||||
},
|
||||
());
|
||||
let doc = r"
|
||||
{
|
||||
pets {
|
||||
... on Dog {
|
||||
name
|
||||
woofs
|
||||
}
|
||||
... on Cat {
|
||||
name
|
||||
meows
|
||||
}
|
||||
}
|
||||
}";
|
||||
|
||||
let vars = vec![
|
||||
].into_iter().collect();
|
||||
|
||||
let (result, errs) = ::execute(doc, None, &schema, &vars, &())
|
||||
.expect("Execution failed");
|
||||
|
||||
assert_eq!(errs, []);
|
||||
|
||||
println!("Result: {:?}", result);
|
||||
|
||||
assert_eq!(
|
||||
result,
|
||||
Value::object(vec![
|
||||
("pets", Value::list(vec![
|
||||
Value::object(vec![
|
||||
("name", Value::string("Odie")),
|
||||
("woofs", Value::boolean(true)),
|
||||
].into_iter().collect()),
|
||||
Value::object(vec![
|
||||
("name", Value::string("Garfield")),
|
||||
("meows", Value::boolean(false)),
|
||||
].into_iter().collect()),
|
||||
])),
|
||||
].into_iter().collect()));
|
||||
}
|
||||
}
|
|
@ -3,3 +3,4 @@ mod variables;
|
|||
mod enums;
|
||||
mod directives;
|
||||
mod executor;
|
||||
mod interfaces_unions;
|
||||
|
|
|
@ -169,6 +169,19 @@ macro_rules! graphql_interface {
|
|||
graphql_interface!(@gather_meta, ($reg, $acc, $descr), $( $rest )*)
|
||||
};
|
||||
|
||||
// instance_resolvers: | <ctxtvar> | [...]
|
||||
(
|
||||
@ gather_meta,
|
||||
($reg:expr, $acc:expr, $descr:expr),
|
||||
instance_resolvers : | $ctxtvar:pat | { $( $srctype:ty => $resolver:expr ),* $(,)* } $( $rest:tt )*
|
||||
) => {
|
||||
$(
|
||||
let _ = $reg.get_type::<$srctype>();
|
||||
)*
|
||||
|
||||
graphql_interface!(@gather_meta, ($reg, $acc, $descr), $( $rest )*)
|
||||
};
|
||||
|
||||
// instance_resolvers: | <ctxtvar> | [...]
|
||||
(
|
||||
@ concrete_type_name,
|
||||
|
|
Loading…
Reference in a new issue