Beispiel #1
0
 private OperationCompiler(
     ISchema schema,
     FragmentCollection fragments)
 {
     _schema    = schema;
     _fragments = fragments;
 }
Beispiel #2
0
        public static IPreparedOperation Compile(
            string operationId,
            DocumentNode document,
            OperationDefinitionNode operation,
            ISchema schema,
            ObjectType rootType,
            InputParser inputParser,
            IEnumerable <ISelectionOptimizer>?optimizers = null)
        {
            if (operationId == null)
            {
                throw new ArgumentNullException(nameof(operationId));
            }

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

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

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

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

            if (operation.SelectionSet.Selections.Count == 0)
            {
                throw OperationCompiler_NoOperationSelections(operation);
            }

            var fragments          = new FragmentCollection(schema, document);
            var compiler           = new OperationCompiler(schema, fragments, inputParser);
            var selectionSetLookup = new Dictionary <SelectionSetNode, SelectionVariants>();
            var backlog            = new Stack <CompilerContext>();

            // creates and enqueues the root compiler context.
            CompilerContext.New(
                backlog,
                rootType,
                operation.SelectionSet,
                optimizers?.ToImmutableList() ?? ImmutableList <ISelectionOptimizer> .Empty,
                selectionSetLookup);

            // processes the backlog and by doing so traverses the query graph.
            compiler.Visit(backlog);

            return(new Operation(operationId, document, operation, rootType, selectionSetLookup));
        }
Beispiel #3
0
        public void Defer_Fragment_Spread()
        {
            // arrange
            var variables = new Mock <IVariableValueCollection>();

            ISchema schema = SchemaBuilder.New()
                             .AddStarWarsTypes()
                             .Create();

            DocumentNode document = Utf8GraphQLParser.Parse(
                @"{
                    hero(episode: EMPIRE) {
                        name
                        ... Foo @defer
                    }
                }
                
                fragment Foo on Droid {
                    id
                }
                ");

            OperationDefinitionNode operation =
                document.Definitions.OfType <OperationDefinitionNode>().Single();

            var fragments = new FragmentCollection(schema, document);

            // act
            IReadOnlyDictionary <SelectionSetNode, SelectionVariants> selectionSets =
                OperationCompiler.Compile(schema, fragments, operation, null);

            // assert
            var op = new Operation(
                "abc",
                document,
                operation,
                schema.QueryType,
                selectionSets);

            ISelection rootField = op.GetRootSelectionSet().Selections.Single();

            ObjectType droid = schema.GetType <ObjectType>("Droid");

            Assert.Collection(
                op.GetSelectionSet(rootField.SelectionSet, droid).Fragments,
                f =>
            {
                Assert.Equal(SyntaxKind.FragmentDefinition, f.SyntaxNode.Kind);
                Assert.Collection(
                    f.SelectionSet.Selections,
                    s => Assert.Equal("id", s.ResponseName));
            });

            ObjectType human = schema.GetType <ObjectType>("Human");

            Assert.Empty(op.GetSelectionSet(rootField.SelectionSet, human).Fragments);
        }
Beispiel #4
0
        public void Prepare_Inline_Fragment()
        {
            // arrange
            ISchema schema = SchemaBuilder.New()
                             .AddStarWarsTypes()
                             .Create();

            DocumentNode document = Utf8GraphQLParser.Parse(
                @"{
                hero(episode: EMPIRE) {
                    name
                    ... on Droid {
                        primaryFunction
                    }
                    ... on Human {
                        homePlanet
                    }
                }
             }");

            OperationDefinitionNode operation =
                document.Definitions.OfType <OperationDefinitionNode>().Single();

            var fragments = new FragmentCollection(schema, document);

            // act
            IReadOnlyDictionary <SelectionSetNode, SelectionVariants> selectionVariants =
                OperationCompiler.Compile(schema, fragments, operation);

            // assert
            ISelection hero = selectionVariants[operation.SelectionSet]
                              .GetSelectionSet(schema.QueryType).Selections.Single();

            Assert.Equal("hero", hero.ResponseName);

            Assert.Collection(
                selectionVariants[hero.SelectionSet]
                .GetSelectionSet(schema.GetType <ObjectType>("Droid")).Selections,
                selection => Assert.Equal("name", selection.ResponseName),
                selection => Assert.Equal("primaryFunction", selection.ResponseName));

            Assert.Collection(
                selectionVariants[hero.SelectionSet]
                .GetSelectionSet(schema.GetType <ObjectType>("Human")).Selections,
                selection => Assert.Equal("name", selection.ResponseName),
                selection => Assert.Equal("homePlanet", selection.ResponseName));

            var op = new Operation(
                "abc",
                document,
                operation,
                schema.QueryType,
                selectionVariants);

            op.Print().MatchSnapshot();
        }
