コード例 #1
0
        // This is a state-transition-chain where observers invoke transitions.
        public static async Task TestReactiveFunctionalityAsync(
            this IStateChannel <int> channel, int stepCount, int activeChannelCount = 1)
        {
            var actualStateHistory    = new List <int>();
            var exptectedStateHistory = Enumerable.Range(0, stepCount).ToList();

            bool ShouldProceed(int i) => (i < stepCount);

            bool ShouldStop(int i) => !ShouldProceed(i);

            void LogState(int i) => actualStateHistory.Add(i);

            var tcsStop = new TaskCompletionSource <Unit>();

            channel // Logging
            .OnNext(ShouldProceed)
            .Do(LogState)
            .Subscribe();

            Enumerable // Procedure handlers
            .Range(0, activeChannelCount)
            .Select(_ =>
                    channel
                    .OnNextToHandle(ShouldProceed)
                    .Update(i => i + 1)
                    .Subscribe())
            .ToList();

            channel // Termination
            .OnNextToHandle(ShouldStop)
            .Remove()
            .Do(tcsStop.SetResult)
            .Subscribe();

            const int INITIAL_STATE = 0;

            AssertOk(await channel.AddAsync(INITIAL_STATE));

            await tcsStop.Task;
            await Task.Delay(100);

            Assert.IsTrue(
                condition: Enumerable.SequenceEqual(
                    exptectedStateHistory,
                    actualStateHistory),
                message: "Incorrect state history!"
                );
        }
コード例 #2
0
        public static async Task TestReplayFunctionalityAsync(this IStateChannel <string> channel)
        {
            const string SAMPLE_STATE_1 = "state1";

            const int EXPECTED_ADD_NOTIFICATION_COUNT  = 3;
            const int EXPECTED_NEXT_NOTIFICATION_COUNT = 3;

            const int OBSERVER_DELAY_MS = 500;

            int mut_ActualAddNotificationCount  = 0;
            int mut_ActualNextNotificationCount = 0;

            void SubscribeNextAndAdd()
            {
                channel.OnAdd.Subscribe(_ => mut_ActualAddNotificationCount++);
                channel.OnNext().Subscribe(_ => mut_ActualNextNotificationCount++);
            }

            SubscribeNextAndAdd();

            // Can set
            AssertOk(await channel.AddAsync(SAMPLE_STATE_1));

            SubscribeNextAndAdd();
            SubscribeNextAndAdd();

            await Task.Delay(OBSERVER_DELAY_MS);

            Assert.AreEqual(
                EXPECTED_ADD_NOTIFICATION_COUNT,
                mut_ActualAddNotificationCount);

            Assert.AreEqual(
                EXPECTED_NEXT_NOTIFICATION_COUNT,
                mut_ActualNextNotificationCount);
        }
コード例 #3
0
        public static async Task TestBasicFunctionalityAsync(this IStateChannel <string> channel)
        {
            const string SAMPLE_STATE_1 = "state1";
            const string SAMPLE_STATE_2 = "state2";

            const int EXPECTED_ADD_NOTIFICATION_COUNT      = 1;
            const int EXPECTED_UPDATE_NOTIFICATION_COUNT   = 1;
            const int EXPECTED_REMOVE_NOTIFICATION_COUNT   = 1;
            const int EXPECTED_NEXT_NOTIFICATION_COUNT     = 2;
            const int EXPECTED_PREVIOUS_NOTIFICATION_COUNT = 2;

            int mut_ActualAddNotificationCount      = 0;
            int mut_ActualUpdateNotificationCount   = 0;
            int mut_ActualRemoveNotificationCount   = 0;
            int mut_ActualNextNotificationCount     = 0;
            int mut_ActualPreviousNotificationCount = 0;

            channel.OnAdd
            .Subscribe(_ => mut_ActualAddNotificationCount += 1);
            channel.OnUpdate
            .Subscribe(_ => mut_ActualUpdateNotificationCount += 1);
            channel.OnRemove
            .Subscribe(_ => mut_ActualRemoveNotificationCount += 1);
            channel.OnNext()
            .Subscribe(_ => mut_ActualNextNotificationCount += 1);
            channel.OnPrevious()
            .Subscribe(_ => mut_ActualPreviousNotificationCount += 1);

            const int OBSERVER_DELAY_MS = 200;

            // Can set
            AssertOk(await channel.AddAsync(SAMPLE_STATE_1));
            await Task.Delay(OBSERVER_DELAY_MS);

            // Can update
            AssertOk(await channel.UpdateAsync(SAMPLE_STATE_1, SAMPLE_STATE_2));
            await Task.Delay(OBSERVER_DELAY_MS);

            // Can remove
            AssertOk(await channel.RemoveAsync(SAMPLE_STATE_2));
            await Task.Delay(OBSERVER_DELAY_MS);

            Assert.AreEqual(
                EXPECTED_ADD_NOTIFICATION_COUNT,
                mut_ActualAddNotificationCount);

            Assert.AreEqual(
                EXPECTED_UPDATE_NOTIFICATION_COUNT,
                mut_ActualUpdateNotificationCount);

            Assert.AreEqual(
                EXPECTED_REMOVE_NOTIFICATION_COUNT,
                mut_ActualRemoveNotificationCount);

            Assert.AreEqual(
                EXPECTED_NEXT_NOTIFICATION_COUNT,
                mut_ActualNextNotificationCount);

            Assert.AreEqual(
                EXPECTED_PREVIOUS_NOTIFICATION_COUNT,
                mut_ActualPreviousNotificationCount);
        }
コード例 #4
0
 public static IObservable <IImmutableStateHandle <TState> > ToHandle <TState>(
     this IStateChannel <TState> channel,
     Func <IStateChannel <TState>, IObservable <TState> > filter) =>
 (filter ?? throw new ArgumentNullException(nameof(filter)))
コード例 #5
0
 public static Instance <TState> Create(IStateChannel <TState> channel, TState state) =>
 new Instance <TState>(channel, state);
コード例 #6
0
 private Instance(IStateChannel <TState> channel, TState state)
 {
     this.channel = channel;
     this.State   = state;
 }
コード例 #7
0
 public static IObservable <IImmutableStateHandle <TState> > OnNextToHandle <TState>(
     this IStateChannel <TState> channel, TState filter) =>
 (channel ?? throw new ArgumentNullException(nameof(channel)))
コード例 #8
0
 public static IObservable <IImmutableStateHandle <TState> > UpdateToHandle <TState>(
     this IStateChannel <TState> channel, TState currentState, TState nextState) =>
 Observable
 .FromAsync(() => channel.UpdateAsync(currentState, nextState))
 .Where(r => r is Ok)
 .Select(_ => Instance <TState> .Create(channel, nextState));