diff --git a/DryWetMidi.Tests/Devices/Clock/TickGenerator/HighPrecisionTickGeneratorTests.cs b/DryWetMidi.Tests/Devices/Clock/TickGenerator/HighPrecisionTickGeneratorTests.cs new file mode 100644 index 000000000..af9a39797 --- /dev/null +++ b/DryWetMidi.Tests/Devices/Clock/TickGenerator/HighPrecisionTickGeneratorTests.cs @@ -0,0 +1,49 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Threading; +using Melanchall.DryWetMidi.Devices; +using NUnit.Framework; + +namespace Melanchall.DryWetMidi.Tests.Devices +{ + [TestFixture] + public sealed class HighPrecisionTickGeneratorTests + { + #region Test methods + + [Retry(5)] + [Test] + public void CheckInterval([Values(1, 10, 100)] int interval) + { + using (var tickGenerator = new HighPrecisionTickGenerator()) + { + var stopwatch = new Stopwatch(); + var elapsedTimes = new List(150); + + tickGenerator.TickGenerated += (_, __) => elapsedTimes.Add(stopwatch.ElapsedMilliseconds); + + tickGenerator.TryStart(TimeSpan.FromMilliseconds(interval)); + stopwatch.Start(); + + SpinWait.SpinUntil(() => elapsedTimes.Count >= 100); + tickGenerator.TryStop(); + stopwatch.Stop(); + + var time = elapsedTimes[0]; + var maxDelta = 0L; + var tolerance = interval * 0.2; + + foreach (var t in elapsedTimes) + { + maxDelta = Math.Max(t - time, maxDelta); + time = t; + } + + Assert.Less(maxDelta, interval + tolerance, "Max time delta is too big."); + } + } + + #endregion + } +}