@@ -14,6 +14,7 @@ import (
1414// during a test, triggering any timers or tickers automatically. 
1515type  Mock  struct  {
1616	tb        testing.TB 
17+ 	logger    Logger 
1718	mu        sync.Mutex 
1819	testOver  bool 
1920
@@ -199,7 +200,7 @@ func (m *Mock) matchCallLocked(c *apiCall) {
199200		}
200201	}
201202	if  ! m .testOver  {
202- 		m .tb .Logf ("Mock Clock - %s call, matched %d traps" , c , len (traps ))
203+ 		m .logger .Logf ("Mock Clock - %s call, matched %d traps" , c , len (traps ))
203204	}
204205	if  len (traps ) ==  0  {
205206		return 
@@ -265,7 +266,7 @@ func (m *Mock) Advance(d time.Duration) AdvanceWaiter {
265266	w  :=  AdvanceWaiter {tb : m .tb , ch : make (chan  struct {})}
266267	m .mu .Lock ()
267268	if  ! m .testOver  {
268- 		m .tb .Logf ("Mock Clock - Advance(%s)" , d )
269+ 		m .logger .Logf ("Mock Clock - Advance(%s)" , d )
269270	}
270271	fin  :=  m .cur .Add (d )
271272	// nextTime.IsZero implies no events scheduled. 
@@ -315,7 +316,7 @@ func (m *Mock) Set(t time.Time) AdvanceWaiter {
315316	w  :=  AdvanceWaiter {tb : m .tb , ch : make (chan  struct {})}
316317	m .mu .Lock ()
317318	if  ! m .testOver  {
318- 		m .tb .Logf ("Mock Clock - Set(%s)" , t )
319+ 		m .logger .Logf ("Mock Clock - Set(%s)" , t )
319320	}
320321	if  t .Before (m .cur ) {
321322		defer  close (w .ch )
@@ -354,7 +355,7 @@ func (m *Mock) Set(t time.Time) AdvanceWaiter {
354355func  (m  * Mock ) AdvanceNext () (time.Duration , AdvanceWaiter ) {
355356	m .mu .Lock ()
356357	if  ! m .testOver  {
357- 		m .tb .Logf ("Mock Clock - AdvanceNext()" )
358+ 		m .logger .Logf ("Mock Clock - AdvanceNext()" )
358359	}
359360	m .tb .Helper ()
360361	w  :=  AdvanceWaiter {tb : m .tb , ch : make (chan  struct {})}
@@ -445,7 +446,7 @@ func (m *Mock) newTrap(fn clockFunction, tags []string) *Trap {
445446	m .mu .Lock ()
446447	defer  m .mu .Unlock ()
447448	if  ! m .testOver  {
448- 		m .tb .Logf ("Mock Clock - Trap %s(..., %v)" , fn , tags )
449+ 		m .logger .Logf ("Mock Clock - Trap %s(..., %v)" , fn , tags )
449450	}
450451	tr  :=  & Trap {
451452		fn :    fn ,
@@ -458,6 +459,18 @@ func (m *Mock) newTrap(fn clockFunction, tags []string) *Trap {
458459	return  tr 
459460}
460461
462+ // WithLogger replaces the default testing logger with a custom one. 
463+ // 
464+ // This can be used to discard log messages with: 
465+ // 
466+ //	quartz.NewMock(t).WithLogger(quartz.NoOpLogger) 
467+ func  (m  * Mock ) WithLogger (l  Logger ) * Mock  {
468+ 	m .mu .Lock ()
469+ 	defer  m .mu .Unlock ()
470+ 	m .logger  =  l 
471+ 	return  m 
472+ }
473+ 
461474// NewMock creates a new Mock with the time set to midnight UTC on Jan 1, 2024. 
462475// You may re-set the time earlier than this, but only before timers or tickers 
463476// are created. 
@@ -467,14 +480,15 @@ func NewMock(tb testing.TB) *Mock {
467480		panic (err )
468481	}
469482	m  :=  & Mock {
470- 		tb :  tb ,
471- 		cur : cur ,
483+ 		tb :     tb ,
484+ 		logger : tb ,
485+ 		cur :    cur ,
472486	}
473487	tb .Cleanup (func () {
474488		m .mu .Lock ()
475489		defer  m .mu .Unlock ()
476490		m .testOver  =  true 
477- 		tb .Logf ("Mock Clock - test cleanup; will no longer log clock events" )
491+ 		m . logger .Logf ("Mock Clock - test cleanup; will no longer log clock events" )
478492	})
479493	return  m 
480494}
@@ -806,3 +820,16 @@ func (t *Trap) MustWait(ctx context.Context) *Call {
806820	}
807821	return  c 
808822}
823+ 
824+ type  Logger  interface  {
825+ 	Log (args  ... any )
826+ 	Logf (format  string , args  ... any )
827+ }
828+ 
829+ // NoOpLogger is a Logger that discards all log messages. 
830+ var  NoOpLogger  Logger  =  noOpLogger {}
831+ 
832+ type  noOpLogger  struct {}
833+ 
834+ func  (noOpLogger ) Log (args  ... any )                 {}
835+ func  (noOpLogger ) Logf (format  string , args  ... any ) {}
0 commit comments