-
Notifications
You must be signed in to change notification settings - Fork 234
/
Copy pathAsyncDebouncerTests.cs
138 lines (105 loc) · 4 KB
/
AsyncDebouncerTests.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
//
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
using Microsoft.PowerShell.EditorServices.Utility;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Xunit;
namespace Microsoft.PowerShell.EditorServices.Test.Utility
{
public class AsyncDebouncerTests
{
[Fact]
public async Task AsyncDebouncerFlushesAfterInterval()
{
TestAsyncDebouncer debouncer = new TestAsyncDebouncer();
await debouncer.Invoke(1);
await debouncer.Invoke(2);
await debouncer.Invoke(3);
await Task.Delay(TestAsyncDebouncer.Interval + 100);
// Add a few more items to ensure they are added after the initial interval
await debouncer.Invoke(4);
await debouncer.Invoke(5);
await debouncer.Invoke(6);
Assert.Equal(new List<int> { 1, 2, 3 }, debouncer.FlushedBuffer);
Assert.True(
debouncer.TimeToFlush >
TimeSpan.FromMilliseconds(TestAsyncDebouncer.Interval),
"Debouncer flushed before interval lapsed.");
// Check for the later items to see if they've been flushed
await Task.Delay(TestAsyncDebouncer.Interval + 100);
Assert.Equal(new List<int> { 4, 5, 6 }, debouncer.FlushedBuffer);
}
[Fact]
public async Task AsyncDebouncerRestartsAfterInvoke()
{
TestAsyncRestartDebouncer debouncer = new TestAsyncRestartDebouncer();
// Invoke the debouncer and wait a bit between each
// invoke to make sure the debouncer isn't flushed
// until after the last invoke.
await debouncer.Invoke(1);
await Task.Delay(TestAsyncRestartDebouncer.Interval - 100);
await debouncer.Invoke(2);
await Task.Delay(TestAsyncRestartDebouncer.Interval - 100);
await debouncer.Invoke(3);
await Task.Delay(TestAsyncRestartDebouncer.Interval + 100);
// The only item flushed should be 3 since its interval has lapsed
Assert.Equal(new List<int> { 3 }, debouncer.FlushedBuffer);
}
}
#region TestAsyncDebouncer
internal class TestAsyncDebouncer : AsyncDebouncer<int>
{
public const int Interval = 1500;
DateTime? firstInvoke;
private List<int> invokeBuffer = new List<int>();
public List<int> FlushedBuffer { get; private set; }
public TimeSpan TimeToFlush { get; private set; }
public TestAsyncDebouncer() : base(Interval, false)
{
}
protected override Task OnInvoke(int args)
{
if (!this.firstInvoke.HasValue)
{
this.firstInvoke = DateTime.Now;
}
this.invokeBuffer.Add(args);
return Task.FromResult(true);
}
protected override Task OnFlush()
{
// Mark the flush time
this.TimeToFlush = DateTime.Now - this.firstInvoke.Value;
// Copy the buffer contents
this.FlushedBuffer = this.invokeBuffer.ToList();
this.invokeBuffer.Clear();
return Task.FromResult(true);
}
}
#endregion
#region TestAsyncRestartDebouncer
internal class TestAsyncRestartDebouncer : AsyncDebouncer<int>
{
public const int Interval = 300;
private int lastInvokeInt = -1;
public List<int> FlushedBuffer { get; } = new List<int>();
public TestAsyncRestartDebouncer() : base(Interval, true)
{
}
protected override Task OnInvoke(int args)
{
this.lastInvokeInt = args;
return Task.FromResult(true);
}
protected override Task OnFlush()
{
this.FlushedBuffer.Add(this.lastInvokeInt);
return Task.FromResult(true);
}
}
#endregion
}