コード例 #1
0
        public void CreateRepeatableDirectiveType()
        {
            // arrange
            var source = "directive @foo(a:String) repeatable on QUERY";

            // act
            ISchema schema = SchemaBuilder.New()
                             .AddDocumentFromString(source)
                             .AddQueryType <DummyQuery>()
                             .Create();

            // assert
            DirectiveType type = schema.GetDirectiveType("foo");

            Assert.Equal("foo", type.Name);
            Assert.True(type.IsRepeatable);

            Assert.Collection(type.Locations,
                              t => Assert.Equal(DirectiveLocation.Query, t));

            Assert.Collection(type.Arguments,
                              t =>
            {
                Assert.Equal("a", t.Name);
                Assert.IsType <StringType>(t.Type);
            });
        }
コード例 #2
0
        private void CompleteDirective(
            ITypeInitializationContext context,
            DirectiveDescription description,
            HashSet <string> processed)
        {
            DirectiveReference reference =
                DirectiveReference.FromDescription(description);
            DirectiveType directiveType = context.GetDirectiveType(reference);

            if (directiveType != null)
            {
                if (!processed.Add(directiveType.Name) &&
                    !directiveType.IsRepeatable)
                {
                    context.ReportError(new SchemaError(
                                            $"The specified directive `@{directiveType.Name}` " +
                                            "is unique and cannot be added twice.",
                                            context.Type as INamedType));
                }
                else if (directiveType.Locations.Contains(_location))
                {
                    _directives.Add(Directive.FromDescription(
                                        directiveType, description, _source));
                }
                else
                {
                    context.ReportError(new SchemaError(
                                            $"The specified directive `@{directiveType.Name}` " +
                                            "is not allowed on the current location " +
                                            $"`{_location}`.",
                                            context.Type as INamedType));
                }
            }
        }
コード例 #3
0
        public void DirectiveOrderIsSignificant()
        {
            // arrange
            var someType = new ObjectType(t =>
                                          t.Name("Foo")
                                          .Field("abc")
                                          .Type <StringType>()
                                          .Resolve("abc")
                                          .Directive(new DirectiveNode("foo"))
                                          .Directive(new DirectiveNode("bar")));

            var foo = new DirectiveType(d => d
                                        .Name("foo")
                                        .Location(DirectiveLocation.FieldDefinition));

            var bar = new DirectiveType(d => d
                                        .Name("bar")
                                        .Location(DirectiveLocation.FieldDefinition));

            // act
            ISchema schema = CreateSchema(b =>
            {
                b.AddType(someType);
                b.AddDirectiveType(foo);
                b.AddDirectiveType(bar);
            });

            // assert
            Assert.Collection(someType.Fields["abc"].Directives,
                              t => Assert.Equal("foo", t.Name),
                              t => Assert.Equal("bar", t.Name));
        }
コード例 #4
0
        public void CreateSkipDirective()
        {
            // arrange
            SchemaContext       schemaContext       = SchemaContextFactory.Create();
            SchemaConfiguration schemaConfiguration =
                new SchemaConfiguration(
                    sp => { },
                    schemaContext.Types,
                    schemaContext.Resolvers,
                    schemaContext.Directives);
            TypeFinalizer typeFinalizer = new TypeFinalizer(schemaConfiguration);

            typeFinalizer.FinalizeTypes(schemaContext, null);

            // assert
            DirectiveType directive = schemaContext.Directives
                                      .GetDirectiveTypes().FirstOrDefault(t => t.Name == "skip");

            // assert
            Assert.NotNull(directive);
            Assert.IsType <SkipDirective>(directive);
            Assert.Equal("skip", directive.Name);
            Assert.Collection(directive.Arguments,
                              t =>
            {
                Assert.Equal("if", t.Name);
                Assert.IsType <NonNullType>(t.Type);
                Assert.IsType <BooleanType>(((NonNullType)t.Type).Type);
            });
            Assert.Collection(directive.Locations,
                              t => Assert.Equal(DirectiveLocation.Field, t),
                              t => Assert.Equal(DirectiveLocation.FragmentSpread, t),
                              t => Assert.Equal(DirectiveLocation.InlineFragment, t));
        }
