sync_client_test.go

  1package sync
  2
  3import (
  4	"sync"
  5	"testing"
  6)
  7
  8type mockDoc struct {
  9	readTx    func(func(Transaction) error) error
 10	writeTx   func(func(Transaction) error) error
 11	stateDiff []byte
 12}
 13
 14func (m *mockDoc) WithReadTransaction(fn func(Transaction) error) error {
 15	return m.readTx(fn)
 16}
 17
 18func (m *mockDoc) WithWriteTransaction(fn func(Transaction) error) error {
 19	return m.writeTx(fn)
 20}
 21
 22func (m *mockDoc) GetStateDiff(stateVector []byte) []byte {
 23	return m.stateDiff
 24}
 25
 26func TestSyncClientStruct(t *testing.T) {
 27	doc := &mockDoc{}
 28
 29	onUpdate := func(doc DocInterface) error { return nil }
 30
 31	client := &SyncClient{
 32		endpoint:     "ws://localhost:1234",
 33		authToken:    "mytoken",
 34		doc:          doc,
 35		status:       StatusDisconnected,
 36		onUpdate:     onUpdate,
 37		ackedVersion: 0,
 38		localVersion: 0,
 39		retries:      0,
 40		awareness:    nil,
 41		done:         make(chan struct{}),
 42	}
 43
 44	if client.endpoint != "ws://localhost:1234" {
 45		t.Errorf("expected endpoint ws://localhost:1234, got %s", client.endpoint)
 46	}
 47	if client.authToken != "mytoken" {
 48		t.Errorf("expected authToken mytoken, got %s", client.authToken)
 49	}
 50	if client.doc != doc {
 51		t.Error("doc mismatch")
 52	}
 53	if client.status != StatusDisconnected {
 54		t.Errorf("expected status StatusDisconnected, got %d", client.status)
 55	}
 56	if client.onUpdate == nil {
 57		t.Error("onUpdate should not be nil")
 58	}
 59	if client.ackedVersion != 0 {
 60		t.Errorf("expected ackedVersion 0, got %d", client.ackedVersion)
 61	}
 62	if client.localVersion != 0 {
 63		t.Errorf("expected localVersion 0, got %d", client.localVersion)
 64	}
 65	if client.retries != 0 {
 66		t.Errorf("expected retries 0, got %d", client.retries)
 67	}
 68	if client.done == nil {
 69		t.Error("done channel should not be nil")
 70	}
 71}
 72
 73func TestSyncClientDone(t *testing.T) {
 74	client := &SyncClient{
 75		done: make(chan struct{}),
 76	}
 77
 78	done := client.Done()
 79	if done == nil {
 80		t.Error("Done() returned nil channel")
 81	}
 82
 83	select {
 84	case <-done:
 85		t.Error("channel should not be closed yet")
 86	default:
 87	}
 88
 89	close(client.done)
 90
 91	select {
 92	case <-done:
 93	default:
 94		t.Error("channel should be closed after client.done is closed")
 95	}
 96}
 97
 98func TestSyncClientStatus(t *testing.T) {
 99	client := &SyncClient{
100		status: StatusConnected,
101	}
102
103	if client.Status() != StatusConnected {
104		t.Errorf("expected StatusConnected, got %d", client.Status())
105	}
106
107	client.status = StatusDisconnecting
108	if client.Status() != StatusDisconnecting {
109		t.Errorf("expected StatusDisconnecting, got %d", client.Status())
110	}
111}
112
113func TestSyncClientCloseOnce(t *testing.T) {
114	client := &SyncClient{
115		closeOnce: sync.Once{},
116		done:      make(chan struct{}),
117	}
118
119	callCount := 0
120	var wg sync.WaitGroup
121	wg.Add(2)
122
123	go func() {
124		client.closeOnce.Do(func() { callCount++ })
125		wg.Done()
126	}()
127	go func() {
128		client.closeOnce.Do(func() { callCount++ })
129		wg.Done()
130	}()
131
132	wg.Wait()
133
134	if callCount != 1 {
135		t.Errorf("expected callCount 1, got %d", callCount)
136	}
137}
138
139func TestNewSyncClient(t *testing.T) {
140	doc := &mockDoc{}
141
142	client := NewSyncClient(doc, WithEndpoint("ws://localhost:8080"), WithAuthToken("test-token"), WithOnUpdate(func(doc DocInterface) error { return nil }))
143
144	if client == nil {
145		t.Error("expected non-nil client")
146	}
147
148	if client.doc != doc {
149		t.Error("expected doc to be set")
150	}
151
152	if client.status != StatusDisconnected {
153		t.Errorf("expected initial status to be StatusDisconnected, got %d", client.status)
154	}
155
156	if client.endpoint != "ws://localhost:8080" {
157		t.Errorf("expected endpoint to be ws://localhost:8080, got %s", client.endpoint)
158	}
159
160	if client.authToken != "test-token" {
161		t.Errorf("expected authToken to be test-token, got %s", client.authToken)
162	}
163
164	if client.done == nil {
165		t.Error("expected done channel to be initialized")
166	}
167}
168
169func TestNewSyncClientDefaultOptions(t *testing.T) {
170	doc := &mockDoc{}
171
172	client := NewSyncClient(doc)
173
174	if client == nil {
175		t.Error("expected non-nil client")
176	}
177
178	if client.endpoint != "" {
179		t.Errorf("expected default endpoint to be empty, got %s", client.endpoint)
180	}
181
182	if client.authToken != "" {
183		t.Errorf("expected default authToken to be empty, got %s", client.authToken)
184	}
185}