forked from rclone/gofakes3
-
Notifications
You must be signed in to change notification settings - Fork 1
/
prefix_test.go
131 lines (118 loc) · 3.58 KB
/
prefix_test.go
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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
package gofakes3
import (
"fmt"
"reflect"
"testing"
)
func TestPrefixMatch(t *testing.T) {
// Cheapo helpers for hiding pointer strings, which are used to increase
// information density in the test case table:
s := func(v string) *string { return &v }
for idx, tc := range []struct {
key string
p *string
d *string
out *string
common bool
}{
{key: "foo/bar", p: s("foo"), d: s("/"), out: s("foo/"), common: true},
{key: "foo/bar", p: s("foo/ba"), d: s("/"), out: s("foo/bar")},
{key: "foo/bar", p: s("foo/ba/"), d: s("/"), out: nil},
{key: "foo/bar", p: s("/"), d: s("/"), out: s("foo/"), common: true},
// Without a delimiter, it's just a boring ol' prefix match:
{key: "foo/bar", p: s("foo/b"), out: s("foo/b")},
{key: "foo/bar", p: s("foo/"), out: s("foo/")},
{key: "foo/bar", p: s("foo"), out: s("foo")},
{key: "foo/bar", p: s("fo"), out: s("fo")},
{key: "foo/bar", p: s("f"), out: s("f")},
{key: "foo/bar", p: s("q"), out: nil},
// This could be a source of trouble - does "no prefix" mean "match
// everything" or "match nothing"? What about "empty prefix"? For now,
// these cases simply document what the curret algorithm is expected to
// do, but this needs further exploration:
{key: "foo/bar", p: nil, out: s("foo/bar")},
{key: "foo/bar", p: s(""), out: s("")},
} {
t.Run("", func(t *testing.T) {
prefix := Prefix{
HasPrefix: tc.p != nil,
HasDelimiter: tc.d != nil,
Prefix: unwrapStr(tc.p),
Delimiter: unwrapStr(tc.d),
}
var match PrefixMatch
matched := prefix.Match(tc.key, &match)
if (tc.out == nil) != (!matched) {
t.Fatal("prefix match failed at index", idx)
}
if tc.out != nil {
if *tc.out != match.MatchedPart {
t.Fatal("prefix matched part failed at index", idx, *tc.out, "!=", match.MatchedPart)
}
if tc.common != match.CommonPrefix {
t.Fatal("prefix common failed at index", idx)
}
}
})
}
}
func TestNewPrefix(t *testing.T) {
s := func(in string) *string { return &in }
for _, tc := range []struct {
prefix, delim *string
out Prefix
}{
{nil, nil, Prefix{}},
{s("foo"), nil, Prefix{HasPrefix: true, Prefix: "foo"}},
{nil, s("foo"), Prefix{HasDelimiter: true, Delimiter: "foo"}},
{s("foo"), s("bar"), Prefix{HasPrefix: true, Prefix: "foo", HasDelimiter: true, Delimiter: "bar"}},
} {
t.Run("", func(t *testing.T) {
exp := NewPrefix(tc.prefix, tc.delim)
if !reflect.DeepEqual(tc.out, exp) {
t.Fatal(tc.out, "!=", exp)
}
})
}
}
func TestPrefixFilePrefix(t *testing.T) {
s := func(v string) *string { return &v }
for idx, tc := range []struct {
p, d *string
ok bool
path, rem string
}{
{s("foo/bar"), s("/"), true, "foo", "bar"},
{s("foo/bar/"), s("/"), true, "foo/bar", ""},
{s("foo/bar/b"), s("/"), true, "foo/bar", "b"},
{s("foo"), s("/"), true, "", "foo"},
{s("foo/"), s("/"), true, "foo", ""},
{s("/"), s("/"), true, "", ""},
{s(""), s("/"), true, "", ""},
{s(""), nil, false, "", ""},
{s("foo"), nil, false, "", ""},
{s("foo/bar"), nil, false, "", ""},
{s("foo-bar"), s("-"), false, "", ""},
} {
t.Run(fmt.Sprintf("%d/(%s-%s)", idx, tc.path, tc.rem), func(t *testing.T) {
prefix := NewPrefix(tc.p, tc.d)
foundPath, foundRem, ok := prefix.FilePrefix()
if tc.ok != ok {
t.Fatal()
} else if tc.ok {
if tc.path != foundPath {
t.Fatal("prefix path", tc.path, "!=", foundPath)
}
if tc.rem != foundRem {
t.Fatal("prefix rem", tc.rem, "!=", foundRem)
}
}
})
}
}
func unwrapStr(v *string) string {
if v != nil {
return *v
}
return ""
}