Test GraphQL scalar implementation using custom ScalarValue (#791)

This commit is contained in:
tyranron 2020-10-23 12:13:34 +02:00
parent 3e4cf680e2
commit 61d1365b15
No known key found for this signature in database
GPG key ID: 762E144FB230A4F0

View file

@ -1,8 +1,10 @@
use juniper::{
DefaultScalarValue, EmptyMutation, EmptySubscription, Object, ParseScalarResult,
ParseScalarValue, RootNode, Value, Variables,
execute, graphql_object, graphql_scalar, graphql_value, DefaultScalarValue, EmptyMutation,
EmptySubscription, Object, ParseScalarResult, ParseScalarValue, RootNode, Value, Variables,
};
use crate::custom_scalar::MyScalarValue;
struct DefaultName(i32);
struct OtherOrder(i32);
struct Named(i32);
@ -19,72 +21,72 @@ Syntax to validate:
*/
#[juniper::graphql_scalar]
#[graphql_scalar]
impl<S> GraphQLScalar for DefaultName
where
S: juniper::ScalarValue,
S: ScalarValue,
{
fn resolve(&self) -> Value {
Value::scalar(self.0)
}
fn from_input_value(v: &juniper::InputValue) -> Option<DefaultName> {
fn from_input_value(v: &InputValue) -> Option<DefaultName> {
v.as_scalar_value()
.and_then(|s| s.as_int())
.map(|i| DefaultName(i))
}
fn from_str<'a>(value: juniper::ScalarToken<'a>) -> ParseScalarResult<'a, S> {
fn from_str<'a>(value: ScalarToken<'a>) -> ParseScalarResult<'a, S> {
<i32 as ParseScalarValue<S>>::from_str(value)
}
}
#[juniper::graphql_scalar]
#[graphql_scalar]
impl GraphQLScalar for OtherOrder {
fn resolve(&self) -> Value {
Value::scalar(self.0)
}
fn from_input_value(v: &juniper::InputValue) -> Option<OtherOrder> {
fn from_input_value(v: &InputValue) -> Option<OtherOrder> {
v.as_scalar_value::<i32>().map(|i| OtherOrder(*i))
}
fn from_str<'a>(value: juniper::ScalarToken<'a>) -> ParseScalarResult<'a, DefaultScalarValue> {
fn from_str<'a>(value: ScalarToken<'a>) -> ParseScalarResult<'a, DefaultScalarValue> {
<i32 as ParseScalarValue>::from_str(value)
}
}
#[juniper::graphql_scalar(name = "ANamedScalar")]
#[graphql_scalar(name = "ANamedScalar")]
impl GraphQLScalar for Named {
fn resolve(&self) -> Value {
Value::scalar(self.0)
}
fn from_input_value(v: &juniper::InputValue) -> Option<Named> {
fn from_input_value(v: &InputValue) -> Option<Named> {
v.as_scalar_value::<i32>().map(|i| Named(*i))
}
fn from_str<'a>(value: juniper::ScalarToken<'a>) -> ParseScalarResult<'a, DefaultScalarValue> {
fn from_str<'a>(value: ScalarToken<'a>) -> ParseScalarResult<'a, DefaultScalarValue> {
<i32 as ParseScalarValue>::from_str(value)
}
}
#[juniper::graphql_scalar(description = "A sample scalar, represented as an integer")]
#[graphql_scalar(description = "A sample scalar, represented as an integer")]
impl GraphQLScalar for ScalarDescription {
fn resolve(&self) -> Value {
Value::scalar(self.0)
}
fn from_input_value(v: &juniper::InputValue) -> Option<ScalarDescription> {
fn from_input_value(v: &InputValue) -> Option<ScalarDescription> {
v.as_scalar_value::<i32>().map(|i| ScalarDescription(*i))
}
fn from_str<'a>(value: juniper::ScalarToken<'a>) -> ParseScalarResult<'a, DefaultScalarValue> {
fn from_str<'a>(value: ScalarToken<'a>) -> ParseScalarResult<'a, DefaultScalarValue> {
<i32 as ParseScalarValue>::from_str(value)
}
}
#[juniper::graphql_object]
#[graphql_object]
impl Root {
fn default_name() -> DefaultName {
DefaultName(0)
@ -100,6 +102,33 @@ impl Root {
}
}
struct WithCustomScalarValue(i32);
#[graphql_scalar]
impl GraphQLScalar for WithCustomScalarValue {
fn resolve(&self) -> Value<MyScalarValue> {
Value::scalar(self.0)
}
fn from_input_value(v: &InputValue<MyScalarValue>) -> Option<WithCustomScalarValue> {
v.as_scalar_value::<i32>()
.map(|i| WithCustomScalarValue(*i))
}
fn from_str<'a>(value: ScalarToken<'a>) -> ParseScalarResult<'a, MyScalarValue> {
<i32 as ParseScalarValue<MyScalarValue>>::from_str(value)
}
}
struct RootWithCustomScalarValue;
#[graphql_object(scalar = MyScalarValue)]
impl RootWithCustomScalarValue {
fn with_custom_scalar_value() -> WithCustomScalarValue {
WithCustomScalarValue(0)
}
}
async fn run_type_info_query<F>(doc: &str, f: F)
where
F: Fn(&Object<DefaultScalarValue>) -> (),
@ -110,7 +139,7 @@ where
EmptySubscription::<()>::new(),
);
let (result, errs) = juniper::execute(doc, None, &schema, &Variables::new(), &())
let (result, errs) = execute(doc, None, &schema, &Variables::new(), &())
.await
.expect("Execution failed");
@ -133,19 +162,17 @@ where
fn path_in_resolve_return_type() {
struct ResolvePath(i32);
#[juniper::graphql_scalar]
#[graphql_scalar]
impl GraphQLScalar for ResolvePath {
fn resolve(&self) -> self::Value {
Value::scalar(self.0)
}
fn from_input_value(v: &juniper::InputValue) -> Option<ResolvePath> {
fn from_input_value(v: &InputValue) -> Option<ResolvePath> {
v.as_scalar_value::<i32>().map(|i| ResolvePath(*i))
}
fn from_str<'a>(
value: juniper::ScalarToken<'a>,
) -> ParseScalarResult<'a, DefaultScalarValue> {
fn from_str<'a>(value: ScalarToken<'a>) -> ParseScalarResult<'a, DefaultScalarValue> {
<i32 as ParseScalarValue>::from_str(value)
}
}
@ -246,3 +273,19 @@ async fn scalar_description_introspection() {
})
.await;
}
#[tokio::test]
async fn resolves_with_custom_scalar_value() {
const DOC: &str = r#"{ withCustomScalarValue }"#;
let schema = RootNode::<_, _, _, MyScalarValue>::new(
RootWithCustomScalarValue,
EmptyMutation::<()>::new(),
EmptySubscription::<()>::new(),
);
assert_eq!(
execute(DOC, None, &schema, &Variables::new(), &()).await,
Ok((graphql_value!({"withCustomScalarValue": 0}), vec![])),
);
}