maui-linux/Xamarin.Forms.Core.UnitTests/MotionTests.cs

285 строки
5.7 KiB
C#

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading.Tasks;
using NUnit.Framework;
using Xamarin.Forms.Internals;
namespace Xamarin.Forms.Core.UnitTests
{
internal class BlockingTicker : Ticker
{
bool _enabled;
protected override void EnableTimer ()
{
_enabled = true;
while (_enabled) {
SendSignals (16);
}
}
protected override void DisableTimer ()
{
_enabled = false;
}
}
internal class AsyncTicker : Ticker
{
bool _systemEnabled = true;
public override bool SystemEnabled => _systemEnabled;
bool _enabled;
public void SetEnabled(bool enabled)
{
_systemEnabled = enabled;
_enabled = enabled;
OnSystemEnabledChanged();
}
protected override async void EnableTimer ()
{
_enabled = true;
while (_enabled)
{
SendSignals(16);
await Task.Delay(16);
}
}
protected override void DisableTimer ()
{
_enabled = false;
}
}
[TestFixture]
public class MotionTests : BaseTestFixture
{
[OneTimeSetUp]
public void Init ()
{
Device.PlatformServices = new MockPlatformServices ();
Ticker.Default = new BlockingTicker ();
}
[OneTimeTearDown]
public void End ()
{
Device.PlatformServices = null;
Ticker.Default = null;
}
[Test]
public void TestLinearTween ()
{
var tweener = new Tweener (250);
double value = 0;
int updates = 0;
tweener.ValueUpdated += (sender, args) => {
Assert.That (tweener.Value, Is.GreaterThanOrEqualTo (value));
value = tweener.Value;
updates++;
};
tweener.Start ();
Assert.That (updates, Is.GreaterThanOrEqualTo (10));
}
[Test]
public void ThrowsWithNullCallback ()
{
Assert.Throws<ArgumentNullException> (() => new View().Animate ("Test", (Action<double>) null));
}
[Test]
public void ThrowsWithNullTransform ()
{
Assert.Throws<ArgumentNullException> (() => new View().Animate<float> ("Test", null, f => { }));
}
[Test]
public void ThrowsWithNullSelf ()
{
Assert.Throws<ArgumentNullException> (() => AnimationExtensions.Animate (null, "Foo", d => (float)d, f => { }));
}
[Test]
public void Kinetic ()
{
var view = new View ();
var resultList = new List<Tuple<double, double>> ();
view.AnimateKinetic (
name: "Kinetics",
callback: (distance, velocity) => {
resultList.Add (new Tuple<double, double> (distance, velocity));
return true;
},
velocity: 100,
drag: 1);
Assert.That (resultList, Is.Not.Empty);
int checkVelo = 100;
int dragStep = 16;
foreach (var item in resultList) {
checkVelo -= dragStep;
Assert.AreEqual (checkVelo, item.Item2);
Assert.AreEqual (checkVelo * dragStep, item.Item1);
}
}
[Test]
public void KineticFinished ()
{
var view = new View ();
bool finished = false;
view.AnimateKinetic (
name: "Kinetics",
callback: (distance, velocity) => true,
velocity: 100,
drag: 1,
finished: () => finished = true);
Assert.True (finished);
}
}
[TestFixture]
public class TickerSystemEnabledTests
{
[OneTimeSetUp]
public void Init ()
{
Device.PlatformServices = new MockPlatformServices ();
Ticker.Default = new AsyncTicker();
}
[OneTimeTearDown]
public void End ()
{
Device.PlatformServices = null;
Ticker.Default = null;
}
static async Task DisableTicker()
{
await Task.Delay(32);
((AsyncTicker)Ticker.Default).SetEnabled(false);
}
static async Task EnableTicker()
{
await Task.Delay(32);
((AsyncTicker)Ticker.Default).SetEnabled(true);
}
async Task SwapFadeViews(View view1, View view2)
{
await view1.FadeTo(0, 1000);
await view2.FadeTo(1, 1000);
}
[Test, Timeout(3000)]
public async Task DisablingTickerFinishesAnimationInProgress()
{
var view = new View { Opacity = 1 };
await Task.WhenAll(view.FadeTo(0, 2000), DisableTicker());
Assert.That (view.Opacity, Is.EqualTo(0));
}
[Test, Timeout(3000)]
public async Task DisablingTickerFinishesAllAnimationsInChain()
{
var view1 = new View { Opacity = 1 };
var view2 = new View { Opacity = 0 };
await Task.WhenAll(SwapFadeViews(view1, view2), DisableTicker());
Assert.That(view1.Opacity, Is.EqualTo(0));
}
static Task<bool> RepeatFade(View view)
{
var tcs = new TaskCompletionSource<bool>();
var fadeIn = new Animation(d => { view.Opacity = d; }, 0, 1);
var i = 0;
fadeIn.Commit(view, "fadeIn", length: 2000, repeat: () => ++i < 2, finished: (d, b) =>
{
tcs.SetResult(b);
});
return tcs.Task;
}
[Test, Timeout(3000)]
public async Task DisablingTickerPreventsAnimationFromRepeating()
{
var view = new View { Opacity = 0 };
await Task.WhenAll(RepeatFade(view), DisableTicker());
Assert.That(view.Opacity, Is.EqualTo(1));
}
[Test]
public async Task NewAnimationsFinishImmediatelyWhenTickerDisabled()
{
var view = new View { Opacity = 1 };
await DisableTicker();
await view.RotateYTo(200);
Assert.That(view.RotationY, Is.EqualTo(200));
}
[Test]
public async Task AnimationExtensionsReturnTrueIfAnimationsDisabled()
{
await DisableTicker();
var label = new Label { Text = "Foo" };
var result = await label.ScaleTo(2, 500);
Assert.That(result, Is.True);
}
[Test, Timeout(2000)]
public async Task CanExitAnimationLoopIfAnimationsDisabled()
{
await DisableTicker();
var run = true;
var label = new Label { Text = "Foo" };
while (run)
{
await label.ScaleTo(2, 500);
run = !(await label.ScaleTo(0.5, 500));
}
}
[Test]
public async Task CanCheckThatAnimationsAreEnabled()
{
await EnableTicker();
Assert.That(Animation.IsEnabled, Is.True);
await DisableTicker();
Assert.That(Animation.IsEnabled, Is.False);
}
}
}