test_data_provider.go 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. package testutil
  2. import (
  3. "bytes"
  4. "io"
  5. "os"
  6. "path/filepath"
  7. "github.com/stretchr/testify/require"
  8. )
  9. const (
  10. // TestDataFolderName is the name of the testdata directory
  11. TestDataFolderName = "testdata"
  12. )
  13. // TestDataProvider provides access to test data images
  14. type TestDataProvider struct {
  15. path string
  16. t require.TestingT
  17. }
  18. // New creates a new TestDataProvider
  19. func NewTestDataProvider(t require.TestingT) *TestDataProvider {
  20. if h, ok := t.(interface{ Helper() }); ok {
  21. h.Helper()
  22. }
  23. path, err := findProjectRoot()
  24. if err != nil {
  25. require.NoError(t, err)
  26. }
  27. return &TestDataProvider{
  28. path: filepath.Join(path, TestDataFolderName),
  29. t: t,
  30. }
  31. }
  32. // findProjectRoot finds the absolute path to the project root by looking for go.mod
  33. func findProjectRoot() (string, error) {
  34. // Start from current working directory
  35. wd, err := os.Getwd()
  36. if err != nil {
  37. return "", err
  38. }
  39. // Walk up the directory tree looking for go.mod
  40. dir := wd
  41. for {
  42. goModPath := filepath.Join(dir, "go.mod")
  43. if _, err := os.Stat(goModPath); err == nil {
  44. // Found go.mod, this is our project root
  45. return dir, nil
  46. }
  47. parent := filepath.Dir(dir)
  48. if parent == dir {
  49. // Reached filesystem root without finding go.mod
  50. break
  51. }
  52. dir = parent
  53. }
  54. return "", os.ErrNotExist
  55. }
  56. // Root returns the absolute path to the testdata directory
  57. func (p *TestDataProvider) Root() string {
  58. return p.path
  59. }
  60. // Path returns the absolute path to a file in the testdata directory
  61. func (p *TestDataProvider) Path(parts ...string) string {
  62. allParts := append([]string{p.path}, parts...)
  63. return filepath.Join(allParts...)
  64. }
  65. // Read reads a test data file and returns it as bytes
  66. func (p *TestDataProvider) Read(name string) []byte {
  67. if h, ok := p.t.(interface{ Helper() }); ok {
  68. h.Helper()
  69. }
  70. data, err := os.ReadFile(p.Path(name))
  71. require.NoError(p.t, err)
  72. return data
  73. }
  74. // Data reads a test data file and returns it as imagedata.ImageData
  75. func (p *TestDataProvider) Reader(name string) *bytes.Reader {
  76. return bytes.NewReader(p.Read(name))
  77. }
  78. // FileEqualsToReader compares the contents of a test data file with the contents of the given reader
  79. func (p *TestDataProvider) FileEqualsToReader(name string, reader io.Reader) bool {
  80. expected := p.Reader(name)
  81. return ReadersEqual(p.t, expected, reader)
  82. }