/// <summary>
        /// Creates the resolver.
        /// </summary>
        /// <param name="graphType">The graph type to generate a resolver for.</param>
        /// <param name="expression">The expression represneting how the type should be wrapped.</param>
        /// <returns>IQueryInputValueResolver.</returns>
        private IInputValueResolver CreateResolver(IGraphType graphType, GraphTypeExpression expression)
        {
            // extract the core resolver for the input type being processed
            IInputValueResolver coreResolver = null;
            Type coreType = null;

            if (graphType is IScalarGraphType scalar)
            {
                coreType     = _schema.KnownTypes.FindConcreteType(scalar);
                coreResolver = new ScalarInputResolver(scalar.SourceResolver);
            }
            else if (graphType is IEnumGraphType enumGraphType)
            {
                coreType     = _schema.KnownTypes.FindConcreteType(enumGraphType);
                coreResolver = new EnumValueResolver(coreType);
            }
            else if (graphType is IInputObjectGraphType inputType)
            {
                coreType     = _schema.KnownTypes.FindConcreteType(inputType);
                coreResolver = this.CreateObjectResolver(inputType, coreType);
            }

            // wrap any list wrappers around core resolver according to the type expression
            for (var i = expression.Wrappers.Length - 1; i >= 0; i--)
            {
                if (expression.Wrappers[i] == MetaGraphTypes.IsList)
                {
                    coreResolver = new ListValueResolver(coreType, coreResolver);
                    coreType     = typeof(IEnumerable <>).MakeGenericType(coreType);
                }
            }

            return(coreResolver);
        }
Example #2
0
        public void ListOfListValueResolver()
        {
            var innerList1 = new QueryListInputValue(new FakeSyntaxNode());

            innerList1.ListItems.Add(new QueryScalarInputValue(new FakeSyntaxNode(), "15", ScalarValueType.Number));
            innerList1.ListItems.Add(new QueryScalarInputValue(new FakeSyntaxNode(), "12", ScalarValueType.Number));

            var innerList2 = new QueryListInputValue(new FakeSyntaxNode());

            innerList2.ListItems.Add(new QueryScalarInputValue(new FakeSyntaxNode(), "30", ScalarValueType.Number));
            innerList2.ListItems.Add(new QueryScalarInputValue(new FakeSyntaxNode(), "40", ScalarValueType.Number));

            var outerList = new QueryListInputValue(new FakeSyntaxNode());

            outerList.ListItems.Add(innerList1);
            outerList.ListItems.Add(innerList2);

            var typeExpression = GraphTypeExpression.FromDeclaration("[[Int]]");
            var generator      = new InputResolverMethodGenerator(this.CreateSchema());

            var resolver = generator.CreateResolver(typeExpression);
            var result   = resolver.Resolve(outerList) as IEnumerable;

            CollectionAssert.AreEqual(new List <IEnumerable <int> > {
                new List <int> {
                    15, 12
                }, new List <int> {
                    30, 40
                }
            }, result);
        }
Example #3
0
        public void DefaultScalarValueResolvers_InvalidInputValue(string expressionText, string inputText)
        {
            var generator = new InputResolverMethodGenerator(this.CreateSchema());

            var text        = inputText?.AsMemory() ?? ReadOnlyMemory <char> .Empty;
            var source      = new SourceText(text);
            var tokenStream = Lexer.Tokenize(source);

            tokenStream.Prime();
            InputValueNode node = null;

            if (!tokenStream.EndOfStream)
            {
                var maker = ValueMakerFactory.CreateMaker(tokenStream.ActiveToken);
                if (maker != null)
                {
                    node = maker.MakeNode(tokenStream) as InputValueNode;
                }
            }

            var inputValue     = QueryInputValueFactory.CreateInputValue(node);
            var typeExpression = GraphTypeExpression.FromDeclaration(expressionText);
            var resolver       = generator.CreateResolver(typeExpression);

            Assert.Throws <UnresolvedValueException>(() =>
            {
                resolver.Resolve(inputValue);
            });
        }
Example #4
0
 /// <summary>
 /// Initializes a new instance of the <see cref="QueryVariable" /> class.
 /// </summary>
 /// <param name="node">The node.</param>
 public QueryVariable(VariableNode node)
 {
     this.Node            = Validation.ThrowIfNullOrReturn(node, nameof(node));
     this.Name            = node.Name.ToString();
     this.TypeExpression  = GraphTypeExpression.FromDeclaration(node.TypeExpression.Span);
     this.UsedByArguments = new List <QueryInputArgument>();
 }
        public void Matches_TestObject(object objectToTest, IEnumerable <GTW> wrappers, bool expectedResult)
        {
            var typeExpression = new GraphTypeExpression("SomeType", wrappers?.ToArray());

            var matches = typeExpression.Matches(objectToTest);

            Assert.AreEqual(expectedResult, matches);
        }
        /// <summary>
        /// Creates the resolver for the given expression. The Typename of the expression must be
        /// type represented in the schema this generator references or null will be returned.
        /// </summary>
        /// <param name="expression">The expression.</param>
        /// <returns>IQueryInputValueResolver.</returns>
        public IInputValueResolver CreateResolver(GraphTypeExpression expression)
        {
            var graphType = _schema.KnownTypes.FindGraphType(expression.TypeName);

            if (graphType == null)
            {
                return(null);
            }

            return(this.CreateResolver(graphType, expression));
        }
