/// <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); }
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); }
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); }); }
/// <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)); }
/// <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; }
/// <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)); }
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); }
/// <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; }
/// <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)); }