test_data_provider.go 2.4 KB

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