public async Task TestOfferMessage()
        {
            var generators = new Func <TransformManyBlock <int, int> >[]
            {
                () => new TransformManyBlock <int, int>(DataflowTestHelpers.ToEnumerable),
                () => new TransformManyBlock <int, int>(DataflowTestHelpers.ToEnumerable, new ExecutionDataflowBlockOptions {
                    BoundedCapacity = 10
                }),
                () => new TransformManyBlock <int, int>(i => Task.Run(() => DataflowTestHelpers.ToEnumerable(i)), new ExecutionDataflowBlockOptions {
                    BoundedCapacity = 10, MaxMessagesPerTask = 1
                })
            };

            foreach (var generator in generators)
            {
                DataflowTestHelpers.TestOfferMessage_ArgumentValidation(generator());

                var target = generator();
                DataflowTestHelpers.TestOfferMessage_AcceptsDataDirectly(target);
                DataflowTestHelpers.TestOfferMessage_CompleteAndOffer(target);

                target = generator();
                await DataflowTestHelpers.TestOfferMessage_AcceptsViaLinking(target);

                DataflowTestHelpers.TestOfferMessage_CompleteAndOffer(target);
            }
        }
        public async Task TestMessagePostponement()
        {
            const int Excess = 10;

            foreach (int boundedCapacity in new[] { 1, 3 })
            {
                var options = new ExecutionDataflowBlockOptions {
                    BoundedCapacity = boundedCapacity
                };
                foreach (var tb in new[] {
                    new TransformManyBlock <int, int>(DataflowTestHelpers.ToEnumerable, options),
                    new TransformManyBlock <int, int>(i => Task.Run(() => DataflowTestHelpers.ToEnumerable(i)), options)
                })
                {
                    var sendAsync = new Task <bool> [boundedCapacity + Excess];
                    for (int i = 0; i < boundedCapacity + Excess; i++)
                    {
                        sendAsync[i] = tb.SendAsync(i);
                    }
                    tb.Complete();

                    for (int i = 0; i < boundedCapacity; i++)
                    {
                        Assert.True(sendAsync[i].IsCompleted);
                        Assert.True(sendAsync[i].Result);
                    }

                    for (int i = 0; i < Excess; i++)
                    {
                        Assert.False(await sendAsync[boundedCapacity + i]);
                    }
                }
            }
        }
        public async Task TestLinkToOptions()
        {
            const int Messages = 1;

            foreach (bool append in DataflowTestHelpers.BooleanValues)
            {
                foreach (var tb in new[] {
                    new TransformManyBlock <int, int>(DataflowTestHelpers.ToEnumerable),
                    new TransformManyBlock <int, int>(i => Task.Run(() => DataflowTestHelpers.ToEnumerable(i)))
                })
                {
                    var values  = new int[Messages];
                    var targets = new ActionBlock <int> [Messages];
                    for (int i = 0; i < Messages; i++)
                    {
                        int slot = i;
                        targets[i] = new ActionBlock <int>(item => values[slot] = item);
                        tb.LinkTo(targets[i], new DataflowLinkOptions {
                            MaxMessages = 1, Append = append
                        });
                    }

                    tb.PostRange(0, Messages);
                    tb.Complete();
                    await tb.Completion;

                    for (int i = 0; i < Messages; i++)
                    {
                        Assert.Equal(
                            expected: append ? i : Messages - i - 1,
                            actual: values[i]);
                    }
                }
            }
        }
 public void TestPost()
 {
     foreach (bool bounded in DataflowTestHelpers.BooleanValues)
     {
         foreach (var tb in new[] {
             new TransformManyBlock <int, int>(DataflowTestHelpers.ToEnumerable, new ExecutionDataflowBlockOptions {
                 BoundedCapacity = bounded ? 1 : -1
             }),
             new TransformManyBlock <int, int>(i => Task.Run(() => DataflowTestHelpers.ToEnumerable(i)), new ExecutionDataflowBlockOptions {
                 BoundedCapacity = bounded ? 1 : -1
             })
         })
         {
             Assert.True(tb.Post(0));
             tb.Complete();
             Assert.False(tb.Post(0));
         }
     }
 }
        public async Task TestCtor()
        {
            var blocks = new[] {
                new TransformManyBlock <int, int>(DataflowTestHelpers.ToEnumerable),
                new TransformManyBlock <int, int>(DataflowTestHelpers.ToEnumerable, new ExecutionDataflowBlockOptions {
                    MaxMessagesPerTask = 1
                }),
                new TransformManyBlock <int, int>(i => Task.Run(() => DataflowTestHelpers.ToEnumerable(i)), new ExecutionDataflowBlockOptions {
                    MaxMessagesPerTask = 1
                })
            };

            foreach (var block in blocks)
            {
                Assert.Equal(expected: 0, actual: block.InputCount);
                Assert.Equal(expected: 0, actual: block.OutputCount);
                Assert.False(block.Completion.IsCompleted);
            }

            blocks = new[] {
                new TransformManyBlock <int, int>(DataflowTestHelpers.ToEnumerable,
                                                  new ExecutionDataflowBlockOptions {
                    CancellationToken = new CancellationToken(true)
                }),
                new TransformManyBlock <int, int>(i => Task.Run(() => DataflowTestHelpers.ToEnumerable(i)),
                                                  new ExecutionDataflowBlockOptions {
                    CancellationToken = new CancellationToken(true)
                })
            };
            foreach (var block in blocks)
            {
                Assert.Equal(expected: 0, actual: block.InputCount);
                Assert.Equal(expected: 0, actual: block.OutputCount);
                await Assert.ThrowsAnyAsync <OperationCanceledException>(() => block.Completion);
            }
        }
        public void TestArgumentExceptions()
        {
            Assert.Throws <ArgumentNullException>(() => new TransformManyBlock <int, int>((Func <int, IEnumerable <int> >)null));
            Assert.Throws <ArgumentNullException>(() => new TransformManyBlock <int, int>((Func <int, Task <IEnumerable <int> > >)null));
            Assert.Throws <ArgumentNullException>(() => new TransformManyBlock <int, int>(DataflowTestHelpers.ToEnumerable, null));
            Assert.Throws <ArgumentNullException>(() => new TransformManyBlock <int, int>(i => Task.Run(() => DataflowTestHelpers.ToEnumerable(i)), null));

            DataflowTestHelpers.TestArgumentsExceptions(new TransformManyBlock <int, int>(DataflowTestHelpers.ToEnumerable));
        }