github.com/haraldrudell/parl@v0.4.176/closable-chan_test.go (about)

     1  /*
     2  © 2022–present Harald Rudell <harald.rudell@gmail.com> (https://haraldrudell.github.io/haraldrudell/)
     3  ISC License
     4  */
     5  
     6  package parl
     7  
     8  import (
     9  	"sync"
    10  	"testing"
    11  )
    12  
    13  func TestClosableChanClosing(t *testing.T) {
    14  
    15  	// Closer can be invoked multiple times
    16  	ch := make(chan struct{})
    17  	cl := NewClosableChan(ch)
    18  	ch2 := cl.Ch()
    19  	if ch2 != ch {
    20  		t.Errorf("NewCloser Ch bad")
    21  	}
    22  	if cl.IsClosed() {
    23  		t.Errorf("NewCloser isClosed true")
    24  	}
    25  	// first close
    26  	didClose, err := cl.Close()
    27  	if err != nil {
    28  		t.Errorf("cl.Close err %T %[1]v", err)
    29  	}
    30  	if !didClose {
    31  		t.Errorf("cl.Close didClose false")
    32  	}
    33  	// second close
    34  	didClose, err = cl.Close()
    35  	if err != nil {
    36  		t.Errorf("cl.Close err %T %[1]v", err)
    37  	}
    38  	if didClose {
    39  		t.Errorf("cl.Close didClose true")
    40  	}
    41  	if !cl.IsClosed() {
    42  		t.Errorf("NewCloser isClosed true")
    43  	}
    44  
    45  	// does not panic
    46  	{
    47  		ch := make(chan struct{})
    48  		close(ch)
    49  		cl := NewClosableChan(ch)
    50  		var err2 error
    51  		didClose, err := cl.Close(&err2)
    52  		if err == nil {
    53  			t.Errorf("cl.Close no err")
    54  		}
    55  		if err2 == nil {
    56  			t.Errorf("cl.Close no err2")
    57  		}
    58  		if !didClose {
    59  			t.Errorf("cl.Close didClose false")
    60  		}
    61  	}
    62  }
    63  
    64  func TestByValue(t *testing.T) {
    65  	var ch ClosableChan[int]
    66  	_ = &ch
    67  
    68  	// A sync.Mutex field cannot be passed by value
    69  	// func passes lock by value: github.com/haraldrudell/parl.ClosableChan[int] contains sync.Mutex
    70  	/*
    71  		f := func(c ClosableChan[int]) {}
    72  		f(ch)
    73  	*/
    74  
    75  	// instead, pass by reference
    76  	g := func(c *ClosableChan[int]) {}
    77  	g(&ch)
    78  
    79  	// sync.Once can be passed by value
    80  	// 230120 sync.Once can no longer be passed by value
    81  	//var o sync.Once
    82  	//fo := func(p sync.Once) {}
    83  	//fo(o)
    84  
    85  	// sync.WaitGroup unlike previously by 1.19.3 not be passed by value
    86  	//var wg sync.WaitGroup
    87  
    88  	// func passes lock by value: sync.WaitGroup contains sync.noCopy
    89  	//fw := func(g sync.WaitGroup) {}
    90  
    91  	// call of fw copies lock value: sync.WaitGroup contains sync.noCopy
    92  	//fw(wg)
    93  
    94  	// *sync.Cond can be pased by value
    95  	c := sync.NewCond(&sync.Mutex{})
    96  	fc := func(d *sync.Cond) {}
    97  	fc(c)
    98  
    99  }