1 package fs
2
3 import (
4 "fmt"
5 "path/filepath"
6 "runtime"
7 "testing"
8
9 "gotest.tools/v3/assert"
10 is "gotest.tools/v3/assert/cmp"
11 "gotest.tools/v3/skip"
12 )
13
14 func TestEqualMissingRoot(t *testing.T) {
15 result := Equal("/bogus/path/does/not/exist", Expected(t))()
16 assert.Assert(t, !result.Success())
17 expected := "stat /bogus/path/does/not/exist: no such file or directory"
18 if runtime.GOOS == "windows" {
19 expected = "CreateFile /bogus/path/does/not/exist"
20 }
21 assert.Assert(t, is.Contains(result.(cmpFailure).FailureMessage(), expected))
22 }
23
24 func TestEqualModeMismatch(t *testing.T) {
25 dir := NewDir(t, t.Name(), WithMode(0500))
26 defer dir.Remove()
27
28 result := Equal(dir.Path(), Expected(t))()
29 assert.Assert(t, !result.Success())
30 expected := fmtExpected(`directory %s does not match expected:
31 /
32 mode: expected drwx------ got dr-x------
33 `, dir.Path())
34 if runtime.GOOS == "windows" {
35 expected = fmtExpected(`directory %s does not match expected:
36 \
37 mode: expected drwxrwxrwx got dr-xr-xr-x
38 `, dir.Path())
39 }
40 assert.Equal(t, result.(cmpFailure).FailureMessage(), expected)
41 }
42
43 func TestEqualRootIsAFile(t *testing.T) {
44 file := NewFile(t, t.Name())
45 defer file.Remove()
46
47 result := Equal(file.Path(), Expected(t))()
48 assert.Assert(t, !result.Success())
49 expected := fmt.Sprintf("path %s must be a directory", file.Path())
50 assert.Equal(t, result.(cmpFailure).FailureMessage(), expected)
51 }
52
53 func TestEqualSuccess(t *testing.T) {
54 dir := NewDir(t, t.Name(), WithMode(0700))
55 defer dir.Remove()
56
57 assert.Assert(t, Equal(dir.Path(), Expected(t)))
58 }
59
60 func TestEqualDirectoryHasWithExtraFiles(t *testing.T) {
61 dir := NewDir(t, t.Name(),
62 WithFile("extra1", "content"))
63 defer dir.Remove()
64
65 manifest := Expected(t, WithFile("file1", "content"))
66 result := Equal(dir.Path(), manifest)()
67 assert.Assert(t, !result.Success())
68 expected := fmtExpected(`directory %s does not match expected:
69 /
70 file1: expected file to exist
71 extra1: unexpected file
72 `, dir.Path())
73 assert.Equal(t, result.(cmpFailure).FailureMessage(), expected)
74 }
75
76 func fmtExpected(format string, args ...interface{}) string {
77 return filepath.FromSlash(fmt.Sprintf(format, args...))
78 }
79
80 func TestEqualWithMatchAnyFileContent(t *testing.T) {
81 dir := NewDir(t, t.Name(),
82 WithFile("data", "this is some data"))
83 defer dir.Remove()
84
85 expected := Expected(t,
86 WithFile("data", "different content", MatchAnyFileContent))
87 assert.Assert(t, Equal(dir.Path(), expected))
88 }
89
90 func TestEqualWithFileContent(t *testing.T) {
91 dir := NewDir(t, "assert-test-root",
92 WithFile("file1", "line1\nline2\nline3"))
93 defer dir.Remove()
94
95 manifest := Expected(t,
96 WithFile("file1", "line2\nline3"))
97
98 result := Equal(dir.Path(), manifest)()
99 expected := fmtExpected(`directory %s does not match expected:
100 /file1
101 content:
102 --- expected
103 +++ actual
104 @@ -1,2 +1,3 @@
105 +line1
106 line2
107 line3
108 `, dir.Path())
109 assert.Equal(t, result.(cmpFailure).FailureMessage(), expected)
110 }
111
112 func TestEqualWithMatchContentIgnoreCarriageReturn(t *testing.T) {
113 dir := NewDir(t, t.Name(),
114 WithFile("file1", "line1\r\nline2"))
115 defer dir.Remove()
116
117 manifest := Expected(t,
118 WithFile("file1", "line1\nline2", MatchContentIgnoreCarriageReturn))
119
120 result := Equal(dir.Path(), manifest)()
121 assert.Assert(t, result.Success())
122 }
123
124 func TestEqualDirectoryWithMatchExtraFiles(t *testing.T) {
125 file1 := WithFile("file1", "same in both")
126 dir := NewDir(t, t.Name(),
127 file1,
128 WithFile("extra", "some content"))
129 defer dir.Remove()
130
131 expected := Expected(t, file1, MatchExtraFiles)
132 assert.Assert(t, Equal(dir.Path(), expected))
133 }
134
135 func TestEqualManyFailures(t *testing.T) {
136 dir := NewDir(t, t.Name(),
137 WithFile("file1", "same in both"),
138 WithFile("extra", "some content"),
139 WithSymlink("sym1", "extra"))
140 defer dir.Remove()
141
142 manifest := Expected(t,
143 WithDir("subdir",
144 WithFile("somefile", "")),
145 WithFile("file1", "not the\nsame in both"))
146
147 result := Equal(dir.Path(), manifest)()
148 assert.Assert(t, !result.Success())
149
150 expected := fmtExpected(`directory %s does not match expected:
151 /
152 subdir: expected directory to exist
153 extra: unexpected file
154 sym1: unexpected symlink
155 /file1
156 content:
157 --- expected
158 +++ actual
159 @@ -1,2 +1 @@
160 -not the
161 same in both
162 `, dir.Path())
163 assert.Equal(t, result.(cmpFailure).FailureMessage(), expected)
164 }
165
166 type cmpFailure interface {
167 FailureMessage() string
168 }
169
170 func TestMatchAnyFileMode(t *testing.T) {
171 dir := NewDir(t, t.Name(),
172 WithFile("data", "content",
173 WithMode(0777)))
174 defer dir.Remove()
175
176 expected := Expected(t,
177 WithFile("data", "content", MatchAnyFileMode))
178 assert.Assert(t, Equal(dir.Path(), expected))
179 }
180
181 func TestMatchFileContent(t *testing.T) {
182 dir := NewDir(t, t.Name(),
183 WithFile("data", "content"))
184 defer dir.Remove()
185
186 t.Run("content matches", func(t *testing.T) {
187 matcher := func([]byte) CompareResult {
188 return is.ResultSuccess
189 }
190 manifest := Expected(t,
191 WithFile("data", "different", MatchFileContent(matcher)))
192 assert.Assert(t, Equal(dir.Path(), manifest))
193 })
194
195 t.Run("content does not match", func(t *testing.T) {
196 matcher := func([]byte) CompareResult {
197 return is.ResultFailure("data content differs from expected")
198 }
199 manifest := Expected(t,
200 WithFile("data", "content", MatchFileContent(matcher)))
201 result := Equal(dir.Path(), manifest)()
202 assert.Assert(t, !result.Success())
203
204 expected := fmtExpected(`directory %s does not match expected:
205 /data
206 content: data content differs from expected
207 `, dir.Path())
208 assert.Equal(t, result.(cmpFailure).FailureMessage(), expected)
209 })
210 }
211
212 func TestMatchExtraFilesGlob(t *testing.T) {
213 dir := NewDir(t, t.Name(),
214 WithFile("t.go", "data"),
215 WithFile("a.go", "data"),
216 WithFile("conf.yml", "content", WithMode(0600)))
217 defer dir.Remove()
218
219 t.Run("matching globs", func(t *testing.T) {
220 manifest := Expected(t,
221 MatchFilesWithGlob("*.go", MatchAnyFileMode, MatchAnyFileContent),
222 MatchFilesWithGlob("*.yml", MatchAnyFileMode, MatchAnyFileContent))
223 assert.Assert(t, Equal(dir.Path(), manifest))
224 })
225
226 t.Run("matching globs with wrong mode", func(t *testing.T) {
227 skip.If(t, runtime.GOOS == "windows", "expect mode does not match on windows")
228 manifest := Expected(t,
229 MatchFilesWithGlob("*.go", MatchAnyFileMode, MatchAnyFileContent),
230 MatchFilesWithGlob("*.yml", MatchAnyFileContent, WithMode(0700)))
231
232 result := Equal(dir.Path(), manifest)()
233
234 assert.Assert(t, !result.Success())
235 expected := fmtExpected(`directory %s does not match expected:
236 conf.yml
237 mode: expected -rwx------ got -rw-------
238 `, dir.Path())
239 assert.Equal(t, result.(cmpFailure).FailureMessage(), expected)
240 })
241
242 t.Run("matching partial glob", func(t *testing.T) {
243 manifest := Expected(t, MatchFilesWithGlob("*.go", MatchAnyFileMode, MatchAnyFileContent))
244 result := Equal(dir.Path(), manifest)()
245 assert.Assert(t, !result.Success())
246
247 expected := fmtExpected(`directory %s does not match expected:
248 /
249 conf.yml: unexpected file
250 `, dir.Path())
251 assert.Equal(t, result.(cmpFailure).FailureMessage(), expected)
252 })
253
254 t.Run("invalid glob", func(t *testing.T) {
255 manifest := Expected(t, MatchFilesWithGlob("[-x]"))
256 result := Equal(dir.Path(), manifest)()
257 assert.Assert(t, !result.Success())
258
259 expected := fmtExpected(`directory %s does not match expected:
260 /
261 a.go: unexpected file
262 conf.yml: unexpected file
263 t.go: unexpected file
264 a.go
265 failed to match glob pattern: syntax error in pattern
266 conf.yml
267 failed to match glob pattern: syntax error in pattern
268 t.go
269 failed to match glob pattern: syntax error in pattern
270 `, dir.Path())
271 assert.Equal(t, result.(cmpFailure).FailureMessage(), expected)
272 })
273 }
274
View as plain text