github.com/ratrocket/u-root@v0.0.0-20180201221235-1cf9f48ee2cf/cmds/ed/ed_test.go (about) 1 // iopyright 2012-2017 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 // Ed is a simple line-oriented editor 6 // 7 // Synopsis: 8 // dd 9 // 10 // Description: 11 // 12 // Options: 13 package main 14 15 import ( 16 "bytes" 17 "fmt" 18 "io/ioutil" 19 "os" 20 "reflect" 21 "testing" 22 ) 23 24 func TestNewTextFile(t *testing.T) { 25 var test = []struct { 26 d string 27 start, end int 28 f file 29 }{ 30 {d: "a\nb\nc\n", start: 1, end: 3, f: file{dot: 1, data: []byte("a\nb\nc\n"), lines: []int{0, 2, 4}}}, 31 // I'm not sure this is right. 32 {d: "", start: 1, end: 1, f: file{dot: 1}}, 33 } 34 35 for _, v := range test { 36 f, err := NewTextEditor(readerio(bytes.NewBufferString(v.d))) 37 if err != nil { 38 t.Errorf("%v: want nil, got %v", v.d, err) 39 continue 40 } 41 if err := v.f.Equal(f); err != nil { 42 t.Errorf("%v vs %v: want nil, got %v", v.f, *f.(*file), err) 43 } 44 45 } 46 47 } 48 49 func TestReadTextFile(t *testing.T) { 50 var test = []struct { 51 d string 52 where int 53 f file 54 }{ 55 //{"a\nb\nc\n", 1, file{dot: 1, data: []byte("a\na\nb\nc\nb\nc\n"), lines: []int{0, 2, 4, 6, 8, 10}}}, 56 //{"a\nb\nc\n", 4, file{dot: 4, data: []byte("a\nb\nc\na\nb\nc\n"), lines: []int{0, 2, 4, 6, 8, 10}}}, 57 //{"a\nb\nc\n", 2, file{dot: 2, data: []byte("a\nb\na\nb\nc\nc\n"), lines: []int{0, 2, 4, 6, 8, 10}}}, 58 {"a\nb\nc\n", 0, file{dot: 1, data: []byte("a\nb\nc\na\nb\nc\n"), lines: []int{0, 2, 4, 6, 8, 10}}}, 59 } 60 debug = t.Logf 61 for _, v := range test { 62 r := bytes.NewBufferString(v.d) 63 f, err := NewTextEditor(readerio(r)) 64 // We are adding the file after a 0-length slice 65 // We want dot to be at the point we added it. 66 f.Move(v.where) 67 r = bytes.NewBufferString(v.d) 68 _, err = f.Read(r, v.where, v.where) 69 if err != nil { 70 t.Errorf("Error reading %v: %v", v.d, err) 71 continue 72 } 73 if err := v.f.Equal(f); err != nil { 74 t.Errorf("%v vs. %v: want nil, got %v", v.f, *f.(*file), err) 75 } 76 77 } 78 79 } 80 81 func TestWriteTextFile(t *testing.T) { 82 var test = []struct { 83 d string 84 start, end int 85 err string 86 f file 87 }{ 88 {d: "a\nb\n", start: 1, end: 3, f: file{dot: 1, data: []byte("a\nb\nc\na\nb\nc"), lines: []int{0, 2, 4, 6, 8, 10}}}, 89 {d: "b\nc\n", start: 2, end: 4, f: file{dot: 3, data: []byte("a\nb\nc\na\nb\nc\n"), lines: []int{0, 2, 4, 6, 8, 10}}}, 90 {d: "b\n", start: 2, end: 3, f: file{dot: 2, data: []byte("a\nb\nc\na\nb\nc"), lines: []int{0, 2, 4, 6, 8, 10}}}, 91 {d: "a\n", start: 1, end: 2, f: file{dot: 1, data: []byte("a\nb\nc\na\nb\nc"), lines: []int{0, 2, 4, 6, 8, 10}}}, 92 {err: "file is 6 lines and [start, end] is [40, 1]", start: 40, end: 1, f: file{dot: 1, data: []byte("a\nb\nc\na\nb\nc"), lines: []int{0, 2, 4, 6, 8, 10}}}, 93 {err: "file is 6 lines and [start, end] is [1, 40]", start: 1, end: 40, f: file{dot: 1, data: []byte("a\nb\nc\na\nb\nc"), lines: []int{0, 2, 4, 6, 8, 10}}}, 94 {err: "file is 6 lines and [start, end] is [40, 60]", start: 40, end: 60, f: file{dot: 1, data: []byte("a\nb\nc\na\nb\nc"), lines: []int{0, 2, 4, 6, 8, 10}}}, 95 } 96 97 debug = t.Logf 98 for _, v := range test { 99 n, err := ioutil.TempFile("", "ed") 100 if err != nil { 101 t.Fatalf("TempFile: want nil, got %v", err) 102 } 103 defer os.Remove(n.Name()) 104 105 _, err = v.f.WriteFile(n.Name(), v.start, v.end) 106 if err != nil && v.err != err.Error() { 107 t.Errorf("Error Writing %v, want err \n%v got err \n%v", v.f, v.err, err) 108 continue 109 } 110 check, err := ioutil.ReadFile(n.Name()) 111 if err != nil { 112 t.Errorf("Error reading back %v: %v", n.Name(), err) 113 continue 114 } 115 if string(check) != v.d { 116 t.Errorf("Error reading back: want %v, got %v", v.d, string(check)) 117 } 118 119 } 120 121 } 122 123 func TestSimpleTextCommand(t *testing.T) { 124 var test = []struct { 125 c string 126 start, end int 127 err string 128 f *file 129 }{ 130 {c: "Z", err: "Z: unknown command", start: 1, end: 2, f: &file{dot: 1, data: []byte("a\nb\nc\na\nb\nc"), lines: []int{0, 2, 4, 6, 8, 10}}}, 131 {c: ".Z", err: "Z: unknown command", start: 1, end: 2, f: &file{dot: 1, data: []byte("a\nb\nc\na\nb\nc"), lines: []int{0, 2, 4, 6, 8, 10}}}, 132 {c: "4Z", err: "Z: unknown command", start: 1, end: 2, f: &file{dot: 1, data: []byte("a\nb\nc\na\nb\nc"), lines: []int{0, 2, 4, 6, 8, 10}}}, 133 {c: "1,3Z", err: "Z: unknown command", start: 1, end: 2, f: &file{dot: 1, data: []byte("a\nb\nc\na\nb\nc"), lines: []int{0, 2, 4, 6, 8, 10}}}, 134 {c: "/a/Z", err: "Z: unknown command", start: 1, end: 2, f: &file{dot: 1, data: []byte("a\nb\nc\na\nb\nc"), lines: []int{0, 2, 4, 6, 8, 10}}}, 135 } 136 137 for _, v := range test { 138 err := DoCommand(v.f, v.c) 139 if err != nil && v.err != err.Error() { 140 t.Error(err.Error()) 141 } 142 } 143 144 } 145 146 func TestFileTextCommand(t *testing.T) { 147 var test = []struct { 148 c string 149 start, end int 150 err string 151 res string 152 f file 153 }{ 154 {c: "e%s", start: 1, end: 7, f: file{dot: 1, data: []byte("a\nb\nc\na\nb\nc\n"), lines: []int{0, 2, 4, 6, 8, 10}}}, 155 {c: "0r%s", start: 1, end: 12, f: file{dot: 1, data: []byte("a\nb\nc\na\nb\nc\na\nb\nc\na\nb\nc\n"), lines: []int{0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22}}}, 156 } 157 158 n, err := ioutil.TempFile("", "ed") 159 if err != nil { 160 t.Fatalf("TempFile: want nil, got %v", err) 161 } 162 defer os.Remove(n.Name()) 163 164 d := "a\nb\nc\na\nb\nc\n" 165 if err := ioutil.WriteFile(n.Name(), []byte(d), 0666); err != nil { 166 t.Fatalf("writing test data %s: %v", d, err) 167 } 168 169 f, err := NewTextEditor(readerio(bytes.NewBufferString(d))) 170 if err != nil { 171 t.Fatal(err.Error()) 172 } 173 for _, v := range test { 174 cmd := fmt.Sprintf(v.c, n.Name()) 175 err := DoCommand(f, cmd) 176 t.Logf("f after %v command is %v", v.c, f) 177 if err != nil && v.err != err.Error() { 178 t.Error(err.Error()) 179 } 180 if err := v.f.Equal(f); err != nil { 181 t.Errorf("%v: want nil, got %v", cmd, err) 182 } 183 } 184 185 } 186 187 func TestFileDelete(t *testing.T) { 188 var test = []struct { 189 start, end int 190 fi *file 191 fo *file 192 }{ 193 { 194 start: 1, end: 2, 195 fi: &file{dot: 1, data: []byte("a\nb\nc\na\nb\nc"), lines: []int{0, 2, 4, 6, 8, 10}}, 196 fo: &file{dot: 1, data: []byte("b\nc\na\nb\nc"), lines: []int{0, 2, 4, 6, 8}}, 197 }, 198 { 199 start: 1, end: 4, 200 fi: &file{dot: 1, data: []byte("a\nb\nc\na\nb\nc"), lines: []int{0, 2, 4, 6, 8, 10}}, 201 fo: &file{dot: 1, data: []byte("a\nb\nc"), lines: []int{0, 2, 4}}, 202 }, 203 } 204 205 debug = t.Logf 206 for _, v := range test { 207 v.fi.Replace([]byte{}, v.start, v.end) 208 if v.fi.dot != v.fo.dot { 209 t.Errorf("Delete [%d, %d]: want dot %v, got %v", v.start, v.end, v.fo.dot, v.fi.dot) 210 } 211 if !reflect.DeepEqual(v.fi.lines, v.fo.lines) { 212 t.Errorf("Delete [%d, %d]: want %v, got %v", v.start, v.end, v.fo.lines, v.fi.lines) 213 } 214 if !reflect.DeepEqual(v.fi.data, v.fo.data) { 215 t.Errorf("Delete [%d, %d]: want %v, got %v", v.start, v.end, v.fo.data, v.fi.data) 216 } 217 } 218 219 } 220 221 func TestFileDCommand(t *testing.T) { 222 var test = []struct { 223 c string 224 fi *file 225 err string 226 fo *file 227 }{ 228 { 229 c: "1d", 230 fi: &file{dot: 1, data: []byte("a\nb\nc\na\nb\nc"), lines: []int{0, 2, 4, 6, 8, 10}}, 231 fo: &file{dot: 1, data: []byte("b\nc\na\nb\nc"), lines: []int{0, 2, 4, 6, 8}}, 232 }, 233 { 234 c: "1,3d", 235 fi: &file{dot: 1, data: []byte("a\nb\nc\na\nb\nc"), lines: []int{0, 2, 4, 6, 8, 10}}, 236 fo: &file{dot: 1, data: []byte("a\nb\nc"), lines: []int{0, 2, 4}}, 237 }, 238 } 239 240 debug = t.Logf 241 for _, v := range test { 242 err := DoCommand(v.fi, v.c) 243 if v.err == "" && err != nil { 244 t.Errorf("%v: want nil, got %v", v.c, err) 245 continue 246 } 247 if err != nil && err.Error() != v.err { 248 t.Errorf("%v: want %v, got %v", v.c, v.err, err) 249 continue 250 } 251 if v.fi.dot != v.fo.dot { 252 t.Errorf("want dot %v, got %v", v.fo.dot, v.fi.dot) 253 } 254 if !reflect.DeepEqual(v.fi.lines, v.fo.lines) { 255 t.Errorf("%v: want %v, got %v", v.c, v.fo.lines, v.fi.lines) 256 } 257 if !reflect.DeepEqual(v.fi.data, v.fo.data) { 258 t.Errorf("%v: want %v, got %v", v.c, v.fo.data, v.fi.data) 259 } 260 } 261 262 } 263 264 func TestFileSCommand(t *testing.T) { 265 var test = []struct { 266 c string 267 fi *file 268 err string 269 fo *file 270 }{ 271 { 272 c: "1s/a/b/", 273 fi: &file{dot: 1, data: []byte("a\nb\nc\na\nb\nc\n"), lines: []int{0, 2, 4, 6, 8, 10}}, 274 fo: &file{dot: 1, data: []byte("b\nb\nc\na\nb\nc\n"), lines: []int{0, 2, 4, 6, 8, 10}}, 275 }, 276 { 277 c: "1,2s/a/A/g", 278 fi: &file{dot: 1, data: []byte("a\nb\nc\na\nb\nc"), lines: []int{0, 2, 4, 6, 8, 10}}, 279 fo: &file{dot: 1, data: []byte("A\nb\nc\na\nb\nc"), lines: []int{0, 2, 4, 6, 8, 10}}, 280 }, 281 { 282 c: "1,$s/a/A/g", 283 fi: &file{dot: 1, data: []byte("a\nb\nc\na\nb\nc\n"), lines: []int{0, 2, 4, 6, 8, 10}}, 284 fo: &file{dot: 1, data: []byte("A\nb\nc\nA\nb\nc\n"), lines: []int{0, 2, 4, 6, 8, 10}}, 285 }, 286 { 287 c: "1,$s/a/A/g", 288 fi: &file{dot: 1, data: []byte("a\nb\nc\na\nb\nc"), lines: []int{0, 2, 4, 6, 8, 10}}, 289 fo: &file{dot: 1, data: []byte("A\nb\nc\nA\nb\nc"), lines: []int{0, 2, 4, 6, 8, 10}}, 290 }, 291 } 292 293 debug = t.Logf 294 for _, v := range test { 295 err := DoCommand(v.fi, v.c) 296 if v.err == "" && err != nil { 297 t.Errorf("%v: want nil, got %v", v.c, err) 298 continue 299 } 300 if err != nil && err.Error() != v.err { 301 t.Errorf("%v: want %v, got %v", v.c, v.err, err) 302 continue 303 } 304 if v.fi.dot != v.fo.dot { 305 t.Errorf("want dot %v, got %v", v.fo.dot, v.fi.dot) 306 } 307 if !reflect.DeepEqual(v.fi.lines, v.fo.lines) { 308 t.Errorf("%v: want %v, got %v", v.c, v.fo.lines, v.fi.lines) 309 } 310 if !reflect.DeepEqual(v.fi.data, v.fo.data) { 311 t.Errorf("%v: want %v, got %v", v.c, v.fo.data, v.fi.data) 312 } 313 } 314 315 }