github.com/anishathalye/periscope@v0.3.5/internal/periscope/ls_test.go (about) 1 package periscope 2 3 import ( 4 "github.com/anishathalye/periscope/internal/testfs" 5 6 "io/ioutil" 7 "os" 8 "path/filepath" 9 "strings" 10 "testing" 11 12 "github.com/spf13/afero" 13 ) 14 15 func TestLsBasic(t *testing.T) { 16 fs := testfs.Read(` 17 /d1/a [10000 1] 18 /d1/b [1392 2] 19 /d1/c [1191 3] 20 /d2/a [10000 1] 21 /d2/b [1392 2] 22 /d2/c [1002 5] 23 `).Mkfs() 24 ps, out, _ := newTest(fs) 25 ps.Scan([]string{"/"}, &ScanOptions{}) 26 err := ps.Ls([]string{"/d1"}, &LsOptions{}) 27 check(t, err) 28 got := strings.TrimRight(out.String(), "\n") 29 expected := strings.TrimSpace(` 30 1 a 31 1 b 32 c 33 `) 34 if got != expected { 35 t.Fatalf("expected '%s', got '%s'", expected, got) 36 } 37 } 38 39 func TestLsOutsideScan(t *testing.T) { 40 fs := testfs.Read(` 41 /d1/a [10000 1] 42 /d1/a2 [10000 1] 43 /d1/b [1002 5] 44 /d2/b [1002 5] 45 `).Mkfs() 46 ps, out, _ := newTest(fs) 47 ps.Scan([]string{"/d2"}, &ScanOptions{}) 48 err := ps.Ls([]string{"/d1"}, &LsOptions{}) 49 check(t, err) 50 got := strings.TrimRight(out.String(), "\n") 51 expected := strings.TrimSpace(` 52 a 53 a2 54 b 55 `) 56 if got != expected { 57 t.Fatalf("expected '%s', got '%s'", expected, got) 58 } 59 } 60 61 func TestLsCountDuplicates(t *testing.T) { 62 fs := testfs.Read(` 63 /d1/a [10000 1] 64 /d1/b [1392 2] 65 /d1/c [1191 3] 66 /d2/a [10000 1] 67 /d2/b [1392 2] 68 /d2/c [1002 5] 69 /d3/a [10000 1] 70 /d4/a [10000 1] 71 `).Mkfs() 72 ps, out, _ := newTest(fs) 73 ps.Scan([]string{"/"}, &ScanOptions{}) 74 err := ps.Ls([]string{"/d1"}, &LsOptions{}) 75 check(t, err) 76 got := strings.TrimRight(out.String(), "\n") 77 expected := strings.TrimSpace(` 78 3 a 79 1 b 80 c 81 `) 82 if got != expected { 83 t.Fatalf("expected '%s', got '%s'", expected, got) 84 } 85 } 86 87 func TestLsCountOver10(t *testing.T) { 88 fs := testfs.Read(` 89 /d1/a [10000 1] 90 /d1/b [1234 2] 91 /d2/a1 [10000 1] 92 /d2/a2 [10000 1] 93 /d2/a3 [10000 1] 94 /d2/a4 [10000 1] 95 /d2/a5 [10000 1] 96 /d2/a6 [10000 1] 97 /d2/a7 [10000 1] 98 /d2/a8 [10000 1] 99 /d2/a9 [10000 1] 100 /d2/a10 [10000 1] 101 /d2/a11 [10000 1] 102 /d2/a12 [10000 1] 103 /d2/b [1234 2] 104 `).Mkfs() 105 ps, out, _ := newTest(fs) 106 ps.Scan([]string{"/"}, &ScanOptions{}) 107 err := ps.Ls([]string{"/d1"}, &LsOptions{}) 108 check(t, err) 109 got := strings.TrimRight(out.String(), "\n") 110 expected := strings.TrimSpace(` 111 12 a 112 1 b 113 `) 114 if got != expected { 115 t.Fatalf("expected '%s', got '%s'", expected, got) 116 } 117 } 118 119 func TestLsDuplicateSameDir(t *testing.T) { 120 fs := testfs.Read(` 121 /d1/a [10000 1] 122 /d1/a2 [10000 1] 123 /d1/a3 [10000 1] 124 /d1/b [1392 2] 125 /d2/a [10000 1] 126 /d2/b [1392 2] 127 `).Mkfs() 128 ps, out, _ := newTest(fs) 129 ps.Scan([]string{"/"}, &ScanOptions{}) 130 err := ps.Ls([]string{"/d1"}, &LsOptions{}) 131 check(t, err) 132 got := strings.TrimRight(out.String(), "\n") 133 expected := strings.TrimSpace(` 134 3 a 135 3 a2 136 3 a3 137 1 b 138 `) 139 if got != expected { 140 t.Fatalf("expected '%s', got '%s'", expected, got) 141 } 142 } 143 144 func TestLsNoCountUnique(t *testing.T) { 145 fs := testfs.Read(` 146 /d1/a [10000 1] 147 /d1/b [1234 2] 148 /d1/c [1111 3] 149 `).Mkfs() 150 ps, out, _ := newTest(fs) 151 ps.Scan([]string{"/"}, &ScanOptions{}) 152 err := ps.Ls([]string{"/d1"}, &LsOptions{}) 153 check(t, err) 154 got := strings.TrimRight(out.String(), "\n") 155 expected := strings.TrimSpace(` 156 a 157 b 158 c 159 `) 160 if got != expected { 161 t.Fatalf("expected '%s', got '%s'", expected, got) 162 } 163 } 164 165 func TestLsShowOnlyUnique(t *testing.T) { 166 fs := testfs.Read(` 167 /d1/a [10000 1] 168 /d1/b [1392 2] 169 /d1/c [1191 3] 170 /d1/d [1337 3] 171 /d2/a [10000 1] 172 /d2/b [1392 2] 173 /d2/c [1002 5] 174 `).Mkfs() 175 ps, out, _ := newTest(fs) 176 ps.Scan([]string{"/"}, &ScanOptions{}) 177 err := ps.Ls([]string{"/d1"}, &LsOptions{Unique: true}) 178 check(t, err) 179 got := strings.TrimRight(out.String(), "\n") 180 expected := strings.TrimSpace(` 181 c 182 d 183 `) 184 if got != expected { 185 t.Fatalf("expected '%s', got '%s'", expected, got) 186 } 187 } 188 189 func TestLsShowOnlyDuplicate(t *testing.T) { 190 fs := testfs.Read(` 191 /d1/a [10000 1] 192 /d1/b [1392 2] 193 /d1/c [1191 3] 194 /d1/d [1337 3] 195 /d2/a [10000 1] 196 /d2/b [1392 2] 197 /d2/c [1002 5] 198 `).Mkfs() 199 ps, out, _ := newTest(fs) 200 ps.Scan([]string{"/"}, &ScanOptions{}) 201 err := ps.Ls([]string{"/d1"}, &LsOptions{Duplicate: true}) 202 check(t, err) 203 got := strings.TrimRight(out.String(), "\n") 204 expected := strings.TrimSpace(` 205 1 a 206 1 b 207 `) 208 if got != expected { 209 t.Fatalf("expected '%s', got '%s'", expected, got) 210 } 211 } 212 213 func TestLsDirectories(t *testing.T) { 214 fs := testfs.Read(` 215 /d1/a [10000 1] 216 /d1/b [1392 2] 217 /d1/dir/x [1191 3] 218 /d2/a [10000 1] 219 /d2/b [1392 2] 220 `).Mkfs() 221 ps, out, _ := newTest(fs) 222 ps.Scan([]string{"/"}, &ScanOptions{}) 223 err := ps.Ls([]string{"/d1"}, &LsOptions{}) 224 check(t, err) 225 got := strings.TrimRight(out.String(), "\n") 226 expected := strings.TrimSpace(` 227 1 a 228 1 b 229 d dir 230 `) 231 if got != expected { 232 t.Fatalf("expected '%s', got '%s'", expected, got) 233 } 234 } 235 236 func TestLsSpecialModes(t *testing.T) { 237 fs := afero.NewOsFs() 238 dir := tempDir() 239 defer os.RemoveAll(dir) 240 ioutil.WriteFile(filepath.Join(dir, "x"), []byte{'a'}, 0o644) 241 ioutil.WriteFile(filepath.Join(dir, "y"), []byte{'a'}, 0o644) 242 os.Symlink(filepath.Join(dir, "x"), filepath.Join(dir, "z")) 243 ps, out, _ := newTest(fs) 244 ps.Scan([]string{dir}, &ScanOptions{}) 245 err := ps.Ls([]string{dir}, &LsOptions{}) 246 check(t, err) 247 got := strings.TrimRight(out.String(), "\n") 248 expected := strings.TrimSpace(` 249 1 x 250 1 y 251 L z 252 `) 253 if got != expected { 254 t.Fatalf("expected '%s', got '%s'", expected, got) 255 } 256 } 257 258 func TestLsVerbose(t *testing.T) { 259 fs := testfs.Read(` 260 /d1/a [10000 1] 261 /d1/a2 [10000 1] 262 /d1/a3 [10000 1] 263 /d1/b [1392 2] 264 /d2/a [10000 1] 265 /d2/b [1392 2] 266 `).Mkfs() 267 ps, out, _ := newTest(fs) 268 ps.Scan([]string{"/"}, &ScanOptions{}) 269 err := ps.Ls([]string{"/d1"}, &LsOptions{Verbose: true}) 270 check(t, err) 271 got := strings.TrimRight(out.String(), "\n") 272 expected := strings.TrimSpace(` 273 3 a 274 /d1/a2 275 /d1/a3 276 /d2/a 277 3 a2 278 /d1/a 279 /d1/a3 280 /d2/a 281 3 a3 282 /d1/a 283 /d1/a2 284 /d2/a 285 1 b 286 /d2/b 287 `) 288 if got != expected { 289 t.Fatalf("expected '%s', got '%s'", expected, got) 290 } 291 } 292 293 func TestLsVerboseRelative(t *testing.T) { 294 fs := testfs.Read(` 295 /d1/a [10000 1] 296 /d1/a2 [10000 1] 297 /d1/a3 [10000 1] 298 /d1/b [1392 2] 299 /d2/a [10000 1] 300 /d2/b [1392 2] 301 `).Mkfs() 302 ps, out, _ := newTest(fs) 303 ps.Scan([]string{"/"}, &ScanOptions{}) 304 err := ps.Ls([]string{"/d1"}, &LsOptions{Verbose: true, Relative: true}) 305 check(t, err) 306 got := strings.TrimRight(out.String(), "\n") 307 expected := strings.TrimSpace(` 308 3 a 309 a2 310 a3 311 /d2/a 312 3 a2 313 a 314 a3 315 /d2/a 316 3 a3 317 a 318 a2 319 /d2/a 320 1 b 321 /d2/b 322 `) 323 if got != expected { 324 t.Fatalf("expected '%s', got '%s'", expected, got) 325 } 326 } 327 328 func TestLsVerboseRelativeLong(t *testing.T) { 329 fs := testfs.Read(` 330 /long/directory/a [10 1] 331 /long/directory/b [10 1] 332 /long/x/c [10 1] 333 /other/directory/d [10 1] 334 `).Mkfs() 335 ps, out, _ := newTest(fs) 336 ps.Scan([]string{"/"}, &ScanOptions{}) 337 err := ps.Ls([]string{"/long/directory"}, &LsOptions{Verbose: true, Relative: true}) 338 check(t, err) 339 got := strings.TrimRight(out.String(), "\n") 340 expected := strings.TrimSpace(` 341 3 a 342 b 343 ../x/c 344 /other/directory/d 345 3 b 346 a 347 ../x/c 348 /other/directory/d 349 `) 350 if got != expected { 351 t.Fatalf("expected '%s', got '%s'", expected, got) 352 } 353 } 354 355 func TestLsHidden(t *testing.T) { 356 fs := testfs.Read(` 357 /d1/a [10000 1] 358 /d1/.b [1392 2] 359 /d2/.a [10000 1] 360 /d2/b [1392 2] 361 `).Mkfs() 362 ps, out, _ := newTest(fs) 363 ps.Scan([]string{"/"}, &ScanOptions{}) 364 err := ps.Ls([]string{"/d1"}, &LsOptions{}) 365 check(t, err) 366 got := strings.TrimRight(out.String(), "\n") 367 expected := strings.TrimSpace(` 368 1 a 369 `) 370 if got != expected { 371 t.Fatalf("expected '%s', got '%s'", expected, got) 372 } 373 out.Reset() 374 err = ps.Ls([]string{"/d1"}, &LsOptions{All: true}) 375 check(t, err) 376 got = strings.TrimSpace(out.String()) 377 expected = strings.TrimSpace(` 378 1 .b 379 1 a 380 `) 381 if got != expected { 382 t.Fatalf("expected '%s', got '%s'", expected, got) 383 } 384 } 385 386 func TestLsMultiple(t *testing.T) { 387 fs := testfs.Read(` 388 /d1/a [10000 1] 389 /d1/.b [1392 2] 390 /d2/.a [10000 1] 391 /d2/b [1392 2] 392 `).Mkfs() 393 ps, out, _ := newTest(fs) 394 ps.Scan([]string{"/"}, &ScanOptions{}) 395 err := ps.Ls([]string{"/d1", "/d2"}, &LsOptions{All: true}) 396 check(t, err) 397 got := strings.TrimRight(out.String(), "\n") 398 expected := strings.TrimSpace(` 399 /d1: 400 1 .b 401 1 a 402 403 /d2: 404 1 .a 405 1 b 406 `) 407 if got != expected { 408 t.Fatalf("expected '%s', got '%s'", expected, got) 409 } 410 } 411 412 func TestLsInaccessible(t *testing.T) { 413 dir := tempDir() 414 defer os.RemoveAll(dir) 415 inner := filepath.Join(dir, "d") 416 os.Mkdir(inner, 0111) 417 fs := afero.NewOsFs() 418 ps, out, stderr := newTest(fs) 419 err := ps.Ls([]string{inner}, &LsOptions{}) 420 checkErr(t, err) 421 got := strings.TrimRight(out.String(), "\n") 422 if got != "" { 423 t.Fatalf("expected no output, got '%s'", got) 424 } 425 expected := "permission denied" 426 got = stderr.String() 427 if !strings.Contains(got, expected) { 428 t.Fatalf("expected stderr to contain '%s', was '%s'", expected, got) 429 } 430 } 431 432 func TestLsNonexistent(t *testing.T) { 433 fs := testfs.Read(` 434 /d1/a [10000 1] 435 /d1/.b [1392 2] 436 `).Mkfs() 437 ps, out, stderr := newTest(fs) 438 err := ps.Ls([]string{"/d2"}, &LsOptions{}) 439 checkErr(t, err) 440 got := strings.TrimRight(out.String(), "\n") 441 if got != "" { 442 t.Fatalf("expected no output, got '%s'", got) 443 } 444 expected := "no such file or directory" 445 got = stderr.String() 446 if !strings.Contains(got, expected) { 447 t.Fatalf("expected stderr to contain '%s', was '%s'", expected, got) 448 } 449 } 450 451 func TestLsFile(t *testing.T) { 452 fs := testfs.Read(` 453 /d1/a [10000 1] 454 `).Mkfs() 455 ps, out, stderr := newTest(fs) 456 err := ps.Ls([]string{"/d1/a"}, &LsOptions{}) 457 checkErr(t, err) 458 got := strings.TrimRight(out.String(), "\n") 459 if got != "" { 460 t.Fatalf("expected no output, got '%s'", got) 461 } 462 expected := "not a directory" 463 got = stderr.String() 464 if !strings.Contains(got, expected) { 465 t.Fatalf("expected stderr to contain '%s', was '%s'", expected, got) 466 } 467 } 468 469 func TestLsSomeInaccessible(t *testing.T) { 470 fs := testfs.Read(` 471 /d1/a [10000 1] 472 /d3/a [10000 1] 473 /d3/b [1337 2] 474 `).Mkfs() 475 ps, out, stderr := newTest(fs) 476 ps.Scan([]string{"/"}, &ScanOptions{}) 477 err := ps.Ls([]string{"/d1", "/d2", "/d3"}, &LsOptions{}) 478 checkErr(t, err) 479 got := strings.TrimRight(out.String(), "\n") 480 expected := strings.TrimSpace(` 481 /d1: 482 1 a 483 484 /d3: 485 1 a 486 b 487 `) 488 if got != expected { 489 t.Fatalf("expected '%s', got '%s'", expected, got) 490 } 491 expected = "cannot list '/d2': no such file or directory" 492 got = stderr.String() 493 if !strings.Contains(got, expected) { 494 t.Fatalf("expected stderr to contain '%s', was '%s'", expected, got) 495 } 496 } 497 498 func TestLsRejectSymlink(t *testing.T) { 499 fs := afero.NewOsFs() 500 dir := tempDir() 501 defer os.RemoveAll(dir) 502 ioutil.WriteFile(filepath.Join(dir, "x"), []byte{'a'}, 0o644) 503 ioutil.WriteFile(filepath.Join(dir, "y"), []byte{'a'}, 0o644) 504 os.Symlink(dir, filepath.Join(dir, "rec")) 505 ps, out, stderr := newTest(fs) 506 err := ps.Ls([]string{filepath.Join(dir, "rec")}, &LsOptions{}) 507 checkErr(t, err) 508 got := strings.TrimRight(out.String(), "\n") 509 if got != "" { 510 t.Fatalf("expected no output, got '%s'", got) 511 } 512 expected := "path has symbolic links" 513 got = stderr.String() 514 if !strings.Contains(got, expected) { 515 t.Fatalf("expected stderr to contain '%s', was '%s'", expected, got) 516 } 517 } 518 519 func TestLsRecursive(t *testing.T) { 520 fs := testfs.Read(` 521 /foo.txt [100 1] 522 /Pictures/2020/January/IMG_1234.JPG [1000 3] 523 /Pictures/2021/August/DSC1337.HEIC [1000 2] 524 /Pictures/2021/August/DSC1337.copy.HEIC [1000 2] 525 /Temporary/recovered.heic [1000 2] 526 `).Mkfs() 527 ps, out, _ := newTest(fs) 528 ps.Scan([]string{"/"}, &ScanOptions{}) 529 err := ps.Ls([]string{"/"}, &LsOptions{Recursive: true}) 530 check(t, err) 531 got := strings.TrimRight(out.String(), "\n") 532 expected := strings.TrimSpace(` 533 /: 534 d Pictures 535 d Temporary 536 foo.txt 537 538 /Pictures: 539 d 2020 540 d 2021 541 542 /Pictures/2020: 543 d January 544 545 /Pictures/2020/January: 546 IMG_1234.JPG 547 548 /Pictures/2021: 549 d August 550 551 /Pictures/2021/August: 552 2 DSC1337.HEIC 553 2 DSC1337.copy.HEIC 554 555 /Temporary: 556 2 recovered.heic 557 `) 558 if got != expected { 559 t.Fatalf("expected '%s', got '%s'", expected, got) 560 } 561 } 562 563 func TestLsRecursiveDuplicateOnly(t *testing.T) { 564 fs := testfs.Read(` 565 /foo.txt [100 1] 566 /Pictures/2020/January/IMG_1234.JPG [1000 3] 567 /Pictures/2021/August/DSC1337.HEIC [1000 2] 568 /Pictures/2021/August/DSC1337.copy.HEIC [1000 2] 569 /Temporary/recovered.heic [1000 2] 570 `).Mkfs() 571 ps, out, _ := newTest(fs) 572 ps.Scan([]string{"/"}, &ScanOptions{}) 573 err := ps.Ls([]string{"/"}, &LsOptions{Recursive: true, Duplicate: true}) 574 check(t, err) 575 got := strings.TrimRight(out.String(), "\n") 576 expected := strings.TrimSpace(` 577 /Pictures/2021/August: 578 2 DSC1337.HEIC 579 2 DSC1337.copy.HEIC 580 581 /Temporary: 582 2 recovered.heic 583 `) 584 if got != expected { 585 t.Fatalf("expected '%s', got '%s'", expected, got) 586 } 587 } 588 589 func TestLsRecursiveHidden(t *testing.T) { 590 fs := testfs.Read(` 591 /d1/a [10000 1] 592 /d1/.b [1392 2] 593 /d2/.a [10000 1] 594 /d2/b [1392 2] 595 `).Mkfs() 596 ps, out, _ := newTest(fs) 597 ps.Scan([]string{"/"}, &ScanOptions{}) 598 err := ps.Ls([]string{"/"}, &LsOptions{Recursive: true, Duplicate: true}) 599 check(t, err) 600 got := strings.TrimSpace(out.String()) 601 expected := strings.TrimSpace(` 602 /d1: 603 1 a 604 605 /d2: 606 1 b 607 `) 608 if got != expected { 609 t.Fatalf("expected '%s', got '%s'", expected, got) 610 } 611 out.Reset() 612 err = ps.Ls([]string{"/"}, &LsOptions{Recursive: true, Duplicate: true, All: true}) 613 check(t, err) 614 got = strings.TrimSpace(out.String()) 615 expected = strings.TrimSpace(` 616 /d1: 617 1 .b 618 1 a 619 620 /d2: 621 1 .a 622 1 b 623 `) 624 if got != expected { 625 t.Fatalf("expected '%s', got '%s'", expected, got) 626 } 627 } 628 629 func TestLsRelative(t *testing.T) { 630 fs := afero.NewOsFs() 631 dir := tempDir() 632 defer os.RemoveAll(dir) 633 ioutil.WriteFile(filepath.Join(dir, "x"), []byte{'a'}, 0o644) 634 ioutil.WriteFile(filepath.Join(dir, "y"), []byte{'a'}, 0o644) 635 os.Mkdir(filepath.Join(dir, "d"), 0o755) 636 ioutil.WriteFile(filepath.Join(dir, "d", "a"), []byte{'b'}, 0o644) 637 ioutil.WriteFile(filepath.Join(dir, "d", "b"), []byte{'b'}, 0o644) 638 ps, out, _ := newTest(fs) 639 oldWd, err := os.Getwd() 640 if err != nil { 641 panic(err) 642 } 643 os.Chdir(dir) 644 defer os.Chdir(oldWd) 645 ps.Scan([]string{"."}, &ScanOptions{}) 646 err = ps.Ls([]string{".", "d"}, &LsOptions{}) 647 check(t, err) 648 got := strings.TrimSpace(out.String()) 649 expected := strings.TrimSpace(` 650 .: 651 d d 652 1 x 653 1 y 654 655 d: 656 1 a 657 1 b 658 `) 659 if got != expected { 660 t.Fatalf("expected '%s', got '%s'", expected, got) 661 } 662 } 663 664 func TestLsRelativeRecursive(t *testing.T) { 665 fs := afero.NewOsFs() 666 dir := tempDir() 667 defer os.RemoveAll(dir) 668 ioutil.WriteFile(filepath.Join(dir, "x"), []byte{'a'}, 0o644) 669 ioutil.WriteFile(filepath.Join(dir, "y"), []byte{'a'}, 0o644) 670 os.Mkdir(filepath.Join(dir, "d"), 0o755) 671 ioutil.WriteFile(filepath.Join(dir, "d", "a"), []byte{'b'}, 0o644) 672 ioutil.WriteFile(filepath.Join(dir, "d", "b"), []byte{'b'}, 0o644) 673 ps, out, _ := newTest(fs) 674 oldWd, err := os.Getwd() 675 if err != nil { 676 panic(err) 677 } 678 os.Chdir(dir) 679 defer os.Chdir(oldWd) 680 ps.Scan([]string{"."}, &ScanOptions{}) 681 err = ps.Ls([]string{"."}, &LsOptions{Recursive: true, Duplicate: true}) 682 check(t, err) 683 got := strings.TrimSpace(out.String()) 684 expected := strings.TrimSpace(` 685 .: 686 1 x 687 1 y 688 689 d: 690 1 a 691 1 b 692 `) 693 if got != expected { 694 t.Fatalf("expected '%s', got '%s'", expected, got) 695 } 696 } 697 698 func TestLsRelativeDir(t *testing.T) { 699 fs := afero.NewOsFs() 700 dir := tempDir() 701 defer os.RemoveAll(dir) 702 ioutil.WriteFile(filepath.Join(dir, "x"), []byte{'a'}, 0o644) 703 ioutil.WriteFile(filepath.Join(dir, "y"), []byte{'a'}, 0o644) 704 os.Mkdir(filepath.Join(dir, "d"), 0o755) 705 ioutil.WriteFile(filepath.Join(dir, "d", "a"), []byte{'b'}, 0o644) 706 ioutil.WriteFile(filepath.Join(dir, "d", "b"), []byte{'b'}, 0o644) 707 ps, out, _ := newTest(fs) 708 oldWd, err := os.Getwd() 709 if err != nil { 710 panic(err) 711 } 712 os.Chdir(dir) 713 defer os.Chdir(oldWd) 714 ps.Scan([]string{"."}, &ScanOptions{}) 715 err = ps.Ls([]string{"d"}, &LsOptions{}) 716 check(t, err) 717 got := strings.TrimSpace(out.String()) 718 expected := strings.TrimSpace(` 719 1 a 720 1 b 721 `) 722 if got != expected { 723 t.Fatalf("expected '%s', got '%s'", expected, got) 724 } 725 }