@@ -150,7 +150,7 @@ func (s *CCStatuslineTestSuite) TestGetDaemonInfo_UsesDefaultSocketPath() {
150150// formatStatuslineOutput Tests
151151
152152func (s * CCStatuslineTestSuite ) TestFormatStatuslineOutput_AllValues () {
153- output := formatStatuslineOutput ("claude-opus-4" , 1.23 , 4.56 , 3661 , 75.0 , "main" , false )
153+ output := formatStatuslineOutput ("claude-opus-4" , 1.23 , 4.56 , 3661 , 75.0 , "main" , false , nil , nil )
154154
155155 // Should contain all components
156156 assert .Contains (s .T (), output , "🌿 main" )
@@ -162,46 +162,46 @@ func (s *CCStatuslineTestSuite) TestFormatStatuslineOutput_AllValues() {
162162}
163163
164164func (s * CCStatuslineTestSuite ) TestFormatStatuslineOutput_WithDirtyBranch () {
165- output := formatStatuslineOutput ("claude-opus-4" , 1.23 , 4.56 , 3661 , 75.0 , "feature/test" , true )
165+ output := formatStatuslineOutput ("claude-opus-4" , 1.23 , 4.56 , 3661 , 75.0 , "feature/test" , true , nil , nil )
166166
167167 // Should contain branch with asterisk for dirty
168168 assert .Contains (s .T (), output , "🌿 feature/test*" )
169169 assert .Contains (s .T (), output , "🤖 claude-opus-4" )
170170}
171171
172172func (s * CCStatuslineTestSuite ) TestFormatStatuslineOutput_NoBranch () {
173- output := formatStatuslineOutput ("claude-opus-4" , 1.23 , 4.56 , 3661 , 75.0 , "" , false )
173+ output := formatStatuslineOutput ("claude-opus-4" , 1.23 , 4.56 , 3661 , 75.0 , "" , false , nil , nil )
174174
175175 // Should show "-" for no branch
176176 assert .Contains (s .T (), output , "🌿 -" )
177177 assert .Contains (s .T (), output , "🤖 claude-opus-4" )
178178}
179179
180180func (s * CCStatuslineTestSuite ) TestFormatStatuslineOutput_ZeroDailyCost () {
181- output := formatStatuslineOutput ("claude-sonnet" , 0.50 , 0 , 300 , 50.0 , "main" , false )
181+ output := formatStatuslineOutput ("claude-sonnet" , 0.50 , 0 , 300 , 50.0 , "main" , false , nil , nil )
182182
183183 // Should show "-" for zero daily cost
184184 assert .Contains (s .T (), output , "📊 -" )
185185 assert .Contains (s .T (), output , "5m0s" ) // Session time (300 seconds = 5m)
186186}
187187
188188func (s * CCStatuslineTestSuite ) TestFormatStatuslineOutput_ZeroSessionSeconds () {
189- output := formatStatuslineOutput ("claude-sonnet" , 0.50 , 1.0 , 0 , 50.0 , "main" , false )
189+ output := formatStatuslineOutput ("claude-sonnet" , 0.50 , 1.0 , 0 , 50.0 , "main" , false , nil , nil )
190190
191191 // Should show "-" for zero session seconds
192192 assert .Contains (s .T (), output , "⏱️ -" )
193193}
194194
195195func (s * CCStatuslineTestSuite ) TestFormatStatuslineOutput_HighContextPercentage () {
196- output := formatStatuslineOutput ("test-model" , 1.0 , 1.0 , 60 , 85.0 , "main" , false )
196+ output := formatStatuslineOutput ("test-model" , 1.0 , 1.0 , 60 , 85.0 , "main" , false , nil , nil )
197197
198198 // Should contain the percentage (color codes may vary)
199199 assert .Contains (s .T (), output , "85%" )
200200 assert .Contains (s .T (), output , "1m0s" )
201201}
202202
203203func (s * CCStatuslineTestSuite ) TestFormatStatuslineOutput_LowContextPercentage () {
204- output := formatStatuslineOutput ("test-model" , 1.0 , 1.0 , 45 , 25.0 , "main" , false )
204+ output := formatStatuslineOutput ("test-model" , 1.0 , 1.0 , 45 , 25.0 , "main" , false , nil , nil )
205205
206206 // Should contain the percentage
207207 assert .Contains (s .T (), output , "25%" )
@@ -275,6 +275,115 @@ func (s *CCStatuslineTestSuite) TestCalculateContextPercent_WithoutCurrentUsage(
275275 assert .Equal (s .T (), float64 (50 ), percent )
276276}
277277
278+ // formatQuotaPart Tests
279+
280+ func (s * CCStatuslineTestSuite ) TestFormatQuotaPart_NilValues () {
281+ result := formatQuotaPart (nil , nil )
282+ assert .Contains (s .T (), result , "🚦 -" )
283+ }
284+
285+ func (s * CCStatuslineTestSuite ) TestFormatQuotaPart_OnlyFiveHourNil () {
286+ sd := 0.23
287+ result := formatQuotaPart (nil , & sd )
288+ assert .Contains (s .T (), result , "🚦 -" )
289+ }
290+
291+ func (s * CCStatuslineTestSuite ) TestFormatQuotaPart_LowUtilization () {
292+ fh := 0.10
293+ sd := 0.20
294+ result := formatQuotaPart (& fh , & sd )
295+ assert .Contains (s .T (), result , "5h:10%" )
296+ assert .Contains (s .T (), result , "7d:20%" )
297+ }
298+
299+ func (s * CCStatuslineTestSuite ) TestFormatQuotaPart_MediumUtilization () {
300+ fh := 0.55
301+ sd := 0.30
302+ result := formatQuotaPart (& fh , & sd )
303+ assert .Contains (s .T (), result , "5h:55%" )
304+ assert .Contains (s .T (), result , "7d:30%" )
305+ }
306+
307+ func (s * CCStatuslineTestSuite ) TestFormatQuotaPart_HighUtilization () {
308+ fh := 0.45
309+ sd := 0.85
310+ result := formatQuotaPart (& fh , & sd )
311+ assert .Contains (s .T (), result , "5h:45%" )
312+ assert .Contains (s .T (), result , "7d:85%" )
313+ }
314+
315+ func (s * CCStatuslineTestSuite ) TestFormatQuotaPart_ContainsLink () {
316+ // Nil case
317+ result := formatQuotaPart (nil , nil )
318+ assert .Contains (s .T (), result , "claude.ai/settings/usage" )
319+ assert .Contains (s .T (), result , "\033 ]8;;" )
320+
321+ // With values
322+ fh := 0.45
323+ sd := 0.23
324+ result = formatQuotaPart (& fh , & sd )
325+ assert .Contains (s .T (), result , "claude.ai/settings/usage" )
326+ assert .Contains (s .T (), result , "\033 ]8;;" )
327+ assert .Contains (s .T (), result , "5h:45%" )
328+ assert .Contains (s .T (), result , "7d:23%" )
329+ }
330+
331+ func (s * CCStatuslineTestSuite ) TestFormatStatuslineOutput_WithQuota () {
332+ fh := 0.45
333+ sd := 0.23
334+ output := formatStatuslineOutput ("claude-opus-4" , 1.23 , 4.56 , 3661 , 75.0 , "main" , false , & fh , & sd )
335+
336+ assert .Contains (s .T (), output , "5h:45%" )
337+ assert .Contains (s .T (), output , "7d:23%" )
338+ assert .Contains (s .T (), output , "🚦" )
339+ }
340+
341+ func (s * CCStatuslineTestSuite ) TestFormatStatuslineOutput_WithoutQuota () {
342+ output := formatStatuslineOutput ("claude-opus-4" , 1.23 , 4.56 , 3661 , 75.0 , "main" , false , nil , nil )
343+
344+ assert .Contains (s .T (), output , "🚦 -" )
345+ }
346+
347+ func (s * CCStatuslineTestSuite ) TestGetDaemonInfo_PropagatesRateLimitFields () {
348+ listener , err := net .Listen ("unix" , s .socketPath )
349+ assert .NoError (s .T (), err )
350+ s .listener = listener
351+
352+ fh := 0.45
353+ sd := 0.23
354+ go func () {
355+ conn , _ := listener .Accept ()
356+ defer conn .Close ()
357+
358+ var msg daemon.SocketMessage
359+ json .NewDecoder (conn ).Decode (& msg )
360+
361+ response := daemon.CCInfoResponse {
362+ TotalCostUSD : 1.23 ,
363+ TotalSessionSeconds : 100 ,
364+ TimeRange : "today" ,
365+ CachedAt : time .Now (),
366+ GitBranch : "main" ,
367+ FiveHourUtilization : & fh ,
368+ SevenDayUtilization : & sd ,
369+ }
370+ json .NewEncoder (conn ).Encode (response )
371+ }()
372+
373+ time .Sleep (10 * time .Millisecond )
374+
375+ config := model.ShellTimeConfig {
376+ SocketPath : s .socketPath ,
377+ }
378+
379+ result := getDaemonInfoWithFallback (context .Background (), config , "/some/path" )
380+
381+ assert .NotNil (s .T (), result .FiveHourUtilization )
382+ assert .NotNil (s .T (), result .SevenDayUtilization )
383+ assert .Equal (s .T (), 0.45 , * result .FiveHourUtilization )
384+ assert .Equal (s .T (), 0.23 , * result .SevenDayUtilization )
385+ }
386+
278387func TestCCStatuslineTestSuite (t * testing.T ) {
279388 suite .Run (t , new (CCStatuslineTestSuite ))
280389}
0 commit comments