<commit_before>package client

import (
	"github.com/smancke/guble/guble"

	"fmt"
	"github.com/golang/mock/gomock"
	"github.com/gorilla/websocket"
	"github.com/stretchr/testify/assert"
	"strings"
	"testing"
	"time"
)

var aNormalMessage = `42,/foo/bar,user01,phone01,id123,2015-01-01T12:00:00+01:00

Hello World`

var aSendNotification = "#send"

var anErrorNotification = "!error-send"

var ctrl *gomock.Controller

func init() {
	// disable error output while testing
	// because also negative tests are tested
	guble.LogLevel = guble.LEVEL_ERR + 1
}

func initCtrl(t *testing.T) func() {
	ctrl = gomock.NewController(t)
	return func() { ctrl.Finish() }
}

func enableDebugForMethod() func() {
	reset := guble.LogLevel
	guble.LogLevel = guble.LEVEL_DEBUG
	return func() { guble.LogLevel = reset }
}

func MockConnectionFactory(connectionMock *MockWSConnection) func(string, string) (WSConnection, error) {
	return func(url string, origin string) (WSConnection, error) {
		return connectionMock, nil
	}
}

func TestConnectErrorWithoutReconnection(t *testing.T) {
	defer initCtrl(t)()
	a := assert.New(t)

	// given a client
	c := New("url", "origin", 1, false)

	// which raises an error on connect
	callCounter := 0
	c.WSConnectionFactory = func(url string, origin string) (WSConnection, error) {
		a.Equal("url", url)
		a.Equal("origin", origin)
		callCounter++
		return nil, fmt.Errorf("emulate connection error")
	}

	// when we start
	err := c.Start()

	// then
	a.Error(err)
	a.Equal(1, callCounter)
}

func TestConnectErrorWithReconnection(t *testing.T) {
	defer initCtrl(t)()
	a := assert.New(t)

	// given a client
	c := New("url", "origin", 1, true)

	// which raises an error twice and then allows to connect
	callCounter := 0
	connMock := NewMockWSConnection(ctrl)
	connMock.EXPECT().ReadMessage().Do(func() { time.Sleep(time.Second) })
	c.WSConnectionFactory = func(url string, origin string) (WSConnection, error) {
		a.Equal("url", url)
		a.Equal("origin", origin)
		if callCounter <= 2 {
			callCounter++
			return nil, fmt.Errorf("emulate connection error")
		}
		return connMock, nil
	}

	// when we start
	err := c.Start()

	// then we get an error, first
	a.Error(err)
	a.False(c.Connected)

	// when we wait for two iterations
	time.Sleep(time.Millisecond * 101)

	// then we got connected
	a.True(c.Connected)
	a.Equal(3, callCounter)
}

func TestStopableClient(t *testing.T) {
	defer initCtrl(t)()
	a := assert.New(t)

	// given a client
	c := New("url", "origin", 1, true)

	// with a closeable connection
	connMock := NewMockWSConnection(ctrl)
	close := make(chan bool, 1)
	connMock.EXPECT().ReadMessage().
		Do(func() { <-close }).
		Return(0, []byte{}, fmt.Errorf("expected close error"))

	connMock.EXPECT().Close().Do(func() {
		close <- true
	})

	c.WSConnectionFactory = MockConnectionFactory(connMock)

	// when we start
	err := c.Start()

	// than we are connected
	a.NoError(err)
	a.True(c.Connected)

	// when we clode
	c.Close()
	time.Sleep(time.Millisecond * 1)

	// than the client returns
	a.False(c.Connected)
}

