| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364 |
- using System;
- using System.Threading.Tasks;
- using Avalonia.Animation;
- using Avalonia.Controls;
- using Avalonia.Styling;
- using Xunit;
- using Avalonia.Animation.Easings;
- using System.Threading;
- using System.Reactive.Linq;
- using Avalonia.Layout;
- namespace Avalonia.Base.UnitTests.Animation
- {
- using Animation = Avalonia.Animation.Animation;
- public class AnimationIterationTests
- {
- [Fact]
- public void Check_KeyTime_Correctly_Converted_To_Cue()
- {
- var keyframe1 = new KeyFrame()
- {
- Setters = { new Setter(Layoutable.WidthProperty, 100d), }, KeyTime = TimeSpan.FromSeconds(0.5)
- };
- var keyframe2 = new KeyFrame()
- {
- Setters = { new Setter(Layoutable.WidthProperty, 0d), }, KeyTime = TimeSpan.FromSeconds(0)
- };
- var animation = new Animation() { Duration = TimeSpan.FromSeconds(1), Children = { keyframe2, keyframe1 } };
- var border = new Border() { Height = 100d, Width = 100d };
- var clock = new TestClock();
- animation.RunAsync(border, clock);
- clock.Step(TimeSpan.Zero);
- Assert.Equal(border.Width, 0d);
- clock.Step(TimeSpan.FromSeconds(1));
- Assert.Equal(border.Width, 100d);
- }
- [Fact]
- public void Check_Initial_Inter_and_Trailing_Delay_Values()
- {
- var keyframe1 = new KeyFrame()
- {
- Setters = { new Setter(Layoutable.WidthProperty, 200d), }, Cue = new Cue(1d)
- };
- var keyframe2 = new KeyFrame()
- {
- Setters = { new Setter(Layoutable.WidthProperty, 100d), }, Cue = new Cue(0d)
- };
- var animation = new Animation()
- {
- Duration = TimeSpan.FromSeconds(3),
- Delay = TimeSpan.FromSeconds(3),
- DelayBetweenIterations = TimeSpan.FromSeconds(3),
- IterationCount = new IterationCount(2),
- Children = { keyframe2, keyframe1 }
- };
- var border = new Border() { Height = 100d, Width = 100d };
- var clock = new TestClock();
- var animationRun = animation.RunAsync(border, clock);
- clock.Step(TimeSpan.Zero);
- // Initial Delay.
- clock.Step(TimeSpan.FromSeconds(1));
- Assert.Equal(border.Width, 0d);
- clock.Step(TimeSpan.FromSeconds(6));
- // First Inter-Iteration delay.
- clock.Step(TimeSpan.FromSeconds(8));
- Assert.Equal(border.Width, 200d);
- // Trailing Delay should be non-existent.
- clock.Step(TimeSpan.FromSeconds(14));
- Assert.True(animationRun.Status == TaskStatus.RanToCompletion);
- Assert.Equal(border.Width, 100d);
- }
- [Fact]
- public void Check_FillModes_Start_and_End_Values_if_Retained()
- {
- var keyframe1 = new KeyFrame()
- {
- Setters = { new Setter(Layoutable.WidthProperty, 0d), }, Cue = new Cue(0.0d)
- };
- var keyframe2 = new KeyFrame()
- {
- Setters = { new Setter(Layoutable.WidthProperty, 300d), }, Cue = new Cue(1.0d)
- };
- var animation = new Animation()
- {
- Duration = TimeSpan.FromSeconds(0.05d),
- Delay = TimeSpan.FromSeconds(0.05d),
- Easing = new SineEaseInOut(),
- FillMode = FillMode.Both,
- Children = { keyframe1, keyframe2 }
- };
- var border = new Border() { Height = 100d, Width = 100d, };
- var clock = new TestClock();
- animation.RunAsync(border, clock);
- clock.Step(TimeSpan.FromSeconds(0d));
- Assert.Equal(border.Width, 0d);
- clock.Step(TimeSpan.FromSeconds(0.050d));
- Assert.Equal(border.Width, 0d);
- clock.Step(TimeSpan.FromSeconds(0.100d));
- Assert.Equal(border.Width, 300d);
- }
- [Fact]
- public void Dispose_Subscription_Should_Stop_Animation()
- {
- var keyframe1 = new KeyFrame()
- {
- Setters = { new Setter(Layoutable.WidthProperty, 200d), }, Cue = new Cue(1d)
- };
- var keyframe2 = new KeyFrame()
- {
- Setters = { new Setter(Layoutable.WidthProperty, 100d), }, Cue = new Cue(0d)
- };
- var animation = new Animation()
- {
- Duration = TimeSpan.FromSeconds(10),
- Delay = TimeSpan.FromSeconds(0),
- DelayBetweenIterations = TimeSpan.FromSeconds(0),
- IterationCount = new IterationCount(1),
- Children = { keyframe2, keyframe1 }
- };
- var border = new Border() { Height = 100d, Width = 50d };
- var propertyChangedCount = 0;
- var animationCompletedCount = 0;
- border.PropertyChanged += (_, e) =>
- {
- if (e.Property == Layoutable.WidthProperty)
- {
- propertyChangedCount++;
- }
- };
- var clock = new TestClock();
- var disposable = animation.Apply(border, clock, Observable.Return(true), () => animationCompletedCount++);
- Assert.Equal(0, propertyChangedCount);
- clock.Step(TimeSpan.FromSeconds(0));
- Assert.Equal(0, animationCompletedCount);
- Assert.Equal(1, propertyChangedCount);
- disposable.Dispose();
- // Clock ticks should be ignored after Dispose
- clock.Step(TimeSpan.FromSeconds(5));
- clock.Step(TimeSpan.FromSeconds(6));
- clock.Step(TimeSpan.FromSeconds(7));
- // On animation disposing (cancellation) on completed is not invoked (is it expected?)
- Assert.Equal(0, animationCompletedCount);
- // Initial property changed before cancellation + animation value removal.
- Assert.Equal(2, propertyChangedCount);
- }
- [Fact]
- public void Do_Not_Run_Cancelled_Animation()
- {
- var keyframe1 = new KeyFrame()
- {
- Setters = { new Setter(Layoutable.WidthProperty, 200d), }, Cue = new Cue(1d)
- };
- var keyframe2 = new KeyFrame()
- {
- Setters = { new Setter(Layoutable.WidthProperty, 100d), }, Cue = new Cue(0d)
- };
- var animation = new Animation()
- {
- Duration = TimeSpan.FromSeconds(10),
- Delay = TimeSpan.FromSeconds(0),
- DelayBetweenIterations = TimeSpan.FromSeconds(0),
- IterationCount = new IterationCount(1),
- Children = { keyframe2, keyframe1 }
- };
- var border = new Border() { Height = 100d, Width = 100d };
- var propertyChangedCount = 0;
- border.PropertyChanged += (_, e) =>
- {
- if (e.Property == Layoutable.WidthProperty)
- {
- propertyChangedCount++;
- }
- };
- var clock = new TestClock();
- var cancellationTokenSource = new CancellationTokenSource();
- cancellationTokenSource.Cancel();
- var animationRun = animation.RunAsync(border, clock, cancellationTokenSource.Token);
- clock.Step(TimeSpan.FromSeconds(10));
- Assert.Equal(0, propertyChangedCount);
- Assert.True(animationRun.IsCompleted);
- }
- [Fact]
- public void Cancellation_Should_Stop_Animation()
- {
- var keyframe1 = new KeyFrame()
- {
- Setters = { new Setter(Layoutable.WidthProperty, 200d), }, Cue = new Cue(1d)
- };
- var keyframe2 = new KeyFrame()
- {
- Setters = { new Setter(Layoutable.WidthProperty, 100d), }, Cue = new Cue(0d)
- };
- var animation = new Animation()
- {
- Duration = TimeSpan.FromSeconds(10),
- Delay = TimeSpan.FromSeconds(0),
- DelayBetweenIterations = TimeSpan.FromSeconds(0),
- IterationCount = new IterationCount(1),
- Children = { keyframe2, keyframe1 }
- };
- var border = new Border() { Height = 100d, Width = 50d };
- var propertyChangedCount = 0;
- border.PropertyChanged += (_, e) =>
- {
- if (e.Property == Layoutable.WidthProperty)
- {
- propertyChangedCount++;
- }
- };
- var clock = new TestClock();
- var cancellationTokenSource = new CancellationTokenSource();
- var animationRun = animation.RunAsync(border, clock, cancellationTokenSource.Token);
- Assert.False(animationRun.IsCompleted);
- Assert.Equal(0, propertyChangedCount);
- clock.Step(TimeSpan.FromSeconds(0));
- Assert.False(animationRun.IsCompleted);
- Assert.Equal(1, propertyChangedCount);
- cancellationTokenSource.Cancel();
- clock.Step(TimeSpan.FromSeconds(1));
- clock.Step(TimeSpan.FromSeconds(2));
- clock.Step(TimeSpan.FromSeconds(3));
- animationRun.Wait();
- clock.Step(TimeSpan.FromSeconds(6));
- Assert.True(animationRun.IsCompleted);
- Assert.Equal(2, propertyChangedCount);
- }
- [Fact]
- public void Dont_Run_Infinite_Iteration_Animation_On_RunAsync_Method()
- {
- var keyframe1 = new KeyFrame()
- {
- Setters = { new Setter(Layoutable.WidthProperty, 200d), }, Cue = new Cue(1d)
- };
- var keyframe2 = new KeyFrame()
- {
- Setters = { new Setter(Layoutable.WidthProperty, 100d), }, Cue = new Cue(0d)
- };
- var animation = new Animation()
- {
- Duration = TimeSpan.FromSeconds(10),
- Delay = TimeSpan.FromSeconds(0),
- DelayBetweenIterations = TimeSpan.FromSeconds(0),
- IterationCount = IterationCount.Infinite,
- Children = { keyframe2, keyframe1 }
- };
- var border = new Border() { Height = 100d, Width = 50d };
- var clock = new TestClock();
- var cancellationTokenSource = new CancellationTokenSource();
- var animationRun = animation.RunAsync(border, clock, cancellationTokenSource.Token);
- Assert.True(animationRun.IsCompleted);
- Assert.NotNull(animationRun.Exception);
- }
- [Fact]
- public void Cancellation_Of_Completed_Animation_Does_Not_Fail()
- {
- var keyframe1 = new KeyFrame()
- {
- Setters = { new Setter(Layoutable.WidthProperty, 200d), }, Cue = new Cue(1d)
- };
- var keyframe2 = new KeyFrame()
- {
- Setters = { new Setter(Layoutable.WidthProperty, 100d), }, Cue = new Cue(0d)
- };
- var animation = new Animation()
- {
- Duration = TimeSpan.FromSeconds(10),
- Delay = TimeSpan.FromSeconds(0),
- DelayBetweenIterations = TimeSpan.FromSeconds(0),
- IterationCount = new IterationCount(1),
- Children = { keyframe2, keyframe1 }
- };
- var border = new Border() { Height = 100d, Width = 50d };
- var propertyChangedCount = 0;
- border.PropertyChanged += (_, e) =>
- {
- if (e.Property == Layoutable.WidthProperty)
- {
- propertyChangedCount++;
- }
- };
- var clock = new TestClock();
- var cancellationTokenSource = new CancellationTokenSource();
- var animationRun = animation.RunAsync(border, clock, cancellationTokenSource.Token);
- Assert.Equal(0, propertyChangedCount);
- clock.Step(TimeSpan.FromSeconds(0));
- Assert.False(animationRun.IsCompleted);
- Assert.Equal(1, propertyChangedCount);
- clock.Step(TimeSpan.FromSeconds(10));
- Assert.True(animationRun.IsCompleted);
- Assert.Equal(2, propertyChangedCount);
- cancellationTokenSource.Cancel();
- animationRun.Wait();
- }
- }
- }
|