Beispiel #5
0
        public void Field_Is_Visible_When_One_Selection_Is_Visible_4()
        {
            // arrange
            var variables = new Mock <IVariableValueCollection>();

            variables.Setup(t => t.GetVariable <bool>(It.IsAny <NameString>())).Returns(false);

            ISchema schema = SchemaBuilder.New()
                             .AddStarWarsTypes()
                             .Create();

            ObjectType droid = schema.GetType <ObjectType>("Droid");

            DocumentNode document = Utf8GraphQLParser.Parse(
                @"query foo($v: Boolean){
                    hero(episode: EMPIRE) {
                        name @include(if: $v)
                        ... abc
                    }
                }

                fragment abc on Droid {
                    name
                    ... {
                        name
                    }
                }");

            OperationDefinitionNode operation =
                document.Definitions.OfType <OperationDefinitionNode>().Single();

            var fragments = new FragmentCollection(schema, document);

            // act
            IReadOnlyDictionary <SelectionSetNode, SelectionVariants> selectionSets =
                OperationCompiler.Compile(schema, fragments, operation);

            // assert
            var op = new Operation(
                "abc",
                document,
                operation,
                schema.QueryType,
                selectionSets);
            ISelectionSet rootSelections =
                op.RootSelectionVariants.GetSelectionSet(
                    op.RootSelectionVariants.GetPossibleTypes().First());
            ISelectionSet droidSelections =
                op.GetSelectionSet(rootSelections.Selections[0].SelectionSet !, droid);

            Assert.Equal("name", droidSelections.Selections[0].ResponseName);
            Assert.False(droidSelections.Selections[0].IsConditional);
            Assert.True(droidSelections.Selections[0].IsIncluded(variables.Object));
            Assert.False(droidSelections.IsConditional);
        }
Beispiel #6
0
        public void Field_Based_Optimizers()
        {
            // arrange
            var variables = new Mock <IVariableValueCollection>();

            variables.Setup(t => t.GetVariable <bool>(It.IsAny <NameString>()))
            .Returns((NameString name) => name.Equals("v"));

            ISchema schema = SchemaBuilder.New()
                             .AddQueryType(d => d
                                           .Name("Query")
                                           .Field("root")
                                           .Resolve(new Foo())
                                           .UseOptimizer(new SimpleOptimizer()))
                             .Create();

            DocumentNode document = Utf8GraphQLParser.Parse(
                @"{
                    root {
                        bar {
                            text
                        }
                    }
                }");

            OperationDefinitionNode operation =
                document.Definitions.OfType <OperationDefinitionNode>().Single();

            var fragments = new FragmentCollection(schema, document);

            var optimizers = new List <NoopOptimizer> {
                new NoopOptimizer()
            };

            // act
            IReadOnlyDictionary <SelectionSetNode, SelectionVariants> selectionSets =
                OperationCompiler.Compile(schema, fragments, operation, optimizers);

            // assert
            var op = new Operation(
                "abc",
                document,
                operation,
                schema.QueryType,
                selectionSets);

            op.Print().MatchSnapshot();
        }
