public async Task ShouldCallMoreOnceAndReturnRecords()
            {
                var actions = new Queue <Action>();
                var builder =
                    new StatementResultCursorBuilder(CreateSummaryBuilder(), CreateTaskQueue(actions),
                                                     MoreFunction(), CancelFunction(), null);

                actions.Enqueue(() => builder.RunCompleted(0, new[] { "a" }, null));
                actions.Enqueue(() => builder.PushRecord(new object[] { 1 }));
                actions.Enqueue(() => builder.PushRecord(new object[] { 2 }));
                actions.Enqueue(() => builder.PushRecord(new object[] { 3 }));
                actions.Enqueue(() => builder.PullCompleted(false, null));

                var list = await builder.CreateCursor().ToListAsync(r => r[0].As <int>());

                list.Should().BeEquivalentTo(1, 2, 3);
                moreCallCount.Should().Be(1);
                cancelCallCount.Should().Be(0);
            }
            public async Task ShouldReturnFirstBatchOfRecordsAndCancel()
            {
                var actions = new Queue <Action>();
                var builder =
                    new StatementResultCursorBuilder(CreateSummaryBuilder(), CreateTaskQueue(actions),
                                                     MoreFunction(), CancelFunction(), null);

                actions.Enqueue(() => builder.RunCompleted(0, new[] { "a" }, null));
                actions.Enqueue(() => builder.PushRecord(new object[] { 1 }));
                actions.Enqueue(() => builder.PushRecord(new object[] { 2 }));
                actions.Enqueue(() => builder.PullCompleted(true, null));
                actions.Enqueue(() => builder.PullCompleted(false, null));

                var cursor = builder.CreateCursor();

                var keys = await cursor.KeysAsync();

                keys.Should().BeEquivalentTo("a");

                var hasRecord1 = await cursor.FetchAsync();

                var record1 = cursor.Current;

                hasRecord1.Should().BeTrue();
                record1[0].Should().Be(1);

                var hasRecord2 = await cursor.FetchAsync();

                var record2 = cursor.Current;

                hasRecord2.Should().BeTrue();
                record2[0].Should().Be(2);

                cursor.Discard();

                var list = await cursor.ToListAsync(r => r[0].As <int>());

                list.Should().BeEmpty();
                moreCallCount.Should().Be(1);
                cancelCallCount.Should().Be(1);
            }
        public void ShouldTransitionToRecordsStreamingStreamingWhenRecordIsPushed()
        {
            var builder =
                new StatementResultCursorBuilder(CreateSummaryBuilder(), CreateTaskQueue(), null, null, null);

            builder.CurrentState.Should().Be(StatementResultCursorBuilder.State.RunRequested);

            builder.RunCompleted(0, new[] { "a", "b", "c" }, null);
            builder.CurrentState.Should().Be(StatementResultCursorBuilder.State.RunCompleted);

            builder.PushRecord(new object[] { 1, 2, 3 });
            builder.CurrentState.Should().Be(StatementResultCursorBuilder.State.RecordsStreaming);
        }
        public async Task ShouldInvokeResourceHandlerWhenCompleted()
        {
            var actions         = new Queue <Action>();
            var resourceHandler = new Mock <IResultResourceHandler>();
            var builder         =
                new StatementResultCursorBuilder(CreateSummaryBuilder(), CreateTaskQueue(actions), null, null,
                                                 resourceHandler.Object);

            actions.Enqueue(() => builder.RunCompleted(0, new[] { "a" }, null));
            actions.Enqueue(() => builder.PushRecord(new object[] { 1 }));
            actions.Enqueue(() => builder.PushRecord(new object[] { 2 }));
            actions.Enqueue(() => builder.PushRecord(new object[] { 3 }));
            actions.Enqueue(() => builder.PullCompleted(false, null));

            var cursor = builder.CreateCursor();

            var hasNext = await cursor.FetchAsync();

            hasNext.Should().BeTrue();
            resourceHandler.Verify(x => x.OnResultConsumedAsync(), Times.Never);

            hasNext = await cursor.FetchAsync();

            hasNext.Should().BeTrue();
            resourceHandler.Verify(x => x.OnResultConsumedAsync(), Times.Never);

            hasNext = await cursor.FetchAsync();

            hasNext.Should().BeTrue();
            resourceHandler.Verify(x => x.OnResultConsumedAsync(), Times.Never);

            hasNext = await cursor.FetchAsync();

            hasNext.Should().BeFalse();
            resourceHandler.Verify(x => x.OnResultConsumedAsync(), Times.Once);
        }