diff --git a/src/Avalonia.Animation/AnimationInstance`1.cs b/src/Avalonia.Animation/AnimationInstance`1.cs
index eca1942cac..0c7ae9c13c 100644
--- a/src/Avalonia.Animation/AnimationInstance`1.cs
+++ b/src/Avalonia.Animation/AnimationInstance`1.cs
@@ -56,7 +56,7 @@ namespace Avalonia.Animation
if (animation.IterationCount.RepeatType == IterationType.Many)
_iterationCount = animation.IterationCount.Value;
-
+
_animationDirection = animation.PlaybackDirection;
_fillMode = animation.FillMode;
_onCompleteAction = OnComplete;
@@ -174,11 +174,13 @@ namespace Avalonia.Animation
}
else if (playbackTime > iterDuration &
playbackTime <= iterationTime &
- iterDelay > 0 &
- // The last iteration's trailing delay should be skipped.
- (_currentIteration + 1) < _iterationCount)
+ iterDelay > 0)
{
- DoDelay();
+ // The last iteration's trailing delay should be skipped.
+ if ((_currentIteration + 1) < _iterationCount)
+ DoDelay();
+ else
+ DoComplete();
}
}
}
diff --git a/tests/Avalonia.Animation.UnitTests/AnimationIterationTests.cs b/tests/Avalonia.Animation.UnitTests/AnimationIterationTests.cs
new file mode 100644
index 0000000000..9b59dd4cc9
--- /dev/null
+++ b/tests/Avalonia.Animation.UnitTests/AnimationIterationTests.cs
@@ -0,0 +1,72 @@
+using System;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Avalonia.Animation;
+using Avalonia.Controls;
+using Avalonia.Styling;
+using Avalonia.UnitTests;
+using Avalonia.Data;
+using Xunit;
+
+namespace Avalonia.Animation.UnitTests
+{
+ public class AnimationIterationTests
+ {
+ [Fact]
+ public void Check_Initial_Inter_and_Trailing_Delay_Values()
+ {
+ var keyframe1 = new KeyFrame()
+ {
+ new Setter(Border.WidthProperty, 200d),
+ };
+
+ var keyframe2 = new KeyFrame()
+ {
+ new Setter(Border.WidthProperty, 100d),
+ };
+
+ keyframe1.Cue = new Cue(1d);
+ keyframe2.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);
+ }
+ }
+}
\ No newline at end of file
diff --git a/tests/Avalonia.Animation.UnitTests/Avalonia.Animation.UnitTests.csproj b/tests/Avalonia.Animation.UnitTests/Avalonia.Animation.UnitTests.csproj
new file mode 100644
index 0000000000..1b2ba3c7de
--- /dev/null
+++ b/tests/Avalonia.Animation.UnitTests/Avalonia.Animation.UnitTests.csproj
@@ -0,0 +1,25 @@
+
+
+ netcoreapp2.0
+ Library
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/tests/Avalonia.Animation.UnitTests/Properties/AssemblyInfo.cs b/tests/Avalonia.Animation.UnitTests/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000000..b00c205f10
--- /dev/null
+++ b/tests/Avalonia.Animation.UnitTests/Properties/AssemblyInfo.cs
@@ -0,0 +1,10 @@
+// Copyright (c) The Avalonia Project. All rights reserved.
+// Licensed under the MIT license. See licence.md file in the project root for full license information.
+
+using System.Reflection;
+using Xunit;
+
+[assembly: AssemblyTitle("Avalonia.Animation.UnitTests")]
+
+// Don't run tests in parallel.
+[assembly: CollectionBehavior(DisableTestParallelization = true)]
\ No newline at end of file
diff --git a/tests/Avalonia.Animation.UnitTests/TestClock.cs b/tests/Avalonia.Animation.UnitTests/TestClock.cs
new file mode 100644
index 0000000000..a1c4ff9277
--- /dev/null
+++ b/tests/Avalonia.Animation.UnitTests/TestClock.cs
@@ -0,0 +1,28 @@
+using System;
+using System.Collections.Generic;
+
+namespace Avalonia.Animation.UnitTests
+{
+ internal class TestClock : IClock, IDisposable
+ {
+ private IObserver _observer;
+
+ public PlayState PlayState { get; set; } = PlayState.Run;
+
+ public void Dispose()
+ {
+ _observer?.OnCompleted();
+ }
+
+ public void Step(TimeSpan time)
+ {
+ _observer?.OnNext(time);
+ }
+
+ public IDisposable Subscribe(IObserver observer)
+ {
+ _observer = observer;
+ return this;
+ }
+ }
+}
\ No newline at end of file