Example #7
0
 /// <summary>
 /// Initializes a new instance of the <see cref="SubscriptionMethodGraphField" /> class.
 /// </summary>
 /// <param name="fieldName">Name of the field in the type declaration..</param>
 /// <param name="typeExpression">The meta data about how this type field is implemented.</param>
 /// <param name="route">The formal route to this field in the object graph.</param>
 /// <param name="mode">The execution mode of this field.</param>
 /// <param name="resolver">The resolver.</param>
 /// <param name="securityPolicies">The security policies.</param>
 /// <param name="eventName">Alterante name of the event that has been assigned to this field.</param>
 public SubscriptionMethodGraphField(
     string fieldName,
     GraphTypeExpression typeExpression,
     GraphFieldPath route,
     Execution.FieldResolutionMode mode = Execution.FieldResolutionMode.PerSourceItem,
     Interfaces.Execution.IGraphFieldResolver resolver          = null,
     IEnumerable <Security.FieldSecurityGroup> securityPolicies = null,
     string eventName = null)
     : base(fieldName, typeExpression, route, mode, resolver, securityPolicies)
 {
     this.EventName = eventName;
 }
        /// <summary>
        /// Adds the input argument to the growing collection.
        /// </summary>
        /// <param name="name">The name of the argument in the object graph.</param>
        /// <param name="internalName">Name of the argument as it was defined in the code.</param>
        /// <param name="typeExpression">The type expression representing how this value is represented in this graph schema.</param>
        /// <param name="concreteType">The concrete type this field is on the server.</param>
        /// <returns>IGraphFieldArgument.</returns>
        public IGraphFieldArgument AddArgument(
            string name,
            string internalName,
            GraphTypeExpression typeExpression,
            Type concreteType)
        {
            var argument = new VirtualGraphFieldArgument(
                name,
                internalName,
                typeExpression,
                concreteType);

            return(this.AddArgument(argument));
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="PropertyGraphField" /> class.
 /// </summary>
 /// <param name="fieldName">Name of the field in the public graph.</param>
 /// <param name="typeExpression">The type expression declaring what type of data this field returns.</param>
 /// <param name="route">The route to this field in the graph.</param>
 /// <param name="propertyType">The property metadata.</param>
 /// <param name="propertyDeclaredName">The name of the property as it was declared on the <see cref="Type"/> (its internal name).</param>
 /// <param name="mode">The mode in which the runtime will process this field.</param>
 /// <param name="resolver">The resolver to be invoked to produce data when this field is called.</param>
 /// <param name="securityPolicies">The security policies that apply to this field.</param>
 public PropertyGraphField(
     string fieldName,
     GraphTypeExpression typeExpression,
     GraphFieldPath route,
     Type propertyType,
     string propertyDeclaredName,
     FieldResolutionMode mode     = FieldResolutionMode.PerSourceItem,
     IGraphFieldResolver resolver = null,
     IEnumerable <FieldSecurityGroup> securityPolicies = null)
     : base(fieldName, typeExpression, route, mode, resolver, securityPolicies)
 {
     this.ObjectType   = propertyType;
     this.InternalName = propertyDeclaredName;
 }
Example #10
0
 /// <summary>
 /// Initializes a new instance of the <see cref="MethodGraphField" /> class.
 /// </summary>
 /// <param name="fieldName">Name of the field in the graph.</param>
 /// <param name="typeExpression">The meta data describing the type of data this field returns.</param>
 /// <param name="route">The formal route to this field in the object graph.</param>
 /// <param name="mode">The mode in which the runtime will process this field.</param>
 /// <param name="resolver">The resolver to be invoked to produce data when this field is called.</param>
 /// <param name="securityPolicies">The security policies that apply to this field.</param>
 public MethodGraphField(
     string fieldName,
     GraphTypeExpression typeExpression,
     GraphFieldPath route,
     FieldResolutionMode mode     = FieldResolutionMode.PerSourceItem,
     IGraphFieldResolver resolver = null,
     IEnumerable <FieldSecurityGroup> securityPolicies = null)
 {
     this.Name           = fieldName;
     this.TypeExpression = Validation.ThrowIfNullOrReturn(typeExpression, nameof(typeExpression));
     this.Route          = Validation.ThrowIfNullOrReturn(route, nameof(route));
     this.Arguments      = new GraphFieldArgumentCollection();
     this.SecurityGroups = securityPolicies ?? Enumerable.Empty <FieldSecurityGroup>();
     this.UpdateResolver(resolver, mode);
 }
 /// <summary>
 /// Creates and adds a new <see cref="IGraphField" /> to the growing collection.
 /// </summary>
 /// <param name="fieldName">Name of the field.</param>
 /// <param name="typeExpression">The item representing how this field returns a graph type.</param>
 /// <param name="route">The formal route that identifies this field in the object graph.</param>
 /// <param name="resolver">The resolver used to fulfil requests to this field.</param>
 /// <param name="securityPolicies">The security policies enforced by this field, if any.</param>
 /// <returns>IGraphTypeField.</returns>
 public IGraphField AddField(
     string fieldName,
     GraphTypeExpression typeExpression,
     GraphFieldPath route,
     IGraphFieldResolver resolver = null,
     IEnumerable <FieldSecurityGroup> securityPolicies = null)
 {
     return(this.AddField(new MethodGraphField(
                              fieldName,
                              typeExpression,
                              route,
                              FieldResolutionMode.PerSourceItem,
                              resolver,
                              securityPolicies)));
 }
 /// <summary>
 /// Initializes a new instance of the <see cref="VirtualGraphFieldArgument" /> class.
 /// </summary>
 /// <param name="name">The name of this field in the object graph.</param>
 /// <param name="internalName">The name of this field as it exists in the .NET code.</param>
 /// <param name="typeExpression">The graph type expression representing this field.</param>
 /// <param name="concreteType">The concrete graph type in the server code that this argument is mapped to.</param>
 /// <param name="argModifiers">The argument modifiers.</param>
 /// <param name="defaultValue">The default value.</param>
 public VirtualGraphFieldArgument(
     string name,
     string internalName,
     GraphTypeExpression typeExpression,
     Type concreteType,
     GraphArgumentModifiers argModifiers = GraphArgumentModifiers.None,
     object defaultValue = null)
 {
     this.ObjectType        = Validation.ThrowIfNullOrReturn(concreteType, nameof(concreteType));
     this.InternalName      = Validation.ThrowIfNullWhiteSpaceOrReturn(internalName, nameof(internalName));
     this.Name              = Validation.ThrowIfNullWhiteSpaceOrReturn(name, nameof(name));
     this.ParameterName     = this.Name;
     this.TypeExpression    = Validation.ThrowIfNullOrReturn(typeExpression, nameof(typeExpression));
     this.ArgumentModifiers = argModifiers;
     this.DefaultValue      = defaultValue;
 }
        /// <summary>
        /// Adds the input argument to the growing collection.
        /// </summary>
        /// <param name="name">The name of the argument in the object graph.</param>
        /// <param name="internalName">Name of the argument as it was defined in the code.</param>
        /// <param name="typeExpression">The type expression representing how this value is represented in this graph schema.</param>
        /// <param name="concreteType">The concrete type this field is on the server.</param>
        /// <param name="defaultValue">The default value to set for the argument. If null, indicates
        /// the argument supplies null as the default value.</param>
        /// <returns>IGraphFieldArgument.</returns>
        public IGraphFieldArgument AddArgument(
            string name,
            string internalName,
            GraphTypeExpression typeExpression,
            Type concreteType,
            object defaultValue)
        {
            var argument = new VirtualGraphFieldArgument(
                name,
                internalName,
                typeExpression,
                concreteType,
                GraphArgumentModifiers.None,
                defaultValue);

            return(this.AddArgument(argument));
        }
Example #14
0
        public void BasicListValueResolver()
        {
            var sourceList = new QueryListInputValue(new FakeSyntaxNode());

            sourceList.ListItems.Add(new QueryScalarInputValue(new FakeSyntaxNode(), "15", ScalarValueType.Number));
            sourceList.ListItems.Add(new QueryScalarInputValue(new FakeSyntaxNode(), "12", ScalarValueType.Number));

            var typeExpression = GraphTypeExpression.FromDeclaration("[Int]");
            var generator      = new InputResolverMethodGenerator(this.CreateSchema());

            var resolver = generator.CreateResolver(typeExpression);
            var result   = resolver.Resolve(sourceList) as IEnumerable;

            CollectionAssert.AreEqual(new List <int> {
                15, 12
            }, result);
        }
Example #15
0
 /// <summary>
 /// Initializes a new instance of the <see cref="GraphFieldArgument" /> class.
 /// </summary>
 /// <param name="argumentName">Name of the argument.</param>
 /// <param name="typeExpression">The type expression.</param>
 /// <param name="modifiers">The modifiers.</param>
 /// <param name="parameterName">Name of the parameter as it is declared in the source code.</param>
 /// <param name="internalname">The fully qualified internal name identifiying this argument.</param>
 /// <param name="objectType">The concrete type of the object representing this argument.</param>
 /// <param name="defaultValue">The default value.</param>
 public GraphFieldArgument(
     string argumentName,
     GraphTypeExpression typeExpression,
     GraphArgumentModifiers modifiers,
     string parameterName,
     string internalname,
     Type objectType,
     object defaultValue = null)
 {
     this.Name              = Validation.ThrowIfNullWhiteSpaceOrReturn(argumentName, nameof(argumentName));
     this.InternalName      = Validation.ThrowIfNullWhiteSpaceOrReturn(internalname, nameof(internalname));
     this.ParameterName     = Validation.ThrowIfNullWhiteSpaceOrReturn(parameterName, nameof(parameterName));
     this.TypeExpression    = Validation.ThrowIfNullOrReturn(typeExpression, nameof(typeExpression));
     this.ObjectType        = Validation.ThrowIfNullOrReturn(objectType, nameof(objectType));
     this.ArgumentModifiers = modifiers;
     this.DefaultValue      = defaultValue;
 }
        /// <summary>
        /// Creates and adds a new <see cref="IGraphField" /> to the growing collection.
        /// </summary>
        /// <typeparam name="TSource">The expected type of the source data supplied to the resolver.</typeparam>
        /// <typeparam name="TReturn">The expected type of data to be returned from this field.</typeparam>
        /// <param name="fieldName">Name of the field.</param>
        /// <param name="typeExpression">The item representing how this field returns a graph type.</param>
        /// <param name="route">The formal route that identifies this field in the object graph.</param>
        /// <param name="resolver">The resolver used to fulfil requests to this field.</param>
        /// <param name="description">The description to assign to the field.</param>
        /// <returns>IGraphTypeField.</returns>
        public IGraphField AddField <TSource, TReturn>(
            string fieldName,
            GraphTypeExpression typeExpression,
            GraphFieldPath route,
            Func <TSource, Task <TReturn> > resolver,
            string description = null)
            where TSource : class
        {
            var field = new MethodGraphField(
                fieldName,
                typeExpression,
                route,
                FieldResolutionMode.PerSourceItem,
                new GraphDataValueResolver <TSource, TReturn>(resolver));

            field.Description = description;
            return(this.AddField(field));
        }
        public void ParseDeclaration(
            string declarationText,
            bool isValid,
            GTW[] expectedModifiers,
            string expectedTypeName)
        {
            var declaration = GraphTypeExpression.FromDeclaration(declarationText.AsSpan());

            Assert.AreEqual(isValid, declaration.IsValid);

            if (isValid)
            {
                Assert.AreEqual(expectedTypeName, declaration.TypeName);
                Assert.AreEqual(expectedModifiers.Length, declaration.Wrappers.Length);
                for (var i = 0; i < expectedModifiers.Length; i++)
                {
                    Assert.AreEqual(expectedModifiers[i], declaration.Wrappers[i]);
                }

                Assert.AreEqual(declarationText, declaration.ToString());
            }
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="DataBatch" /> class.
 /// </summary>
 /// <param name="fieldTypeExpression">The type expression provided by teh field attempting to resolve the data.</param>
 /// <param name="dictionary">The dictionary.</param>
 public DataBatch(GraphTypeExpression fieldTypeExpression, IDictionary dictionary)
 {
     _fieldTypeExpression = fieldTypeExpression;
     _dictionary          = dictionary;
 }
Example #19
0
 /// <summary>
 /// Initializes a new instance of the <see cref="ResolvedVariable"/> class.
 /// </summary>
 /// <param name="name">The name.</param>
 /// <param name="typeExpression">The type expression.</param>
 /// <param name="value">The value.</param>
 public ResolvedVariable(string name, GraphTypeExpression typeExpression, object value)
 {
     this.Name           = Validation.ThrowIfNullWhiteSpaceOrReturn(name, nameof(name));
     this.TypeExpression = Validation.ThrowIfNullOrReturn(typeExpression, nameof(typeExpression));
     this.Value          = value;
 }
 /// <summary>
 /// Wraps the base type with any necessary modifier types to generate the full type declaration.
 /// </summary>
 /// <param name="baseType">The base type to wrap.</param>
 /// <param name="typeExpression">The type expression.</param>
 /// <returns>IIntrospectedType.</returns>
 public static IntrospectedType WrapBaseTypeWithModifiers(IntrospectedType baseType, GraphTypeExpression typeExpression)
 {
     return(Introspection.WrapBaseTypeWithModifiers(baseType, typeExpression.Wrappers));
 }