github.com/oweisse/u-root@v0.0.0-20181109060735-d005ad25fef1/pkg/lineio/lineio_test.go (about) 1 // Copyright 2018 the u-root 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 lineio 6 7 import ( 8 "bytes" 9 "io" 10 "reflect" 11 "regexp" 12 "testing" 13 ) 14 15 type lineCase struct { 16 line int64 17 bufSize int 18 err error 19 data string 20 size int 21 } 22 23 type dataCase struct { 24 data string 25 tests []lineCase 26 } 27 28 var cases = []dataCase{ 29 { 30 data: `Hello World!`, 31 tests: []lineCase{ 32 { 33 line: 1, 34 bufSize: 128, 35 err: io.EOF, 36 data: "Hello World!", 37 size: 12, 38 }, 39 { 40 line: 2, 41 bufSize: 128, 42 err: io.EOF, 43 data: "", 44 size: 0, 45 }, 46 }, 47 }, 48 { 49 data: `Line 1 50 Line 2 51 Line 3 52 Line 4 53 Line 5 54 55 Line 7 56 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 57 Line 9`, 58 tests: []lineCase{ 59 { 60 line: 1, 61 bufSize: 128, 62 err: io.EOF, 63 data: "Line 1", 64 size: 6, 65 }, 66 { 67 line: 2, 68 bufSize: 128, 69 err: io.EOF, 70 data: "Line 2", 71 size: 6, 72 }, 73 // Skip some lines before the next one. 74 { 75 line: 5, 76 bufSize: 128, 77 err: io.EOF, 78 data: "Line 5", 79 size: 6, 80 }, 81 // Exact size 82 { 83 line: 1, 84 bufSize: 6, 85 err: nil, 86 data: "Line 1", 87 size: 6, 88 }, 89 // Less then entire line 90 { 91 line: 1, 92 bufSize: 4, 93 err: nil, 94 data: "Line", 95 size: 4, 96 }, 97 // Empty line 98 { 99 line: 6, 100 bufSize: 128, 101 err: io.EOF, 102 data: "", 103 size: 0, 104 }, 105 // After empty line 106 { 107 line: 7, 108 bufSize: 128, 109 err: io.EOF, 110 data: "Line 7", 111 size: 6, 112 }, 113 // After long line 114 { 115 line: 9, 116 bufSize: 128, 117 err: io.EOF, 118 data: "Line 9", 119 size: 6, 120 }, 121 }, 122 }, 123 } 124 125 func TestReadLine(t *testing.T) { 126 for _, c := range cases { 127 r := NewLineReader(bytes.NewReader([]byte(c.data))) 128 129 for _, l := range c.tests { 130 buf := make([]byte, l.bufSize) 131 132 n, err := r.ReadLine(buf, l.line) 133 if err != l.err { 134 t.Errorf("data: '%s', ReadLine(%d): err got %v want %v", c.data, l.line, err, l.err) 135 } 136 137 if n != l.size { 138 t.Errorf("data: '%s', ReadLine(%d): n got %d want %d", c.data, l.line, n, l.size) 139 } 140 141 s := string(buf[:n]) 142 143 if s != l.data { 144 t.Errorf("data: '%s', ReadLine(%d): buf got '%s' want '%s'", c.data, l.line, s, l.data) 145 } 146 } 147 } 148 149 } 150 151 func TestLineExists(t *testing.T) { 152 input := `Line 1 153 Line 2 154 Line 3` 155 156 r := NewLineReader(bytes.NewReader([]byte(input))) 157 158 if !r.LineExists(1) { 159 t.Errorf("LineExists(1) = false want true") 160 } 161 162 if !r.LineExists(2) { 163 t.Errorf("LineExists(2) = false want true") 164 } 165 166 if !r.LineExists(3) { 167 t.Errorf("LineExists(3) = false want true") 168 } 169 170 if r.LineExists(4) { 171 t.Errorf("LineExists(4) = true want false") 172 } 173 } 174 175 // Newline at the end of a file shouldn't count as a line. 176 func TestLineExistsNewline(t *testing.T) { 177 input := `Line 1 178 ` 179 180 r := NewLineReader(bytes.NewReader([]byte(input))) 181 182 if !r.LineExists(1) { 183 t.Errorf("LineExists(1) = false want true") 184 } 185 186 if r.LineExists(2) { 187 t.Errorf("LineExists(2) = true want false") 188 } 189 } 190 191 func TestSearchLine(t *testing.T) { 192 input := `Line 1 193 aaa bbb ccc 194 Last line` 195 196 searchCases := []struct { 197 line int64 198 reg *regexp.Regexp 199 ret [][]int 200 err error 201 }{ 202 { 203 line: 1, 204 reg: regexp.MustCompile(`Line 1`), 205 ret: [][]int{{0, 6}}, 206 err: nil, 207 }, 208 { 209 line: 1, 210 reg: regexp.MustCompile(`^Line 1$`), 211 ret: [][]int{{0, 6}}, 212 err: nil, 213 }, 214 { 215 line: 1, 216 reg: regexp.MustCompile(`\d`), 217 ret: [][]int{{5, 6}}, 218 err: nil, 219 }, 220 { 221 line: 2, 222 reg: regexp.MustCompile(`[a-z]+`), 223 ret: [][]int{{0, 3}, {4, 7}, {8, 11}}, 224 err: nil, 225 }, 226 { 227 line: 3, 228 reg: regexp.MustCompile(`^Last line$`), 229 ret: [][]int{{0, 9}}, 230 err: nil, 231 }, 232 } 233 234 for _, c := range searchCases { 235 r := NewLineReader(bytes.NewReader([]byte(input))) 236 237 ret, err := r.SearchLine(c.reg, c.line) 238 if err != c.err { 239 t.Errorf("SearchLine(%v, %d): err got %v want %v", c.reg, c.line, err, c.err) 240 } 241 242 if !reflect.DeepEqual(ret, c.ret) { 243 t.Errorf("SearchLine(%v, %d) = %v want %v", c.reg, c.line, ret, c.ret) 244 } 245 } 246 }