Skip to content

Commit a76dda0

Browse files
committed
added test script for interval timer
1 parent 08d8c6b commit a76dda0

File tree

1 file changed

+263
-0
lines changed

1 file changed

+263
-0
lines changed
Lines changed: 263 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,263 @@
1+
import { IntervalTimer, ExampleIntervalTimer } from '../IntervalTimer'
2+
3+
describe('IntervalTimer', () => {
4+
let timerInstances = []
5+
6+
// Reset singleton instance before each test
7+
beforeEach(() => {
8+
// Clear any existing timer instances
9+
timerInstances.forEach((timer) => {
10+
if (timer && timer.timer) {
11+
clearInterval(timer.timer)
12+
}
13+
if (timer && timer.instance) {
14+
timer.instance = null
15+
}
16+
})
17+
timerInstances = []
18+
})
19+
20+
afterEach(() => {
21+
// Clean up any running timers
22+
timerInstances.forEach((timer) => {
23+
if (timer && timer.timer) {
24+
clearInterval(timer.timer)
25+
}
26+
})
27+
})
28+
29+
describe('Constructor', () => {
30+
it('should create an instance with default parameters', () => {
31+
const timer = new IntervalTimer()
32+
timerInstances.push(timer)
33+
expect(timer).toBeInstanceOf(IntervalTimer)
34+
expect(timer.interval).toBe(10)
35+
expect(typeof timer.callBack).toBe('function')
36+
})
37+
38+
it('should create an instance with custom interval', () => {
39+
const timer = new IntervalTimer(50)
40+
timerInstances.push(timer)
41+
expect(timer.interval).toBe(50)
42+
})
43+
44+
it('should create an instance with custom callback', () => {
45+
const mockCallback = vi.fn()
46+
const timer = new IntervalTimer(10, mockCallback)
47+
timerInstances.push(timer)
48+
expect(timer.callBack).toBe(mockCallback)
49+
})
50+
51+
it('should implement singleton pattern', () => {
52+
const timer1 = new IntervalTimer(20)
53+
timerInstances.push(timer1)
54+
const timer2 = new IntervalTimer(30)
55+
timerInstances.push(timer2)
56+
57+
// Both should reference the same instance
58+
expect(timer1).toBe(timer2)
59+
expect(timer1.interval).toBe(20) // First instance's interval should be preserved
60+
})
61+
})
62+
63+
describe('startTimer', () => {
64+
it('should start the timer interval', (done) => {
65+
const mockCallback = vi.fn(() => {
66+
mockCallback.mockClear()
67+
})
68+
const timer = new IntervalTimer(10, mockCallback)
69+
timerInstances.push(timer)
70+
71+
timer.startTimer()
72+
73+
// Wait for callback to be called
74+
setTimeout(() => {
75+
expect(mockCallback).toHaveBeenCalled()
76+
clearInterval(timer.timer)
77+
done()
78+
}, 15)
79+
})
80+
81+
it('should store the timer ID', () => {
82+
const timer = new IntervalTimer()
83+
timerInstances.push(timer)
84+
timer.startTimer()
85+
86+
expect(timer.timer).toBeDefined()
87+
expect(typeof timer.timer).toBe('number')
88+
89+
clearInterval(timer.timer)
90+
})
91+
})
92+
93+
describe('getElapsedTime', () => {
94+
it('should return elapsed time with default offset', () => {
95+
const timer = new IntervalTimer()
96+
timerInstances.push(timer)
97+
timer.startTimer()
98+
99+
// getElapsedTime uses timer ID arithmetic which may not work as expected
100+
// but we test the actual behavior
101+
const elapsed = timer.getElapsedTime()
102+
103+
expect(typeof elapsed).toBe('number')
104+
105+
clearInterval(timer.timer)
106+
})
107+
108+
it('should subtract offset from elapsed time', () => {
109+
const timer = new IntervalTimer()
110+
timerInstances.push(timer)
111+
timer.startTimer()
112+
113+
const offset = 100
114+
const elapsed = timer.getElapsedTime(offset)
115+
116+
expect(typeof elapsed).toBe('number')
117+
118+
clearInterval(timer.timer)
119+
})
120+
121+
it('should update prevInterval on each call', () => {
122+
const timer = new IntervalTimer()
123+
timerInstances.push(timer)
124+
timer.startTimer()
125+
126+
const prevIntervalBefore = timer.prevInterval
127+
timer.getElapsedTime()
128+
const prevIntervalAfter = timer.prevInterval
129+
130+
expect(prevIntervalAfter).not.toBe(prevIntervalBefore)
131+
132+
clearInterval(timer.timer)
133+
})
134+
})
135+
136+
describe('getRunTime', () => {
137+
it('should return the timer ID', () => {
138+
const timer = new IntervalTimer()
139+
timerInstances.push(timer)
140+
timer.startTimer()
141+
142+
const runTime = timer.getRunTime()
143+
144+
expect(runTime).toBe(timer.timer)
145+
expect(typeof runTime).toBe('number')
146+
147+
clearInterval(timer.timer)
148+
})
149+
})
150+
151+
describe('resetTimer', () => {
152+
it('should clear the timer interval', (done) => {
153+
const mockCallback = vi.fn()
154+
const timer = new IntervalTimer(10, mockCallback)
155+
timerInstances.push(timer)
156+
timer.startTimer()
157+
158+
timer.resetTimer()
159+
160+
// Verify timer was cleared - callback should not be called after reset
161+
mockCallback.mockClear()
162+
setTimeout(() => {
163+
expect(mockCallback).not.toHaveBeenCalled()
164+
done()
165+
}, 20)
166+
})
167+
168+
it('should reset the callback to empty function', () => {
169+
const mockCallback = vi.fn()
170+
const timer = new IntervalTimer(10, mockCallback)
171+
timerInstances.push(timer)
172+
timer.startTimer()
173+
174+
timer.resetTimer()
175+
176+
expect(timer.callBack).not.toBe(mockCallback)
177+
expect(typeof timer.callBack).toBe('function')
178+
})
179+
180+
it('should return elapsed time', () => {
181+
const timer = new IntervalTimer()
182+
timerInstances.push(timer)
183+
timer.startTimer()
184+
185+
const elapsed = timer.resetTimer()
186+
187+
expect(typeof elapsed).toBe('number')
188+
})
189+
190+
it('should allow timer to be started again after reset', (done) => {
191+
const mockCallback = vi.fn()
192+
const timer = new IntervalTimer(10, mockCallback)
193+
timerInstances.push(timer)
194+
195+
timer.startTimer()
196+
timer.resetTimer()
197+
198+
// Set new callback and start again
199+
timer.callBack = mockCallback
200+
timer.startTimer()
201+
202+
setTimeout(() => {
203+
expect(mockCallback).toHaveBeenCalled()
204+
clearInterval(timer.timer)
205+
done()
206+
}, 15)
207+
})
208+
})
209+
210+
describe('Integration tests', () => {
211+
it('should work with typical usage pattern', () => {
212+
const timer = new IntervalTimer(10)
213+
timerInstances.push(timer)
214+
timer.startTimer()
215+
216+
// Simulate initialization
217+
const initOffset = timer.getRunTime()
218+
219+
// Simulate some work
220+
const elapsed = timer.getElapsedTime(initOffset)
221+
222+
expect(typeof elapsed).toBe('number')
223+
224+
// Reset
225+
const finalElapsed = timer.resetTimer()
226+
expect(typeof finalElapsed).toBe('number')
227+
})
228+
229+
it('should handle multiple getElapsedTime calls', () => {
230+
const timer = new IntervalTimer()
231+
timerInstances.push(timer)
232+
timer.startTimer()
233+
234+
const elapsed1 = timer.getElapsedTime()
235+
const elapsed2 = timer.getElapsedTime()
236+
const elapsed3 = timer.getElapsedTime()
237+
238+
expect(typeof elapsed1).toBe('number')
239+
expect(typeof elapsed2).toBe('number')
240+
expect(typeof elapsed3).toBe('number')
241+
242+
clearInterval(timer.timer)
243+
})
244+
})
245+
})
246+
247+
describe('ExampleIntervalTimer', () => {
248+
it('should execute without errors', () => {
249+
const mockOutput = vi.fn()
250+
251+
expect(() => {
252+
ExampleIntervalTimer(mockOutput)
253+
}).not.toThrow()
254+
255+
// Clean up - the ExampleIntervalTimer creates a timer instance
256+
// We need to access it through the singleton pattern
257+
const timer = new IntervalTimer()
258+
if (timer.instance && timer.instance.timer) {
259+
clearInterval(timer.instance.timer)
260+
timer.instance.instance = null
261+
}
262+
})
263+
})

0 commit comments

Comments
 (0)