github.com/btwiuse/jiri@v0.0.0-20191125065820-53353bcfef54/textutil/writer_test.go (about) 1 // Copyright 2015 The Vanadium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package textutil 6 7 import ( 8 "bytes" 9 "errors" 10 "fmt" 11 "reflect" 12 "strings" 13 "testing" 14 ) 15 16 func TestPrefixWriter(t *testing.T) { 17 tests := []struct { 18 Prefix string 19 Writes []string 20 Want string 21 }{ 22 {"", nil, ""}, 23 {"", []string{""}, ""}, 24 {"", []string{"a"}, "a"}, 25 {"", []string{"a", ""}, "a"}, 26 {"", []string{"", "a"}, "a"}, 27 {"", []string{"a", "b"}, "ab"}, 28 {"", []string{"ab"}, "ab"}, 29 {"", []string{"\n"}, "\n"}, 30 {"", []string{"\n", ""}, "\n"}, 31 {"", []string{"", "\n"}, "\n"}, 32 {"", []string{"a", "\n"}, "a\n"}, 33 {"", []string{"a\n"}, "a\n"}, 34 {"", []string{"\n", "a"}, "\na"}, 35 {"", []string{"\na"}, "\na"}, 36 {"", []string{"a\nb\nc"}, "a\nb\nc"}, 37 {"PRE", nil, ""}, 38 {"PRE", []string{""}, ""}, 39 {"PRE", []string{"a"}, "PREa"}, 40 {"PRE", []string{"a", ""}, "PREa"}, 41 {"PRE", []string{"", "a"}, "PREa"}, 42 {"PRE", []string{"a", "b"}, "PREab"}, 43 {"PRE", []string{"ab"}, "PREab"}, 44 {"PRE", []string{"\n"}, "PRE\n"}, 45 {"PRE", []string{"\n", ""}, "PRE\n"}, 46 {"PRE", []string{"", "\n"}, "PRE\n"}, 47 {"PRE", []string{"a", "\n"}, "PREa\n"}, 48 {"PRE", []string{"a\n"}, "PREa\n"}, 49 {"PRE", []string{"\n", "a"}, "PRE\na"}, 50 {"PRE", []string{"\na"}, "PRE\na"}, 51 {"PRE", []string{"a", "\n", "b", "\n", "c"}, "PREa\nb\nc"}, 52 {"PRE", []string{"a\nb\nc"}, "PREa\nb\nc"}, 53 {"PRE", []string{"a\nb\nc\n"}, "PREa\nb\nc\n"}, 54 } 55 for _, test := range tests { 56 var buf bytes.Buffer 57 w := PrefixWriter(&buf, test.Prefix) 58 name := fmt.Sprintf("(%q, %q)", test.Want, test.Writes) 59 for _, write := range test.Writes { 60 name := name + fmt.Sprintf("(%q)", write) 61 n, err := w.Write([]byte(write)) 62 if got, want := n, len(write); got != want { 63 t.Errorf("%s got len %d, want %d", name, got, want) 64 } 65 if err != nil { 66 t.Errorf("%s got error: %v", name, err) 67 } 68 } 69 if got, want := buf.String(), test.Want; got != want { 70 t.Errorf("%s got %q, want %q", name, got, want) 71 } 72 } 73 } 74 75 func TestPrefixLineWriter(t *testing.T) { 76 tests := []struct { 77 Prefix string 78 Writes []string 79 Wants []string 80 }{ 81 {"", nil, nil}, 82 {"", []string{""}, nil}, 83 {"", []string{"a"}, []string{"a."}}, 84 {"", []string{"a", ""}, []string{"a."}}, 85 {"", []string{"", "a"}, []string{"a."}}, 86 {"", []string{"a", "b"}, []string{"ab."}}, 87 {"", []string{"ab"}, []string{"ab."}}, 88 {"", []string{"\n"}, []string{"\n"}}, 89 {"", []string{"\n", ""}, []string{"\n"}}, 90 {"", []string{"", "\n"}, []string{"\n"}}, 91 {"", []string{"a", "\n"}, []string{"a\n"}}, 92 {"", []string{"a\n"}, []string{"a\n"}}, 93 {"", []string{"\n", "a"}, []string{"\n", "a."}}, 94 {"", []string{"\na"}, []string{"\n", "a."}}, 95 {"", []string{"a\nb\nc"}, []string{"a\n", "b\n", "c."}}, 96 {"", []string{"a\nb\nc\n"}, []string{"a\n", "b\n", "c\n"}}, 97 {"PRE", nil, nil}, 98 {"PRE", []string{""}, nil}, 99 {"PRE", []string{"a"}, []string{"PREa."}}, 100 {"PRE", []string{"a", ""}, []string{"PREa."}}, 101 {"PRE", []string{"", "a"}, []string{"PREa."}}, 102 {"PRE", []string{"a", "b"}, []string{"PREab."}}, 103 {"PRE", []string{"ab"}, []string{"PREab."}}, 104 {"PRE", []string{"\n"}, []string{"PRE\n"}}, 105 {"PRE", []string{"\n", ""}, []string{"PRE\n"}}, 106 {"PRE", []string{"", "\n"}, []string{"PRE\n"}}, 107 {"PRE", []string{"a", "\n"}, []string{"PREa\n"}}, 108 {"PRE", []string{"a\n"}, []string{"PREa\n"}}, 109 {"PRE", []string{"\n", "a"}, []string{"PRE\n", "PREa."}}, 110 {"PRE", []string{"\na"}, []string{"PRE\n", "PREa."}}, 111 {"PRE", []string{"a", "\n", "b", "\n", "c"}, []string{"PREa\n", "PREb\n", "PREc."}}, 112 {"PRE", []string{"a\nb\nc"}, []string{"PREa\n", "PREb\n", "PREc."}}, 113 {"PRE", []string{"a\nb\nc\n"}, []string{"PREa\n", "PREb\n", "PREc\n"}}, 114 } 115 for _, test := range tests { 116 for _, eol := range eolRunesAsString { 117 // Replace '\n' in Writes and Wants with the test eol rune, and replace '.' 118 // in Wants with '\n'. 119 var writes, wants []string 120 for _, x := range test.Writes { 121 x = strings.Replace(x, "\n", string(eol), -1) 122 writes = append(writes, x) 123 } 124 for _, x := range test.Wants { 125 x = strings.Replace(x, "\n", string(eol), -1) 126 x = strings.Replace(x, ".", "\n", -1) 127 wants = append(wants, x) 128 } 129 // Run the actual tests. 130 capture := &captureWriter{} 131 w := PrefixLineWriter(capture, test.Prefix) 132 name := fmt.Sprintf("(%q, %q)", wants, writes) 133 for _, write := range writes { 134 name := name + fmt.Sprintf("(%q)", write) 135 n, err := w.Write([]byte(write)) 136 if got, want := n, len(write); got != want { 137 t.Errorf("%s got len %d, want %d", name, got, want) 138 } 139 if err != nil { 140 t.Errorf("%s got error: %v", name, err) 141 } 142 } 143 if err := w.Flush(); err != nil { 144 t.Errorf("%s Flush got error: %v", name, err) 145 } 146 if got, want := capture.Writes, wants; !reflect.DeepEqual(got, want) { 147 t.Errorf("%s got %q, want %q", name, got, want) 148 } 149 } 150 } 151 } 152 153 type captureWriter struct { 154 Writes []string 155 } 156 157 func (w *captureWriter) Write(p []byte) (int, error) { 158 w.Writes = append(w.Writes, string(p)) 159 return len(p), nil 160 } 161 162 var ( 163 err1 = errors.New("error 1") 164 err2 = errors.New("error 2") 165 ) 166 167 type fakeWriteFlusher struct { 168 writeErr error 169 flushErr error 170 flushed bool 171 } 172 173 func (f *fakeWriteFlusher) Write(p []byte) (int, error) { 174 return len(p), f.writeErr 175 } 176 177 func (f *fakeWriteFlusher) Flush() error { 178 f.flushed = true 179 return f.flushErr 180 } 181 182 func TestPrefixLineWriter_Flush(t *testing.T) { 183 fake := &fakeWriteFlusher{} 184 w := PrefixLineWriter(fake, "prefix") 185 if err := w.Flush(); err != nil { 186 t.Errorf("Flush got error %v, want nil", err) 187 } 188 if !fake.flushed { 189 t.Errorf("Flush not propagated") 190 } 191 } 192 193 func TestPrefixLineWriter_FlushError(t *testing.T) { 194 fake := &fakeWriteFlusher{flushErr: err1} 195 w := PrefixLineWriter(fake, "prefix") 196 if err := w.Flush(); err != err1 { 197 t.Errorf("Flush got error %v, want %v", err, err1) 198 } 199 if !fake.flushed { 200 t.Errorf("Flush not propagated") 201 } 202 } 203 204 func TestPrefixLineWriter_WriteFlush(t *testing.T) { 205 fake := &fakeWriteFlusher{} 206 w := PrefixLineWriter(fake, "prefix") 207 if n, err := w.Write([]byte("abc")); n != 3 || err != nil { 208 t.Errorf("Write got (%v,%v), want (3,nil)", n, err) 209 } 210 if err := w.Flush(); err != nil { 211 t.Errorf("Flush got error %v, want nil", err) 212 } 213 if !fake.flushed { 214 t.Errorf("Flush not propagated") 215 } 216 } 217 218 func TestPrefixLineWriter_WriteFlushError(t *testing.T) { 219 fake := &fakeWriteFlusher{flushErr: err1} 220 w := PrefixLineWriter(fake, "prefix") 221 if n, err := w.Write([]byte("abc")); n != 3 || err != nil { 222 t.Errorf("Write got (%v,%v), want (3,nil)", n, err) 223 } 224 if err := w.Flush(); err != err1 { 225 t.Errorf("Flush got error %v, want %v", err, err1) 226 } 227 if !fake.flushed { 228 t.Errorf("Flush not propagated") 229 } 230 } 231 232 func TestPrefixLineWriter_WriteErrorFlush(t *testing.T) { 233 fake := &fakeWriteFlusher{writeErr: err1} 234 w := PrefixLineWriter(fake, "prefix") 235 if n, err := w.Write([]byte("abc")); n != 3 || err != nil { 236 t.Errorf("Write got (%v,%v), want (3,nil)", n, err) 237 } 238 if err := w.Flush(); err != err1 { 239 t.Errorf("Flush got error %v, want %v", err, err1) 240 } 241 if !fake.flushed { 242 t.Errorf("Flush not propagated") 243 } 244 } 245 246 func TestPrefixLineWriter_WriteErrorFlushError(t *testing.T) { 247 fake := &fakeWriteFlusher{writeErr: err1, flushErr: err2} 248 w := PrefixLineWriter(fake, "prefix") 249 if n, err := w.Write([]byte("abc")); n != 3 || err != nil { 250 t.Errorf("Write got (%v,%v), want (3,nil)", n, err) 251 } 252 if err := w.Flush(); err != err1 { 253 t.Errorf("Flush got error %v, want %v", err, err1) 254 } 255 if !fake.flushed { 256 t.Errorf("Flush not propagated") 257 } 258 } 259 260 func TestPrefixLineWriter_EOLWriteErrorFlushError(t *testing.T) { 261 fake := &fakeWriteFlusher{writeErr: err1, flushErr: err2} 262 w := PrefixLineWriter(fake, "prefix") 263 if n, err := w.Write([]byte("ab\n")); n != 3 || err != err1 { 264 t.Errorf("Write got (%v,%v), want (3,%v)", n, err, err1) 265 } 266 if err := w.Flush(); err != err2 { 267 t.Errorf("Flush got error %v, want %v", err, err2) 268 } 269 if !fake.flushed { 270 t.Errorf("Flush not propagated") 271 } 272 } 273 274 func TestByteReplaceWriter(t *testing.T) { 275 tests := []struct { 276 Old byte 277 New string 278 Writes []string 279 Want string 280 }{ 281 {'a', "", nil, ""}, 282 {'a', "", []string{""}, ""}, 283 {'a', "", []string{"a"}, ""}, 284 {'a', "", []string{"b"}, "b"}, 285 {'a', "", []string{"aba"}, "b"}, 286 {'a', "", []string{"aba", "bab"}, "bbb"}, 287 {'a', "X", nil, ""}, 288 {'a', "X", []string{""}, ""}, 289 {'a', "X", []string{"a"}, "X"}, 290 {'a', "X", []string{"b"}, "b"}, 291 {'a', "X", []string{"aba"}, "XbX"}, 292 {'a', "X", []string{"aba", "bab"}, "XbXbXb"}, 293 {'a', "ZZZ", nil, ""}, 294 {'a', "ZZZ", []string{""}, ""}, 295 {'a', "ZZZ", []string{"a"}, "ZZZ"}, 296 {'a', "ZZZ", []string{"b"}, "b"}, 297 {'a', "ZZZ", []string{"aba"}, "ZZZbZZZ"}, 298 {'a', "ZZZ", []string{"aba", "bab"}, "ZZZbZZZbZZZb"}, 299 } 300 for _, test := range tests { 301 var buf bytes.Buffer 302 w := ByteReplaceWriter(&buf, test.Old, test.New) 303 name := fmt.Sprintf("(%q, %q, %q, %q)", test.Old, test.New, test.Want, test.Writes) 304 for _, write := range test.Writes { 305 name := name + fmt.Sprintf("(%q)", write) 306 n, err := w.Write([]byte(write)) 307 if got, want := n, len(write); got != want { 308 t.Errorf("%s got len %d, want %d", name, got, want) 309 } 310 if err != nil { 311 t.Errorf("%s got error: %v", name, err) 312 } 313 } 314 if got, want := buf.String(), test.Want; got != want { 315 t.Errorf("%s got %q, want %q", name, got, want) 316 } 317 } 318 }