aboutsummaryrefslogtreecommitdiff
path: root/internal/ignore/ignore_test.go
blob: 04b60c415feb64394e44f1624756ba29b40363cd (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
// SPDX-License-Identifier: GPL-3.0-or-later

package ignore

import "testing"

func TestMatch(t *testing.T) {
	type c struct {
		rel   string
		isDir bool
		want  bool
	}
	tests := []struct {
		patterns []string
		cases    []c
	}{
		{[]string{"*.log"}, []c{{"a.log", false, true}, {"dir/b.log", false, true}, {"a.txt", false, false}}},
		{[]string{"/a.txt"}, []c{{"a.txt", false, true}, {"dir/a.txt", false, false}}},
		{[]string{"build/"}, []c{{"build", true, true}, {"build", false, false}, {"src/build", true, true}, {"build/x.bin", false, true}}},
		{[]string{"doc/*.md"}, []c{{"doc/r.md", false, true}, {"doc/sub/r.md", false, false}, {"x/doc/r.md", false, false}}},
		{[]string{"**/readme.md"}, []c{{"readme.md", false, true}, {"a/b/readme.md", false, true}}},
		{[]string{"deep/**"}, []c{{"deep", true, false}, {"deep/a", true, true}, {"deep/a/b/f.tmp", false, true}}},
		{[]string{"x/**/z.txt"}, []c{{"x/z.txt", false, true}, {"x/y/z.txt", false, true}, {"x/y/w/z.txt", false, true}, {"q/x/z.txt", false, false}}},
		{[]string{"*.part", "!keep.part"}, []c{{"a.part", false, true}, {"keep.part", false, false}}},
		{[]string{"dir/", "!dir/c.txt"}, []c{{"dir/c.txt", false, true}}},
		{[]string{".*"}, []c{{".hidden", false, true}, {"a/.cfg", false, true}, {"visible", false, false}}},
		{[]string{"a?.txt", "[bc].txt"}, []c{{"a1.txt", false, true}, {"a12.txt", false, false}, {"b.txt", false, true}, {"d.txt", false, false}}},
		{[]string{"[!a]*.txt"}, []c{{"b.txt", false, true}, {"a.txt", false, false}}},
		{[]string{"sub"}, []c{{"sub", true, true}, {"x/sub", true, true}, {"x/sub/f", false, true}, {"subx", false, false}}},
		{[]string{"\\#notes", "\\!bang"}, []c{{"#notes", false, true}, {"!bang", false, true}}},
		{[]string{"", "# comment"}, []c{{"# comment", false, false}}},
		{nil, []c{{"anything", false, false}}},
		{[]string{"x[]a]y"}, []c{{"x]y", false, true}, {"xay", false, true}, {"xby", false, false}}},
		{[]string{"a[/]b"}, []c{{"a/b", false, false}}},
	}
	for _, tt := range tests {
		m, err := New(tt.patterns)
		if err != nil {
			t.Fatalf("New(%q): %v", tt.patterns, err)
		}
		for _, cs := range tt.cases {
			if got := m.Match(cs.rel, cs.isDir); got != cs.want {
				t.Errorf("patterns %q: Match(%q, dir=%v) = %v, want %v", tt.patterns, cs.rel, cs.isDir, got, cs.want)
			}
		}
	}
}

func TestBadPattern(t *testing.T) {
	if _, err := New([]string{"[abc"}); err == nil || err.Error() != `bad ignore pattern "[abc": unterminated [` {
		t.Fatalf("got %v", err)
	}
	// "\]" escapes the only "]" to a literal member, leaving the class
	// with no terminator.
	if _, err := New([]string{"a[\\]d"}); err == nil || err.Error() != `bad ignore pattern "a[\\]d": unterminated [` {
		t.Fatalf("got %v", err)
	}
}