public static IServiceCollection AddGraphQL(
            this IServiceCollection services,
            Action <ISchemaConfiguration> configure,
            IQueryExecutionOptionsAccessor options)
        {
            if (services == null)
            {
                throw new ArgumentNullException(nameof(services));
            }

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

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

            QueryExecutionBuilder.BuildDefault(services, options);

            return(services.AddSchema(s =>
                                      Schema.Create(c =>
            {
                c.RegisterServiceProvider(s);
                configure(c);
            }))
                   .AddSingleton <IBatchQueryExecutor, BatchQueryExecutor>());
        }
        public static IServiceCollection AddGraphQL(
            this IServiceCollection services,
            string schemaSource,
            Action <ISchemaConfiguration> configure)
        {
            if (services == null)
            {
                throw new ArgumentNullException(nameof(services));
            }

            if (string.IsNullOrEmpty(schemaSource))
            {
                throw new ArgumentNullException(nameof(schemaSource));
            }

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

            QueryExecutionBuilder.BuildDefault(services);

            return(services.AddSchema(s =>
                                      Schema.Create(schemaSource, c =>
            {
                c.RegisterServiceProvider(s);
                configure(c);
            }))
                   .AddSingleton <IBatchQueryExecutor, BatchQueryExecutor>());
        }
        public static IServiceCollection AddGraphQL(
            this IServiceCollection services,
            Action <ISchemaConfiguration> configure,
            Action <IQueryExecutionBuilder> build)
        {
            if (services == null)
            {
                throw new ArgumentNullException(nameof(services));
            }

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

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

            QueryExecutionBuilder builder = QueryExecutionBuilder.New();

            build(builder);
            builder.Populate(services);

            return(services.AddSchema(s => Schema.Create(c =>
            {
                c.RegisterServiceProvider(s);
                configure(c);
            }))
                   .AddSingleton <IBatchQueryExecutor, BatchQueryExecutor>());
        }
        public static IServiceCollection AddGraphQL(
            this IServiceCollection services,
            Func <IServiceProvider, ISchema> schemaFactory,
            Action <IQueryExecutionBuilder> build)
        {
            if (services == null)
            {
                throw new ArgumentNullException(nameof(services));
            }

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

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

            QueryExecutionBuilder builder = QueryExecutionBuilder.New();

            build(builder);
            builder.Populate(services);

            return(services.AddSchema(schemaFactory)
                   .AddSingleton <IBatchQueryExecutor, BatchQueryExecutor>());
        }
예제 #5
0
 public QueryExecutorBenchmarkBase(int cacheSize)
 {
     _schema        = SchemaFactory.Create();
     _queryExecutor = QueryExecutionBuilder.New()
                      .UseDefaultPipeline()
                      .AddQueryCache(cacheSize)
                      .Build(_schema);
 }
예제 #6
0
        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllers();

            //services.AddGraphQL(SchemaBuilder.New());

            /*
             * This is an alternative approach (workaround) to fix this behavior
             */
            #region Workaround

            Func <IServiceProvider, ISchema> factory = s => SchemaBuilder.New()
                                                       .AddServices(s)
                                                       .AddType <AuthorType>()
                                                       .AddType <BookType>()
                                                       .AddQueryType <Query>()
                                                       .Create();

            var opts = new QueryExecutionOptions {
            };

            services.AddSingleton(sp =>
            {
                var d = sp.GetRequiredService <DiagnosticListener>();
                var o = sp.GetServices <IDiagnosticObserver>();

                BindingFlags flags   = BindingFlags.NonPublic | BindingFlags.Instance;
                CultureInfo culture  = null;
                var instantiatedType = Activator.CreateInstance(typeof(QueryExecutionDiagnostics), flags, null, new object[] { d, o }, culture);
                return(instantiatedType as QueryExecutionDiagnostics);
            });

            QueryExecutionBuilder.New()
            .AddDefaultServices(opts)
            .UseRequestTimeout()
            .UseExceptionHandling()


            .UseQueryParser()
            .UseNoCachedQueryError()
            .UseValidation()
            .UseOperationResolver()
            .UseMaxComplexity()
            .UseOperationExecutor()
            .Populate(services);

            services.AddSingleton(factory);
            services.AddSingleton <IIdSerializer, IdSerializer>()
            .AddGraphQLSubscriptions();
            services.AddJsonQueryResultSerializer().AddJsonArrayResponseStreamSerializer();

            services.AddSingleton <IBatchQueryExecutor, BatchQueryExecutor>();

            /* END */
            #endregion

            services.AddApplicationInsightsTelemetry();
        }