func TestReceiveAMessage(t *testing.T) {
	defer initCtrl(t)()
	a := assert.New(t)

	// given a client
	c := New("url", "origin", 1, true)

	// with a closeable connection
	connMock := NewMockWSConnection(ctrl)
	close := make(chan bool, 1)

	// I don't understand, how to order this

	// normal message
	connMock.EXPECT().ReadMessage().
		Return(4, []byte(aNormalMessage), nil)

	// close
	connMock.EXPECT().ReadMessage().
		Do(func() { <-close }).
		Return(0, []byte{}, fmt.Errorf("expected close error"))

	// error notification
	connMock.EXPECT().ReadMessage().
		Return(4, []byte(anErrorNotification), nil)

	// parse error
	connMock.EXPECT().ReadMessage().
		Return(4, []byte("---"), nil)

	// send notification
	connMock.EXPECT().ReadMessage().
		Return(4, []byte(aSendNotification), nil)

	c.WSConnectionFactory = MockConnectionFactory(connMock)

	connMock.EXPECT().Close().Do(func() {
		close <- true
	})

	// when we start
	err := c.Start()
	a.NoError(err)
	a.True(c.Connected)

	// than we receive the expected message
	select {<commit_msg>fixed call order of test<commit_after>package client

import (
	"github.com/smancke/guble/guble"

	"fmt"
	"github.com/golang/mock/gomock"
	"github.com/gorilla/websocket"
	"github.com/stretchr/testify/assert"
	"strings"
	"testing"
	"time"
)

var aNormalMessage = `42,/foo/bar,user01,phone01,id123,2015-01-01T12:00:00+01:00

Hello World`

var aSendNotification = "#send"

var anErrorNotification = "!error-send"

var ctrl *gomock.Controller

func init() {
	// disable error output while testing
	// because also negative tests are tested
	guble.LogLevel = guble.LEVEL_ERR + 1
}

func initCtrl(t *testing.T) func() {
	ctrl = gomock.NewController(t)
	return func() { ctrl.Finish() }
}

func enableDebugForMethod() func() {
	reset := guble.LogLevel
	guble.LogLevel = guble.LEVEL_DEBUG
	return func() { guble.LogLevel = reset }
}

func MockConnectionFactory(connectionMock *MockWSConnection) func(string, string) (WSConnection, error) {
	return func(url string, origin string) (WSConnection, error) {
		return connectionMock, nil
	}
}

func TestConnectErrorWithoutReconnection(t *testing.T) {
	defer initCtrl(t)()
	a := assert.New(t)

	// given a client
	c := New("url", "origin", 1, false)

	// which raises an error on connect
	callCounter := 0
	c.WSConnectionFactory = func(url string, origin string) (WSConnection, error) {
		a.Equal("url", url)
		a.Equal("origin", origin)
		callCounter++
		return nil, fmt.Errorf("emulate connection error")
	}

	// when we start
	err := c.Start()

	// then
	a.Error(err)
	a.Equal(1, callCounter)
}

func TestConnectErrorWithReconnection(t *testing.T) {
	defer initCtrl(t)()
	a := assert.New(t)

	// given a client
	c := New("url", "origin", 1, true)

	// which raises an error twice and then allows to connect
	callCounter := 0
	connMock := NewMockWSConnection(ctrl)
	connMock.EXPECT().ReadMessage().Do(func() { time.Sleep(time.Second) })
	c.WSConnectionFactory = func(url string, origin string) (WSConnection, error) {
		a.Equal("url", url)
		a.Equal("origin", origin)
		if callCounter <= 2 {
			callCounter++
			return nil, fmt.Errorf("emulate connection error")
		}
		return connMock, nil
	}

	// when we start
	err := c.Start()

	// then we get an error, first
	a.Error(err)
	a.False(c.Connected)

	// when we wait for two iterations
	time.Sleep(time.Millisecond * 101)

	// then we got connected
	a.True(c.Connected)
	a.Equal(3, callCounter)
}

func TestStopableClient(t *testing.T) {
	defer initCtrl(t)()
	a := assert.New(t)

	// given a client
	c := New("url", "origin", 1, true)

	// with a closeable connection
	connMock := NewMockWSConnection(ctrl)
	close := make(chan bool, 1)
	connMock.EXPECT().ReadMessage().
		Do(func() { <-close }).
		Return(0, []byte{}, fmt.Errorf("expected close error"))

	connMock.EXPECT().Close().Do(func() {
		close <- true
	})

	c.WSConnectionFactory = MockConnectionFactory(connMock)

	// when we start
	err := c.Start()

	// than we are connected
	a.NoError(err)
	a.True(c.Connected)

	// when we clode
	c.Close()
	time.Sleep(time.Millisecond * 1)

	// than the client returns
	a.False(c.Connected)
}

func TestReceiveAMessage(t *testing.T) {
	defer initCtrl(t)()
	a := assert.New(t)

	// given a client
	c := New("url", "origin", 1, true)

	// with a closeable connection
	connMock := NewMockWSConnection(ctrl)
	close := make(chan bool, 1)

	// normal message
	call1 := connMock.EXPECT().ReadMessage().
		Return(4, []byte(aNormalMessage), nil)
	call2 := connMock.EXPECT().ReadMessage().
		Return(4, []byte(aSendNotification), nil)
	call3 := connMock.EXPECT().ReadMessage().
		Return(4, []byte("---"), nil)
	call4 := connMock.EXPECT().ReadMessage().
		Return(4, []byte(anErrorNotification), nil)
	call5 := connMock.EXPECT().ReadMessage().
		Do(func() { <-close }).
		Return(0, []byte{}, fmt.Errorf("expected close error"))

	call5.After(call4)
	call4.After(call3)
	call3.After(call2)
	call2.After(call1)

	c.WSConnectionFactory = MockConnectionFactory(connMock)

	connMock.EXPECT().Close().Do(func() {
		close <- true
	})

	// when we start
	err := c.Start()
	a.NoError(err)
	a.True(c.Connected)

	// than we receive the expected message
	select {
{'fraction_non_alphanumeric': 0.15513677811550153, 'fraction_numerical': 0.013495440729483282, 'mean_word_length': 4.074645280690931, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7181379', 'n_tokens_mistral': 3066, 'n_tokens_neox': 2878, 'n_words': 705}