コード例 #5
0
        internal static Directive FromDescription(
            DirectiveType directiveType,
            DirectiveDescription description,
            object source)
        {
            if (directiveType == null)
            {
                throw new ArgumentNullException(nameof(directiveType));
            }

            if (description == null)
            {
                throw new ArgumentNullException(nameof(description));
            }

            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }

            if (description.CustomDirective is null)
            {
                return(new Directive(directiveType,
                                     description.ParsedDirective,
                                     source));
            }
            else
            {
                return(new Directive(directiveType,
                                     description.CustomDirective,
                                     source));
            }
        }
コード例 #6
0
        public void MapCustomDirectiveToDifferentType()
        {
            // arrange
            ISchema       schema        = CreateSchema();
            DirectiveType directiveType = schema.GetDirectiveType("Foo");
            var           fooDirective  = new FooDirective
            {
                Bar   = "123",
                Child = new FooChild
                {
                    Bar = "456"
                }
            };

            // act
            var directive = Directive.FromDescription(
                directiveType,
                new DirectiveDefinition(
                    fooDirective,
                    _typeInspector.GetTypeRef(fooDirective.GetType())),
                new object());
            FooChild mappedObject = directive.ToObject <FooChild>();

            // assert
            Assert.Equal("123", mappedObject.Bar);
        }
コード例 #7
0
        public void EnsureSkipDirectiveIsAvailable()
        {
            // arrange
            ISchema schema = CreateSchema(b => { });

            // act
            DirectiveType directive =
                schema.DirectiveTypes.FirstOrDefault(
                    t => t.Name.Equals("skip"));

            // assert
            Assert.NotNull(directive);
            Assert.IsType <SkipDirectiveType>(directive);
            Assert.Equal("skip", directive.Name);
            Assert.Collection(directive.Arguments,
                              t =>
            {
                Assert.Equal("if", t.Name);
                Assert.IsType <NonNullType>(t.Type);
                Assert.IsType <BooleanType>(((NonNullType)t.Type).Type);
            });
            Assert.Collection(directive.Locations,
                              t => Assert.Equal(DirectiveLocation.Field, t),
                              t => Assert.Equal(DirectiveLocation.FragmentSpread, t),
                              t => Assert.Equal(DirectiveLocation.InlineFragment, t));
        }
コード例 #8
0
        public void GetArgumentFromCustomDirective()
        {
            // arrange
            ISchema       schema        = CreateSchema();
            DirectiveType directiveType = schema.GetDirectiveType("Foo");
            var           fooDirective  = new FooDirective
            {
                Bar   = "123",
                Child = new FooChild
                {
                    Bar = "456"
                }
            };

            // act
            var directive = Directive.FromDescription(
                directiveType,
                new DirectiveDefinition(
                    fooDirective,
                    _typeInspector.GetTypeRef(fooDirective.GetType())),
                new object());
            var barValue = directive.GetArgument <string>("bar");

            // assert
            Assert.Equal("123", barValue);
        }
コード例 #9
0
        public void DirectiveIsRepeatable()
        {
            // arrange
            var someType = new ObjectType(t =>
                                          t.Name("Foo")
                                          .Field("abc")
                                          .Type <StringType>()
                                          .Resolve("abc")
                                          .Directive(new DirectiveNode("foo"))
                                          .Directive(new DirectiveNode("foo")));

            var foo = new DirectiveType(d => d
                                        .Name("foo")
                                        .Location(DirectiveLocation.FieldDefinition)
                                        .Repeatable());

            // act
            CreateSchema(b =>
            {
                b.AddType(someType);
                b.AddDirectiveType(foo);
            });

            // assert
            Assert.Collection(someType.Fields["abc"].Directives,
                              t => Assert.Equal("foo", t.Name),
                              t => Assert.Equal("foo", t.Name));
        }
コード例 #10
0
        public void DirectiveIsNotRepeatable()
        {
            // arrange
            var someType = new ObjectType(t =>
                                          t.Name("Foo")
                                          .Field("abc")
                                          .Type <StringType>()
                                          .Resolve("abc")
                                          .Directive(new DirectiveNode("foo"))
                                          .Directive(new DirectiveNode("foo")));

            var foo = new DirectiveType(d =>
                                        d.Name("foo").Location(DirectiveLocation.FieldDefinition));

            // act
            Action action = () => CreateSchema(b =>
            {
                b.AddType(someType);
                b.AddDirectiveType(foo);
            });

            // assert
            Assert.Collection(Assert.Throws <SchemaException>(action).Errors,
                              t => Assert.Equal(
                                  "The specified directive `@foo` " +
                                  "is unique and cannot be added twice.",
                                  t.Message));
        }
