public void AppliesEasingFunction() { const double defaultOrigin = 0; const double defaultDestination = 100; var defaultAnimation = new FromToByDoubleAnimation(); var easingAnimation = new FromToByDoubleAnimation(); var clock = new ControllableAnimationClock(); var easingFunction = new QuadraticEase(); easingAnimation.EasingFunction = easingFunction; for (double progress = 0d; progress <= 1d; progress += 0.01) { // Manually apply the easing function. double easedProgress = easingFunction.Ease(progress); clock.CurrentProgress = easedProgress; double expectedResult = defaultAnimation.GetCurrentValue(defaultOrigin, defaultDestination, clock); // Then test if the animation does it on its own. clock.CurrentProgress = progress; double easedResult = easingAnimation.GetCurrentValue(defaultOrigin, defaultDestination, clock); Assert.Equal(expectedResult, easedResult); } }
public void AnimationRespectsIsAdditive(FromToByAnimationData animationData) { var animation = new FromToByDoubleAnimation( animationData.From, animationData.To, animationData.By ); var clock = new ControllableAnimationClock(); animation.IsAdditive = true; for (double progress = 0d; progress <= 1d; progress += 0.01) { clock.CurrentProgress = progress; double result = animation.GetCurrentValue( animationData.DefaultOrigin, animationData.DefaultDestination, clock ); double expectedResult = animationData.GetExpectedValueForProgress(clock.CurrentProgress.Value); // If the animation supports IsAdditive, we add the DefaultOrigin value to the expected result. // IsAdditive only gets supported, if both From and To/By are set. // See https://docs.microsoft.com/en-us/dotnet/api/system.windows.media.animation.doubleanimation.isadditive?view=netframework-4.7.2 // for details. if (animationData.From.HasValue && (animationData.To.HasValue || animationData.By.HasValue)) { expectedResult += animationData.DefaultOrigin; } Assert.Equal(expectedResult, result); } }
public void ReturnsExpectedIntermediaryValues(FromToByAnimationData animationData) { var animation = new FromToByDoubleAnimation( animationData.From, animationData.To, animationData.By ); var clock = new ControllableAnimationClock(); // We want to test for intermediary values, meaning that we loop the progress from // 0 to 1 in small steps. // In each step, we assert that the animation returns the correct value. for (double progress = 0d; progress <= 1d; progress += 0.01) { clock.CurrentProgress = progress; double result = animation.GetCurrentValue( animationData.DefaultOrigin, animationData.DefaultDestination, clock ); double expectedResult = animationData.GetExpectedValueForProgress(clock.CurrentProgress.Value); Assert.Equal(expectedResult, result); } }
public void ReturnsExpectedValueWhenFinished(FromToByAnimationData animationData) { var animation = new FromToByDoubleAnimation( animationData.From, animationData.To, animationData.By ); var clock = ControllableAnimationClock.NewFinished(); double result = animation.GetCurrentValue( animationData.DefaultOrigin, animationData.DefaultDestination, clock ); double expectedResult = animationData.GetExpectedValueForProgress(clock.CurrentProgress.Value); Assert.Equal(expectedResult, result); }
public void AnimationRespectsIsCumulative(FromToByAnimationData animationData) { const int repeatCount = 10; var animation = new FromToByDoubleAnimation( animationData.From, animationData.To, animationData.By ); var clock = new ControllableAnimationClock(); animation.IsCumulative = true; animation.RepeatBehavior = new RepeatBehavior(repeatCount); // IsCumulative only works, if the animation repeats. // In each iteration, the previously calculated value gets set as the starting value // of the next iteration. // This basically means that an animation doesn't get reset after each repetition. // // WPF's CurrentIteration always starts from 1, not 0! for (int iteration = 1; iteration <= repeatCount; iteration++) { for (double progress = 0d; progress <= 1d; progress += 0.01) { clock.CurrentProgress = progress; clock.CurrentIteration = iteration; double result = animation.GetCurrentValue( animationData.DefaultOrigin, animationData.DefaultDestination, clock ); double expectedResult = animationData.GetExpectedValueForProgress(clock.CurrentProgress.Value); // Calculate the value which should be added on top of the expected result for the current // iteration. double toFromDiff = animationData.ActualTo - animationData.ActualFrom; double accumulatedValue = toFromDiff * (iteration - 1); expectedResult += accumulatedValue; Assert.Equal(expectedResult, result); } } }