| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196 | // Licensed to the .NET Foundation under one or more agreements.// The .NET Foundation licenses this file to you under the Apache 2.0 License.// See the LICENSE file in the project root for more information. using System.Reactive;using Xunit;using System;using System.Collections.Generic;namespace ReactiveTests.Tests{    public class HalfSerializerTest    {        int wip;        Exception error;        Consumer consumer = new Consumer();        [Fact]        public void HalfSerializer_OnNext()        {            HalfSerializer.ForwardOnNext(consumer, 1, ref wip, ref error);            Assert.Equal(0, wip);            Assert.Null(error);            Assert.Equal(1, consumer.items.Count);            Assert.Equal(1, consumer.items[0]);            Assert.Equal(0, consumer.done);            Assert.Null(consumer.exc);        }        [Fact]        public void HalfSerializer_OnError()        {            var ex = new InvalidOperationException();            HalfSerializer.ForwardOnError(consumer, ex, ref wip, ref error);            Assert.Equal(1, wip);            Assert.Equal(error, ExceptionHelper.Terminated);            HalfSerializer.ForwardOnNext(consumer, 2, ref wip, ref error);            Assert.Equal(0, consumer.items.Count);            Assert.Equal(0, consumer.done);            Assert.Equal(ex, consumer.exc);        }        [Fact]        public void HalfSerializer_OnError_Ignore_Further_Events()        {            var ex = new InvalidOperationException();            HalfSerializer.ForwardOnError(consumer, ex, ref wip, ref error);            Assert.Equal(1, wip);            Assert.Equal(error, ExceptionHelper.Terminated);            HalfSerializer.ForwardOnNext(consumer, 2, ref wip, ref error);            var ex2 = new NotSupportedException();            HalfSerializer.ForwardOnError(consumer, ex2, ref wip, ref error);            HalfSerializer.ForwardOnCompleted(consumer, ref wip, ref error);            Assert.Equal(0, consumer.items.Count);            Assert.Equal(0, consumer.done);            Assert.Equal(ex, consumer.exc);        }        [Fact]        public void HalfSerializer_OnCompleted()        {            HalfSerializer.ForwardOnCompleted(consumer, ref wip, ref error);            Assert.Equal(1, wip);            Assert.Equal(error, ExceptionHelper.Terminated);            HalfSerializer.ForwardOnNext(consumer, 2, ref wip, ref error);            Assert.Equal(0, consumer.items.Count);            Assert.Equal(1, consumer.done);            Assert.Null(consumer.exc);        }        [Fact]        public void HalfSerializer_OnCompleted_Ignore_Further_Events()        {            HalfSerializer.ForwardOnCompleted(consumer, ref wip, ref error);            Assert.Equal(1, wip);            Assert.Equal(error, ExceptionHelper.Terminated);            HalfSerializer.ForwardOnNext(consumer, 2, ref wip, ref error);            var ex2 = new NotSupportedException();            HalfSerializer.ForwardOnError(consumer, ex2, ref wip, ref error);            HalfSerializer.ForwardOnCompleted(consumer, ref wip, ref error);            Assert.Equal(0, consumer.items.Count);            Assert.Equal(1, consumer.done);            Assert.Null(consumer.exc);        }        // Practically simulates concurrent invocation of the HalfSerializer methods        [Fact]        public void HalfSerializer_OnNext_Reentrant_Error()        {            var c = new ReentrantConsumer(this, true);            HalfSerializer.ForwardOnNext(c, 1, ref wip, ref error);            Assert.Equal(1, wip);            Assert.Equal(error, ExceptionHelper.Terminated);            Assert.Equal(1, consumer.items.Count);            Assert.Equal(1, consumer.items[0]);            Assert.Equal(0, consumer.done);            Assert.Equal(c.x, consumer.exc);        }        // Practically simulates concurrent invocation of the HalfSerializer methods        [Fact]        public void HalfSerializer_OnNext_Reentrant_OnCompleted()        {            var c = new ReentrantConsumer(this, false);            HalfSerializer.ForwardOnNext(c, 1, ref wip, ref error);            Assert.Equal(1, wip);            Assert.Equal(error, ExceptionHelper.Terminated);            Assert.Equal(1, consumer.items.Count);            Assert.Equal(1, consumer.items[0]);            Assert.Equal(1, consumer.done);            Assert.Null(consumer.exc);        }        sealed class Consumer : ISink<int>        {            internal List<int> items = new List<int>();            internal int done;            internal Exception exc;            public void ForwardOnCompleted()            {                done++;            }            public void ForwardOnError(Exception error)            {                exc = error;            }            public void ForwardOnNext(int value)            {                items.Add(value);            }        }        sealed class ReentrantConsumer : ISink<int>        {            readonly HalfSerializerTest parent;            readonly bool errorReenter;            internal readonly Exception x = new IndexOutOfRangeException();            public ReentrantConsumer(HalfSerializerTest parent, bool errorReenter)            {                this.parent = parent;                this.errorReenter = errorReenter;            }            public void ForwardOnCompleted()            {                parent.consumer.ForwardOnCompleted();            }            public void ForwardOnError(Exception error)            {                parent.consumer.ForwardOnError(error);            }            public void ForwardOnNext(int value)            {                parent.consumer.ForwardOnNext(value);                if (errorReenter)                {                    HalfSerializer.ForwardOnError(this, x, ref parent.wip, ref parent.error);                } else                {                    HalfSerializer.ForwardOnCompleted(this, ref parent.wip, ref parent.error);                }            }        }    }}
 |