コード例 #11
0
        public void InvalidLocation()
        {
            // arrange
            var someType = new ObjectType(t => t
                                          .Name("Foo")
                                          .Field("abc")
                                          .Type <StringType>()
                                          .Resolve("abc")
                                          .Directive(new DirectiveNode("foo")));

            var foo = new DirectiveType(d => d
                                        .Name("foo")
                                        .Location(DirectiveLocation.Object));

            // act
            Action action = () => CreateSchema(b =>
            {
                b.AddType(someType);
                b.AddDirectiveType(foo);
            });

            // assert
            Assert.Collection(Assert.Throws <SchemaException>(action).Errors,
                              t => Assert.Equal(
                                  "The specified directive `@foo` " +
                                  "is not allowed on the current location " +
                                  $"`{DirectiveLocation.FieldDefinition}`.",
                                  t.Message));
        }
コード例 #12
0
        public void UniqueDirective()
        {
            // arrange
            var directiveType = new DirectiveType(
                t => t.Name("foo")
                .Location(DirectiveLocation.Object)
                .Argument("a").Type <StringType>());

            var objectType = new ObjectType(t =>
            {
                t.Name("Bar");
                t.Directive("foo", new ArgumentNode("a", "1"));
                t.Directive("foo", new ArgumentNode("a", "2"));
                t.Field("foo").Resolver(() => "baz");
            });

            // act
            Action a = () => Schema.Create(t =>
            {
                t.RegisterDirective(directiveType);
                t.RegisterQueryType(objectType);
            });

            // assert
            SchemaException exception = Assert.Throws <SchemaException>(a);

            Assert.Collection(exception.Errors,
                              t =>
            {
                Assert.Equal(
                    "The specified directive `@foo` " +
                    "is unique and cannot be added twice.",
                    t.Message);
            });
        }
コード例 #13
0
        public static void MergeDirectives(
            ICompletionContext context,
            IList <DirectiveDefinition> extension,
            IList <DirectiveDefinition> type)
        {
            var directives =
                new List <(DirectiveType type, DirectiveDefinition def)>();

            foreach (DirectiveDefinition directive in type)
            {
                DirectiveType directiveType =
                    context.GetDirectiveType(directive.Reference);
                directives.Add((directiveType, directive));
            }

            foreach (DirectiveDefinition directive in extension)
            {
                MergeDirective(context, directives, directive);
            }

            type.Clear();

            foreach (DirectiveDefinition directive in
                     directives.Select(t => t.def))
            {
                type.Add(directive);
            }
        }
コード例 #14
0
        public void DirectiveOrderIsSignificant()
        {
            // act
            var someType = new ObjectType(t => t.Name("Foo"));
            var directiveDescriptions = new List <DirectiveDescription>
            {
                new DirectiveDescription(new DirectiveNode("foo")),
                new DirectiveDescription(new DirectiveNode("bar"))
            };

            var foo = new DirectiveType(d =>
                                        d.Name("foo").Location(DirectiveLocation.Field));

            var bar = new DirectiveType(d =>
                                        d.Name("bar").Location(DirectiveLocation.Field));

            var context = new Mock <ITypeInitializationContext>(
                MockBehavior.Strict);

            context.Setup(
                t => t.GetDirectiveType(It.IsAny <DirectiveReference>()))
            .Returns(new Func <DirectiveReference, DirectiveType>(
                         r =>
            {
                if (r.Name == "foo")
                {
                    return(foo);
                }

                if (r.Name == "bar")
                {
                    return(bar);
                }

                return(null);
            }
                         ));


            // act
            var collection = new DirectiveCollection(
                someType, DirectiveLocation.Field,
                directiveDescriptions);

            ((INeedsInitialization)collection)
            .RegisterDependencies(context.Object);
            ((INeedsInitialization)collection)
            .CompleteType(context.Object);

            // assert
            Assert.Collection(collection,
                              t => Assert.Equal("foo", t.Name),
                              t => Assert.Equal("bar", t.Name));
        }
