-
Notifications
You must be signed in to change notification settings - Fork 1
/
subscriber_test.go
74 lines (62 loc) · 2.23 KB
/
subscriber_test.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
package signal_test
import (
"os"
"os/signal"
"testing"
"time"
"unsafe"
"bou.ke/monkey"
"github.com/stretchr/testify/assert"
sig "github.com/gol4ng/signal"
)
func TestSubscribe(t *testing.T) {
var signalChan chan<- os.Signal
var subscribedSignals = []os.Signal{os.Interrupt, os.Kill}
var realSignal = os.Interrupt
var callbackCalled = false
monkey.Patch(signal.Notify, func(c chan<- os.Signal, signals ...os.Signal) {
// get subscriber internal chan in order to simulate signal receive
signalChan = c
for _, s := range subscribedSignals {
assert.Contains(t, signals, s)
}
})
defer monkey.UnpatchAll()
sig.Subscribe(func(signal os.Signal) {
assert.Equal(t, realSignal, signal, "wrong signal ingested by subscriber.")
callbackCalled = true
}, subscribedSignals...)
// simulate signal receive
signalChan <- realSignal
// wait for goroutine callback func fulfilment (@see subscriber.go `go callback(subscribedSignals)`)
time.Sleep(1 * time.Millisecond)
assert.True(t, callbackCalled, "callback func should be called.")
}
func TestUnSubscribe(t *testing.T) {
var signalChan chan<- os.Signal
var subscribedSignal = os.Interrupt
var stopCalled = false
var callbackCalled = false
monkey.Patch(signal.Notify, func(c chan<- os.Signal, signals ...os.Signal) {
// get subscriber internal chan in order to simulate signal receive
signalChan = c
assert.Equal(t, subscribedSignal, signals[0])
})
monkey.Patch(signal.Stop, func(c chan<- os.Signal) {
assert.Equal(t, signalChan, c)
stopCalled = true
})
defer monkey.UnpatchAll()
unsubscribeFunc := sig.Subscribe(func(signal os.Signal) {
t.Error("callback func must not be called.")
callbackCalled = true
}, subscribedSignal)
unsubscribeFunc()
// wait for goroutine signal.Stop func call (@see subscriber.go `case <-stopChan:`)
time.Sleep(1 * time.Millisecond)
// `signalChan` is a bidirectional chan as it is equal to the `subscriber signalChan` value
_, ok := <-*(*chan os.Signal)(unsafe.Pointer(&signalChan))
assert.False(t, ok, "signal channel should be closed.")
assert.True(t, stopCalled, "`signal.Stop` should be called when `unsubscribeFunc` is called.")
assert.False(t, callbackCalled, "callback func should not be called as `unsubscribeFunc` is called.")
}