public void MakeCollectBlocksOperation_OperationIsDisposed_OperationIsRecycled(int handlerCount, int blockCount)
        {
            var testContext          = new TestContext();
            var mockBackgroundWorker = new FakeBackgroundWorker();

            foreach (var _ in Enumerable.Repeat(0, blockCount))
            {
                testContext.AddMockBlock();
            }

            foreach (var _ in Enumerable.Repeat(0, handlerCount))
            {
                testContext.AddMockBlockCollectionHandler(BlockCollectionResult.Ignored);
            }

            var result = testContext.Uut.MakeCollectBlocksOperation();

            result.ShouldRunToCompletion(mockBackgroundWorker);

            var mockBlocksInvocations = testContext.MockBlocks
                                        .Select(x => x.Invocations.ToArray())
                                        .ToArray();

            var mockBlockCollectionHandlersInvocations = testContext.MockBlockCollectionHandlers
                                                         .Select(x => x.Invocations.ToArray())
                                                         .ToArray();

            result.ShouldBeAssignableTo <IDisposable>();
            (result as IDisposable).Dispose();

            testContext.MockBlocks
            .ForEach(x => x.Invocations.Clear());
            testContext.MockBlockCollectionHandlers
            .ForEach(x => x.Invocations.Clear());

            testContext.Uut.MakeCollectBlocksOperation()
            .ShouldBeSameAs(result);

            result.ShouldRunToCompletion(mockBackgroundWorker);

            foreach (var i in Enumerable.Range(0, mockBlocksInvocations.Length))
            {
                testContext.MockBlocks[i].Invocations.Count.ShouldBe(mockBlocksInvocations[i].Length);
                foreach (var j in Enumerable.Range(0, mockBlocksInvocations[i].Length))
                {
                    testContext.MockBlocks[i].Invocations[j].ShouldBe(mockBlocksInvocations[i][j]);
                }
            }

            foreach (var i in Enumerable.Range(0, mockBlockCollectionHandlersInvocations.Length))
            {
                testContext.MockBlockCollectionHandlers[i].Invocations.Count.ShouldBe(mockBlockCollectionHandlersInvocations[i].Length);
                foreach (var j in Enumerable.Range(0, mockBlockCollectionHandlersInvocations[i].Length))
                {
                    testContext.MockBlockCollectionHandlers[i].Invocations[j].ShouldBe(mockBlockCollectionHandlersInvocations[i][j]);
                }
            }
        }
        public void MakeCollectBlocksOperation_BlockCollectionHandlersIsEmpty_CompletesImmediately(int blockCount)
        {
            var testContext = new TestContext();

            foreach (var _ in Enumerable.Repeat(0, blockCount))
            {
                testContext.AddMockBlock();
            }

            testContext.Uut.MakeCollectBlocksOperation()
            .ShouldRunToCompletionIn(1);

            testContext.ShouldNotHaveReceivedGetBlocks();
        }
        public void MakeCollectBlocksOperation_BlockCollectionResultsAreSkipped_TerminatesBlockCollectionEarly(int handlerCount, int blockCount)
        {
            var testContext          = new TestContext();
            var mockBackgroundWorker = new FakeBackgroundWorker();

            foreach (var _ in Enumerable.Repeat(0, blockCount))
            {
                testContext.AddMockBlock();
            }

            foreach (var _ in Enumerable.Repeat(0, handlerCount))
            {
                testContext.AddMockBlockCollectionHandler(BlockCollectionResult.Skipped);
            }

            testContext.Uut.MakeCollectBlocksOperation()
            .ShouldRunToCompletion(mockBackgroundWorker);

            testContext.ShouldHaveReceivedGetBlocks();

            foreach (var mockBlockCollectionHandler in testContext.MockBlockCollectionHandlers)
            {
                mockBlockCollectionHandler
                .ShouldHaveReceived(x => x.OnStarting(), 1);
                mockBlockCollectionHandler
                .ShouldHaveReceived(x => x.OnCompleted(), 1);
            }

            foreach (var mockBlock in testContext.MockBlocks)
            {
                testContext.MockBlockCollectionHandlers.First()
                .ShouldHaveReceived(x => x.MakeCollectBlockOperation(mockBlock.Object), 1);

                foreach (var mockBlockCollectionHandler in testContext.MockBlockCollectionHandlers.Skip(1))
                {
                    mockBlockCollectionHandler
                    .ShouldNotHaveReceived(x => x.MakeCollectBlockOperation(It.IsAny <IMyTerminalBlock>()));
                }
            }

            testContext.MockCollectBlockOperations.Count.ShouldBe(blockCount);

            foreach (var mockCollectBlockOperation in testContext.MockCollectBlockOperations)
            {
                mockBackgroundWorker.MockSubOperationScheduler
                .ShouldHaveReceived(x => x(mockCollectBlockOperation.Object));
            }
        }
        public void MakeCollectBlocksOperation_BlockCollectionResultsAreIgnored_PerformsAllBlockCollections(int handlerCount, int blockCount)
        {
            var testContext          = new TestContext();
            var mockBackgroundWorker = new FakeBackgroundWorker();

            foreach (var _ in Enumerable.Repeat(0, blockCount))
            {
                testContext.AddMockBlock();
            }

            foreach (var _ in Enumerable.Repeat(0, handlerCount))
            {
                testContext.AddMockBlockCollectionHandler(BlockCollectionResult.Ignored);
            }

            testContext.Uut.MakeCollectBlocksOperation()
            .ShouldRunToCompletion(mockBackgroundWorker);

            testContext.ShouldHaveReceivedGetBlocks();

            foreach (var mockBlockCollectionHandler in testContext.MockBlockCollectionHandlers)
            {
                mockBlockCollectionHandler
                .ShouldHaveReceived(x => x.OnStarting(), 1);

                foreach (var mockBlock in testContext.MockBlocks)
                {
                    mockBlockCollectionHandler
                    .ShouldHaveReceived(x => x.MakeCollectBlockOperation(mockBlock.Object), 1);
                }

                mockBlockCollectionHandler
                .ShouldHaveReceived(x => x.OnCompleted(), 1);
            }

            testContext.MockCollectBlockOperations.Count.ShouldBe(handlerCount * blockCount);

            foreach (var mockCollectBlockOperation in testContext.MockCollectBlockOperations)
            {
                mockBackgroundWorker.MockSubOperationScheduler
                .ShouldHaveReceived(x => x(mockCollectBlockOperation.Object));
            }
        }