1- import { describe , expect , it , vi } from "vitest"
1+ import { afterEach , describe , expect , it , vi } from "vitest"
22import { RooCodeEventName , type ClineMessage } from "@roo-code/types"
33
44import { UsageTracker } from "../UsageTracker.js"
@@ -11,6 +11,10 @@ const createUsageMessage = (text: string, ts = 1000): ClineMessage => ({
1111} )
1212
1313describe ( "UsageTracker" , ( ) => {
14+ afterEach ( ( ) => {
15+ vi . useRealTimers ( )
16+ } )
17+
1418 it ( "recomputes tokenUsage on each read after an emitted snapshot exists" , ( ) => {
1519 const messages : ClineMessage [ ] = [
1620 { type : "say" , say : "text" , text : "task" , ts : 1 } ,
@@ -53,4 +57,31 @@ describe("UsageTracker", () => {
5357 )
5458 expect ( ( tracker as any ) . tokenUsageSnapshot . totalTokensIn ) . toBe ( 100 )
5559 } )
60+
61+ it ( "cancels pending debounced token usage emissions on dispose" , ( ) => {
62+ vi . useFakeTimers ( )
63+
64+ const emit = vi . fn ( )
65+ const messages : ClineMessage [ ] = [
66+ { type : "say" , say : "text" , text : "task" , ts : 1 } ,
67+ createUsageMessage ( '{"tokensIn":100,"tokensOut":50,"cost":0.01}' , 1000 ) ,
68+ ]
69+ const tracker = new UsageTracker ( {
70+ taskId : "task-id" ,
71+ getMessages : ( ) => messages ,
72+ emit,
73+ emitIntervalMs : 1000 ,
74+ } )
75+
76+ tracker . emitTokenUsageUpdate ( tracker . getTokenUsage ( ) )
77+ messages [ 1 ] = createUsageMessage ( '{"tokensIn":250,"tokensOut":50,"cost":0.02}' , 1000 )
78+ tracker . emitTokenUsageUpdate ( tracker . getTokenUsage ( ) )
79+
80+ expect ( emit ) . toHaveBeenCalledTimes ( 1 )
81+
82+ tracker . dispose ( )
83+ vi . advanceTimersByTime ( 1000 )
84+
85+ expect ( emit ) . toHaveBeenCalledTimes ( 1 )
86+ } )
5687} )
0 commit comments