...
1 package gbytes_test
2
3 import (
4 "io"
5 "time"
6
7 . "github.com/onsi/gomega/gbytes"
8
9 "bytes"
10
11 . "github.com/onsi/ginkgo/v2"
12 . "github.com/onsi/gomega"
13 )
14
15 type SlowReader struct {
16 R io.Reader
17 D time.Duration
18 }
19
20 func (s SlowReader) Read(p []byte) (int, error) {
21 time.Sleep(s.D)
22 return s.R.Read(p)
23 }
24
25 var _ = Describe("Buffer", func() {
26 var buffer *Buffer
27
28 BeforeEach(func() {
29 buffer = NewBuffer()
30 })
31
32 Describe("dumping the entire contents of the buffer", func() {
33 It("should return everything that's been written", func() {
34 buffer.Write([]byte("abc"))
35 buffer.Write([]byte("def"))
36 Expect(buffer.Contents()).Should(Equal([]byte("abcdef")))
37
38 Expect(buffer).Should(Say("bcd"))
39 Expect(buffer.Contents()).Should(Equal([]byte("abcdef")))
40 })
41 })
42
43 Describe("creating a buffer with bytes", func() {
44 It("should create the buffer with the cursor set to the beginning", func() {
45 buffer := BufferWithBytes([]byte("abcdef"))
46 Expect(buffer.Contents()).Should(Equal([]byte("abcdef")))
47 Expect(buffer).Should(Say("abc"))
48 Expect(buffer).ShouldNot(Say("abc"))
49 Expect(buffer).Should(Say("def"))
50 })
51 })
52
53 Describe("creating a buffer that wraps a reader", func() {
54 Context("for a well-behaved reader", func() {
55 It("should buffer the contents of the reader", func() {
56 reader := bytes.NewBuffer([]byte("abcdef"))
57 buffer := BufferReader(reader)
58 Eventually(buffer).Should(Say("abc"))
59 Expect(buffer).ShouldNot(Say("abc"))
60 Eventually(buffer).Should(Say("def"))
61 Eventually(buffer.Closed).Should(BeTrue())
62 })
63 })
64
65 Context("for a slow reader", func() {
66 It("should allow Eventually to time out", func() {
67 slowReader := SlowReader{
68 R: bytes.NewBuffer([]byte("abcdef")),
69 D: time.Second,
70 }
71 buffer := BufferReader(slowReader)
72 failures := InterceptGomegaFailures(func() {
73 Eventually(buffer, 100*time.Millisecond).Should(Say("abc"))
74 })
75 Expect(failures).ShouldNot(BeEmpty())
76
77 fastReader := SlowReader{
78 R: bytes.NewBuffer([]byte("abcdef")),
79 D: time.Millisecond,
80 }
81 buffer = BufferReader(fastReader)
82 Eventually(buffer, 100*time.Millisecond).Should(Say("abc"))
83 Eventually(buffer.Closed).Should(BeTrue())
84 })
85 })
86 })
87
88 Describe("reading from a buffer", func() {
89 It("should read the current contents of the buffer", func() {
90 buffer := BufferWithBytes([]byte("abcde"))
91
92 dest := make([]byte, 3)
93 n, err := buffer.Read(dest)
94 Expect(err).ShouldNot(HaveOccurred())
95 Expect(n).Should(Equal(3))
96 Expect(string(dest)).Should(Equal("abc"))
97
98 dest = make([]byte, 3)
99 n, err = buffer.Read(dest)
100 Expect(err).ShouldNot(HaveOccurred())
101 Expect(n).Should(Equal(2))
102 Expect(string(dest[:n])).Should(Equal("de"))
103
104 n, err = buffer.Read(dest)
105 Expect(err).Should(Equal(io.EOF))
106 Expect(n).Should(Equal(0))
107 })
108 })
109
110 Describe("detecting regular expressions", func() {
111 It("should fire the appropriate channel when the passed in pattern matches, then close it", func() {
112 go func() {
113 time.Sleep(10 * time.Millisecond)
114 buffer.Write([]byte("abcde"))
115 }()
116
117 A := buffer.Detect("%s", "a.c")
118 B := buffer.Detect("def")
119
120 var gotIt bool
121 select {
122 case gotIt = <-A:
123 case <-B:
124 Fail("should not have gotten here")
125 case <-time.After(time.Second):
126 Fail("timed out waiting for detection")
127 }
128
129 Expect(gotIt).Should(BeTrue())
130 Eventually(A).Should(BeClosed())
131
132 buffer.Write([]byte("f"))
133 Eventually(B).Should(Receive())
134 Eventually(B).Should(BeClosed())
135 })
136
137 It("should fast-forward the buffer upon detection", func() {
138 buffer.Write([]byte("abcde"))
139 select {
140 case <-buffer.Detect("abc"):
141 case <-time.After(time.Second):
142 Fail("timed out waiting for detection")
143 }
144 Expect(buffer).ShouldNot(Say("abc"))
145 Expect(buffer).Should(Say("de"))
146 })
147
148 It("should only fast-forward the buffer when the channel is read, and only if doing so would not rewind it", func() {
149 buffer.Write([]byte("abcde"))
150 A := buffer.Detect("abc")
151 time.Sleep(20 * time.Millisecond)
152 Expect(buffer).Should(Say("abcd"))
153 select {
154 case <-A:
155 case <-time.After(time.Second):
156 Fail("timed out waiting for detection")
157 }
158 Expect(buffer).ShouldNot(Say("d"))
159 Expect(buffer).Should(Say("e"))
160 Eventually(A).Should(BeClosed())
161 })
162
163 It("should be possible to cancel a detection", func() {
164 A := buffer.Detect("abc")
165 B := buffer.Detect("def")
166 buffer.CancelDetects()
167 buffer.Write([]byte("abcdef"))
168 Eventually(A).Should(BeClosed())
169 Eventually(B).Should(BeClosed())
170
171 Expect(buffer).Should(Say("bcde"))
172 select {
173 case <-buffer.Detect("f"):
174 case <-time.After(time.Second):
175 Fail("timed out waiting for detection")
176 }
177 })
178 })
179
180 Describe("clearing the buffer", func() {
181 It("should clear out the contents of the buffer", func() {
182 buffer.Write([]byte("abc"))
183 Expect(buffer).To(Say("ab"))
184 Expect(buffer.Clear()).To(Succeed())
185 Expect(buffer).NotTo(Say("c"))
186 Expect(buffer.Contents()).To(BeEmpty())
187 buffer.Write([]byte("123"))
188 Expect(buffer).To(Say("123"))
189 Expect(buffer.Contents()).To(Equal([]byte("123")))
190 })
191
192 It("should error when the buffer is closed", func() {
193 buffer.Write([]byte("abc"))
194 buffer.Close()
195 err := buffer.Clear()
196 Expect(err).To(HaveOccurred())
197 })
198 })
199
200 Describe("closing the buffer", func() {
201 It("should error when further write attempts are made", func() {
202 _, err := buffer.Write([]byte("abc"))
203 Expect(err).ShouldNot(HaveOccurred())
204
205 buffer.Close()
206
207 _, err = buffer.Write([]byte("def"))
208 Expect(err).Should(HaveOccurred())
209
210 Expect(buffer.Contents()).Should(Equal([]byte("abc")))
211 })
212
213 It("should be closed", func() {
214 Expect(buffer.Closed()).Should(BeFalse())
215
216 buffer.Close()
217
218 Expect(buffer.Closed()).Should(BeTrue())
219 })
220 })
221 })
222
View as plain text