github.com/naoina/kocha@v0.7.1-0.20171129072645-78c7a531f799/event/event_test.go (about)

     1  package event_test
     2  
     3  import (
     4  	"fmt"
     5  	"reflect"
     6  	"strings"
     7  	"testing"
     8  	"time"
     9  
    10  	"github.com/naoina/kocha/event"
    11  )
    12  
    13  const (
    14  	queueName = "fakeQueue"
    15  )
    16  
    17  var stopped []struct{}
    18  
    19  type fakeQueue struct {
    20  	c    chan string
    21  	done chan struct{}
    22  }
    23  
    24  func (q *fakeQueue) New(n int) event.Queue {
    25  	return q
    26  }
    27  
    28  func (q *fakeQueue) Enqueue(data string) error {
    29  	q.c <- data
    30  	return nil
    31  }
    32  
    33  func (q *fakeQueue) Dequeue() (string, error) {
    34  	select {
    35  	case data := <-q.c:
    36  		return data, nil
    37  	case <-q.done:
    38  		return "", event.ErrDone
    39  	}
    40  }
    41  
    42  func (q *fakeQueue) Stop() {
    43  	stopped = append(stopped, struct{}{})
    44  	close(q.done)
    45  }
    46  
    47  func TestDefaultEvent(t *testing.T) {
    48  	actual := event.DefaultEvent
    49  	expect := event.New()
    50  	if !reflect.DeepEqual(actual, expect) {
    51  		t.Errorf(`DefaultEvent => %#v; want %#v`, actual, expect)
    52  	}
    53  }
    54  
    55  func TestEvent_AddHandler(t *testing.T) {
    56  	e := event.New()
    57  	e.RegisterQueue(queueName, &fakeQueue{c: make(chan string), done: make(chan struct{})})
    58  
    59  	handlerName := "testAddHandler"
    60  	for _, v := range []struct {
    61  		queueName string
    62  		expect    error
    63  	}{
    64  		{"unknownQueue", fmt.Errorf("kocha: event: queue `unknownQueue' isn't registered")},
    65  		{queueName, nil},
    66  		{queueName, nil}, // testcase for override.
    67  	} {
    68  		actual := e.AddHandler(handlerName, v.queueName, func(args ...interface{}) error {
    69  			return nil
    70  		})
    71  		expect := v.expect
    72  		if !reflect.DeepEqual(actual, expect) {
    73  			t.Errorf("AddHandler(%q, %q, func) => %#v, want %#v", handlerName, v.queueName, actual, expect)
    74  		}
    75  	}
    76  }
    77  
    78  func TestEvent_Trigger(t *testing.T) {
    79  	e := event.New()
    80  	e.RegisterQueue(queueName, &fakeQueue{c: make(chan string), done: make(chan struct{})})
    81  	e.Start()
    82  	defer e.Stop()
    83  
    84  	handlerName := "unknownHandler"
    85  	var expect interface{} = fmt.Errorf("kocha: event: handler `unknownHandler' isn't added")
    86  	if err := e.Trigger(handlerName); err == nil {
    87  		t.Errorf("Trigger(%q) => %#v, want %#v", handlerName, err, expect)
    88  	}
    89  
    90  	handlerName = "testTrigger"
    91  	var actual string
    92  	timer := make(chan struct{})
    93  	if err := e.AddHandler(handlerName, queueName, func(args ...interface{}) error {
    94  		defer func() {
    95  			timer <- struct{}{}
    96  		}()
    97  		actual += fmt.Sprintf("|call %s(%v)", handlerName, args)
    98  		return nil
    99  	}); err != nil {
   100  		t.Fatal(err)
   101  	}
   102  	for i := 1; i <= 2; i++ {
   103  		if err := e.Trigger(handlerName); err != nil {
   104  			t.Errorf("Trigger(%#v) => %#v, want nil", handlerName, err)
   105  		}
   106  		select {
   107  		case <-timer:
   108  		case <-time.After(3 * time.Second):
   109  			t.Fatalf("Trigger(%q) has try to call handler but hasn't been called within 3 seconds", handlerName)
   110  		}
   111  		expected := strings.Repeat("|call testTrigger([])", i)
   112  		if !reflect.DeepEqual(actual, expected) {
   113  			t.Errorf("Trigger(%q) has try to call handler, actual => %#v, want %#v", handlerName, actual, expected)
   114  		}
   115  	}
   116  
   117  	handlerName = "testTriggerWithArgs"
   118  	actual = ""
   119  	if err := e.AddHandler(handlerName, queueName, func(args ...interface{}) error {
   120  		defer func() {
   121  			timer <- struct{}{}
   122  		}()
   123  		actual += fmt.Sprintf("|call %s(%v)", handlerName, args)
   124  		return nil
   125  	}); err != nil {
   126  		t.Fatal(err)
   127  	}
   128  	for i := 1; i <= 2; i++ {
   129  		if err := e.Trigger(handlerName, 1, true, "arg"); err != nil {
   130  			t.Errorf("Trigger(%q) => %#v, want nil", handlerName, err)
   131  		}
   132  		select {
   133  		case <-timer:
   134  		case <-time.After(3 * time.Second):
   135  			t.Fatalf("Trigger(%q) has try to call handler but hasn't been called within 3 seconds", handlerName)
   136  		}
   137  		expected := strings.Repeat("|call testTriggerWithArgs([1 true arg])", i)
   138  		if !reflect.DeepEqual(actual, expected) {
   139  			t.Errorf("Trigger(%q) has try to call handler, actual => %#v, want %#v", handlerName, actual, expected)
   140  		}
   141  	}
   142  
   143  	handlerName = "testTriggerWithMultipleHandlers"
   144  	actual = ""
   145  	actual2 := ""
   146  	timer2 := make(chan struct{})
   147  	if err := e.AddHandler(handlerName, queueName, func(args ...interface{}) error {
   148  		defer func() {
   149  			timer <- struct{}{}
   150  		}()
   151  		actual += fmt.Sprintf("|call1 %s(%v)", handlerName, args)
   152  		return nil
   153  	}); err != nil {
   154  		t.Fatal(err)
   155  	}
   156  	if err := e.AddHandler(handlerName, queueName, func(args ...interface{}) error {
   157  		defer func() {
   158  			timer2 <- struct{}{}
   159  		}()
   160  		actual2 += fmt.Sprintf("|call2 %s(%v)", handlerName, args)
   161  		return nil
   162  	}); err != nil {
   163  		t.Fatal(err)
   164  	}
   165  	for i := 1; i <= 2; i++ {
   166  		if err := e.Trigger(handlerName); err != nil {
   167  			t.Errorf("Trigger(%q) => %#v, want nil", handlerName, err)
   168  		}
   169  		select {
   170  		case <-timer:
   171  		case <-time.After(3 * time.Second):
   172  			t.Fatalf("Trigger(%q) has try to call handler but hasn't been called within 3 seconds", handlerName)
   173  		}
   174  		expected := strings.Repeat("|call1 testTriggerWithMultipleHandlers([])", i)
   175  		if !reflect.DeepEqual(actual, expected) {
   176  			t.Errorf("Trigger(%q) has try to call handler, actual => %#v, want %#v", handlerName, actual, expected)
   177  		}
   178  		select {
   179  		case <-timer2:
   180  		case <-time.After(3 * time.Second):
   181  			t.Fatalf("Trigger(%q) has try to call handler but hasn't been called within 3 seconds", handlerName)
   182  		}
   183  		expected = strings.Repeat("|call2 testTriggerWithMultipleHandlers([])", i)
   184  		if !reflect.DeepEqual(actual2, expected) {
   185  			t.Errorf("Trigger(%q) has try to call handler, actual => %#v, want %#v", handlerName, actual2, expected)
   186  		}
   187  	}
   188  }
   189  
   190  func TestEvent_RegisterQueue(t *testing.T) {
   191  	e := event.New()
   192  	for _, v := range []struct {
   193  		name   string
   194  		queue  event.Queue
   195  		expect error
   196  	}{
   197  		{"test_queue", nil, fmt.Errorf("kocha: event: Register queue is nil")},
   198  		{"test_queue", &fakeQueue{}, nil},
   199  		{"test_queue", &fakeQueue{}, fmt.Errorf("kocha: event: Register queue `test_queue' is already registered")},
   200  	} {
   201  		actual := e.RegisterQueue(v.name, v.queue)
   202  		expect := v.expect
   203  		if !reflect.DeepEqual(actual, expect) {
   204  			t.Errorf(`Event.RegisterQueue(%q, %#v) => %#v; want %#v`, v.name, v.queue, actual, expect)
   205  		}
   206  	}
   207  }
   208  
   209  func TestEvent_Stop(t *testing.T) {
   210  	e := event.New()
   211  	e.RegisterQueue(queueName, &fakeQueue{c: make(chan string), done: make(chan struct{})})
   212  	e.Start()
   213  	defer e.Stop()
   214  
   215  	stopped = nil
   216  	actual := len(stopped)
   217  	expected := 0
   218  	if !reflect.DeepEqual(actual, expected) {
   219  		t.Errorf("len(stopped) before Stop => %#v, want %#v", actual, expected)
   220  	}
   221  	e.Stop()
   222  	actual = len(stopped)
   223  	expected = 1
   224  	if !reflect.DeepEqual(actual, expected) {
   225  		t.Errorf("len(stopped) after Stop => %#v, want %#v", actual, expected)
   226  	}
   227  }
   228  
   229  func TestEvent_ErrorHandler(t *testing.T) {
   230  	e := event.New()
   231  	e.RegisterQueue(queueName, &fakeQueue{c: make(chan string), done: make(chan struct{})})
   232  	e.Start()
   233  	defer e.Stop()
   234  
   235  	handlerName := "testErrorHandler"
   236  	expected := fmt.Errorf("testErrorHandlerError")
   237  	if err := e.AddHandler(handlerName, queueName, func(args ...interface{}) error {
   238  		return expected
   239  	}); err != nil {
   240  		t.Fatal(err)
   241  	}
   242  	called := make(chan struct{})
   243  	e.ErrorHandler = func(err interface{}) {
   244  		if !reflect.DeepEqual(err, expected) {
   245  			t.Errorf("ErrorHandler called with %#v, want %#v", err, expected)
   246  		}
   247  		called <- struct{}{}
   248  	}
   249  	if err := e.Trigger(handlerName); err != nil {
   250  		t.Fatal(err)
   251  	}
   252  	select {
   253  	case <-called:
   254  	case <-time.After(3 * time.Second):
   255  		t.Errorf("ErrorHandler hasn't been called within 3 seconds")
   256  	}
   257  }