1 package ghfs
2
3 import (
4 "io"
5 "io/fs"
6 "os"
7 "path/filepath"
8 "testing"
9
10 "github.com/google/go-github/v47/github"
11 "github.com/stretchr/testify/assert"
12 )
13
14 type testFetcher struct{}
15
16 func (f *testFetcher) getContents(name string) (
17 *github.RepositoryContent, []*github.RepositoryContent, error,
18 ) {
19 path := filepath.Join("testdata", name)
20 file, err := os.Open(path)
21 if err != nil {
22 return nil, nil, err
23 }
24 stat, err := file.Stat()
25 if err != nil {
26 return nil, nil, err
27 }
28
29 if stat.IsDir() {
30 contents := []*github.RepositoryContent{
31 dirRepoContent(name),
32 }
33
34 entries, err := file.ReadDir(-1)
35 if err != nil {
36 return nil, nil, err
37 }
38
39 for _, e := range entries {
40 p := filepath.Join(path, e.Name())
41 if e.IsDir() {
42 contents = append(contents, dirRepoContent(p))
43 continue
44 }
45 stat, err := os.Stat(p)
46 if err != nil {
47 return nil, nil, err
48 }
49 contents = append(contents, fileRepoContent(p, stat.Size()))
50 }
51
52 return nil, contents, nil
53 }
54
55 return fileRepoContent(path, stat.Size()), nil, nil
56 }
57
58 func (f *testFetcher) downloadContents(c *github.RepositoryContent) (io.ReadCloser, error) {
59 return os.Open(c.GetPath())
60 }
61
62 func dirRepoContent(path string) *github.RepositoryContent {
63 typeDir := "dir"
64 name := filepath.Base(path)
65 return &github.RepositoryContent{
66 Type: &typeDir,
67 Name: &name,
68 Path: &path,
69 }
70 }
71
72 func fileRepoContent(path string, fsize int64) *github.RepositoryContent {
73 typeFile := "file"
74 name := filepath.Base(path)
75 size := int(fsize)
76 return &github.RepositoryContent{
77 Type: &typeFile,
78 Name: &name,
79 Path: &path,
80 Size: &size,
81 }
82 }
83
84 func TestFS(t *testing.T) {
85 ghFS := &FS{&testFetcher{}}
86
87 t.Run("Open File Exists", func(t *testing.T) {
88 files := []string{".version", "config.yaml", "foo/bar/baz/baz.txt"}
89 for _, f := range files {
90 file, err := ghFS.Open(f)
91 assert.NoError(t, err)
92
93 stat, err := file.Stat()
94 assert.NoError(t, err)
95 assert.False(t, stat.IsDir())
96 assert.True(t, stat.Mode().IsRegular())
97 assert.Equal(t, filepath.Base(f), stat.Name())
98
99 actual, err := io.ReadAll(file)
100 assert.NoError(t, err)
101
102 fixture, err := os.Open(filepath.Join("testdata", f))
103 assert.NoError(t, err)
104 expected, err := io.ReadAll(fixture)
105 assert.NoError(t, err)
106
107 assert.Equal(t, expected, actual)
108
109 expStat, err := fixture.Stat()
110 assert.NoError(t, err)
111 assert.Equal(t, expStat.Size(), stat.Size())
112 }
113 })
114
115 t.Run("Open Nonexistent File", func(t *testing.T) {
116 files := []string{".foo", "bar", "foo/bar/bing/file.txt"}
117 for _, f := range files {
118 file, err := ghFS.Open(f)
119 assert.ErrorIs(t, err, fs.ErrNotExist)
120 assert.Nil(t, file)
121 }
122 })
123
124 t.Run("Open Dir Exists", func(t *testing.T) {
125 dirs := []string{"foo", "foo/bar", "foo/bar/baz"}
126 for _, d := range dirs {
127 file, err := ghFS.Open(d)
128 assert.NoError(t, err)
129
130 stat, err := file.Stat()
131 assert.NoError(t, err)
132 assert.True(t, stat.IsDir())
133 assert.False(t, stat.Mode().IsRegular())
134 assert.Equal(t, filepath.Base(d), stat.Name())
135
136 _, err = file.Read(nil)
137 var pathErr *fs.PathError
138 assert.ErrorAs(t, err, &pathErr)
139 }
140 })
141
142 t.Run("ReadDir", func(t *testing.T) {
143 ee, err := ghFS.ReadDir("foo")
144 assert.NoError(t, err)
145 entriesContainsDir(t, ee, "bar")
146 entriesContainsFile(t, ee, "foo", "foo_test.txt")
147 entriesContainsFile(t, ee, "foo", "foo.txt")
148
149 ee, err = ghFS.ReadDir(".")
150 assert.NoError(t, err)
151 entriesContainsDir(t, ee, "foo")
152 entriesContainsFile(t, ee, "", ".version")
153 entriesContainsFile(t, ee, "", "config.yaml")
154 })
155 }
156
157 func entriesContainsDir(t *testing.T, ee []fs.DirEntry, dir string) {
158 t.Helper()
159 for _, e := range ee {
160 if e.Name() == dir && e.IsDir() {
161 return
162 }
163 }
164 t.Errorf("%s not found in entries", dir)
165 }
166
167 func entriesContainsFile(t *testing.T, ee []fs.DirEntry, dir, path string) {
168 t.Helper()
169 for _, e := range ee {
170 if e.Name() == path && !e.IsDir() {
171 actual, err := e.Info()
172 assert.NoError(t, err)
173
174 file, err := os.Open(filepath.Join("testdata", dir, path))
175 assert.NoError(t, err)
176 expected, err := file.Stat()
177 assert.NoError(t, err)
178
179 assert.False(t, expected.IsDir())
180 assert.True(t, expected.Mode().IsRegular())
181
182 assert.Equal(t, expected.Size(), actual.Size(), "%s not expected size", path)
183 return
184 }
185 }
186 t.Errorf("%s not found in entries", path)
187 }
188
View as plain text