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}