コード例 #15
0
        public void ConfigureTypedDirectiveWithResolver()
        {
            // arrange
            // act
            DirectiveType directiveType =
                CreateDirective <CustomDirectiveType>();

            // assert
            Assert.True(directiveType.IsExecutable);
            Assert.NotNull(directiveType.Middleware);
            Assert.Equal(typeof(CustomDirective), directiveType.ClrType);
        }
コード例 #16
0
        public void ConfigureTypedDirectiveWithResolver()
        {
            // arrange
            // act
            DirectiveType directiveType =
                CreateDirective(new CustomDirectiveType());

            // assert
            Assert.True(directiveType.IsExecutable);
            Assert.NotEmpty(directiveType.MiddlewareComponents);
            Assert.Equal(typeof(CustomDirective), directiveType.ClrType);
        }
コード例 #17
0
 internal Directive(
     DirectiveType directiveType,
     DirectiveNode parsedDirective,
     object source)
 {
     Type = directiveType
            ?? throw new ArgumentNullException(nameof(directiveType));
     _parsedDirective = parsedDirective
                        ?? throw new ArgumentNullException(nameof(parsedDirective));
     Source = source
              ?? throw new ArgumentNullException(nameof(source));
     Name = directiveType.Name;
 }
コード例 #18
0
 internal Directive(
     DirectiveType directiveType,
     object customDirective,
     object source)
 {
     Type = directiveType
            ?? throw new ArgumentNullException(nameof(directiveType));
     _customDirective = customDirective
                        ?? throw new ArgumentNullException(nameof(customDirective));
     Source = source
              ?? throw new ArgumentNullException(nameof(source));
     Name = directiveType.Name;
 }
コード例 #19
0
        public void ConfigureTypedDirectiveNoArguments()
        {
            // arrange
            // act
            DirectiveType directiveType =
                CreateDirective(new Custom2DirectiveType());

            // assert
            Assert.True(directiveType.HasMiddleware);
            Assert.NotEmpty(directiveType.MiddlewareComponents);
            Assert.Equal(typeof(CustomDirective), directiveType.RuntimeType);
            Assert.Empty(directiveType.Arguments);
        }
コード例 #20
0
        public void ConfigureTypedDirectiveWithResolver()
        {
            // arrange
            // act
            DirectiveType directiveType =
                CreateDirective(new CustomDirectiveType());

            // assert
            Assert.True(directiveType.HasMiddleware);
            Assert.NotEmpty(directiveType.MiddlewareComponents);
            Assert.Equal(typeof(CustomDirective), directiveType.RuntimeType);
            Assert.Collection(directiveType.Arguments,
                              t => Assert.Equal("argument", t.Name.Value));
        }
コード例 #21
0
        public void ConfigureTypedDirective_DefaultBinding_Explicit()
        {
            // arrange
            // act
            DirectiveType directiveType =
                CreateDirective(new CustomDirectiveType(),
                                b => b.ModifyOptions(o =>
                                                     o.DefaultBindingBehavior = BindingBehavior.Explicit));

            // assert
            Assert.True(directiveType.IsExecutable);
            Assert.NotEmpty(directiveType.MiddlewareComponents);
            Assert.Equal(typeof(CustomDirective), directiveType.ClrType);
            Assert.Empty(directiveType.Arguments);
        }
コード例 #22
0
 private Directive(
     DirectiveType directiveType,
     DirectiveNode parsedDirective,
     object?customDirective,
     object source)
 {
     Type = directiveType
            ?? throw new ArgumentNullException(nameof(directiveType));
     _parsedDirective = parsedDirective
                        ?? throw new ArgumentNullException(nameof(parsedDirective));
     _customDirective = customDirective;
     Source           = source
                        ?? throw new ArgumentNullException(nameof(source));
     Name = directiveType.Name;
 }
