From 61d1365b15110e92a001ba262b7ee7387933eb67 Mon Sep 17 00:00:00 2001
From: tyranron <tyranron@gmail.com>
Date: Fri, 23 Oct 2020 12:13:34 +0200
Subject: [PATCH] Test GraphQL scalar implementation using custom ScalarValue
 (#791)

---
 .../juniper_tests/src/codegen/impl_scalar.rs  | 87 ++++++++++++++-----
 1 file changed, 65 insertions(+), 22 deletions(-)

diff --git a/integration_tests/juniper_tests/src/codegen/impl_scalar.rs b/integration_tests/juniper_tests/src/codegen/impl_scalar.rs
index dc732b1a..640937fa 100644
--- a/integration_tests/juniper_tests/src/codegen/impl_scalar.rs
+++ b/integration_tests/juniper_tests/src/codegen/impl_scalar.rs
@@ -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![])),
+    );
+}