use std::marker::PhantomData;
use crate::{
ast::InputValue,
schema::model::RootNode,
types::scalars::EmptyMutation,
value::{DefaultScalarValue, Object, Value},
};
struct Concrete;
struct CustomName;
#[allow(dead_code)]
struct WithLifetime<'a> {
data: PhantomData<&'a i32>,
}
#[allow(dead_code)]
struct WithGenerics<T> {
data: T,
}
struct DescriptionFirst;
struct FieldsFirst;
struct InterfacesFirst;
struct CommasWithTrailing;
struct CommasOnMeta;
struct ResolversWithTrailingComma;
struct Root;
#[crate::object_internal]
impl Concrete {
fn simple() -> i32 {
0
}
}
graphql_interface!(CustomName: () as "ACustomNamedInterface" |&self| {
field simple() -> i32 { 0 }
instance_resolvers: |_| { Concrete => Some(Concrete) }
});
graphql_interface!(<'a> WithLifetime<'a>: () as "WithLifetime" |&self| {
field simple() -> i32 { 0 }
instance_resolvers: |_| { Concrete => Some(Concrete) }
});
graphql_interface!(<T> WithGenerics<T>: () as "WithGenerics" |&self| {
field simple() -> i32 { 0 }
instance_resolvers: |_| { Concrete => Some(Concrete) }
});
graphql_interface!(DescriptionFirst: () |&self| {
description: "A description"
field simple() -> i32 { 0 }
instance_resolvers: |_| { Concrete => Some(Concrete) }
});
graphql_interface!(FieldsFirst: () |&self| {
field simple() -> i32 { 0 }
description: "A description"
instance_resolvers: |_| { Concrete => Some(Concrete) }
});
graphql_interface!(InterfacesFirst: () |&self| {
instance_resolvers: |_| { Concrete => Some(Concrete) }
field simple() -> i32 { 0 }
description: "A description"
});
graphql_interface!(CommasWithTrailing: () |&self| {
instance_resolvers: |_| { Concrete => Some(Concrete) },
field simple() -> i32 { 0 },
description: "A description",
});
graphql_interface!(CommasOnMeta: () |&self| {
instance_resolvers: |_| { Concrete => Some(Concrete) }
description: "A description",
field simple() -> i32 { 0 }
});
graphql_interface!(ResolversWithTrailingComma: () |&self| {
instance_resolvers: |_| { Concrete => Some(Concrete), }
description: "A description",
field simple() -> i32 { 0 }
});
#[crate::object_internal]
impl<'a> Root {
fn custom_name() -> CustomName {
CustomName {}
}
fn with_lifetime() -> WithLifetime<'a> {
WithLifetime { data: PhantomData }
}
fn with_generics() -> WithGenerics<i32> {
WithGenerics { data: 123 }
}
fn description_first() -> DescriptionFirst {
DescriptionFirst {}
}
fn fields_first() -> FieldsFirst {
FieldsFirst {}
}
fn interfaces_first() -> InterfacesFirst {
InterfacesFirst {}
}
fn commas_with_trailing() -> CommasWithTrailing {
CommasWithTrailing {}
}
fn commas_on_meta() -> CommasOnMeta {
CommasOnMeta {}
}
fn resolvers_with_trailing_comma() -> ResolversWithTrailingComma {
ResolversWithTrailingComma {}
}
}
fn run_type_info_query<F>(type_name: &str, f: F)
where
F: Fn(&Object<DefaultScalarValue>, &Vec<Value<DefaultScalarValue>>) -> (),
{
let doc = r#"
query ($typeName: String!) {
__type(name: $typeName) {
name
description
fields(includeDeprecated: true) {
name
}
}
}
"#;
let schema = RootNode::new(Root {}, EmptyMutation::<()>::new());
let vars = vec![("typeName".to_owned(), InputValue::scalar(type_name))]
.into_iter()
.collect();
let (result, errs) = crate::execute(doc, None, &schema, &vars, &()).expect("Execution failed");
assert_eq!(errs, []);
println!("Result: {:#?}", result);
let type_info = result
.as_object_value()
.expect("Result is not an object")
.get_field_value("__type")
.expect("__type field missing")
.as_object_value()
.expect("__type field not an object value");
let fields = type_info
.get_field_value("fields")
.expect("fields field missing")
.as_list_value()
.expect("fields field not a list value");
f(type_info, fields);
}
#[test]
fn introspect_custom_name() {
run_type_info_query("ACustomNamedInterface", |object, fields| {
assert_eq!(
object.get_field_value("name"),
Some(&Value::scalar("ACustomNamedInterface"))
);
assert_eq!(object.get_field_value("description"), Some(&Value::null()));
assert!(fields.contains(&Value::object(
vec![("name", Value::scalar("simple"))]
.into_iter()
.collect(),
)));
});
}
#[test]
fn introspect_with_lifetime() {
run_type_info_query("WithLifetime", |object, fields| {
assert_eq!(
object.get_field_value("name"),
Some(&Value::scalar("WithLifetime"))
);
assert_eq!(object.get_field_value("description"), Some(&Value::null()));
assert!(fields.contains(&Value::object(
vec![("name", Value::scalar("simple"))]
.into_iter()
.collect(),
)));
});
}
#[test]
fn introspect_with_generics() {
run_type_info_query("WithGenerics", |object, fields| {
assert_eq!(
object.get_field_value("name"),
Some(&Value::scalar("WithGenerics"))
);
assert_eq!(object.get_field_value("description"), Some(&Value::null()));
assert!(fields.contains(&Value::object(
vec![("name", Value::scalar("simple"))]
.into_iter()
.collect(),
)));
});
}
#[test]
fn introspect_description_first() {
run_type_info_query("DescriptionFirst", |object, fields| {
assert_eq!(
object.get_field_value("name"),
Some(&Value::scalar("DescriptionFirst"))
);
assert_eq!(
object.get_field_value("description"),
Some(&Value::scalar("A description"))
);
assert!(fields.contains(&Value::object(
vec![("name", Value::scalar("simple"))]
.into_iter()
.collect(),
)));
});
}
#[test]
fn introspect_fields_first() {
run_type_info_query("FieldsFirst", |object, fields| {
assert_eq!(
object.get_field_value("name"),
Some(&Value::scalar("FieldsFirst"))
);
assert_eq!(
object.get_field_value("description"),
Some(&Value::scalar("A description"))
);
assert!(fields.contains(&Value::object(
vec![("name", Value::scalar("simple"))]
.into_iter()
.collect(),
)));
});
}
#[test]
fn introspect_interfaces_first() {
run_type_info_query("InterfacesFirst", |object, fields| {
assert_eq!(
object.get_field_value("name"),
Some(&Value::scalar("InterfacesFirst"))
);
assert_eq!(
object.get_field_value("description"),
Some(&Value::scalar("A description"))
);
assert!(fields.contains(&Value::object(
vec![("name", Value::scalar("simple"))]
.into_iter()
.collect(),
)));
});
}
#[test]
fn introspect_commas_with_trailing() {
run_type_info_query("CommasWithTrailing", |object, fields| {
assert_eq!(
object.get_field_value("name"),
Some(&Value::scalar("CommasWithTrailing"))
);
assert_eq!(
object.get_field_value("description"),
Some(&Value::scalar("A description"))
);
assert!(fields.contains(&Value::object(
vec![("name", Value::scalar("simple"))]
.into_iter()
.collect(),
)));
});
}
#[test]
fn introspect_commas_on_meta() {
run_type_info_query("CommasOnMeta", |object, fields| {
assert_eq!(
object.get_field_value("name"),
Some(&Value::scalar("CommasOnMeta"))
);
assert_eq!(
object.get_field_value("description"),
Some(&Value::scalar("A description"))
);
assert!(fields.contains(&Value::object(
vec![("name", Value::scalar("simple"))]
.into_iter()
.collect(),
)));
});
}
#[test]
fn introspect_resolvers_with_trailing_comma() {
run_type_info_query("ResolversWithTrailingComma", |object, fields| {
assert_eq!(
object.get_field_value("name"),
Some(&Value::scalar("ResolversWithTrailingComma"))
);
assert_eq!(
object.get_field_value("description"),
Some(&Value::scalar("A description"))
);
assert!(fields.contains(&Value::object(
vec![("name", Value::scalar("simple"))]
.into_iter()
.collect(),
)));
});
}