예제 #7
0
        public static IQueryExecutor MakeExecutable(
            this ISchema schema,
            Func <IQueryExecutionBuilder, IQueryExecutionBuilder> configure)
        {
            IQueryExecutionBuilder builder = configure(
                QueryExecutionBuilder.New());

            return(builder.Build(schema));
        }
예제 #8
0
        public static IQueryExecutor MakeExecutable(
            this ISchema schema,
            Action <IQueryExecutionBuilder> configure)
        {
            QueryExecutionBuilder builder = QueryExecutionBuilder.New();

            configure(builder);
            return(builder.Build(schema));
        }
예제 #9
0
        public static IServiceCollection AddQueryExecutor(
            this IServiceCollection services,
            Action <IQueryExecutionBuilder> configure)
        {
            var builder = QueryExecutionBuilder.New();

            configure(builder);
            builder.Populate(services);
            return(services);
        }
 public static async Task <IExecutionResult> ExecuteAsync(
     this ISchema schema, QueryRequest request,
     CancellationToken cancellationToken = default)
 {
     using (IQueryExecuter executer = QueryExecutionBuilder.New()
                                      .UseDefaultPipeline().Build(schema))
     {
         return(await executer.ExecuteAsync(request, cancellationToken));
     }
 }
예제 #11
0
        public void Populate(IServiceCollection serviceCollection)
        {
            if (serviceCollection == null)
            {
                throw new ArgumentNullException(nameof(serviceCollection));
            }

            serviceCollection.TryAddSingleton <
                IQueryResultSerializer,
                JsonQueryResultSerializer>();

            foreach (KeyValuePair <NameString, ExecutorFactory> factory in
                     _execFacs)
            {
                serviceCollection.AddSingleton <IRemoteExecutorAccessor>(
                    services => new RemoteExecutorAccessor(
                        factory.Key,
                        factory.Value.Invoke(services)));
            }

            serviceCollection.TryAddSingleton(services =>
                                              StitchingFactory.Create(this, services));

            serviceCollection.TryAddScoped(services =>
                                           services.GetRequiredService <StitchingFactory>()
                                           .CreateStitchingContext(services));

            if (!serviceCollection.Any(d =>
                                       d.ImplementationType == typeof(RemoteQueryBatchOperation)))
            {
                serviceCollection.AddScoped <
                    IBatchOperation,
                    RemoteQueryBatchOperation>();
            }

            serviceCollection.TryAddSingleton <ISchema>(sp =>
                                                        sp.GetRequiredService <StitchingFactory>()
                                                        .CreateStitchedSchema(sp));

            var builder = QueryExecutionBuilder.New();

            foreach (Action <IQueryExecutionBuilder> configure in _execConfigs)
            {
                configure(builder);
            }
            builder.UseStitchingPipeline();
            builder.Populate(serviceCollection, true);

            serviceCollection.TryAddSingleton(services =>
                                              services.GetRequiredService <IQueryExecutor>()
                                              .Schema);
        }
        public static QueryExecutionBuilder ConfigureInterceptors(this QueryExecutionBuilder builder, Action <QueryExecutionBuilder>?addQueryCacherInterceptors)
        {
            // order matters: the earlier an interceptor is registered, the earlier it runs during execution

            // query cacher interceptors should be as close to the caller as possible!
            addQueryCacherInterceptors?.Invoke(builder);

            builder.AddInterceptorFor <IQuery>((sp, next) => new QueryPerformanceLoggerInterceptor(next, sp.GetRequiredService <IGuidProvider>(), sp.GetRequiredService <ILogger <QueryPerformanceLoggerInterceptor> >()));

            builder.AddInterceptorFor <IQuery>((sp, next) => new QueryDataAnnotationsValidatorInterceptor(next));

            return(builder);
        }
        public static IServiceCollection AddGraphQL(
            this IServiceCollection serviceCollection,
            BuildExecuter buildExecuter)
        {
            if (buildExecuter == null)
            {
                throw new ArgumentNullException(nameof(buildExecuter));
            }

            return(serviceCollection
                   .AddSingleton <IQueryExecuter>(s =>
                                                  buildExecuter(s, QueryExecutionBuilder.New()))
                   .AddSingleton(s =>
                                 s.GetRequiredService <IQueryExecuter>().Schema)
                   .AddJsonSerializer());
        }
        public static IServiceCollection AddGraphQL(
            this IServiceCollection serviceCollection,
            Func <IServiceProvider, ISchema> schemaFactory)
        {
            if (serviceCollection == null)
            {
                throw new ArgumentNullException(nameof(serviceCollection));
            }

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

            QueryExecutionBuilder.BuildDefault(serviceCollection);
            return(serviceCollection.AddSchema(schemaFactory));
        }
