Skip to content

Commit 51cebad

Browse files
committed
Move test cases to JSON file
1 parent d045209 commit 51cebad

File tree

2 files changed

+343
-305
lines changed

2 files changed

+343
-305
lines changed

match_test.go

+34-305
Original file line numberDiff line numberDiff line change
@@ -1,330 +1,59 @@
11
package codeowners
22

33
import (
4+
"encoding/json"
45
"io/ioutil"
5-
"os"
6-
"os/exec"
7-
"path"
86
"testing"
97

108
"github.com/stretchr/testify/assert"
119
"github.com/stretchr/testify/require"
1210
)
1311

12+
type patternTest struct {
13+
Name string `json:"name"`
14+
Pattern string `json:"pattern"`
15+
Paths map[string]bool `json:"paths"`
16+
Focus bool `json:"focus"`
17+
}
18+
1419
func TestMatch(t *testing.T) {
15-
examples := []struct {
16-
name string
17-
pattern string
18-
paths map[string]bool
19-
}{
20-
{
21-
name: "single-segment pattern",
22-
pattern: "foo",
23-
paths: map[string]bool{
24-
"foo": true,
25-
"foo/": true,
26-
"foo/bar": true,
27-
"bar/foo": true,
28-
"bar/foo/baz": true,
29-
"bar/baz": false,
30-
},
31-
},
32-
{
33-
name: "single-segment pattern with leading slash",
34-
pattern: "/foo",
35-
paths: map[string]bool{
36-
"foo": true,
37-
"fool": false,
38-
"foo/": true,
39-
"foo/bar": true,
40-
"bar/foo": false,
41-
"bar/foo/baz": false,
42-
"bar/baz": false,
43-
},
44-
},
45-
{
46-
name: "single-segment pattern with trailing slash",
47-
pattern: "foo/",
48-
paths: map[string]bool{
49-
"foo": false,
50-
"foo/": true,
51-
"foo/bar": true,
52-
"bar/foo": false,
53-
"bar/foo/baz": true,
54-
"bar/baz": false,
55-
},
56-
},
57-
{
58-
name: "single-segment pattern with leading and trailing slash",
59-
pattern: "/foo/",
60-
paths: map[string]bool{
61-
"foo": false,
62-
"foo/": true,
63-
"foo/bar": true,
64-
"bar/foo": false,
65-
"bar/foo/baz": false,
66-
"bar/baz": false,
67-
},
68-
},
69-
{
70-
name: "multi-segment pattern",
71-
pattern: "foo/bar",
72-
paths: map[string]bool{
73-
"foo/bar": true,
74-
"foo/bart": false,
75-
"foo/bar/baz": true,
76-
"baz/foo/bar": false,
77-
"baz/foo/bar/qux": false,
78-
},
79-
},
80-
{
81-
name: "multi-segment pattern with leading slash",
82-
pattern: "/foo/bar",
83-
paths: map[string]bool{
84-
"foo/bar": true,
85-
"foo/bar/baz": true,
86-
"baz/foo/bar": false,
87-
"baz/foo/bar/qux": false,
88-
},
89-
},
90-
{
91-
name: "multi-segment pattern with trailing slash",
92-
pattern: "foo/bar/",
93-
paths: map[string]bool{
94-
"foo/bar": false,
95-
"foo/bar/baz": true,
96-
"baz/foo/bar": false,
97-
"baz/foo/bar/qux": false,
98-
},
99-
},
100-
{
101-
name: "multi-segment pattern with leading and trailing slash",
102-
pattern: "/foo/bar/",
103-
paths: map[string]bool{
104-
"foo/bar": false,
105-
"foo/bar/baz": true,
106-
"baz/foo/bar": false,
107-
"baz/foo/bar/qux": false,
108-
},
109-
},
110-
{
111-
name: "single segment pattern with wildcard",
112-
pattern: "f*",
113-
paths: map[string]bool{
114-
"foo": true,
115-
"foo/": true,
116-
"foo/bar": true,
117-
"bar/foo": true,
118-
"bar/foo/baz": true,
119-
"bar/baz": false,
120-
"xfoo": false,
121-
},
122-
},
123-
{
124-
name: "single segment pattern with leading slash and wildcard",
125-
pattern: "/f*",
126-
paths: map[string]bool{
127-
"foo": true,
128-
"foo/": true,
129-
"foo/bar": true,
130-
"bar/foo": false,
131-
"bar/foo/baz": false,
132-
"bar/baz": false,
133-
"xfoo": false,
134-
},
135-
},
136-
{
137-
name: "single segment pattern with trailing slash and wildcard",
138-
pattern: "f*/",
139-
paths: map[string]bool{
140-
"foo": false,
141-
"foo/": true,
142-
"foo/bar": true,
143-
"bar/foo": false,
144-
"bar/foo/baz": true,
145-
"bar/baz": false,
146-
"xfoo": false,
147-
},
148-
},
149-
{
150-
name: "single segment pattern with leading and trailing slash and wildcard",
151-
pattern: "/f*/",
152-
paths: map[string]bool{
153-
"foo": false,
154-
"foo/": true,
155-
"foo/bar": true,
156-
"bar/foo": false,
157-
"bar/foo/baz": false,
158-
"bar/baz": false,
159-
"xfoo": false,
160-
},
161-
},
162-
{
163-
name: "single segment pattern with escaped wildcard",
164-
pattern: "f\\*o",
165-
paths: map[string]bool{
166-
"foo": false,
167-
"f*o": true,
168-
},
169-
},
170-
{
171-
name: "multi-segment pattern with wildcard",
172-
pattern: "foo/*.txt",
173-
paths: map[string]bool{
174-
"foo": false,
175-
"foo/": false,
176-
"foo/bar.txt": true,
177-
"foo/bar/baz.txt": false,
178-
"qux/foo/bar.txt": false,
179-
"qux/foo/bar/baz.txt": false,
180-
},
181-
},
182-
{
183-
name: "single segment pattern with single-character wildcard",
184-
pattern: "f?o",
185-
paths: map[string]bool{
186-
"foo": true,
187-
"fo": false,
188-
"fooo": false,
189-
},
190-
},
191-
{
192-
name: "single segment pattern with escaped single-character wildcard",
193-
pattern: "f\\?o",
194-
paths: map[string]bool{
195-
"foo": false,
196-
"f?o": true,
197-
},
198-
},
199-
{
200-
name: "single segment pattern with character range",
201-
pattern: "[Ffb]oo",
202-
paths: map[string]bool{
203-
"foo": true,
204-
"Foo": true,
205-
"boo": true,
206-
"too": false,
207-
},
208-
},
209-
{
210-
name: "single segment pattern with escaped character range",
211-
pattern: "[\\]f]o\\[o\\]",
212-
paths: map[string]bool{
213-
"fo[o]": true,
214-
"]o[o]": true,
215-
"foo": false,
216-
},
217-
},
218-
{
219-
name: "leading double-asterisk wildcard",
220-
pattern: "**/foo/bar",
221-
paths: map[string]bool{
222-
"foo/bar": true,
223-
"qux/foo/bar": true,
224-
"qux/foo/bar/baz": true,
225-
"foo/baz/bar": false,
226-
"qux/foo/baz/bar": false,
227-
},
228-
},
229-
{
230-
name: "leading double-asterisk wildcard with regular wildcard",
231-
pattern: "**/*bar*",
232-
paths: map[string]bool{
233-
"bar": true,
234-
"foo/bar": true,
235-
"foo/rebar": true,
236-
"foo/barrio": true,
237-
"foo/qux/bar": true,
238-
},
239-
},
240-
{
241-
name: "trailing double-asterisk wildcard",
242-
pattern: "foo/bar/**",
243-
paths: map[string]bool{
244-
"foo/bar": false,
245-
"foo/bar/baz": true,
246-
"foo/bar/baz/qux": true,
247-
"qux/foo/bar": false,
248-
"qux/foo/bar/baz": false,
249-
},
250-
},
251-
{
252-
name: "middle double-asterisk wildcard",
253-
pattern: "foo/**/bar",
254-
paths: map[string]bool{
255-
"foo/bar": true,
256-
"foo/bar/baz": true,
257-
"foo/qux/bar/baz": true,
258-
"foo/qux/quux/bar/baz": true,
259-
"foo/bar/baz/qux": true,
260-
"qux/foo/bar": false,
261-
"qux/foo/bar/baz": false,
262-
},
263-
},
264-
{
265-
name: "middle double-asterisk wildcard with trailing slash",
266-
pattern: "foo/**/",
267-
paths: map[string]bool{
268-
"foo/bar": false,
269-
"foo/bar/": true,
270-
"foo/bar/baz": true,
271-
},
272-
},
273-
}
20+
data, err := ioutil.ReadFile("testdata/patterns.json")
21+
require.NoError(t, err)
27422

275-
tmpRepoPath, cleanup := createGitRepo(t)
276-
defer cleanup()
23+
var tests []patternTest
24+
err = json.Unmarshal(data, &tests)
25+
require.NoError(t, err)
27726

278-
for _, e := range examples {
279-
ioutil.WriteFile(path.Join(tmpRepoPath, ".gitignore"), []byte(e.pattern+"\n"), 0644)
27+
focus := false
28+
for _, test := range tests {
29+
if test.Focus {
30+
focus = true
31+
}
32+
}
28033

281-
t.Run(e.name, func(t *testing.T) {
282-
for path, shouldMatch := range e.paths {
283-
gitMatch := gitCheckIgnore(t, tmpRepoPath, path)
284-
require.Equal(t, gitMatch, shouldMatch, "bad test! pattern=%s path=%s git-match=%v expectation=%v", e.pattern, path, gitMatch, shouldMatch)
34+
for _, test := range tests {
35+
if test.Focus != focus {
36+
continue
37+
}
28538

286-
pattern, err := newPattern(e.pattern)
39+
t.Run(test.Name, func(t *testing.T) {
40+
for path, shouldMatch := range test.Paths {
41+
pattern, err := newPattern(test.Pattern)
28742
require.NoError(t, err)
28843

44+
// Debugging tips:
45+
// - Print the generated regex: `fmt.Println(pattern.regex.String())`
46+
// - Only run a single case by adding `"focus" : true` to the test in the JSON file
47+
28948
actual, err := pattern.match(path)
290-
assert.NoError(t, err)
49+
require.NoError(t, err)
50+
29151
if shouldMatch {
292-
assert.True(t, actual, "expected pattern %s to match path %s", e.pattern, path)
52+
assert.True(t, actual, "expected pattern %s to match path %s", test.Pattern, path)
29353
} else {
294-
assert.False(t, actual, "expected pattern %s to not match path %s", e.pattern, path)
54+
assert.False(t, actual, "expected pattern %s to not match path %s", test.Pattern, path)
29555
}
29656
}
29757
})
29858
}
29959
}
300-
301-
func createGitRepo(t *testing.T) (string, func()) {
302-
dir, err := ioutil.TempDir("", "codeowners-test-")
303-
if err != nil {
304-
t.Fatalf("creating git repo tempdir: %v", err)
305-
}
306-
307-
cmd := exec.Command("git", "init")
308-
cmd.Dir = dir
309-
if err = cmd.Run(); err != nil {
310-
t.Fatalf("initializing git repo: %v", err)
311-
}
312-
313-
cleanup := func() {
314-
os.RemoveAll(dir) // clean up
315-
}
316-
317-
return dir, cleanup
318-
}
319-
320-
func gitCheckIgnore(t *testing.T, dir, path string) bool {
321-
cmd := exec.Command("git", "check-ignore", path)
322-
cmd.Dir = dir
323-
if err := cmd.Run(); err != nil {
324-
if _, isExitError := err.(*exec.ExitError); isExitError {
325-
return false
326-
}
327-
t.Fatalf("running git check-ignore: %v", err)
328-
}
329-
return true
330-
}

0 commit comments

Comments
 (0)