github.com/angenalZZZ/gofunc@v0.0.0-20210507121333-48ff1be3917b/f/timer_test.go (about)

     1  package f_test
     2  
     3  import (
     4  	"fmt"
     5  	"testing"
     6  	"time"
     7  
     8  	"github.com/angenalZZZ/gofunc/f"
     9  )
    10  
    11  func ExampleTimer_Start() {
    12  	tw := f.NewTimer(time.Millisecond, 20)
    13  	tw.Start()
    14  	defer tw.Stop()
    15  
    16  	exitC := make(chan time.Time, 1)
    17  	tw.AfterFunc(time.Second, func() {
    18  		fmt.Println("The timer fires")
    19  		exitC <- time.Now().UTC()
    20  	})
    21  
    22  	<-exitC
    23  
    24  	// Output:
    25  	// The timer fires
    26  }
    27  
    28  func ExampleTimer_Stop() {
    29  	tw := f.NewTimer(time.Millisecond, 20)
    30  	tw.Start()
    31  	defer tw.Stop()
    32  
    33  	t := tw.AfterFunc(time.Second, func() {
    34  		fmt.Println("The timer fires")
    35  	})
    36  
    37  	<-time.After(900 * time.Millisecond)
    38  	// Stop the timer before it fires
    39  	t.Stop()
    40  
    41  	// Output:
    42  	//
    43  }
    44  
    45  func TestTimerBucket_Flush(t *testing.T) {
    46  	b := f.NewTimerBucket()
    47  
    48  	b.Add(&f.TimerElement{})
    49  	b.Add(&f.TimerElement{})
    50  	l1 := b.Timers.Len()
    51  	if l1 != 2 {
    52  		t.Fatalf("Got (%+v) != Want (%+v)", l1, 2)
    53  	}
    54  
    55  	b.Flush(func(*f.TimerElement) {})
    56  	l2 := b.Timers.Len()
    57  	if l2 != 0 {
    58  		t.Fatalf("Got (%+v) != Want (%+v)", l2, 0)
    59  	}
    60  }
    61  
    62  func TestTimer_AfterFunc(t *testing.T) {
    63  	tw := f.NewTimer(time.Millisecond, 20)
    64  	tw.Start()
    65  	defer tw.Stop()
    66  
    67  	durations := []time.Duration{
    68  		1 * time.Millisecond,
    69  		5 * time.Millisecond,
    70  		10 * time.Millisecond,
    71  		50 * time.Millisecond,
    72  		100 * time.Millisecond,
    73  		500 * time.Millisecond,
    74  		1 * time.Second,
    75  	}
    76  	for _, d := range durations {
    77  		t.Run("", func(t *testing.T) {
    78  			exitC := make(chan time.Time)
    79  
    80  			start := time.Now().UTC()
    81  			tw.AfterFunc(d, func() {
    82  				exitC <- time.Now().UTC()
    83  			})
    84  
    85  			got := (<-exitC).Truncate(time.Millisecond)
    86  			min := start.Add(d).Truncate(time.Millisecond)
    87  
    88  			err := 5 * time.Millisecond
    89  			if got.Before(min) || got.After(min.Add(err)) {
    90  				t.Errorf("Timer(%s) expiration: want [%s, %s], got %s", d, min, min.Add(err), got)
    91  			}
    92  		})
    93  	}
    94  }
    95  
    96  type anTimerScheduler struct {
    97  	intervals []time.Duration
    98  	current   int
    99  }
   100  
   101  func (s *anTimerScheduler) Next(prev time.Time) time.Time {
   102  	if s.current >= len(s.intervals) {
   103  		return time.Time{}
   104  	}
   105  	next := prev.Add(s.intervals[s.current])
   106  	s.current++
   107  	return next
   108  }
   109  
   110  func TestTimer_ScheduleFunc(t *testing.T) {
   111  	tw := f.NewTimer(time.Millisecond, 20)
   112  	tw.Start()
   113  	defer tw.Stop()
   114  
   115  	s := &anTimerScheduler{intervals: []time.Duration{
   116  		1 * time.Millisecond,   // start + 1ms
   117  		4 * time.Millisecond,   // start + 5ms
   118  		5 * time.Millisecond,   // start + 10ms
   119  		40 * time.Millisecond,  // start + 50ms
   120  		50 * time.Millisecond,  // start + 100ms
   121  		400 * time.Millisecond, // start + 500ms
   122  		500 * time.Millisecond, // start + 1s
   123  	}}
   124  
   125  	exitC := make(chan time.Time, len(s.intervals))
   126  
   127  	start := time.Now().UTC()
   128  	tw.ScheduleFunc(s, func() {
   129  		exitC <- time.Now().UTC()
   130  	})
   131  
   132  	accum := time.Duration(0)
   133  	for _, d := range s.intervals {
   134  		got := (<-exitC).Truncate(time.Millisecond)
   135  		accum += d
   136  		min := start.Add(accum).Truncate(time.Millisecond)
   137  
   138  		err := 5 * time.Millisecond
   139  		if got.Before(min) || got.After(min.Add(err)) {
   140  			t.Errorf("Timer(%s) expiration: want [%s, %s], got %s", accum, min, min.Add(err), got)
   141  		}
   142  	}
   143  }