예제 #15
0
        public async Task GlobalDataLoader()
        {
            // arrange
            ISchema schema = CreateSchema(ExecutionScope.Global);
            IQueryExecutionOptionsAccessor options = CreateOptions();
            IQueryExecuter executer = QueryExecutionBuilder
                                      .BuildDefault(schema, options);

            // act
            List <IExecutionResult> results = new List <IExecutionResult>();

            results.Add(await executer.ExecuteAsync(new QueryRequest(
                                                        @"{
                    a: withDataLoader(key: ""a"")
                    b: withDataLoader(key: ""b"")
                }")));
            results.Add(await executer.ExecuteAsync(new QueryRequest(
                                                        @"{
                    a: withDataLoader(key: ""a"")
                }")));
            results.Add(await executer.ExecuteAsync(new QueryRequest(
                                                        @"{
                    c: withDataLoader(key: ""c"")
                }")));

            // assert
            Assert.Collection(results,
                              t => Assert.Null(t.Errors),
                              t => Assert.Null(t.Errors),
                              t => Assert.Null(t.Errors));
            results.Snapshot();

            var keyLoads = new HashSet <string>();
            var loads    = (IQueryExecutionResult)await executer
                           .ExecuteAsync(new QueryRequest("{ loads }"));

            foreach (object o in (IEnumerable <object>)loads.Data["loads"])
            {
                string[] keys = o.ToString().Split(',');
                foreach (string key in keys)
                {
                    Assert.True(keyLoads.Add(key));
                }
            }
        }
        public static IServiceCollection AddGraphQL(
            this IServiceCollection services,
            Func <IServiceProvider, ISchema> schemaFactory)
        {
            if (services == null)
            {
                throw new ArgumentNullException(nameof(services));
            }

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

            QueryExecutionBuilder.BuildDefault(services);
            return(services.AddSchema(schemaFactory)
                   .AddSingleton <IBatchQueryExecutor, BatchQueryExecutor>());
        }
예제 #17
0
        public async Task EnsureQueryResultContainsExtensionTracing()
        {
            // arrange
            Schema         schema   = CreateSchema();
            IQueryExecutor executor = QueryExecutionBuilder
                                      .BuildDefault(schema, new QueryExecutionOptions
            {
                TracingPreference = TracingPreference.Always
            });
            var request = new QueryRequest("{ a }");

            // act
            IExecutionResult result = await executor.ExecuteAsync(request);

            // assert
            Assert.NotEmpty(result.Extensions);
            Assert.True(result.Extensions.ContainsKey("tracing"));
        }
        public static IServiceCollection AddGraphQLWithName(
            this IServiceCollection services,
            string schemaName,
            ISchema schema)
        {
            if (services == null)
            {
                throw new ArgumentNullException(nameof(services));
            }

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

            QueryExecutionBuilder.BuildDefault(services, schemaName);
            return(services.AddSchema(schemaName, schema)
                   .AddBatchQueryExecutor(schemaName));
        }
        public static IServiceCollection AddGraphQL(
            this IServiceCollection serviceCollection,
            Action <ISchemaConfiguration> configure)
        {
            if (serviceCollection == null)
            {
                throw new ArgumentNullException(nameof(serviceCollection));
            }

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

            QueryExecutionBuilder.BuildDefault(serviceCollection);
            return(serviceCollection.AddSchema(s => Schema.Create(c =>
            {
                c.RegisterServiceProvider(s);
                configure(c);
            })));
        }
        public static IServiceCollection AddGraphQLWithName(
            this IServiceCollection services,
            string schemaName,
            string schemaSource,
            Action <ISchemaConfiguration> configure,
            Action <IQueryExecutionBuilder> build)
        {
            if (services == null)
            {
                throw new ArgumentNullException(nameof(services));
            }

            if (string.IsNullOrEmpty(schemaSource))
            {
                throw new ArgumentNullException(nameof(schemaSource));
            }

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

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

            QueryExecutionBuilder builder = QueryExecutionBuilder.New();

            build(builder);
            builder.Populate(schemaName, services);

            return(services.AddSchema(schemaName, s =>
                                      Schema.Create(schemaSource, c =>
            {
                c.RegisterServiceProvider(s);
                configure(c);
            }))
                   .AddBatchQueryExecutor(schemaName));
        }
예제 #21
0
        public async Task GlobalCustomContext()
        {
            // arrange
            ISchema        schema   = CreateSchema(ExecutionScope.Global);
            IQueryExecuter executer =
                QueryExecutionBuilder.BuildDefault(schema);

            // act
            var results = new List <IExecutionResult>();

            results.Add(await executer.ExecuteAsync(new QueryRequest("{ a }")));
            results.Add(await executer.ExecuteAsync(new QueryRequest("{ a }")));
            results.Add(await executer.ExecuteAsync(new QueryRequest("{ a }")));
            results.Add(await executer.ExecuteAsync(new QueryRequest("{ a }")));

            // assert
            Assert.Collection(results,
                              t => Assert.Null(t.Errors),
                              t => Assert.Null(t.Errors),
                              t => Assert.Null(t.Errors),
                              t => Assert.Null(t.Errors));
            results.Snapshot();
        }
        public static IServiceCollection AddGraphQL(
            this IServiceCollection serviceCollection,
            ISchema schema,
            IQueryExecutionOptionsAccessor options)
        {
            if (serviceCollection == null)
            {
                throw new ArgumentNullException(nameof(serviceCollection));
            }

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

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

            QueryExecutionBuilder.BuildDefault(serviceCollection, options);
            return(serviceCollection.AddSchema(schema));
        }
        public static IServiceCollection AddGraphQLWithName(
            this IServiceCollection services,
            string schemaName,
            Action <ISchemaConfiguration> configure)
        {
            if (services == null)
            {
                throw new ArgumentNullException(nameof(services));
            }

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

            QueryExecutionBuilder.BuildDefault(services, schemaName);
            return(services.AddSchema(schemaName, s => Schema.Create(c =>
            {
                c.RegisterServiceProvider(s);
                configure(c);
            }))
                   .AddBatchQueryExecutor(schemaName));
        }
        public static IServiceCollection AddGraphQL(
            this IServiceCollection serviceCollection,
            Func <IServiceProvider, ISchema> schemaFactory,
            Func <IQueryExecutionBuilder, IQueryExecutionBuilder> configure)
        {
            if (serviceCollection == null)
            {
                throw new ArgumentNullException(nameof(serviceCollection));
            }

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

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

            configure(QueryExecutionBuilder.New()).Populate(serviceCollection);
            return(serviceCollection.AddSchema(schemaFactory));
        }
        public static IServiceCollection AddGraphQL(
            this IServiceCollection serviceCollection,
            string schemaSource,
            Action <ISchemaConfiguration> configure,
            Func <IQueryExecutionBuilder, IQueryExecutionBuilder>
            configureBuilder)
        {
            if (serviceCollection == null)
            {
                throw new ArgumentNullException(nameof(serviceCollection));
            }

            if (string.IsNullOrEmpty(schemaSource))
            {
                throw new ArgumentNullException(nameof(schemaSource));
            }

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

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

            configureBuilder(QueryExecutionBuilder.New())
            .Populate(serviceCollection);

            return(serviceCollection.AddSchema(s =>
                                               Schema.Create(schemaSource, c =>
            {
                c.RegisterServiceProvider(s);
                configure(c);
            })));
        }
        public static IServiceCollection AddGraphQL(
            this IServiceCollection services,
            ISchema schema,
            Func <IQueryExecutionBuilder, IQueryExecutionBuilder> configure)
        {
            if (services == null)
            {
                throw new ArgumentNullException(nameof(services));
            }

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

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

            configure(QueryExecutionBuilder.New()).Populate(services);
            return(services.AddSchema(schema)
                   .AddSingleton <IBatchQueryExecutor, BatchQueryExecutor>());
        }
예제 #27
0
 public static IServiceCollection AddQueryExecutor(
     this IServiceCollection services)
 {
     QueryExecutionBuilder.BuildDefault(services);
     return(services);
 }
        public async Task Convert_List_To_Single_Value_With_Converters()
        {
            // arrange
            var serviceCollection = new ServiceCollection();

            serviceCollection
            .AddSingleton <ISchema>(sp => SchemaBuilder.New()
                                    .AddServices(sp)
                                    .AddExportDirectiveType()
                                    .AddQueryType(d =>
            {
                d.Name("Query");

                d.Field("foo")
                .Argument("bar", a => a.Type <ListType <StringType> >())
                .Type <ListType <StringType> >()
                .Resolver <List <string> >(c =>
                {
                    var list = c.Argument <List <string> >("bar");
                    list.Add("789");
                    return(list);
                });

                d.Field("baz")
                .Argument("bar", a => a.Type <StringType>())
                .Resolver(c => c.Argument <string>("bar"));
            })
                                    .Create())
            .AddSingleton <IBatchQueryExecutor, BatchQueryExecutor>();

            QueryExecutionBuilder.BuildDefault(serviceCollection);

            IServiceProvider services =
                serviceCollection.BuildServiceProvider();

            var executor = services.GetService <IBatchQueryExecutor>();

            // act
            var batch = new List <IReadOnlyQueryRequest>
            {
                QueryRequestBuilder.New()
                .SetQuery(
                    @"query foo1($b1: [String]) {
                            foo(bar: $b1) @export(as: ""b2"")
                        }")
                .AddVariableValue("b1", new[] { "123" })
                .Create(),
                QueryRequestBuilder.New()
                .SetQuery(
                    @"query foo2($b2: String) {
                            baz(bar: $b2)
                        }")
                .Create()
            };

            IResponseStream stream =
                await executor.ExecuteAsync(batch, CancellationToken.None);

            var results = new List <IReadOnlyQueryResult>();

            await foreach (IReadOnlyQueryResult result in stream)
            {
                if (result != null)
                {
                    results.Add(result);
                }
            }

            Assert.Collection(results,
                              r => r.MatchSnapshot(new SnapshotNameExtension("1")),
                              r => r.MatchSnapshot(new SnapshotNameExtension("2")));
        }
        public async Task ExecuteExportObjectList()
        {
            // arrange
            var serviceCollection = new ServiceCollection();

            serviceCollection
            .AddSingleton <ISchema>(sp => SchemaBuilder.New()
                                    .AddServices(sp)
                                    .AddExportDirectiveType()
                                    .AddDocumentFromString(
                                        @"
                    type Query {
                        foo(f: [FooInput]) : [Foo]
                    }

                    type Foo {
                        bar: String!
                    }

                    input FooInput {
                        bar: String!
                    }
                    ")
                                    .AddResolver("Query", "foo", c =>
            {
                var list =
                    c.Argument <List <object> >("f");
                if (list == null)
                {
                    return(new List <object>
                    {
                        new Dictionary <string, object>
                        {
                            { "bar", "123" }
                        }
                    });
                }
                else
                {
                    list.Add(new Dictionary <string, object>
                    {
                        { "bar", "456" }
                    });
                    return(list);
                }
            })
                                    .Use(next => context =>
            {
                object o = context.Parent <object>();
                if (o is Dictionary <string, object> d &&
                    d.TryGetValue(
                        context.ResponseName,
                        out object v))
                {
                    context.Result = v;
                }
                return(next(context));
            })
                                    .Create())
            .AddSingleton <IBatchQueryExecutor, BatchQueryExecutor>();

            QueryExecutionBuilder.BuildDefault(serviceCollection);

            IServiceProvider services =
                serviceCollection.BuildServiceProvider();

            var executor = services.GetService <IBatchQueryExecutor>();

            // act
            var batch = new List <IReadOnlyQueryRequest>
            {
                QueryRequestBuilder.New()
                .SetQuery(
                    @"{
                            foo @export(as: ""b"")
                            {
                                bar
                            }
                        }")
                .Create(),
                QueryRequestBuilder.New()
                .SetQuery(
                    @"{
                            foo(f: $b)
                            {
                                bar
                            }
                        }")
                .Create()
            };

            IResponseStream stream =
                await executor.ExecuteAsync(batch, CancellationToken.None);

            var results = new List <IReadOnlyQueryResult>();

            await foreach (IReadOnlyQueryResult result in stream)
            {
                if (result != null)
                {
                    results.Add(result);
                }
            }

            Assert.Collection(results,
                              r => r.MatchSnapshot(new SnapshotNameExtension("1")),
                              r => r.MatchSnapshot(new SnapshotNameExtension("2")));
        }
        public async Task ExecuteExportObject()
        {
            // arrange
            var serviceCollection = new ServiceCollection();

            serviceCollection.AddInMemorySubscriptionProvider();

            serviceCollection
            .AddStarWarsRepositories()
            .AddSingleton <IBatchQueryExecutor, BatchQueryExecutor>();

            QueryExecutionBuilder.BuildDefault(serviceCollection);

            serviceCollection.AddSingleton <ISchema>(sp =>
                                                     SchemaBuilder.New()
                                                     .AddStarWarsTypes()
                                                     .AddExportDirectiveType()
                                                     .AddServices(sp)
                                                     .Create());

            IServiceProvider services =
                serviceCollection.BuildServiceProvider();

            var executor = services.GetService <IBatchQueryExecutor>();

            // act
            var batch = new List <IReadOnlyQueryRequest>
            {
                QueryRequestBuilder.New()
                .SetQuery(
                    @"
                        mutation firstReview {
                            createReview(
                                episode: NEWHOPE
                                review: { commentary: ""foo"", stars: 4 })
                                    @export(as: ""r"") {
                                commentary
                                stars
                            }
                        }")
                .Create(),
                QueryRequestBuilder.New()
                .SetQuery(
                    @"
                        mutation secondReview {
                            createReview(
                                episode: EMPIRE
                                review: $r) {
                                commentary
                                stars
                            }
                        }")
                .Create()
            };

            IResponseStream stream =
                await executor.ExecuteAsync(batch, CancellationToken.None);

            var results = new List <IReadOnlyQueryResult>();

            await foreach (IReadOnlyQueryResult result in stream)
            {
                if (result != null)
                {
                    results.Add(result);
                }
            }

            Assert.Collection(results,
                              r => r.MatchSnapshot(new SnapshotNameExtension("1")),
                              r => r.MatchSnapshot(new SnapshotNameExtension("2")));
        }