コード例 #23
0
        public void ConfigureDirectiveWithResolver()
        {
            // arrange
            DirectiveType directiveType = new DirectiveType(
                t => t.Name("Foo")
                .Location(DirectiveLocation.Field)
                .Middleware(next => context => Task.CompletedTask));

            // act
            directiveType = CreateDirective(directiveType);

            // assert
            Assert.True(directiveType.IsExecutable);
            Assert.NotNull(directiveType.Middleware);
            Assert.Null(directiveType.ClrType);
        }
コード例 #24
0
        public void ConfigureDirectiveWithResolver()
        {
            // arrange
            var directiveType = new DirectiveType(t => t
                                                  .Name("Foo")
                                                  .Location(DirectiveLocation.Field)
                                                  .Use(next => context => default(ValueTask)));

            // act
            directiveType = CreateDirective(directiveType);

            // assert
            Assert.True(directiveType.HasMiddleware);
            Assert.NotEmpty(directiveType.MiddlewareComponents);
            Assert.Equal(typeof(object), directiveType.RuntimeType);
        }
コード例 #25
0
        public void ConfigureDirectiveWithResolver()
        {
            // arrange
            var directiveType = new DirectiveType(t => t
                                                  .Name("Foo")
                                                  .Location(DirectiveLocation.Field)
                                                  .Use(next => context => Task.CompletedTask));

            // act
            directiveType = CreateDirective(directiveType);

            // assert
            Assert.True(directiveType.IsExecutable);
            Assert.NotEmpty(directiveType.MiddlewareComponents);
            Assert.Equal(typeof(object), directiveType.ClrType);
        }
コード例 #26
0
        private bool TryCompleteDirective(
            ICompletionContext context,
            DirectiveDefinition definition,
            ISet <string> processed,
            out Directive directive)
        {
            DirectiveType directiveType = context.GetDirectiveType(definition.Reference);

            directive = null;

            if (directiveType != null)
            {
                if (!processed.Add(directiveType.Name) && !directiveType.IsRepeatable)
                {
                    context.ReportError(SchemaErrorBuilder.New()
                                        .SetMessage(string.Format(
                                                        CultureInfo.InvariantCulture,
                                                        TypeResources.DirectiveCollection_DirectiveIsUnique,
                                                        directiveType.Name))
                                        .SetCode(ErrorCodes.Schema.MissingType)
                                        .SetTypeSystemObject(context.Type)
                                        .AddSyntaxNode(definition.ParsedDirective)
                                        .SetExtension("Source", _source)
                                        .Build());
                }
                else if (directiveType.Locations.Contains(_location))
                {
                    directive = Directive.FromDescription(directiveType, definition, _source);
                }
                else
                {
                    context.ReportError(SchemaErrorBuilder.New()
                                        .SetMessage(string.Format(
                                                        CultureInfo.InvariantCulture,
                                                        TypeResources.DirectiveCollection_LocationNotAllowed,
                                                        directiveType.Name,
                                                        _location))
                                        .SetCode(ErrorCodes.Schema.MissingType)
                                        .SetTypeSystemObject(context.Type)
                                        .AddSyntaxNode(definition.ParsedDirective)
                                        .SetExtension("Source", _source)
                                        .Build());
                }
            }

            return(directive != null);
        }
コード例 #27
0
        public void ExecutableRepeatableDirectives()
        {
            // arrange
            var directiveType = new DirectiveType(
                t => t.Name("foo")
                .Repeatable()
                .Location(DirectiveLocation.Object)
                .Location(DirectiveLocation.FieldDefinition)
                .Use(next => context => Task.CompletedTask)
                .Argument("a").Type <StringType>());


            var objectType = new ObjectType(t =>
            {
                t.Name("Bar");
                t.Directive("foo", new ArgumentNode("a", "1"));
                t.Field("foo").Resolver(() => "baz")
                .Directive("foo", new ArgumentNode("a", "2"));
            });

            // act
            var schema = Schema.Create(t =>
            {
                t.RegisterDirective(directiveType);
                t.RegisterQueryType(objectType);
            });

            // assert
            IReadOnlyCollection <IDirective> collection =
                schema.GetType <ObjectType>("Bar")
                .Fields["foo"].ExecutableDirectives;

            Assert.Collection(collection,
                              t =>
            {
                Assert.Equal("foo", t.Name);
                Assert.Equal("1", t.GetArgument <string>("a"));
            },
                              t =>
            {
                Assert.Equal("foo", t.Name);
                Assert.Equal("2", t.GetArgument <string>("a"));
            });
        }
