File utilities and wrappers that may be useful for some projects.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

168 lines
5.3KB

  1. // This particular file tests whatever functions are defined in util.go. For the Windows equivalent, please see util_windows_test.
  2. package fileutils_test
  3. import (
  4. "io/ioutil"
  5. "os"
  6. "path/filepath"
  7. "strings"
  8. "testing"
  9. "git.destrealm.org/go/fileutils"
  10. "gopkg.in/yaml.v2"
  11. )
  12. // For the unit tests involving configuration discovery, most everything should
  13. // be done automatically, but you'll need to do a couple of things first. In
  14. // particular, you'll need to copy the config.sample.yaml file to config.yaml
  15. // and edit it according to your own local configuration. For XDG_CONFIG_HOME
  16. // (which resides in ~/.config), you may need to either create the directory
  17. // ~/.config or you may need to pick a file within. Follow the instructions in
  18. // the YAML file for more specific information.
  19. type App struct {
  20. App struct {
  21. FindConfig *FindConfig `yaml:"find-config"`
  22. } `yaml:"app"`
  23. }
  24. type FindConfig struct {
  25. Abs string `yaml:"abs"`
  26. CWD string
  27. XDGConfigHome string `yaml:"xdg-config-home"`
  28. XDGConfigDirs []string `yaml:"xdg-config-dirs"`
  29. XDGConfigHomeForced string `yaml:"xdg-config-home-forced"`
  30. XDGConfigHomeBase string `yaml:"xdg-config-home-base"`
  31. Etc string
  32. EtcBase string `yaml:"etc-base"`
  33. }
  34. func readConfig(path string) (*FindConfig, error) {
  35. config := &App{}
  36. contents, err := ioutil.ReadFile(path)
  37. if err != nil {
  38. return nil, err
  39. }
  40. if err := yaml.Unmarshal(contents, config); err != nil {
  41. return nil, err
  42. }
  43. return config.App.FindConfig, nil
  44. }
  45. func Test_FindConfig(t *testing.T) {
  46. config, err := readConfig("config.yaml")
  47. if err != nil {
  48. t.Error("unable to read unit test configuration:", err)
  49. return
  50. }
  51. // Test absolute path matches. What this should do in FindConfig is bail and return the absolute path (corrected, if need be, such as if the absolute path specified in the test points to a symlink) before any other tests are performed.
  52. path, err := filepath.Abs(config.Abs)
  53. if err != nil {
  54. t.Errorf("error reading absolute path for file %v", config.Abs)
  55. }
  56. test := fileutils.FindConfig(path, "")
  57. if strings.Compare(test, path) != 0 {
  58. t.Error("ABS path test: located paths don't match")
  59. t.Logf("wanted: %v", path)
  60. t.Logf("found: %v", test)
  61. }
  62. // Test matches in CWD.
  63. path, err = filepath.Abs(config.CWD)
  64. if err != nil {
  65. t.Errorf("error getting absolute path for file %v", config.CWD)
  66. }
  67. test = fileutils.FindConfig(filepath.Base(path), "")
  68. if strings.Compare(test, path) != 0 {
  69. t.Error("CWD test: located paths don't match")
  70. t.Logf("wanted: %v", path)
  71. t.Logf("found: %v", test)
  72. }
  73. // Test XDG_CONFIG_HOME. Requires changing the environment variable. We
  74. // attempt to reconfigure it both if an error occur as well as after we're
  75. // finished with the test.
  76. path, err = filepath.Abs(config.XDGConfigHome)
  77. env, envExists := os.LookupEnv("XDG_CONFIG_HOME")
  78. if err = os.Setenv("XDG_CONFIG_HOME", filepath.Dir(path)); err != nil {
  79. t.Error("could not set the environment variable XDG_CONFIG_HOME:", err)
  80. if envExists {
  81. _ = os.Setenv("XDG_CONFIG_HOME", env)
  82. }
  83. }
  84. test = fileutils.FindConfig(filepath.Base(path), "")
  85. if strings.Compare(test, path) != 0 {
  86. t.Error("XDG_CONFIG_HOME test: located paths don't match")
  87. t.Logf("wanted: %v", path)
  88. t.Logf("found: %v", test)
  89. }
  90. // Reset environment.
  91. if envExists {
  92. _ = os.Setenv("XDG_CONFIG_HOME", env)
  93. }
  94. // Test XDG_CONFIG_DIRS. Requires changing the environment variable. As with
  95. // the previous rendition(s), we attempt to reconfigure it both if an error
  96. // occurs as well as after we've finished with the test. This will reset the
  97. // value to its prior state.
  98. dirs := make([]string, len(config.XDGConfigDirs))
  99. for i, dir := range config.XDGConfigDirs {
  100. dirs[i] = filepath.Dir(fileutils.AbsPath(dir))
  101. }
  102. env, envExists = os.LookupEnv("XDG_CONFIG_DIRS")
  103. if err = os.Setenv("XDG_CONFIG_DIRS", strings.Join(dirs, ":")); err != nil {
  104. t.Error("could not set the environment variable XDG_CONFIG_DIRS:", err)
  105. if envExists {
  106. _ = os.Setenv("XDG_CONFIG_DIRS", env)
  107. }
  108. }
  109. for _, path := range config.XDGConfigDirs {
  110. path = fileutils.AbsPath(path)
  111. if err != nil {
  112. t.Logf("failed reading absolute path for path %v; skipping", path)
  113. continue
  114. }
  115. test = fileutils.FindConfig(filepath.Base(path), "")
  116. if strings.Compare(test, path) != 0 {
  117. t.Error("XDG_CONFIG_DIRS test: located paths don't match")
  118. t.Logf("wanted: %v", path)
  119. t.Logf("found: %v", test)
  120. }
  121. // Reset environment.
  122. if envExists {
  123. _ = os.Setenv("XDG_CONFIG_DIRS", env)
  124. }
  125. }
  126. // Test the hard-coded .config path. If xdg-config-home-base is supplied,
  127. // we'll use that as the base directory and pass it in as FindConfig's second
  128. // argument.
  129. path = fileutils.AbsPath(config.XDGConfigHomeForced)
  130. test = fileutils.FindConfig(filepath.Base(config.XDGConfigHomeForced),
  131. config.XDGConfigHomeBase)
  132. if strings.Compare(test, path) != 0 {
  133. t.Error("XDG_CONFIG_HOME (forced) test: located paths don't match")
  134. t.Logf("wanted: %v", path)
  135. t.Logf("found: %v", test)
  136. }
  137. // Test FindConfig's behavior with /etc.
  138. path, _ = filepath.Abs(config.Etc)
  139. test = fileutils.FindConfig(filepath.Base(config.Etc), config.EtcBase)
  140. if strings.Compare(test, path) != 0 {
  141. t.Error("/etc test: located paths don't match")
  142. t.Logf("wanted: %v", path)
  143. t.Logf("found: %v", test)
  144. }
  145. }