-
Notifications
You must be signed in to change notification settings - Fork 482
/
Copy pathtimeoutUtils.test.ts
202 lines (167 loc) · 7.81 KB
/
timeoutUtils.test.ts
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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
/*!
* Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
import * as assert from 'assert'
import * as FakeTimers from '@sinonjs/fake-timers'
import * as timeoutUtils from '../../../shared/utilities/timeoutUtils'
describe('timeoutUtils', async () => {
let clock: sinon.SinonFakeTimers
before(() => {
clock = FakeTimers.install()
})
after(() => {
clock.uninstall()
})
describe('Timeout', async () => {
it('returns > 0 if the timer is still active', async () => {
const timerLengthMs = 100
const longTimer = new timeoutUtils.Timeout(timerLengthMs)
clock.tick(timerLengthMs / 2)
assert.strictEqual(longTimer.remainingTime > 0, true)
// kill the timer to not mess with other tests
longTimer.killTimer()
})
it('returns 0 if timer is expired', async () => {
const timerLengthMs = 10
const shortTimer = new timeoutUtils.Timeout(timerLengthMs)
clock.tick(timerLengthMs + 1)
setTimeout(() => {
assert.strictEqual(shortTimer.remainingTime, 0)
}, 10)
})
it('returns a Promise if a timer is active', async () => {
const longTimer = new timeoutUtils.Timeout(300)
assert.strictEqual(longTimer.timer instanceof Promise, true)
// kill the timer to not mess with other tests
longTimer.killTimer()
})
it('timer object rejects if a timer is expired', async () => {
const timerLengthMs = 10
const shortTimer = new timeoutUtils.Timeout(timerLengthMs)
clock.tick(timerLengthMs + 1)
await shortTimer.timer.catch(value => {
assert.strictEqual(value, undefined)
})
})
it('successfully kills active timers', async () => {
const longTimer = new timeoutUtils.Timeout(300)
// make sure this is an active Promise
assert.strictEqual(longTimer.timer instanceof Promise, true)
longTimer.killTimer()
try {
// make sure the promise was resolved
await longTimer.timer
} catch {
// if the timer was not killed, promise will reject after 300 ms and test should fail.
assert.fail('the promise was not killed!')
}
})
it('correctly reports an elapsed time', async () => {
const checkTimerMs = 50
const longTimer = new timeoutUtils.Timeout(checkTimerMs * 6)
// Simulate a small amount of time, then measure elapsed time
clock.tick(checkTimerMs)
assert.strictEqual(longTimer.elapsedTime, checkTimerMs)
// kill the timer to not mess with other tests
longTimer.killTimer()
})
it('Correctly reports elapsed time with refresh', async () => {
const longTimer = new timeoutUtils.Timeout(10)
clock.tick(5)
longTimer.refresh()
clock.tick(5)
assert.strictEqual(longTimer.elapsedTime, 10)
assert.strictEqual(longTimer.remainingTime, 5)
// kill the timer to not mess with other tests
longTimer.killTimer()
})
it('Refresh pushes back the start time', async () => {
const longTimer = new timeoutUtils.Timeout(10)
clock.tick(5)
longTimer.refresh()
assert.strictEqual(longTimer.remainingTime, 10)
// kill the timer to not mess with other tests
longTimer.killTimer()
})
})
describe('waitUntil', async () => {
const testSettings = {
callCounter: 0,
callGoal: 0,
functionDelay: 10,
clockInterval: 1,
clockSpeed: 5,
}
let fastClock: sinon.SinonTimerId
// Test function, increments a counter every time it is called
async function testFunction(): Promise<number | undefined> {
if (++testSettings.callCounter >= testSettings.callGoal) {
return testSettings.callGoal
} else {
return undefined
}
}
// Simple wrapper that waits until calling testFunction
async function slowTestFunction(): Promise<number | undefined> {
await new Promise(r => setTimeout(r, testSettings.functionDelay))
return testFunction()
}
before(() => {
clock.uninstall()
// Makes a clock that runs clockSpeed times as fast as a normal clock (uses 1ms intervals)
// This works since we create an interval with the system clock, then trigger our fake clock with it
fastClock = setInterval(() => {
clock.tick(testSettings.clockSpeed * testSettings.clockInterval)
}, testSettings.clockInterval)
clock = FakeTimers.install()
})
after(() => {
clearInterval(fastClock)
})
beforeEach(() => {
testSettings.callCounter = 0
testSettings.functionDelay = 10
})
it('returns value after multiple function calls', async () => {
testSettings.callGoal = 4
const returnValue: number | undefined = await timeoutUtils.waitUntil(testFunction, { timeout: 10000, interval: 10, truthy: false })
assert.strictEqual(returnValue, testSettings.callGoal)
})
it('timeout before function returns defined value', async () => {
testSettings.callGoal = 7
const returnValue: number | undefined = await timeoutUtils.waitUntil(testFunction, { timeout: 30, interval: 10, truthy: false })
assert.strictEqual(returnValue, undefined)
})
it('returns true/false values correctly', async () => {
assert.strictEqual(true, await timeoutUtils.waitUntil(async () => true, { timeout: 10000, interval: 10, truthy: false }))
assert.strictEqual(false, await timeoutUtils.waitUntil(async () => false, { timeout: 10000, interval: 10, truthy: false }))
})
it('timeout when function takes longer than timeout parameter', async () => {
testSettings.functionDelay = 100
const returnValue: number | undefined = await timeoutUtils.waitUntil(slowTestFunction, { timeout: 50, interval: 10, truthy: false })
assert.strictEqual(returnValue, undefined)
})
it('timeout from slow function calls', async () => {
testSettings.callGoal = 10
const returnValue: number | undefined = await timeoutUtils.waitUntil(slowTestFunction, { timeout: 50, interval: 10, truthy: false })
assert.strictEqual(returnValue, undefined)
})
it('returns value with after multiple calls and function delay ', async () => {
testSettings.callGoal = 3
testSettings.functionDelay = 5
const returnValue: number | undefined = await timeoutUtils.waitUntil(slowTestFunction, { timeout: 10000, interval: 5, truthy: false })
assert.strictEqual(returnValue, testSettings.callGoal)
})
it('returns value after setting truthy parameter to true', async () => {
let counter: number = 0
const result: boolean | undefined = await timeoutUtils.waitUntil(async () => counter++ == 5, { timeout: 1000, interval: 5, truthy: true })
assert.strictEqual(result, true)
})
it('timeout after setting truthy parameter to true', async () => {
let counter: number = 0
const result: boolean | undefined = await timeoutUtils.waitUntil(async () => counter++ == 5, { timeout: 15, interval: 5, truthy: true })
assert.strictEqual(result, undefined)
})
})
})