|
15 | 15 | package runtime |
16 | 16 |
|
17 | 17 | import ( |
| 18 | + "bufio" |
| 19 | + "bytes" |
| 20 | + "io" |
| 21 | + "io/ioutil" |
18 | 22 | "net/url" |
| 23 | + "strings" |
19 | 24 | "testing" |
20 | 25 |
|
| 26 | + "github.com/stretchr/testify/require" |
| 27 | + |
21 | 28 | "github.com/stretchr/testify/assert" |
22 | 29 | ) |
23 | 30 |
|
24 | | -/* |
25 | | -type tstreadcloser struct { |
26 | | - closed bool |
| 31 | +type eofReader struct{} |
| 32 | + |
| 33 | +func (e *eofReader) Read(d []byte) (int, error) { |
| 34 | + return 0, io.EOF |
| 35 | +} |
| 36 | + |
| 37 | +func closeReader(rdr io.Reader) *closeCounting { |
| 38 | + return &closeCounting{ |
| 39 | + rdr: rdr, |
| 40 | + } |
| 41 | +} |
| 42 | + |
| 43 | +type closeCounting struct { |
| 44 | + rdr io.Reader |
| 45 | + closed int |
| 46 | +} |
| 47 | + |
| 48 | +func (c *closeCounting) Read(d []byte) (int, error) { |
| 49 | + return c.rdr.Read(d) |
27 | 50 | } |
28 | 51 |
|
29 | | -func (t *tstreadcloser) Read(p []byte) (int, error) { return 0, nil } |
30 | | -func (t *tstreadcloser) Close() error { |
31 | | - t.closed = true |
| 52 | +func (c *closeCounting) Close() error { |
| 53 | + c.closed++ |
| 54 | + if cr, ok := c.rdr.(io.ReadCloser); ok { |
| 55 | + return cr.Close() |
| 56 | + } |
32 | 57 | return nil |
33 | 58 | } |
34 | 59 |
|
| 60 | +type countingBufioReader struct { |
| 61 | + buffereds int |
| 62 | + peeks int |
| 63 | + reads int |
| 64 | + |
| 65 | + br interface { |
| 66 | + Buffered() int |
| 67 | + Peek(int) ([]byte, error) |
| 68 | + Read([]byte) (int, error) |
| 69 | + } |
| 70 | +} |
| 71 | + |
| 72 | +func (c *countingBufioReader) Buffered() int { |
| 73 | + c.buffereds++ |
| 74 | + return c.br.Buffered() |
| 75 | +} |
| 76 | + |
| 77 | +func (c *countingBufioReader) Peek(v int) ([]byte, error) { |
| 78 | + c.peeks++ |
| 79 | + return c.br.Peek(v) |
| 80 | +} |
| 81 | + |
| 82 | +func (c *countingBufioReader) Read(p []byte) (int, error) { |
| 83 | + c.reads++ |
| 84 | + return c.br.Read(p) |
| 85 | +} |
| 86 | + |
35 | 87 | func TestPeekingReader(t *testing.T) { |
36 | 88 | // just passes to original reader when nothing called |
37 | 89 | exp1 := []byte("original") |
38 | | - pr1 := &peekingReader{rdr: ioutil.NopCloser(bytes.NewReader(exp1))} |
| 90 | + pr1 := newPeekingReader(closeReader(bytes.NewReader(exp1))) |
39 | 91 | b1, err := ioutil.ReadAll(pr1) |
40 | 92 | if assert.NoError(t, err) { |
41 | 93 | assert.Equal(t, exp1, b1) |
42 | 94 | } |
43 | 95 |
|
44 | 96 | // uses actual when there was some buffering |
45 | 97 | exp2 := []byte("actual") |
46 | | - pt1, pt2 := []byte("a"), []byte("ctual") |
47 | | - pr2 := &peekingReader{ |
48 | | - rdr: ioutil.NopCloser(bytes.NewReader(exp1)), |
49 | | - actual: io.MultiReader(bytes.NewReader(pt1), bytes.NewReader(pt2)), |
50 | | - peeked: pt1, |
51 | | - } |
| 98 | + pr2 := newPeekingReader(closeReader(bytes.NewReader(exp2))) |
| 99 | + peeked, err := pr2.underlying.Peek(1) |
| 100 | + require.NoError(t, err) |
| 101 | + require.Equal(t, "a", string(peeked)) |
52 | 102 | b2, err := ioutil.ReadAll(pr2) |
53 | 103 | if assert.NoError(t, err) { |
54 | | - assert.Equal(t, exp2, b2) |
| 104 | + assert.Equal(t, string(exp2), string(b2)) |
55 | 105 | } |
56 | 106 |
|
57 | | - // closes original reader |
58 | | - tr := new(tstreadcloser) |
59 | | - pr3 := &peekingReader{ |
60 | | - rdr: tr, |
61 | | - actual: ioutil.NopCloser(bytes.NewBuffer(nil)), |
62 | | - peeked: pt1, |
| 107 | + // passes close call through to original reader |
| 108 | + cr := closeReader(closeReader(bytes.NewReader(exp2))) |
| 109 | + pr3 := newPeekingReader(cr) |
| 110 | + require.NoError(t, pr3.Close()) |
| 111 | + require.Equal(t, 1, cr.closed) |
| 112 | + |
| 113 | + // returns false when the stream is empty |
| 114 | + pr4 := newPeekingReader(closeReader(&eofReader{})) |
| 115 | + require.False(t, pr4.HasContent()) |
| 116 | + |
| 117 | + // returns true when the stream has content |
| 118 | + rdr := closeReader(strings.NewReader("hello")) |
| 119 | + pr := newPeekingReader(rdr) |
| 120 | + cbr := &countingBufioReader{ |
| 121 | + br: bufio.NewReader(rdr), |
63 | 122 | } |
64 | | -
|
65 | | -
|
66 | | - // returns true when peeked previously with data |
67 | | - // returns true when peeked with data |
| 123 | + pr.underlying = cbr |
| 124 | + |
| 125 | + require.True(t, pr.HasContent()) |
| 126 | + require.Equal(t, 1, cbr.buffereds) |
| 127 | + require.Equal(t, 1, cbr.peeks) |
| 128 | + require.Equal(t, 0, cbr.reads) |
| 129 | + require.True(t, pr.HasContent()) |
| 130 | + require.Equal(t, 2, cbr.buffereds) |
| 131 | + require.Equal(t, 1, cbr.peeks) |
| 132 | + require.Equal(t, 0, cbr.reads) |
| 133 | + |
| 134 | + b, err := ioutil.ReadAll(pr) |
| 135 | + require.NoError(t, err) |
| 136 | + require.Equal(t, "hello", string(b)) |
| 137 | + require.Equal(t, 2, cbr.buffereds) |
| 138 | + require.Equal(t, 1, cbr.peeks) |
| 139 | + require.Equal(t, 2, cbr.reads) |
| 140 | + require.Equal(t, 0, cbr.br.Buffered()) |
68 | 141 | } |
69 | | -*/ |
70 | 142 |
|
71 | 143 | func TestJSONRequest(t *testing.T) { |
72 | 144 | req, err := JSONRequest("GET", "/swagger.json", nil) |
|
0 commit comments