コード例 #28
0
        private void CompleteDirective(
            ICompletionContext context,
            DirectiveDefinition definition,
            ISet <string> processed)
        {
            DirectiveType directiveType =
                context.GetDirectiveType(definition.Reference);

            if (directiveType != null)
            {
                if (!processed.Add(directiveType.Name) &&
                    !directiveType.IsRepeatable)
                {
                    // TODO : resources
                    context.ReportError(SchemaErrorBuilder.New()
                                        .SetMessage(
                                            $"The specified directive `@{directiveType.Name}` " +
                                            "is unique and cannot be added twice.")
                                        .SetCode(TypeErrorCodes.MissingType)
                                        .SetTypeSystemObject(context.Type)
                                        .AddSyntaxNode(definition.ParsedDirective)
                                        .Build());
                }
                else if (directiveType.Locations.Contains(_location))
                {
                    _directives.Add(Directive.FromDescription(
                                        directiveType, definition, _source));
                }
                else
                {
                    // TODO : resources
                    context.ReportError(SchemaErrorBuilder.New()
                                        .SetMessage(
                                            $"The specified directive `@{directiveType.Name}` " +
                                            "is not allowed on the current location " +
                                            $"`{_location}`.")
                                        .SetCode(TypeErrorCodes.MissingType)
                                        .SetTypeSystemObject(context.Type)
                                        .AddSyntaxNode(definition.ParsedDirective)
                                        .Build());
                }
            }
        }
コード例 #29
0
        public void ConvertCustomDirectiveToDirectiveNode()
        {
            // arrange
            ISchema       schema        = CreateSchema();
            DirectiveType directiveType = schema.GetDirectiveType("Foo");
            var           fooDirective  = new FooDirective
            {
                Bar   = "123",
                Child = new FooChild
                {
                    Bar = "456"
                }
            };

            // act
            var directive = Directive.FromDescription(
                directiveType,
                new DirectiveDefinition(
                    fooDirective,
                    _typeInspector.GetTypeRef(fooDirective.GetType())),
                new object());
            DirectiveNode directiveNode = directive.ToNode();

            // assert
            Assert.Equal(directiveType.Name, directiveNode.Name.Value);
            Assert.Collection(directiveNode.Arguments,
                              t =>
            {
                Assert.Equal("bar", t.Name.Value);
                Assert.Equal("123", ((StringValueNode)t.Value).Value);
            },
                              t =>
            {
                Assert.Equal("child", t.Name.Value);
                Assert.Collection(((ObjectValueNode)t.Value).Fields,
                                  x =>
                {
                    Assert.Equal("bar", x.Name.Value);
                    Assert.Equal("456",
                                 ((StringValueNode)x.Value).Value);
                });
            });
        }
コード例 #30
0
        public void DirectiveNotRepeatable()
        {
            // act
            var someType = new ObjectType(t => t.Name("Foo"));
            var directiveDescriptions = new List <DirectiveDescription>
            {
                new DirectiveDescription(new DirectiveNode("foo")),
                new DirectiveDescription(new DirectiveNode("foo"))
            };

            var foo = new DirectiveType(d =>
                                        d.Name("foo").Location(DirectiveLocation.Field));

            var errors = new List <SchemaError>();

            var context = new Mock <ITypeInitializationContext>();

            context.Setup(
                t => t.GetDirectiveType(It.IsAny <DirectiveReference>()))
            .Returns(new Func <DirectiveReference, DirectiveType>(
                         r => foo));
            context.Setup(t => t.ReportError(It.IsAny <SchemaError>()))
            .Callback(new Action <SchemaError>(errors.Add));

            // act
            var collection = new DirectiveCollection(
                someType, DirectiveLocation.Field,
                directiveDescriptions);

            ((INeedsInitialization)collection)
            .RegisterDependencies(context.Object);
            ((INeedsInitialization)collection)
            .CompleteType(context.Object);

            // assert
            Assert.Collection(errors,
                              t => Assert.Equal(
                                  "The specified directive `@foo` " +
                                  "is unique and cannot be added twice.",
                                  t.Message));
        }