async-graphql-test 1.0.0

A test framework for Rust GraphQL servers.
Documentation
use std::fmt::{Display, Formatter};

use async_graphql::async_trait::async_trait;
use async_graphql::{Context, CustomDirective, Directive, ResolveFut, ServerResult, Value};

use super::{MatcherError, Numeric, ValueTypeName};

#[Directive(location = "Field", name = "shouldBeGreaterThan")]
pub fn should_be_greater_than(
    i: Option<i64>,
    f: Option<f64>,
    bi: Option<String>,
) -> impl CustomDirective {
    let num = if let Some(i) = i {
        Numeric::Int(i)
    } else if let Some(f) = f {
        Numeric::Float(f)
    } else if let Some(s) = bi {
        Numeric::String(s)
    } else {
        panic!("@shouldBeGreater missing an argument")
    };
    ShouldBeGreaterThan { num }
}

struct ShouldBeGreaterThan {
    num: Numeric,
}

impl Display for ShouldBeGreaterThan {
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
        self.num.fmt(f)
    }
}

#[async_trait]
impl CustomDirective for ShouldBeGreaterThan {
    async fn resolve_field(
        &self,
        ctx: &Context<'_>,
        resolve: ResolveFut<'_>,
    ) -> ServerResult<Option<Value>> {
        match resolve.await {
            Ok(None) => Ok(None),
            Ok(Some(Value::Number(num))) => {
                if self.num > num {
                    Ok(Some(Value::Number(num)))
                } else {
                    Err(MatcherError::new(
                        ctx.item.pos,
                        format!("Expected: > {self}\nReceived:   {num}"),
                    ))
                }
            }
            Ok(Some(value)) => {
                let type_name = ValueTypeName(&value);
                Err(MatcherError::new(
                    ctx.item.pos,
                    format!(
                        "@shouldBeGreaterThen error: value must be numeric.\nReceived has type:  {type_name}\nReceived has value: {value}"
                    ),
                ))
            }
            Err(err) => Err(MatcherError::unexpected_error(err)),
        }
    }
}