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  }