@@ -16,13 +16,9 @@ vi.mock("vscode", () => ({
1616} ) ) ;
1717
1818import * as vscode from "vscode" ;
19- import {
20- ArrayAdapter ,
21- LogLevel ,
22- NoOpAdapter ,
23- OutputChannelAdapter ,
24- logger ,
25- } from "./logger" ;
19+ import { ArrayAdapter , LogLevel , NoOpAdapter , logger } from "./logger" ;
20+ import { OutputChannelAdapter } from "./logging" ;
21+ import { TestConfigProvider } from "./test" ;
2622
2723describe ( "Logger" , ( ) => {
2824 beforeEach ( ( ) => {
@@ -191,79 +187,56 @@ describe("Logger", () => {
191187
192188 describe ( "Configuration" , ( ) => {
193189 it ( "should read verbose setting on initialization" , ( ) => {
194- const mockConfig = {
195- get : vi . fn ( ) . mockReturnValue ( true ) ,
196- } ;
197- vi . mocked ( vscode . workspace . getConfiguration ) . mockReturnValue (
198- mockConfig as unknown as vscode . WorkspaceConfiguration ,
199- ) ;
200-
201- logger . reset ( ) ; // Reset triggers re-initialization
202-
203- expect ( vscode . workspace . getConfiguration ) . toHaveBeenCalledWith ( "coder" ) ;
204- expect ( mockConfig . get ) . toHaveBeenCalledWith ( "verbose" , false ) ;
205- } ) ;
206-
207- it ( "should update log level when configuration changes" , ( ) => {
208- let configChangeCallback : (
209- e : vscode . ConfigurationChangeEvent ,
210- ) => void = ( ) => { } ;
211- const mockDisposable = { dispose : vi . fn ( ) } ;
212-
213- vi . mocked ( vscode . workspace . onDidChangeConfiguration ) . mockImplementation (
214- ( callback ) => {
215- configChangeCallback = callback ;
216- return mockDisposable as vscode . Disposable ;
217- } ,
218- ) ;
190+ const adapter = new ArrayAdapter ( ) ;
191+ const configProvider = new TestConfigProvider ( ) ;
219192
220- const mockConfig = {
221- get : vi . fn ( ) . mockReturnValue ( false ) ,
222- } ;
223- vi . mocked ( vscode . workspace . getConfiguration ) . mockReturnValue (
224- mockConfig as unknown as vscode . WorkspaceConfiguration ,
225- ) ;
193+ logger . setAdapter ( adapter ) ;
194+ logger . setConfigProvider ( configProvider ) ;
226195
227- logger . reset ( ) ;
196+ // Test with verbose = false
197+ configProvider . setVerbose ( false ) ;
198+ logger . debug ( "Debug message" ) ;
199+ logger . info ( "Info message" ) ;
228200
229- // Change config to verbose
230- mockConfig . get . mockReturnValue ( true ) ;
231- configChangeCallback ( {
232- affectsConfiguration : ( section : string ) => section === "coder.verbose" ,
233- } as vscode . ConfigurationChangeEvent ) ;
201+ let logs = adapter . getSnapshot ( ) ;
202+ expect ( logs . length ) . toBe ( 1 ) ; // Only info should be logged
203+ expect ( logs [ 0 ] ) . toContain ( "Info message" ) ;
234204
235- // Verify it reads the new config
236- expect ( mockConfig . get ) . toHaveBeenCalledWith ( "verbose" , false ) ;
205+ // Clear and test with verbose = true
206+ adapter . clear ( ) ;
207+ configProvider . setVerbose ( true ) ;
208+ logger . debug ( "Debug message 2" ) ;
209+ logger . info ( "Info message 2" ) ;
210+
211+ logs = adapter . getSnapshot ( ) ;
212+ expect ( logs . length ) . toBe ( 2 ) ; // Both should be logged
213+ expect ( logs [ 0 ] ) . toContain ( "Debug message 2" ) ;
214+ expect ( logs [ 1 ] ) . toContain ( "Info message 2" ) ;
237215 } ) ;
238216
239- it ( "should ignore non-coder.verbose configuration changes" , ( ) => {
240- let configChangeCallback : (
241- e : vscode . ConfigurationChangeEvent ,
242- ) => void = ( ) => { } ;
243- vi . mocked ( vscode . workspace . onDidChangeConfiguration ) . mockImplementation (
244- ( callback ) => {
245- configChangeCallback = callback ;
246- return { dispose : vi . fn ( ) } as unknown as vscode . Disposable ;
247- } ,
248- ) ;
217+ it ( "should update log level when configuration changes" , ( ) => {
218+ const adapter = new ArrayAdapter ( ) ;
219+ const configProvider = new TestConfigProvider ( ) ;
249220
250- const mockConfig = {
251- get : vi . fn ( ) . mockReturnValue ( false ) ,
252- } ;
253- vi . mocked ( vscode . workspace . getConfiguration ) . mockReturnValue (
254- mockConfig as unknown as vscode . WorkspaceConfiguration ,
255- ) ;
221+ logger . setAdapter ( adapter ) ;
222+ logger . setConfigProvider ( configProvider ) ;
256223
257- logger . reset ( ) ;
258- mockConfig . get . mockClear ( ) ;
224+ // Start with verbose = false
225+ configProvider . setVerbose ( false ) ;
226+ logger . debug ( "Debug 1" ) ;
227+ logger . info ( "Info 1" ) ;
228+
229+ let logs = adapter . getSnapshot ( ) ;
230+ expect ( logs . length ) . toBe ( 1 ) ; // Only info
259231
260- // Trigger non-verbose config change
261- configChangeCallback ( {
262- affectsConfiguration : ( section : string ) => section === "other.setting" ,
263- } as vscode . ConfigurationChangeEvent ) ;
232+ // Change to verbose = true
233+ adapter . clear ( ) ;
234+ configProvider . setVerbose ( true ) ;
235+ logger . debug ( "Debug 2" ) ;
236+ logger . info ( "Info 2" ) ;
264237
265- // Should not re-read config
266- expect ( mockConfig . get ) . not . toHaveBeenCalled ( ) ;
238+ logs = adapter . getSnapshot ( ) ;
239+ expect ( logs . length ) . toBe ( 2 ) ; // Both logged
267240 } ) ;
268241 } ) ;
269242
@@ -345,15 +318,33 @@ describe("Logger", () => {
345318 } ) ;
346319
347320 it ( "should dispose configuration listener on reset" , ( ) => {
348- const mockDisposable = { dispose : vi . fn ( ) } ;
349- vi . mocked ( vscode . workspace . onDidChangeConfiguration ) . mockReturnValue (
350- mockDisposable as unknown as vscode . Disposable ,
351- ) ;
321+ const adapter = new ArrayAdapter ( ) ;
322+ const configProvider = new TestConfigProvider ( ) ;
323+
324+ logger . setAdapter ( adapter ) ;
325+ logger . setConfigProvider ( configProvider ) ;
326+
327+ // Track if dispose was called
328+ let disposed = false ;
329+ const originalOnVerboseChange =
330+ configProvider . onVerboseChange . bind ( configProvider ) ;
331+ configProvider . onVerboseChange = ( callback : ( ) => void ) => {
332+ const result = originalOnVerboseChange ( callback ) ;
333+ return {
334+ dispose : ( ) => {
335+ disposed = true ;
336+ result . dispose ( ) ;
337+ } ,
338+ } ;
339+ } ;
352340
341+ // Re-set config provider to register the wrapped listener
342+ logger . setConfigProvider ( configProvider ) ;
343+
344+ // Reset should dispose the listener
353345 logger . reset ( ) ;
354- logger . reset ( ) ; // Second reset should dispose the first listener
355346
356- expect ( mockDisposable . dispose ) . toHaveBeenCalled ( ) ;
347+ expect ( disposed ) . toBe ( true ) ;
357348 } ) ;
358349 } ) ;
359350
@@ -364,7 +355,12 @@ describe("Logger", () => {
364355 clear : vi . fn ( ) ,
365356 } as unknown as vscode . OutputChannel ;
366357
367- logger . initialize ( mockChannel ) ;
358+ const adapter = new OutputChannelAdapter ( mockChannel ) ;
359+ logger . initialize ( adapter ) ;
360+
361+ // Set up config provider for test
362+ const configProvider = new TestConfigProvider ( ) ;
363+ logger . setConfigProvider ( configProvider ) ;
368364
369365 // Verify we can log after initialization
370366 logger . info ( "Test message" ) ;
@@ -373,9 +369,10 @@ describe("Logger", () => {
373369
374370 it ( "should throw if already initialized" , ( ) => {
375371 const mockChannel = { } as vscode . OutputChannel ;
376- logger . initialize ( mockChannel ) ;
372+ const adapter = new OutputChannelAdapter ( mockChannel ) ;
373+ logger . initialize ( adapter ) ;
377374
378- expect ( ( ) => logger . initialize ( mockChannel ) ) . toThrow (
375+ expect ( ( ) => logger . initialize ( adapter ) ) . toThrow (
379376 "Logger already initialized" ,
380377 ) ;
381378 } ) ;
0 commit comments