Beispiel #7
0
        public void Object_Field_Visibility_Is_Correctly_Inherited_3()
        {
            // arrange
            var variables = new Mock <IVariableValueCollection>();

            variables.Setup(t => t.GetVariable <bool>(It.IsAny <NameString>()))
            .Returns((NameString name) => name.Equals("v"));

            ISchema schema = SchemaBuilder.New()
                             .AddStarWarsTypes()
                             .Create();

            ObjectType droid = schema.GetType <ObjectType>("Droid");

            DocumentNode document = Utf8GraphQLParser.Parse(
                @"query foo($v: Boolean, $q: Boolean) {
                    hero(episode: EMPIRE) @include(if: $v) {
                        name @include(if: $q)
                    }
                }");

            OperationDefinitionNode operation =
                document.Definitions.OfType <OperationDefinitionNode>().Single();

            var fragments = new FragmentCollection(schema, document);

            // act
            IReadOnlyDictionary <SelectionSetNode, SelectionVariants> selectionSets =
                OperationCompiler.Compile(schema, fragments, operation);

            // assert
            var op = new Operation(
                "abc",
                document,
                operation,
                schema.QueryType,
                selectionSets);
            ISelectionSet rootSelections =
                op.RootSelectionVariants.GetSelectionSet(
                    op.RootSelectionVariants.GetPossibleTypes().First());
            ISelectionSet droidSelections =
                op.GetSelectionSet(rootSelections.Selections[0].SelectionSet !, droid);

            Assert.Empty(droidSelections.Selections.Where(t => t.IsIncluded(variables.Object)));

            op.Print().MatchSnapshot();
        }
Beispiel #8
0
        public void Prepare_Fragment_Definition()
        {
            // arrange
            ISchema schema = SchemaBuilder.New()
                             .AddStarWarsTypes()
                             .Create();

            DocumentNode document = Utf8GraphQLParser.Parse(
                @"{
                hero(episode: EMPIRE) {
                    name
                    ... abc
                    ... def
                }
              }

              fragment abc on Droid {
                  primaryFunction
              }

              fragment def on Human {
                  homePlanet
              }
             ");

            OperationDefinitionNode operation =
                document.Definitions.OfType <OperationDefinitionNode>().Single();

            var fragments = new FragmentCollection(schema, document);

            // act
            IReadOnlyDictionary <SelectionSetNode, SelectionVariants> selectionSets =
                OperationCompiler.Compile(schema, fragments, operation);

            // assert
            var op = new Operation(
                "abc",
                document,
                operation,
                schema.QueryType,
                selectionSets);

            op.Print().MatchSnapshot();
        }
Beispiel #9
0
        public void Reuse_Selection()
        {
            // arrange
            var variables = new Mock <IVariableValueCollection>();

            ISchema schema = SchemaBuilder.New()
                             .AddStarWarsTypes()
                             .Create();

            DocumentNode document = Utf8GraphQLParser.Parse(
                @"query Hero($episode: Episode, $withFriends: Boolean!) {
                    hero(episode: $episode) {
                        name
                        friends @include(if: $withFriends) {
                            nodes {
                                id
                            }
                        }
                    }
                }");

            OperationDefinitionNode operation =
                document.Definitions.OfType <OperationDefinitionNode>().Single();

            var fragments = new FragmentCollection(schema, document);

            // act
            IReadOnlyDictionary <SelectionSetNode, SelectionVariants> selectionSets =
                OperationCompiler.Compile(schema, fragments, operation, null);

            // assert
            new Operation(
                "abc",
                document,
                operation,
                schema.QueryType,
                selectionSets)
            .Print()
            .MatchSnapshot();
        }
        public static IReadOnlyDictionary <SelectionSetNode, SelectionVariants> Compile(
            ISchema schema,
            FragmentCollection fragments,
            OperationDefinitionNode operation,
            IEnumerable <ISelectionOptimizer>?optimizers = null)
        {
            var        compiler           = new OperationCompiler(schema, fragments);
            var        selectionSetLookup = new Dictionary <SelectionSetNode, SelectionVariants>();
            ObjectType rootType           = schema.GetOperationType(operation.Operation);
            var        backlog            = new Stack <CompilerContext>();

            // creates and enqueues the root compiler context.
            CompilerContext.New(
                backlog,
                rootType,
                operation.SelectionSet,
                optimizers?.ToImmutableList() ?? ImmutableList <ISelectionOptimizer> .Empty,
                selectionSetLookup);

            // processes the backlog and by doing so traverses the query graph.
            compiler.Visit(backlog);

            return(selectionSetLookup);
        }
Beispiel #11
0
 private OperationCompiler(ISchema schema, FragmentCollection fragments, InputParser parser)
 {
     _schema    = schema ?? throw new ArgumentNullException(nameof(schema));
     _fragments = fragments ?? throw new ArgumentNullException(nameof(fragments));
     _parser    = parser ?? throw new ArgumentNullException(nameof(parser));
 }