private OperationCompiler( ISchema schema, FragmentCollection fragments) { _schema = schema; _fragments = fragments; }
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)); }
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); }
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(); }
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); }
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(); }
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(); }
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(); }
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); }
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)); }