forked from zyanfx/Zyan
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implemented SetTimeout, SetInterval and Debounce, added unit tests, z…
- Loading branch information
Showing
12 changed files
with
218 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
using System; | ||
using SysTimer = System.Timers.Timer; | ||
|
||
namespace Zyan.Communication.Toolbox | ||
{ | ||
internal static class Debouncer | ||
{ | ||
/// <summary> | ||
/// Default debounce interval, milliseconds. | ||
/// </summary> | ||
public const int DefaultDebounceInterval = 300; | ||
|
||
/// <summary> | ||
/// Creates a new debounced version of the passed action. | ||
/// </summary> | ||
/// <param name="action">Action to debounce.</param> | ||
/// <param name="delayMs">Debounce interval in milliseconds.</param> | ||
/// <returns>The debounced version of the given action.</returns> | ||
/// <remarks> | ||
/// Based on these gists: | ||
/// https://gist.github.com/ca0v/73a31f57b397606c9813472f7493a940 | ||
/// https://gist.github.com/fr-ser/ded7690b245223094cd876069456ed6c | ||
/// </remarks> | ||
public static Action Debounce(this Action action, int delayMs = DefaultDebounceInterval) | ||
{ | ||
var timer = default(IDisposable); | ||
|
||
return () => | ||
{ | ||
timer?.Dispose(); | ||
timer = SetTimeout(action, delayMs); | ||
}; | ||
} | ||
|
||
/// <summary> | ||
/// Executes an action at specified intervals (in milliseconds), like setInterval in Javascript. | ||
/// </summary> | ||
/// <param name="action">The action to schedule.</param> | ||
/// <param name="delayMs">The delay in milliseconds.</param> | ||
/// <returns> | ||
/// The value that can be disposed to stop the timer. | ||
/// </returns> | ||
/// <remarks> | ||
/// Based on this gist: | ||
/// https://gist.github.com/CipherLab/10a40f7032be04f0aa6f | ||
/// </remarks> | ||
public static IDisposable SetInterval(Action action, int delayMs) | ||
{ | ||
var timer = new SysTimer(delayMs) | ||
{ | ||
AutoReset = true | ||
}; | ||
|
||
timer.Elapsed += (s, e) => | ||
{ | ||
action(); | ||
}; | ||
|
||
timer.Start(); | ||
return timer; | ||
} | ||
|
||
/// <summary> | ||
/// Executes an action after a specified number of milliseconds. | ||
/// </summary> | ||
/// <param name="action">The action to execute.</param> | ||
/// <param name="delayMs">The delay in milliseconds.</param> | ||
/// <returns> | ||
/// The value that can be disposed to cancel the execution. | ||
/// </returns> | ||
/// <remarks> | ||
/// Based on this gist: | ||
/// https://gist.github.com/CipherLab/10a40f7032be04f0aa6f | ||
/// </remarks> | ||
public static IDisposable SetTimeout(Action action, int delayMs) | ||
{ | ||
var timer = new SysTimer(delayMs) | ||
{ | ||
AutoReset = false | ||
}; | ||
|
||
timer.Elapsed += (s, e) => | ||
{ | ||
action(); | ||
timer.Dispose(); | ||
}; | ||
|
||
timer.Start(); | ||
return timer; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Threading; | ||
using Zyan.Communication.Toolbox; | ||
|
||
namespace Zyan.Tests | ||
{ | ||
#region Unit testing platform abstraction layer | ||
#if NUNIT | ||
using NUnit.Framework; | ||
using TestClass = NUnit.Framework.TestFixtureAttribute; | ||
using TestMethod = NUnit.Framework.TestAttribute; | ||
using ClassInitializeNonStatic = NUnit.Framework.TestFixtureSetUpAttribute; | ||
using ClassInitialize = DummyAttribute; | ||
using ClassCleanupNonStatic = NUnit.Framework.TestFixtureTearDownAttribute; | ||
using ClassCleanup = DummyAttribute; | ||
using TestContext = System.Object; | ||
#else | ||
using Microsoft.VisualStudio.TestTools.UnitTesting; | ||
using ClassCleanupNonStatic = DummyAttribute; | ||
using ClassInitializeNonStatic = DummyAttribute; | ||
#endif | ||
#endregion | ||
|
||
/// <summary> | ||
/// Test class for the debouncer. | ||
///</summary> | ||
[TestClass] | ||
public class DebouncerTests | ||
{ | ||
[TestMethod] | ||
public void SetTimeoutExecutesTheGivenActionAfterAnInterval() | ||
{ | ||
// target function | ||
var counter = 0; | ||
Action inc = () => counter++; | ||
|
||
Debouncer.SetTimeout(inc, 10); | ||
Assert.AreEqual(0, counter); | ||
|
||
Thread.Sleep(50); | ||
Assert.AreEqual(1, counter); | ||
} | ||
|
||
[TestMethod] | ||
public void SetTimeoutCanBeCancelled() | ||
{ | ||
// target function | ||
var counter = 0; | ||
Action inc = () => counter++; | ||
|
||
var timer = Debouncer.SetTimeout(inc, 10); | ||
Assert.AreEqual(0, counter); | ||
timer.Dispose(); | ||
|
||
Thread.Sleep(50); | ||
Assert.AreEqual(0, counter); | ||
} | ||
|
||
[TestMethod] | ||
public void SetIntervalExecutesTheGivenActionAtAGivenInterval() | ||
{ | ||
// target function | ||
var counter = 0; | ||
Action inc = () => counter++; | ||
|
||
Debouncer.SetInterval(inc, 10); | ||
Assert.AreEqual(0, counter); | ||
|
||
Thread.Sleep(50); | ||
Assert.IsTrue(counter > 1); | ||
} | ||
|
||
[TestMethod] | ||
public void SetIntervalCanBeCancelled() | ||
{ | ||
// target function | ||
var counter = 0; | ||
Action inc = () => counter++; | ||
|
||
var timer = Debouncer.SetInterval(inc, 10); | ||
Assert.AreEqual(0, counter); | ||
|
||
Thread.Sleep(50); | ||
Assert.IsTrue(counter > 1); | ||
timer.Dispose(); | ||
|
||
var lastCounter = counter; | ||
Thread.Sleep(50); | ||
Assert.AreEqual(lastCounter, counter); | ||
} | ||
|
||
[TestMethod] | ||
public void DebouncedActionIsCalledOnce() | ||
{ | ||
// target function | ||
var counter = 0; | ||
Action inc = () => counter++; | ||
|
||
// debounce the given function | ||
var debounced = inc.Debounce(10); | ||
Assert.IsNotNull(debounced); | ||
|
||
// try to call the debounced version and make sure the target is not yet called | ||
debounced(); | ||
debounced(); | ||
debounced(); | ||
debounced(); | ||
Assert.AreEqual(0, counter); | ||
|
||
Thread.Sleep(50); | ||
Assert.AreEqual(1, counter); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters