aboutsummaryrefslogtreecommitdiff
path: root/internal/ignore/fuzz_test.go
blob: 0e9f0a39664641b24df94659d6d8345d893c44af (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
// SPDX-License-Identifier: GPL-3.0-or-later

package ignore

import (
	"strings"
	"testing"
)

// FuzzMatch: any pattern either fails to compile or matches any walked
// path without panicking, and gives the same answer twice. The oracle test
// checks answers against git; this checks everything else.
func FuzzMatch(f *testing.F) {
	for _, p := range []string{"*.log", "/a.txt", "build/", "**/readme.md", "[!a]*.txt", "[[:digit:]]*", `\`, "[", "a[/]b", "!", "**/**/**", "*a*a*a*b"} {
		f.Add(p, "dir/sub/a.txt")
	}
	f.Fuzz(func(t *testing.T, pattern, rel string) {
		m, err := New([]string{pattern})
		if err != nil {
			return
		}
		rel = walkedRel(rel)
		if rel == "" {
			return
		}
		if m.Match(rel, false) != m.Match(rel, false) {
			t.Fatalf("Match(%q) under %q is not deterministic", rel, pattern)
		}
		m.Match(rel, true)
	})
}

// walkedRel turns any string into a path of the shape Match accepts, as a
// directory walk produces it: slash-separated, with no empty, "." or ".."
// components.
func walkedRel(s string) string {
	var parts []string
	for _, p := range strings.Split(s, "/") {
		if p != "" && p != "." && p != ".." {
			parts = append(parts, p)
		}
	}
	return strings.Join(parts, "/")
}