github.com/karrick/gorill@v1.10.3/nltr_test.go (about) 1 package gorill 2 3 import ( 4 "bytes" 5 "fmt" 6 "io" 7 "io/ioutil" 8 "os" 9 "testing" 10 ) 11 12 // newTestReader returns a LineTerminatedReader that reads from a testReader 13 // configured to return the specified tuples when read from. 14 func newTestReader(tuples []tuple) *LineTerminatedReader { 15 return &LineTerminatedReader{R: &testReader{tuples: tuples}} 16 } 17 18 func ExampleNewLineTerminatedReader() { 19 r := &LineTerminatedReader{R: bytes.NewReader([]byte("123\n456"))} 20 buf, err := ioutil.ReadAll(r) 21 if err != nil { 22 fmt.Fprintf(os.Stderr, "%s\n", err) 23 os.Exit(1) 24 } 25 if got, want := len(buf), 8; got != want { 26 fmt.Fprintf(os.Stderr, "GOT: %v; WANT: %v\n", got, want) 27 os.Exit(1) 28 } 29 fmt.Printf("%q\n", buf[len(buf)-1]) 30 // Output: '\n' 31 } 32 33 func TestNLTR(t *testing.T) { 34 buf := make([]byte, 64) 35 36 t.Run("compliance", func(t *testing.T) { 37 // Ensures compliance with guidelines set forth in io.Reader 38 // documentation, copied below: 39 40 // When Read encounters an error or end-of-file condition after 41 // successfully reading n > 0 bytes, it returns the number of bytes 42 // read. It may return the (non-nil) error from the same call or return 43 // the error (and n == 0) from a subsequent call. An instance of this 44 // general case is that a Reader returning a non-zero number of bytes at 45 // the end of the input stream may return either err == EOF or err == 46 // nil. The next Read should return 0, EOF. 47 t.Run("error during read", func(t *testing.T) { 48 r := newTestReader([]tuple{ 49 tuple{"some data", io.ErrUnexpectedEOF}, 50 }) 51 52 n, err := r.Read(buf) 53 ensureError(t, err, "unexpected EOF") 54 ensureBuffer(t, buf, n, "some data") 55 }) 56 57 // Implementations of Read are discouraged from returning a zero byte 58 // count with a nil error, except when len(p) == 0. 59 t.Run("final read has no room", func(t *testing.T) { 60 buf := make([]byte, 5) 61 62 r := newTestReader([]tuple{ 63 tuple{"12345", io.EOF}, 64 }) 65 66 n, err := r.Read(buf) 67 ensureError(t, err, "") 68 ensureBuffer(t, buf, n, "12345") 69 70 n, err = r.Read(nil) 71 ensureError(t, err, "") 72 ensureBuffer(t, buf, n, "") 73 }) 74 }) 75 76 t.Run("functional", func(t *testing.T) { 77 t.Run("empty", func(t *testing.T) { 78 t.Run("with newline", func(t *testing.T) { 79 r := newTestReader([]tuple{ 80 tuple{"\n", io.EOF}, 81 }) 82 83 n, err := r.Read(buf) 84 ensureError(t, err, "EOF") 85 ensureBuffer(t, buf, n, "\n") 86 }) 87 88 t.Run("sans newline", func(t *testing.T) { 89 r := newTestReader([]tuple{ 90 tuple{"", io.EOF}, 91 }) 92 93 n, err := r.Read(buf) 94 ensureError(t, err, "EOF") 95 ensureBuffer(t, buf, n, "\n") 96 }) 97 }) 98 99 t.Run("one line", func(t *testing.T) { 100 t.Run("with newline", func(t *testing.T) { 101 t.Run("source returns EOF after final data", func(t *testing.T) { 102 r := newTestReader([]tuple{ 103 tuple{"one\n", nil}, 104 tuple{"", io.EOF}, 105 }) 106 107 n, err := r.Read(buf) 108 ensureError(t, err, "") 109 ensureBuffer(t, buf, n, "one\n") 110 111 n, err = r.Read(buf) 112 ensureError(t, err, "EOF") 113 ensureBuffer(t, buf, n, "") 114 }) 115 116 t.Run("source returns EOF with final data", func(t *testing.T) { 117 r := newTestReader([]tuple{ 118 tuple{"one\n", io.EOF}, 119 }) 120 121 n, err := r.Read(buf) 122 ensureError(t, err, "EOF") 123 ensureBuffer(t, buf, n, "one\n") 124 }) 125 }) 126 127 t.Run("sans newline", func(t *testing.T) { 128 t.Run("source returns EOF after final data", func(t *testing.T) { 129 r := newTestReader([]tuple{ 130 tuple{"one", nil}, 131 tuple{"", io.EOF}, 132 }) 133 134 n, err := r.Read(buf) 135 ensureError(t, err, "") 136 ensureBuffer(t, buf, n, "one") 137 138 n, err = r.Read(buf) 139 ensureError(t, err, "EOF") 140 ensureBuffer(t, buf, n, "\n") 141 }) 142 143 t.Run("source returns EOF with final data", func(t *testing.T) { 144 r := newTestReader([]tuple{ 145 tuple{"one", io.EOF}, 146 }) 147 148 n, err := r.Read(buf) 149 ensureError(t, err, "EOF") 150 ensureBuffer(t, buf, n, "one\n") 151 }) 152 }) 153 }) 154 155 t.Run("two lines", func(t *testing.T) { 156 t.Run("with newline", func(t *testing.T) { 157 t.Run("source returns EOF after final data", func(t *testing.T) { 158 r := newTestReader([]tuple{ 159 tuple{"one\ntwo\n", nil}, 160 tuple{"", io.EOF}, 161 }) 162 163 n, err := r.Read(buf) 164 ensureError(t, err, "") 165 ensureBuffer(t, buf, n, "one\ntwo\n") 166 167 n, err = r.Read(buf) 168 ensureError(t, err, "EOF") 169 ensureBuffer(t, buf, n, "") 170 }) 171 172 t.Run("source returns EOF with final data", func(t *testing.T) { 173 r := newTestReader([]tuple{ 174 tuple{"one\ntwo\n", io.EOF}, 175 }) 176 177 n, err := r.Read(buf) 178 ensureError(t, err, "EOF") 179 ensureBuffer(t, buf, n, "one\ntwo\n") 180 }) 181 }) 182 183 t.Run("sans newline", func(t *testing.T) { 184 t.Run("source returns EOF after final data", func(t *testing.T) { 185 r := newTestReader([]tuple{ 186 tuple{"1234\n1234", nil}, 187 tuple{"", io.EOF}, 188 }) 189 190 n, err := r.Read(buf) 191 ensureError(t, err, "") 192 ensureBuffer(t, buf, n, "1234\n1234") 193 194 n, err = r.Read(buf) 195 ensureError(t, err, "EOF") 196 ensureBuffer(t, buf, n, "\n") 197 }) 198 199 t.Run("source returns EOF with final data", func(t *testing.T) { 200 t.Run("enough room in buf", func(t *testing.T) { 201 r := newTestReader([]tuple{ 202 tuple{"1234\n1234", io.EOF}, 203 }) 204 205 n, err := r.Read(buf) 206 ensureError(t, err, "EOF") 207 ensureBuffer(t, buf, n, "1234\n1234\n") 208 }) 209 t.Run("not enough room in buf", func(t *testing.T) { 210 buf := make([]byte, 5) 211 212 r := newTestReader([]tuple{ 213 tuple{"12345", io.EOF}, 214 }) 215 216 n, err := r.Read(buf) 217 ensureError(t, err, "") 218 ensureBuffer(t, buf, n, "12345") 219 220 n, err = r.Read(buf) 221 ensureError(t, err, "EOF") 222 ensureBuffer(t, buf, n, "\n") 223 }) 224 }) 225 }) 226 }) 227 }) 228 }