public void ResumeWithoutInvalidationFromInputDoesNotInvalidateStage(PipelineSuspensionState resumeState)
        {
            var state = Suspender(PipelineSuspensionState.Suspend);
            var sut   = new SuspendingPipelineStage <int>(1.AsPipelineConstant(), state);
            var test  = sut.AttachTestStage();

            state.SetValue(resumeState);
            test.AssertInvalidations(0);
        }
        public void InvalidateIsOnlyPropagatedInResumedSuspensionStates(PipelineSuspensionState state, int expectedInvalidations)
        {
            var value = Assignable(10);
            var sut   = new SuspendingPipelineStage <int>(value, Suspender(state));
            var test  = sut.AttachTestStage();

            value.SetValue(11);
            test.AssertInvalidations(expectedInvalidations);
        }
 /// <summary>
 /// Gets the weakest state of two.
 /// </summary>
 /// <param name="parent">The parent state.</param>
 /// <param name="child">The child state.</param>
 /// <returns>The weakest state, in the order Resume > ResumeWithoutInvalidate > Suspend.</returns>
 public static PipelineSuspensionState GetWeakestState(PipelineSuspensionState parent, PipelineSuspensionState child)
 {
     return(parent switch
     {
         PipelineSuspensionState.Resume => child,
         PipelineSuspensionState.ResumeWithoutPendingInvalidates => child == PipelineSuspensionState.Resume ? PipelineSuspensionState.ResumeWithoutPendingInvalidates : child,
         PipelineSuspensionState.Suspend => PipelineSuspensionState.Suspend,
         _ => throw new ArgumentException("Invalid argument.", nameof(parent)),
     });
        public void HierarchyPropagateSuspensionStateAsExpected(
            PipelineSuspensionState root,
            PipelineSuspensionState[] hierarchy,
            HierarchicalBehavior[] behaviors,
            PipelineSuspensionState expectedFinalState)
        {
            var parent    = new HierarchicalSuspenderNode(root.AsPipelineConstant());
            var lastStage = hierarchy.Zip(behaviors, (a, b) => (input: a, behavior: b)).Aggregate(parent, (acc, next) => acc.CreateChild(next.input.AsPipelineConstant(), next.behavior));

            PipelineAssert.Value(lastStage.Output, expectedFinalState);
        }
        public void PendingInvalidateIsEnactedWhenChangingState(PipelineSuspensionState resumeState, int expectedInvalidations)
        {
            var value = Assignable(10);
            var state = Suspender(PipelineSuspensionState.Suspend);
            var sut   = new SuspendingPipelineStage <int>(value, state);
            var test  = sut.AttachTestStage();

            value.SetValue(2);
            test.AssertInvalidations(0);
            Assert.IsTrue(sut.HasPendingInvalidate);

            state.SetValue(resumeState);
            test.AssertInvalidations(expectedInvalidations);
        }
        public void NewValueAndChangedStageAtTheSameTimeHasTheIntendedReaction(PipelineSuspensionState initial, PipelineSuspensionState state, int invalidations)
        {
            var stateStage = Suspender(initial);
            var value      = new AssignablePipelineStage <int>("", 1);
            var sut        = new SuspendingPipelineStage <int>(value, stateStage);
            var test       = sut.AttachTestStage();

            value.SetValueWithoutInvalidating(2);
            stateStage.SetValueWithoutInvalidating(state);

            PipelineCore.Invalidate(stateStage, value);

            test.AssertInvalidations(invalidations);
            PipelineAssert.Value(sut, 2);
        }
        public void CreatingSuspenderStageFromHierarchyWillGetHierarchySuspensionState(PipelineSuspensionState state, bool expectInvalidation)
        {
            var hierarchy = new HierarchicalSuspenderNode(state.AsPipelineConstant());

            var input = PipelineTestHelper.Assignable(1);
            var sut   = hierarchy.WithSuspender(input);
            var test  = sut.AttachTestStage();

            input.SetValue(10);

            if (expectInvalidation)
            {
                test.AssertInvalidations(1);
            }
            else
            {
                test.AssertInvalidations(0);
            }
        }
 private static AssignablePipelineStage <PipelineSuspensionState> Suspender(PipelineSuspensionState state) => new AssignablePipelineStage <PipelineSuspensionState>("", state);