├── .github
└── workflows
│ └── ci.yml
├── .gitignore
├── LICENSE
├── README.md
├── events.go
├── events_test.go
├── go.mod
└── logo.jpg
/.github/workflows/ci.yml:
--------------------------------------------------------------------------------
1 | name: CI
2 |
3 | on:
4 | push:
5 | branches: [master]
6 | pull_request:
7 | branches: [master]
8 |
9 | jobs:
10 |
11 | test:
12 | name: Test
13 | runs-on: ubuntu-latest
14 |
15 | strategy:
16 | matrix:
17 | go_version: [1.17]
18 | steps:
19 |
20 | - name: Set up Go 1.x
21 | uses: actions/setup-go@v2
22 | with:
23 | go-version: ${{ matrix.go_version }}
24 |
25 | - name: Check out code into the Go module directory
26 | uses: actions/checkout@v2
27 |
28 | - name: Test
29 | run: go test -v ./...
30 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_STORE
2 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2016-2022 Gerasimos Maropoulos
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | [](https://github.com/kataras/go-events/actions) [](https://gitter.im/events/community) [](https://iris-go.com/donate)
7 |
8 |
9 | Simple EventEmmiter for Go Programming Language. Inspired by [Nodejs EventEmitter](https://nodejs.org/api/events.html). For **Generics** support please wait until go1.18 stable is released, until then switch to [dev branch](https://github.com/kataras/go-events/tree/dev) instead.
10 |
11 | Overview
12 | ------------
13 | `New() EventEmmiter // New returns a new, empty, EventEmmiter`
14 |
15 |
16 | ```go
17 | // AddListener is an alias for .On(eventName, listener).
18 | AddListener(EventName, ...Listener)
19 | // Emit fires a particular event,
20 | // Synchronously calls each of the listeners registered for the event named
21 | // eventName, in the order they were registered,
22 | // passing the supplied arguments to each.
23 | Emit(EventName, ...interface{})
24 | // EventNames returns an array listing the events for which the emitter has registered listeners.
25 | // The values in the array will be strings.
26 | EventNames() []EventName
27 | // GetMaxListeners returns the max listeners for this emmiter
28 | // see SetMaxListeners
29 | GetMaxListeners() int
30 | // ListenerCount returns the length of all registered listeners to a particular event
31 | ListenerCount(EventName) int
32 | // Listeners returns a copy of the array of listeners for the event named eventName.
33 | Listeners(EventName) []Listener
34 | // On registers a particular listener for an event, func receiver parameter(s) is/are optional
35 | On(EventName, ...Listener)
36 | // Once adds a one time listener function for the event named eventName.
37 | // The next time eventName is triggered, this listener is removed and then invoked.
38 | Once(EventName, ...Listener)
39 | // RemoveAllListeners removes all listeners, or those of the specified eventName.
40 | // Note that it will remove the event itself.
41 | // Returns an indicator if event and listeners were found before the remove.
42 | RemoveAllListeners(EventName) bool
43 | // Clear removes all events and all listeners, restores Events to an empty value
44 | Clear()
45 | // SetMaxListeners obviously this function allows the MaxListeners
46 | // to be decrease or increase. Set to zero for unlimited
47 | SetMaxListeners(int)
48 | // Len returns the length of all registered events
49 | Len() int
50 | ```
51 |
52 |
53 | ```go
54 | import "github.com/kataras/go-events"
55 |
56 | // initialize a new EventEmmiter to use
57 | e := events.New()
58 |
59 | // register an event with name "my_event" and one listener
60 | e.On("my_event", func(payload ...interface{}) {
61 | message := payload[0].(string)
62 | print(message) // prints "this is my payload"
63 | })
64 |
65 | // fire the 'my_event' event
66 | e.Emit("my_event", "this is my payload")
67 |
68 | ```
69 |
70 | Default/global EventEmmiter
71 | ```go
72 |
73 | // register an event with name "my_event" and one listener to the global(package level) default EventEmmiter
74 | events.On("my_event", func(payload ...interface{}) {
75 | message := payload[0].(string)
76 | print(message) // prints "this is my payload"
77 | })
78 |
79 | // fire the 'my_event' event
80 | events.Emit("my_event", "this is my payload")
81 |
82 | ```
83 |
84 | Remove an event
85 |
86 | ```go
87 |
88 | events.On("my_event", func(payload ...interface{}) {
89 | // first listener...
90 | },func (payload ...interface{}){
91 | // second listener...
92 | })
93 |
94 | println(events.Len()) // prints 1
95 | println(events.ListenerCount("my_event")) // prints 2
96 |
97 | // Remove our event, when/if we don't need this or we want to clear all of its listeners
98 | events.RemoveAllListeners("my_event")
99 |
100 | println(events.Len()) // prints 0
101 | println(events.ListenerCount("my_event")) // prints 0
102 |
103 |
104 | ```
105 | Installation
106 | ------------
107 |
108 | The only requirement is the [Go Programming Language](https://golang.org/dl).
109 |
110 | ```bash
111 | $ go get -u github.com/kataras/go-events
112 | ```
113 |
114 |
115 | FAQ
116 | ------------
117 |
118 | Explore [these questions](https://github.com/kataras/go-events/issues?go-events=label%3Aquestion) or navigate to the [community chat][Chat].
119 |
120 | Versioning
121 | ------------
122 |
123 | Current: v0.0.3
124 |
125 | Read more about Semantic Versioning 2.0.0
126 |
127 | - http://semver.org/
128 | - https://en.wikipedia.org/wiki/Software_versioning
129 | - https://wiki.debian.org/UpstreamGuide#Releases_and_Versions
130 |
131 | Contributing
132 | ------------
133 |
134 | If you are interested in contributing to the go-events project, please prepare a PR.
135 |
136 | License
137 | ------------
138 |
139 | This project is licensed under the MIT License.
140 |
141 | License can be found [here](LICENSE).
142 |
--------------------------------------------------------------------------------
/events.go:
--------------------------------------------------------------------------------
1 | // Package events provides simple EventEmmiter support for Go Programming Language
2 | package events
3 |
4 | import (
5 | "log"
6 | "reflect"
7 | "sync"
8 | "sync/atomic"
9 | )
10 |
11 | const (
12 | // Version current version number
13 | Version = "0.0.3"
14 | // DefaultMaxListeners is the number of max listeners per event
15 | // default EventEmitters will print a warning if more than x listeners are
16 | // added to it. This is a useful default which helps finding memory leaks.
17 | // Defaults to 0, which means unlimited
18 | DefaultMaxListeners = 0
19 |
20 | // EnableWarning prints a warning when trying to add an event which it's len is equal to the maxListeners
21 | // Defaults to false, which means it does not prints a warning
22 | EnableWarning = false
23 | )
24 |
25 | type (
26 | // EventName is just a type of string, it's the event name
27 | EventName string
28 | // Listener is the type of a Listener, it's a func which receives any,optional, arguments from the caller/emmiter
29 | Listener func(...interface{})
30 | // Events the type for registered listeners, it's just a map[string][]func(...interface{})
31 | Events map[EventName][]Listener
32 |
33 | // EventEmmiter is the message/or/event manager
34 | EventEmmiter interface {
35 | // AddListener is an alias for .On(eventName, listener).
36 | AddListener(EventName, ...Listener)
37 | // Emit fires a particular event,
38 | // Synchronously calls each of the listeners registered for the event named
39 | // eventName, in the order they were registered,
40 | // passing the supplied arguments to each.
41 | Emit(EventName, ...interface{})
42 | // EventNames returns an array listing the events for which the emitter has registered listeners.
43 | // The values in the array will be strings.
44 | EventNames() []EventName
45 | // GetMaxListeners returns the max listeners for this emmiter
46 | // see SetMaxListeners
47 | GetMaxListeners() int
48 | // ListenerCount returns the length of all registered listeners to a particular event
49 | ListenerCount(EventName) int
50 | // Listeners returns a copy of the array of listeners for the event named eventName.
51 | Listeners(EventName) []Listener
52 | // On registers a particular listener for an event, func receiver parameter(s) is/are optional
53 | On(EventName, ...Listener)
54 | // Once adds a one time listener function for the event named eventName.
55 | // The next time eventName is triggered, this listener is removed and then invoked.
56 | Once(EventName, ...Listener)
57 | // RemoveAllListeners removes all listeners, or those of the specified eventName.
58 | // Note that it will remove the event itself.
59 | // Returns an indicator if event and listeners were found before the remove.
60 | RemoveAllListeners(EventName) bool
61 | // RemoveListener removes given listener from the event named eventName.
62 | // Returns an indicator whether listener was removed
63 | RemoveListener(EventName, Listener) bool
64 | // Clear removes all events and all listeners, restores Events to an empty value
65 | Clear()
66 | // SetMaxListeners obviously this function allows the MaxListeners
67 | // to be decrease or increase. Set to zero for unlimited
68 | SetMaxListeners(int)
69 | // Len returns the length of all registered events
70 | Len() int
71 | }
72 |
73 | emmiter struct {
74 | maxListeners int
75 | evtListeners Events
76 | mu sync.RWMutex
77 | }
78 | )
79 |
80 | // CopyTo copies the event listeners to an EventEmmiter
81 | func (e Events) CopyTo(emmiter EventEmmiter) {
82 | if e != nil && len(e) > 0 {
83 | // register the events to/with their listeners
84 | for evt, listeners := range e {
85 | if len(listeners) > 0 {
86 | emmiter.AddListener(evt, listeners...)
87 | }
88 | }
89 | }
90 | }
91 |
92 | // New returns a new, empty, EventEmmiter
93 | func New() EventEmmiter {
94 | return &emmiter{maxListeners: DefaultMaxListeners, evtListeners: Events{}}
95 | }
96 |
97 | var (
98 | _ EventEmmiter = &emmiter{}
99 | defaultEmmiter = New()
100 | )
101 |
102 | // AddListener is an alias for .On(eventName, listener).
103 | func AddListener(evt EventName, listener ...Listener) {
104 | defaultEmmiter.AddListener(evt, listener...)
105 | }
106 |
107 | func (e *emmiter) AddListener(evt EventName, listener ...Listener) {
108 | if len(listener) == 0 {
109 | return
110 | }
111 |
112 | e.mu.Lock()
113 | defer e.mu.Unlock()
114 |
115 | if e.evtListeners == nil {
116 | e.evtListeners = Events{}
117 | }
118 |
119 | listeners := e.evtListeners[evt]
120 |
121 | if e.maxListeners > 0 && len(listeners) == e.maxListeners {
122 | if EnableWarning {
123 | log.Printf(`(events) warning: possible EventEmitter memory '
124 | leak detected. %d listeners added. '
125 | Use emitter.SetMaxListeners(n int) to increase limit.`, len(listeners))
126 | }
127 | return
128 | }
129 |
130 | if listeners == nil {
131 | listeners = make([]Listener, e.maxListeners)
132 | }
133 |
134 | e.evtListeners[evt] = append(listeners, listener...)
135 | }
136 |
137 | // Emit fires a particular event,
138 | // Synchronously calls each of the listeners registered for the event named
139 | // eventName, in the order they were registered,
140 | // passing the supplied arguments to each.
141 | func Emit(evt EventName, data ...interface{}) {
142 | defaultEmmiter.Emit(evt, data...)
143 | }
144 |
145 | func (e *emmiter) Emit(evt EventName, data ...interface{}) {
146 | e.mu.RLock()
147 | defer e.mu.RUnlock()
148 |
149 | if e.evtListeners == nil {
150 | return // has no listeners to emit/speak yet
151 | }
152 | if listeners := e.evtListeners[evt]; len(listeners) > 0 {
153 | for i := range listeners {
154 | l := listeners[i]
155 | if l != nil {
156 | l(data...)
157 | }
158 | }
159 | }
160 | }
161 |
162 | // EventNames returns an array listing the events for which the emitter has registered listeners.
163 | // The values in the array will be strings.
164 | func EventNames() []EventName {
165 | return defaultEmmiter.EventNames()
166 | }
167 |
168 | func (e *emmiter) EventNames() []EventName {
169 | if e.evtListeners == nil || e.Len() == 0 {
170 | return nil
171 | }
172 |
173 | names := make([]EventName, 0, e.Len())
174 | i := 0
175 | for k := range e.evtListeners {
176 | names = append(names, k)
177 | i++
178 | }
179 | return names
180 | }
181 |
182 | // GetMaxListeners returns the max listeners for this emmiter
183 | // see SetMaxListeners
184 | func GetMaxListeners() int {
185 | return defaultEmmiter.GetMaxListeners()
186 | }
187 |
188 | func (e *emmiter) GetMaxListeners() int {
189 | return e.maxListeners
190 | }
191 |
192 | // ListenerCount returns the length of all registered listeners to a particular event
193 | func ListenerCount(evt EventName) int {
194 | return defaultEmmiter.ListenerCount(evt)
195 | }
196 |
197 | func (e *emmiter) ListenerCount(evt EventName) (count int) {
198 | e.mu.RLock()
199 | evtListeners := e.evtListeners[evt]
200 | e.mu.RUnlock()
201 |
202 | return e.listenerCount(evtListeners)
203 | }
204 |
205 | func (e *emmiter) listenerCount(evtListeners []Listener) (count int) {
206 | for _, l := range evtListeners {
207 | if l == nil {
208 | continue
209 | }
210 | count++
211 | }
212 |
213 | return
214 | }
215 |
216 | // Listeners returns a copy of the array of listeners for the event named eventName.
217 | func Listeners(evt EventName) []Listener {
218 | return defaultEmmiter.Listeners(evt)
219 | }
220 |
221 | func (e *emmiter) Listeners(evt EventName) []Listener {
222 | if e.evtListeners == nil {
223 | return nil
224 | }
225 | var listeners []Listener
226 | if evtListeners := e.evtListeners[evt]; evtListeners != nil {
227 | // do not pass any inactive/removed listeners(nil)
228 | for _, l := range evtListeners {
229 | if l == nil {
230 | continue
231 | }
232 |
233 | listeners = append(listeners, l)
234 | }
235 |
236 | if len(listeners) > 0 {
237 | return listeners
238 | }
239 | }
240 |
241 | return nil
242 | }
243 |
244 | // On registers a particular listener for an event, func receiver parameter(s) is/are optional
245 | func On(evt EventName, listener ...Listener) {
246 | defaultEmmiter.On(evt, listener...)
247 | }
248 |
249 | func (e *emmiter) On(evt EventName, listener ...Listener) {
250 | e.AddListener(evt, listener...)
251 | }
252 |
253 | // Once adds a one time listener function for the event named eventName.
254 | // The next time eventName is triggered, this listener is removed and then invoked.
255 | func Once(evt EventName, listener ...Listener) {
256 | defaultEmmiter.Once(evt, listener...)
257 | }
258 |
259 | type oneTimelistener struct {
260 | evt EventName
261 | emitter *emmiter
262 | listener Listener
263 | fired int32
264 | executeRef Listener
265 | }
266 |
267 | func (l *oneTimelistener) execute(vals ...interface{}) {
268 | if atomic.CompareAndSwapInt32(&l.fired, 0, 1) {
269 | l.listener(vals...)
270 | go l.emitter.RemoveListener(l.evt, l.executeRef)
271 | }
272 | }
273 |
274 | func (e *emmiter) Once(evt EventName, listener ...Listener) {
275 | if len(listener) == 0 {
276 | return
277 | }
278 |
279 | var modifiedListeners []Listener
280 |
281 | for _, listener := range listener {
282 | oneTime := &oneTimelistener{
283 | evt: evt,
284 | emitter: e,
285 | listener: listener,
286 | }
287 | oneTime.executeRef = oneTime.execute
288 | modifiedListeners = append(modifiedListeners, oneTime.executeRef)
289 | }
290 | e.AddListener(evt, modifiedListeners...)
291 | }
292 |
293 | // RemoveAllListeners removes all listeners, or those of the specified eventName.
294 | // Note that it will remove the event itself.
295 | // Returns an indicator if event and listeners were found before the remove.
296 | func RemoveAllListeners(evt EventName) bool {
297 | return defaultEmmiter.RemoveAllListeners(evt)
298 | }
299 |
300 | func (e *emmiter) RemoveAllListeners(evt EventName) bool {
301 | e.mu.Lock()
302 | defer e.mu.Unlock()
303 |
304 | if e.evtListeners == nil {
305 | return false // has nothing to remove
306 | }
307 |
308 | if listeners, ok := e.evtListeners[evt]; ok {
309 | count := e.listenerCount(listeners)
310 | delete(e.evtListeners, evt)
311 | return count > 0
312 | }
313 |
314 | return false
315 | }
316 |
317 | // RemoveListener removes the specified listener from the listener array for the event named eventName.
318 | func (e *emmiter) RemoveListener(evt EventName, listener Listener) bool {
319 | if e.evtListeners == nil {
320 | return false
321 | }
322 |
323 | if listener == nil {
324 | return false
325 | }
326 |
327 | e.mu.Lock()
328 | defer e.mu.Unlock()
329 |
330 | listeners := e.evtListeners[evt]
331 |
332 | if listeners == nil {
333 | return false
334 | }
335 |
336 | idx := -1
337 | listenerPointer := reflect.ValueOf(listener).Pointer()
338 |
339 | for index, item := range listeners {
340 | itemPointer := reflect.ValueOf(item).Pointer()
341 | if itemPointer == listenerPointer {
342 | idx = index
343 | break
344 | }
345 | }
346 |
347 | if idx < 0 {
348 | return false
349 | }
350 |
351 | var modifiedListeners []Listener = nil
352 |
353 | if len(listeners) > 1 {
354 | modifiedListeners = append(listeners[:idx], listeners[idx+1:]...)
355 | }
356 |
357 | e.evtListeners[evt] = modifiedListeners
358 |
359 | return true
360 | }
361 |
362 | // Clear removes all events and all listeners, restores Events to an empty value
363 | func Clear() {
364 | defaultEmmiter.Clear()
365 | }
366 |
367 | func (e *emmiter) Clear() {
368 | e.evtListeners = Events{}
369 | }
370 |
371 | // SetMaxListeners obviously this function allows the MaxListeners
372 | // to be decrease or increase. Set to zero for unlimited
373 | func SetMaxListeners(n int) {
374 | defaultEmmiter.SetMaxListeners(n)
375 | }
376 |
377 | func (e *emmiter) SetMaxListeners(n int) {
378 | if n < 0 {
379 | if EnableWarning {
380 | log.Printf("(events) warning: MaxListeners must be positive number, tried to set: %d", n)
381 | return
382 | }
383 | }
384 | e.maxListeners = n
385 | }
386 |
387 | // Len returns the length of all registered events
388 | func Len() int {
389 | return defaultEmmiter.Len()
390 | }
391 |
392 | func (e *emmiter) Len() int {
393 | if e.evtListeners == nil {
394 | return 0
395 | }
396 | return len(e.evtListeners)
397 | }
398 |
--------------------------------------------------------------------------------
/events_test.go:
--------------------------------------------------------------------------------
1 | package events
2 |
3 | import (
4 | "fmt"
5 | "testing"
6 | "time"
7 | )
8 |
9 | var testEvents = Events{
10 | "user_created": []Listener{
11 | func(payload ...interface{}) {
12 | fmt.Printf("A new User just created!\n")
13 | },
14 | func(payload ...interface{}) {
15 | fmt.Printf("A new User just created, *from second event listener\n")
16 | },
17 | },
18 | "user_joined": []Listener{func(payload ...interface{}) {
19 | user := payload[0].(string)
20 | room := payload[1].(string)
21 | fmt.Printf("%s joined to room: %s\n", user, room)
22 | }},
23 | "user_left": []Listener{func(payload ...interface{}) {
24 | user := payload[0].(string)
25 | room := payload[1].(string)
26 | fmt.Printf("%s left from the room: %s\n", user, room)
27 | }},
28 | }
29 |
30 | func createUser(user string) {
31 | Emit("user_created", user)
32 | }
33 |
34 | func joinUserTo(user string, room string) {
35 | Emit("user_joined", user, room)
36 | }
37 |
38 | func leaveFromRoom(user string, room string) {
39 | Emit("user_left", user, room)
40 | }
41 |
42 | func ExampleEvents() {
43 | // regiter our events to the default event emmiter
44 | for evt, listeners := range testEvents {
45 | On(evt, listeners...)
46 | }
47 |
48 | user := "user1"
49 | room := "room1"
50 |
51 | createUser(user)
52 | joinUserTo(user, room)
53 | leaveFromRoom(user, room)
54 |
55 | // Output:
56 | // A new User just created!
57 | // A new User just created, *from second event listener
58 | // user1 joined to room: room1
59 | // user1 left from the room: room1
60 | }
61 |
62 | func TestEvents(t *testing.T) {
63 | e := New()
64 | expectedPayload := "this is my payload"
65 |
66 | e.On("my_event", func(payload ...interface{}) {
67 | if len(payload) <= 0 {
68 | t.Fatal("Expected payload but got nothing")
69 | }
70 |
71 | if s, ok := payload[0].(string); !ok {
72 | t.Fatalf("Payload is not the correct type, got: %#v", payload[0])
73 | } else if s != expectedPayload {
74 | t.Fatalf("Eexpected %s, got: %s", expectedPayload, s)
75 | }
76 | })
77 |
78 | e.Emit("my_event", expectedPayload)
79 | if e.Len() != 1 {
80 | t.Fatalf("Length of the events is: %d, while expecting: %d", e.Len(), 1)
81 | }
82 |
83 | if e.Len() != 1 {
84 | t.Fatalf("Length of the listeners is: %d, while expecting: %d", e.ListenerCount("my_event"), 1)
85 | }
86 |
87 | e.RemoveAllListeners("my_event")
88 | if e.Len() != 0 {
89 | t.Fatalf("Length of the events is: %d, while expecting: %d", e.Len(), 0)
90 | }
91 |
92 | if e.Len() != 0 {
93 | t.Fatalf("Length of the listeners is: %d, while expecting: %d", e.ListenerCount("my_event"), 0)
94 | }
95 | }
96 |
97 | func TestEventsOnce(t *testing.T) {
98 | // on default
99 | Clear()
100 |
101 | var count = 0
102 | Once("my_event", func(payload ...interface{}) {
103 | if count > 0 {
104 | t.Fatalf("Once's listener fired more than one time! count: %d", count)
105 | }
106 | if payload[0] != "foo" {
107 | t.Fatalf("Once's listener payload is incorrect: %+v", payload)
108 | }
109 | count++
110 | })
111 |
112 | if l := ListenerCount("my_event"); l != 1 {
113 | t.Fatalf("Real event's listeners should be: %d but has: %d", 1, l)
114 | }
115 |
116 | if l := len(Listeners("my_event")); l != 1 {
117 | t.Fatalf("Real event's listeners (from Listeners) should be: %d but has: %d", 1, l)
118 | }
119 |
120 | for i := 0; i < 10; i++ {
121 | Emit("my_event", "foo")
122 | }
123 |
124 | time.Sleep(10 * time.Millisecond)
125 |
126 | if l := ListenerCount("my_event"); l > 0 {
127 | t.Fatalf("Real event's listeners length count should be: %d but has: %d", 0, l)
128 | }
129 |
130 | if l := len(Listeners("my_event")); l > 0 {
131 | t.Fatalf("Real event's listeners length count ( from Listeners) should be: %d but has: %d", 0, l)
132 | }
133 |
134 | }
135 |
136 | func TestRemoveListener(t *testing.T) {
137 | // on default
138 | e := New()
139 |
140 | var count = 0
141 | listener := func(payload ...interface{}) {
142 | if count > 1 {
143 | t.Fatal("Event listener should be removed")
144 | }
145 |
146 | count++
147 | }
148 |
149 | e.AddListener("my_event", listener)
150 | e.AddListener("my_event", func(payload ...interface{}) {})
151 | e.AddListener("another_event", func(payload ...interface{}) {})
152 |
153 | e.Emit("my_event")
154 |
155 | if e.RemoveListener("my_event", listener) != true {
156 | t.Fatal("Should return 'true' when removes found listener")
157 | }
158 |
159 | if e.RemoveListener("foo_bar", listener) != false {
160 | t.Fatal("Should return 'false' when removes nothing")
161 | }
162 |
163 | if e.Len() != 2 {
164 | t.Fatal("Length of all listeners must be 2")
165 | }
166 |
167 | if e.ListenerCount("my_event") != 1 {
168 | t.Fatal("Length of 'my_event' event listeners must be 1")
169 | }
170 |
171 | e.Emit("my_event")
172 | }
173 |
--------------------------------------------------------------------------------
/go.mod:
--------------------------------------------------------------------------------
1 | module github.com/kataras/go-events
2 |
3 | go 1.19
4 |
--------------------------------------------------------------------------------
/logo.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kataras/go-events/91567b08c4a76786bae41b5d344d50cf20db3b4d/logo.jpg
--------------------------------------------------------------------------------