navigation_fs_test.go 2.4 KB

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