Skip to content

Commit 61b0542

Browse files
authored
Refactor and add tests (#26)
All tests are updated to look similar and follow the same `t.Run` sub-test format. Also this commit expands the test coverage for Callable and Serializable through examples.
1 parent 3cf4d6d commit 61b0542

26 files changed

+2445
-1635
lines changed

Diff for: adaptor/transport/map/transport_test.go

+117-117
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package tmap_test
22

33
import (
4+
"fmt"
45
"net/http"
56
"net/http/httptest"
67
"strings"
@@ -11,168 +12,167 @@ import (
1112
tmap "github.com/njones/socketio/adaptor/transport/map"
1213
eiop "github.com/njones/socketio/engineio/protocol"
1314
eiot "github.com/njones/socketio/engineio/transport"
15+
itest "github.com/njones/socketio/internal/test"
1416
siop "github.com/njones/socketio/protocol"
1517
sess "github.com/njones/socketio/session"
1618
siot "github.com/njones/socketio/transport"
1719
"github.com/stretchr/testify/assert"
1820
)
1921

22+
var runTest, skipTest = itest.RunTest, itest.SkipTest
23+
2024
func TestMapTransportSet(t *testing.T) {
21-
tsp := tmap.NewMapTransport(siop.NewPacketV2)
22-
id := "sio:aaa"
23-
a := siot.SocketID(id)
25+
memTransport := tmap.NewMapTransport(siop.NewPacketV2)
26+
sidStr := "sio:aaa"
27+
sid := siot.SocketID(sidStr)
2428

25-
nilSocketID := tsp.Receive(a)
26-
assert.Nil(t, nilSocketID)
29+
SocketID_𖣠 := memTransport.Receive(sid)
30+
assert.Nil(t, SocketID_𖣠)
2731

28-
tspr := newMockTransporter(id)
29-
err := tsp.Set(a, tspr)
32+
transport := newMockTransporter(sidStr)
33+
err := memTransport.Set(sid, transport)
3034
assert.NoError(t, err)
3135

32-
socketID := tsp.Receive(a)
33-
assert.NotNil(t, socketID)
36+
socketID_ꤶ := memTransport.Receive(sid)
37+
assert.NotNil(t, socketID_ꤶ)
3438
}
3539

36-
func TestMapTransportSend(t *testing.T) {
37-
sess.GenerateID = func() tmap.SocketID { return tmap.SocketID("ABC123") }
38-
39-
c := eiot.Codec{
40-
PacketEncoder: eiop.NewPacketEncoderV2,
41-
PacketDecoder: eiop.NewPacketDecoderV2,
42-
PayloadEncoder: eiop.NewPayloadEncoderV2,
43-
PayloadDecoder: eiop.NewPayloadDecoderV2,
44-
}
45-
46-
wgrp := new(sync.WaitGroup)
47-
48-
etr := eiot.NewPollingTransport(1000, 10*time.Millisecond)(tmap.SessionID("12345"), c)
49-
str := tmap.NewMapTransport(siop.NewPacketV2)
50-
51-
sid, err := str.Add(etr)
52-
if err != nil {
53-
t.Fatal(err)
40+
func TestTransportAckID(t *testing.T) {
41+
memTransport := tmap.NewMapTransport(siop.NewPacketV2)
42+
43+
collect := make(chan [2]uint64, 100)
44+
unꢠ := new(sync.WaitGroup)
45+
waitUntilDoneLooping := make(chan struct{})
46+
47+
loop := 100
48+
for i := 0; i < loop; i++ {
49+
unꢠ.Add(1)
50+
go func(n int) {
51+
<-waitUntilDoneLooping
52+
collect <- [2]uint64{uint64(n), memTransport.AckID()}
53+
unꢠ.Done()
54+
}(i)
5455
}
5556

56-
errChan := make(chan error, 1)
57-
rec := httptest.NewRecorder()
57+
close(waitUntilDoneLooping) // now fire all go routines at the same time
58+
unꢠ.Wait() // wait until all of the go routines have fired
59+
close(collect) // close up the collection shop so we can loop through to the end
5860

59-
wgrp.Add(1)
60-
go func() {
61-
defer wgrp.Done()
62-
req, err := http.NewRequest("GET", "/", nil)
63-
if err != nil {
64-
errChan <- err
65-
return
61+
var sameIndexAndValue int
62+
for idxVal := range collect {
63+
if idxVal[0] == idxVal[1] {
64+
sameIndexAndValue++
6665
}
67-
errChan <- etr.Run(rec, req)
68-
}()
69-
70-
str.Send(sid, "This is cool")
71-
wgrp.Wait()
72-
73-
if err := <-errChan; err != nil {
74-
t.Fatal(err)
7566
}
7667

77-
have := rec.Body.String()
78-
want := thisIsCoolText
79-
80-
assert.Equal(t, want, have)
68+
assert.Less(t, sameIndexAndValue, loop, "it looks like atomic didn't work as expected.")
8169
}
8270

83-
var thisIsCoolText = `16:40"This is cool"`
71+
func TestMapTransport(t *testing.T) {
72+
var opts = []func(*testing.T){}
8473

85-
func TestMapTransportReceive(t *testing.T) {
86-
sess.GenerateID = func() tmap.SocketID { return tmap.SocketID("ABC123") }
74+
type (
75+
testFn func(*testing.T)
76+
testParamsInFn func(string, string, eiot.Transporter, siot.Transporter) testFn
77+
testParamsOutFn func(*testing.T) (string, string, eiot.Transporter, siot.Transporter)
78+
)
8779

88-
c := eiot.Codec{
89-
PacketEncoder: eiop.NewPacketEncoderV2,
90-
PacketDecoder: eiop.NewPacketDecoderV2,
91-
PayloadEncoder: eiop.NewPayloadEncoderV2,
92-
PayloadDecoder: eiop.NewPayloadDecoderV2,
80+
runWithOptions := map[string]testParamsInFn{
81+
"Send": func(data string, packetData string, etr eiot.Transporter, str siot.Transporter) testFn {
82+
return MapTransportTestSend(opts, data, packetData, etr, str)
83+
},
84+
"Receive": func(data string, packetData string, etr eiot.Transporter, str siot.Transporter) testFn {
85+
return MapTransportTestReceive(opts, data, packetData, etr, str)
86+
},
9387
}
9488

95-
wgrp := new(sync.WaitGroup)
89+
spec := map[string]testParamsOutFn{
90+
"Basic": func(*testing.T) (string, string, eiot.Transporter, siot.Transporter) {
91+
data := `This is cool`
92+
packetData := `16:40"This is cool"`
93+
codec := eiot.Codec{
94+
PacketEncoder: eiop.NewPacketEncoderV2,
95+
PacketDecoder: eiop.NewPacketDecoderV2,
96+
PayloadEncoder: eiop.NewPayloadEncoderV2,
97+
PayloadDecoder: eiop.NewPayloadDecoderV2,
98+
}
99+
100+
eTransporter := eiot.NewPollingTransport(1000, 10*time.Millisecond)(tmap.SessionID("12345"), codec)
101+
sTransporter := tmap.NewMapTransport(siop.NewPacketV2)
96102

97-
etr := eiot.NewPollingTransport(1000, 10*time.Millisecond)(tmap.SessionID("12345"), c)
98-
str := tmap.NewMapTransport(siop.NewPacketV2)
103+
return data, packetData, eTransporter, sTransporter
104+
},
105+
}
99106

100-
sid, err := str.Add(etr)
101-
if err != nil {
102-
t.Fatal(err)
107+
for name, testParams := range spec {
108+
for suffix, run := range runWithOptions {
109+
t.Run(fmt.Sprintf("%s.%s", name, suffix), run(testParams(t)))
110+
}
103111
}
112+
}
104113

105-
errChan := make(chan error, 1)
106-
rec := httptest.NewRecorder()
114+
func MapTransportTestSend(opts []func(*testing.T), data string, packetData string, etr eiot.Transporter, str siot.Transporter) func(t *testing.T) {
115+
sess.GenerateID = func() tmap.SocketID { return tmap.SocketID("ABC123") }
116+
return func(t *testing.T) {
117+
sid, err := str.Add(etr)
118+
assert.NoError(t, err)
107119

108-
wgrp.Add(1)
109-
go func() {
110-
defer wgrp.Done()
120+
rec := httptest.NewRecorder()
111121

112-
req, err := http.NewRequest("POST", "/", strings.NewReader(thisIsCoolText))
113-
if err != nil {
114-
errChan <- err
115-
return
116-
}
122+
transportSend := new(sync.WaitGroup)
123+
transportSend.Add(1)
124+
go func() {
125+
defer transportSend.Done()
126+
req, err := http.NewRequest("GET", "/", nil) // polling is waiting...
127+
assert.NoError(t, err)
117128

118-
errChan <- etr.Run(rec, req)
119-
}()
120-
wgrp.Wait()
129+
err = etr.Run(rec, req)
130+
assert.NoError(t, err)
131+
}()
121132

122-
if err := <-errChan; err != nil {
123-
t.Fatal(err)
124-
}
133+
err = str.Send(sid, data)
134+
assert.NoError(t, err)
135+
transportSend.Wait()
125136

126-
data := "This is cool"
137+
have := rec.Body.String()
138+
want := packetData
127139

128-
have := <-str.Receive(sid)
129-
want := tmap.Socket{
130-
Type: byte(eiop.OpenPacket),
131-
Namespace: "/",
132-
AckID: 0x0,
133-
Data: &data,
140+
assert.Equal(t, want, have)
134141
}
135-
136-
assert.Equal(t, want, have)
137142
}
138143

139-
// Test for an AckID
140-
func TestTransportAckID(t *testing.T) {
141-
tsp := tmap.NewMapTransport(siop.NewPacketV2)
142-
143-
// test to make sure the atomic incrementing works if we get
144-
// concurrent calls to AckID
144+
func MapTransportTestReceive(opts []func(*testing.T), data string, packetData string, etr eiot.Transporter, str siot.Transporter) func(t *testing.T) {
145+
sess.GenerateID = func() tmap.SocketID { return tmap.SocketID("ABC123") }
146+
return func(t *testing.T) {
147+
sid, err := str.Add(etr)
148+
assert.NoError(t, err)
145149

146-
wg := new(sync.WaitGroup)
147-
ch := make(chan uint64, 100)
148-
wait := make(chan struct{})
149-
for i := 0; i < 100; i++ {
150+
rec := httptest.NewRecorder()
150151

151-
wg.Add(1)
152+
transportReceive := new(sync.WaitGroup)
153+
transportReceive.Add(1)
152154
go func() {
153-
<-wait // wait until we are done looping
154-
ch <- tsp.AckID()
155-
wg.Done()
156-
}()
157-
}
158-
close(wait) // now fire all go routines at the same time
159-
160-
wg.Wait()
161-
close(ch)
155+
defer transportReceive.Done()
156+
req, err := http.NewRequest("POST", "/", strings.NewReader(packetData))
157+
assert.NoError(t, err)
162158

163-
cm := map[uint64]struct{}{}
164-
for i := range ch {
165-
cm[i] = struct{}{}
166-
}
159+
err = etr.Run(rec, req)
160+
assert.NoError(t, err)
161+
}()
162+
transportReceive.Wait()
163+
164+
have := <-str.Receive(sid)
165+
want := tmap.Socket{
166+
Type: byte(eiop.OpenPacket),
167+
Namespace: "/",
168+
AckID: 0x0,
169+
Data: &data,
170+
}
167171

168-
if len(cm) != 100 {
169-
t.Log("got:", len(cm))
170-
t.Fatal("it looks like atomic didn't work as expected.")
172+
assert.Equal(t, want, have)
171173
}
172174
}
173175

174-
// Test for a MapTransport Set
175-
176176
type mockTransporter struct {
177177
eiot.Transporter
178178
id string
@@ -183,7 +183,7 @@ func (mt mockTransporter) ID() eiot.SessionID {
183183
}
184184

185185
func (mt mockTransporter) Receive() <-chan eiop.Packet {
186-
return nil
186+
return nil // © 2022 njɵɳᴇѕ
187187
}
188188

189189
func newMockTransporter(id string) mockTransporter {

0 commit comments

Comments
 (0)