forked from donovanhide/eventsource
-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathencoder_test.go
111 lines (96 loc) · 3.36 KB
/
encoder_test.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
package eventsource
import (
"bufio"
"bytes"
"compress/gzip"
"fmt"
"io"
"testing"
"github.com/stretchr/testify/assert"
)
type encoderTestCase struct {
event publication
expected string
}
type writerWithOnlyWriteMethod struct {
buf *bytes.Buffer
}
func (w *writerWithOnlyWriteMethod) Write(data []byte) (int, error) {
return w.buf.Write(data)
}
func TestEncoderOmitsOptionalFieldsWithoutValues(t *testing.T) {
for _, tc := range []encoderTestCase{
{publication{data: "aaa"}, "data: aaa\n\n"},
{publication{event: "aaa", data: "bbb"}, "event: aaa\ndata: bbb\n\n"},
{publication{id: "aaa", data: "bbb"}, "id: aaa\ndata: bbb\n\n"},
{publication{id: "aaa", event: "bbb", data: "ccc"}, "id: aaa\nevent: bbb\ndata: ccc\n\n"},
// An SSE message must *always* have a data field, even if its value is empty.
{publication{data: ""}, "data: \n\n"},
} {
t.Run(fmt.Sprintf("%+v", tc.event), func(t *testing.T) {
buf := bytes.NewBuffer(nil)
NewEncoder(buf, false).Encode(&tc.event)
assert.Equal(t, tc.expected, string(buf.Bytes()))
})
}
}
func TestEncoderMultiLineData(t *testing.T) {
for _, tc := range []encoderTestCase{
{publication{data: "\nfirst"}, "data: \ndata: first\n\n"},
{publication{data: "first\nsecond"}, "data: first\ndata: second\n\n"},
{publication{data: "first\nsecond\nthird"}, "data: first\ndata: second\ndata: third\n\n"},
{publication{data: "ends with newline\n"}, "data: ends with newline\ndata: \n\n"},
{publication{data: "first\nends with newline\n"}, "data: first\ndata: ends with newline\ndata: \n\n"},
} {
t.Run(fmt.Sprintf("%+v", tc.event), func(t *testing.T) {
buf := bytes.NewBuffer(nil)
NewEncoder(buf, false).Encode(&tc.event)
assert.Equal(t, tc.expected, string(buf.Bytes()))
})
}
}
func TestEncoderComment(t *testing.T) {
buf := bytes.NewBuffer(nil)
c := comment{value: "hello"}
NewEncoder(buf, false).Encode(c)
assert.Equal(t, ":hello\n", string(buf.Bytes()))
}
func TestEncoderGzipCompression(t *testing.T) {
uncompressedBuf, compressedBuf, expectedCompressedBuf := bytes.NewBuffer(nil), bytes.NewBuffer(nil), bytes.NewBuffer(nil)
event := &publication{
event: "aaa",
data: "bbb",
}
NewEncoder(uncompressedBuf, false).Encode(event)
zipper := gzip.NewWriter(expectedCompressedBuf)
zipper.Write(uncompressedBuf.Bytes())
zipper.Flush()
NewEncoder(compressedBuf, true).Encode(event)
assert.Equal(t, expectedCompressedBuf.Bytes(), compressedBuf.Bytes())
}
func TestEncoderCanWriteToWriterWithOrWithoutWriteStringMethod(t *testing.T) {
// We're using bufio.WriteString, so that we should get consistent output regardless of whether
// the underlying Writer supports the WriteString method (as the standard http.ResponseWriter
// does), but that is an implementation detail so this test verifies that it really does work.
doTest := func(t *testing.T, withWriteString bool) {
var w io.Writer
buf := bytes.NewBuffer(nil)
if withWriteString {
w = bufio.NewWriter(buf)
} else {
w = &writerWithOnlyWriteMethod{buf: buf}
}
enc := NewEncoder(w, false)
enc.Encode(&publication{
id: "aaa",
event: "bbb",
data: "ccc",
})
if withWriteString {
w.(*bufio.Writer).Flush()
}
assert.Equal(t, "id: aaa\nevent: bbb\ndata: ccc\n\n", string(buf.Bytes()))
}
t.Run("with WriteString", func(t *testing.T) { doTest(t, true) })
t.Run("without WriteString", func(t *testing.T) { doTest(t, false) })
}