github.com/elves/elvish@v0.15.0/pkg/cli/addons/navigation/cursor_test.go (about) 1 package navigation 2 3 import ( 4 "errors" 5 "strings" 6 7 "github.com/elves/elvish/pkg/testutil" 8 "github.com/elves/elvish/pkg/ui" 9 ) 10 11 var ( 12 errCannotCd = errors.New("cannot cd") 13 errNoSuchFile = errors.New("no such file") 14 errNoSuchDir = errors.New("no such directory") 15 ) 16 17 type testCursor struct { 18 root testutil.Dir 19 pwd []string 20 21 currentErr, parentErr, ascendErr, descendErr error 22 } 23 24 func (c *testCursor) Current() (File, error) { 25 if c.currentErr != nil { 26 return nil, c.currentErr 27 } 28 return getDirFile(c.root, c.pwd) 29 } 30 31 func (c *testCursor) Parent() (File, error) { 32 if c.parentErr != nil { 33 return nil, c.parentErr 34 } 35 parent := c.pwd 36 if len(parent) > 0 { 37 parent = parent[:len(parent)-1] 38 } 39 return getDirFile(c.root, parent) 40 } 41 42 func (c *testCursor) Ascend() error { 43 if c.ascendErr != nil { 44 return c.ascendErr 45 } 46 if len(c.pwd) > 0 { 47 c.pwd = c.pwd[:len(c.pwd)-1] 48 } 49 return nil 50 } 51 52 func (c *testCursor) Descend(name string) error { 53 if c.descendErr != nil { 54 return c.descendErr 55 } 56 pwdCopy := append([]string{}, c.pwd...) 57 childPath := append(pwdCopy, name) 58 if _, err := getDirFile(c.root, childPath); err == nil { 59 c.pwd = childPath 60 return nil 61 } 62 return errCannotCd 63 } 64 65 func getFile(root testutil.Dir, path []string) (File, error) { 66 var f interface{} = root 67 for _, p := range path { 68 d, ok := f.(testutil.Dir) 69 if !ok { 70 return nil, errNoSuchFile 71 } 72 f = d[p] 73 } 74 name := "" 75 if len(path) > 0 { 76 name = path[len(path)-1] 77 } 78 return testFile{name, f}, nil 79 } 80 81 func getDirFile(root testutil.Dir, path []string) (File, error) { 82 f, err := getFile(root, path) 83 if err != nil { 84 return nil, err 85 } 86 if !f.IsDirDeep() { 87 return nil, errNoSuchDir 88 } 89 return f, nil 90 } 91 92 type testFile struct { 93 name string 94 data interface{} 95 } 96 97 func (f testFile) Name() string { return f.name } 98 99 func (f testFile) ShowName() ui.Text { 100 // The style matches that of LS_COLORS in the test code. 101 switch { 102 case f.IsDirDeep(): 103 return ui.T(f.name, ui.FgBlue) 104 case strings.HasSuffix(f.name, ".png"): 105 return ui.T(f.name, ui.FgRed) 106 default: 107 return ui.T(f.name) 108 } 109 } 110 111 func (f testFile) IsDirDeep() bool { 112 _, ok := f.data.(testutil.Dir) 113 return ok 114 } 115 116 func (f testFile) Read() ([]File, []byte, error) { 117 if dir, ok := f.data.(testutil.Dir); ok { 118 files := make([]File, 0, len(dir)) 119 for name, data := range dir { 120 files = append(files, testFile{name, data}) 121 } 122 return files, nil, nil 123 } 124 return nil, []byte(f.data.(string)), nil 125 }