Eventer, tests, gitlab CI, etc.

This commit is contained in:
2019-09-02 19:51:38 +05:00
parent a91daed960
commit ad2fbf7b97
58 changed files with 19630 additions and 1 deletions

10
eventer/errors.go Normal file
View File

@@ -0,0 +1,10 @@
package eventer
import (
// stdlib
"errors"
)
var (
EventNotFoundError = errors.New("event not found")
)

125
eventer/eventer_test.go Normal file
View File

@@ -0,0 +1,125 @@
package eventer
import (
// stdlib
"testing"
// other
"github.com/stretchr/testify/require"
)
func TestEventerInitializationAndShutdown(t *testing.T) {
Initialize()
require.NotNil(t, events)
Shutdown()
require.Nil(t, events)
require.False(t, eventsInitialized)
}
func TestEventerAddEventHandler(t *testing.T) {
Initialize()
require.NotNil(t, events)
handler := &EventHandler{
Command: "TEST",
Handler: func(data interface{}) interface{} {
return nil
},
}
AddEventHandler(handler)
hndl, exists := events[handler.Command]
require.Len(t, events, 1)
require.True(t, exists)
require.Equal(t, handler, hndl)
Shutdown()
require.Nil(t, events)
require.False(t, eventsInitialized)
}
func TestEventerAddEventHandlerAfterInitializationCompleted(t *testing.T) {
Initialize()
require.NotNil(t, events)
InitializeCompleted()
handler := &EventHandler{
Command: "TEST",
Handler: func(data interface{}) interface{} {
return nil
},
}
AddEventHandler(handler)
hndl, exists := events[handler.Command]
require.Len(t, events, 0)
require.False(t, exists)
require.Nil(t, hndl)
Shutdown()
require.Nil(t, events)
require.False(t, eventsInitialized)
}
func TestEventerLaunchExistingEvent(t *testing.T) {
Initialize()
require.NotNil(t, events)
handler := &EventHandler{
Command: "TEST",
Handler: func(data interface{}) interface{} {
return true
},
}
AddEventHandler(handler)
hndl, exists := events[handler.Command]
require.Len(t, events, 1)
require.True(t, exists)
require.Equal(t, handler, hndl)
data, err := LaunchEvent(handler.Command, nil)
if err != nil {
t.Fatal("Test event launch failed:", err.Error())
}
switch data.(type) {
case bool:
break
default:
t.Fatalf("Test event returned unacceptable data type: %T", data)
}
Shutdown()
require.Nil(t, events)
require.False(t, eventsInitialized)
}
func TestEventerLaunchNotExistingEvent(t *testing.T) {
Initialize()
require.NotNil(t, events)
handler := &EventHandler{
Command: "TEST",
Handler: func(data interface{}) interface{} {
return true
},
}
AddEventHandler(handler)
hndl, exists := events[handler.Command]
require.Len(t, events, 1)
require.True(t, exists)
require.Equal(t, handler, hndl)
data, err := LaunchEvent(handler.Command+"notexisting", nil)
if err == nil {
t.Fatal("LaunchEvent() returned empty error!")
}
require.Nil(t, data)
Shutdown()
require.Nil(t, events)
require.False(t, eventsInitialized)
}

64
eventer/exported.go Normal file
View File

@@ -0,0 +1,64 @@
package eventer
import (
// stdlib
"log"
)
var (
// List of known event handler.
// Format:
// - commands/CMDNAME - base handler for command. This what
// networker will execute on any new command. Case-insensitive.
// - internals/CMDNAME - all other internal things like database
// access.
// This map will not be changed after gonewsd initialization is
// complete.
events map[string]*EventHandler
// Flag that indicates that we have completed events mapping
// initialization.
// RWMutex can be here, but we also need to write to log if we have
// completed initialization.
eventsInitialized bool
)
// Initialize initializes package.
func Initialize() {
log.Println("Initializing event handler...")
events = make(map[string]*EventHandler)
}
// InitializeCompleted sets eventsInitialized bool to true to avoid
// all further events mapping changes.
func InitializeCompleted() {
eventsInitialized = true
log.Println("Events initialization completed")
}
// AddEventHandler adds event handler to a list of known handlers.
func AddEventHandler(event *EventHandler) {
if !eventsInitialized {
events[event.Command] = event
} else {
log.Println("Can't add event '" + event.Command + "' to a list of known events - events mapping initialization already completed, no more changes allowed.")
}
}
// LaunchEvent launches desired event in synchronous manner.
func LaunchEvent(eventName string, data interface{}) (interface{}, error) {
handler, exists := events[eventName]
if !exists {
return nil, EventNotFoundError
}
returnedData := handler.Handler(data)
return returnedData, nil
}
// Shutdown just nullifies eventer map.
// Useful for testing and, maybe, reload.
func Shutdown() {
events = nil
eventsInitialized = false
}

10
eventer/handler.go Normal file
View File

@@ -0,0 +1,10 @@
package eventer
// EventHandler represents generic event handler.
type EventHandler struct {
// Command is a command name we will use for event registering,
// showing help, etc.
Command string
// Handler if a function that will handle this command.
Handler func(data interface{}) interface{}
}