Imported Upstream version 2.5.1
[scm/test.git] / git / rev_list_scanner_test.go
1 package git
2
3 import (
4         "bufio"
5         "encoding/hex"
6         "errors"
7         "fmt"
8         "io/ioutil"
9         "strings"
10         "sync/atomic"
11         "testing"
12
13         "github.com/stretchr/testify/assert"
14 )
15
16 type ArgsTestCase struct {
17         Include []string
18         Exclude []string
19         Opt     *ScanRefsOptions
20
21         ExpectedStdin string
22         ExpectedArgs  []string
23         ExpectedErr   string
24 }
25
26 func (c *ArgsTestCase) Assert(t *testing.T) {
27         stdin, args, err := revListArgs(c.Include, c.Exclude, c.Opt)
28
29         if len(c.ExpectedErr) > 0 {
30                 assert.EqualError(t, err, c.ExpectedErr)
31         } else {
32                 assert.Nil(t, err)
33         }
34
35         assert.EqualValues(t, c.ExpectedArgs, args)
36
37         if stdin != nil {
38                 b, err := ioutil.ReadAll(stdin)
39                 assert.Nil(t, err)
40
41                 assert.Equal(t, c.ExpectedStdin, string(b))
42         } else if len(c.ExpectedStdin) > 0 {
43                 t.Errorf("git: expected stdin contents %s, got none", c.ExpectedStdin)
44         }
45 }
46
47 var (
48         s1 = "decafdecafdecafdecafdecafdecafdecafdecaf"
49         s2 = "cafecafecafecafecafecafecafecafecafecafe"
50 )
51
52 func TestRevListArgs(t *testing.T) {
53         for desc, c := range map[string]*ArgsTestCase{
54                 "scan refs deleted, left and right": {
55                         Include: []string{s1}, Exclude: []string{s2}, Opt: &ScanRefsOptions{
56                                 Mode:             ScanRefsMode,
57                                 SkipDeletedBlobs: false,
58                         },
59                         ExpectedStdin: fmt.Sprintf("%s\n^%s", s1, s2),
60                         ExpectedArgs:  []string{"rev-list", "--stdin", "--objects", "--do-walk", "--"},
61                 },
62                 "scan refs not deleted, left and right": {
63                         Include: []string{s1}, Exclude: []string{s2}, Opt: &ScanRefsOptions{
64                                 Mode:             ScanRefsMode,
65                                 SkipDeletedBlobs: true,
66                         },
67                         ExpectedStdin: fmt.Sprintf("%s\n^%s", s1, s2),
68                         ExpectedArgs:  []string{"rev-list", "--stdin", "--objects", "--no-walk", "--"},
69                 },
70                 "scan refs deleted, left only": {
71                         Include: []string{s1}, Opt: &ScanRefsOptions{
72                                 Mode:             ScanRefsMode,
73                                 SkipDeletedBlobs: false,
74                         },
75                         ExpectedStdin: s1,
76                         ExpectedArgs:  []string{"rev-list", "--stdin", "--objects", "--do-walk", "--"},
77                 },
78                 "scan refs not deleted, left only": {
79                         Include: []string{s1}, Opt: &ScanRefsOptions{
80                                 Mode:             ScanRefsMode,
81                                 SkipDeletedBlobs: true,
82                         },
83                         ExpectedStdin: s1,
84                         ExpectedArgs:  []string{"rev-list", "--stdin", "--objects", "--no-walk", "--"},
85                 },
86                 "scan all": {
87                         Include: []string{s1}, Exclude: []string{s2}, Opt: &ScanRefsOptions{
88                                 Mode: ScanAllMode,
89                         },
90                         ExpectedArgs: []string{"rev-list", "--stdin", "--objects", "--all", "--"},
91                 },
92                 "scan left to remote, no skipped refs": {
93                         Include: []string{s1}, Opt: &ScanRefsOptions{
94                                 Mode:        ScanLeftToRemoteMode,
95                                 Remote:      "origin",
96                                 SkippedRefs: []string{},
97                         },
98                         ExpectedStdin: s1,
99                         ExpectedArgs:  []string{"rev-list", "--stdin", "--objects", "--not", "--remotes=origin", "--"},
100                 },
101                 "scan left to remote, skipped refs": {
102                         Include: []string{s1}, Exclude: []string{s2}, Opt: &ScanRefsOptions{
103                                 Mode:        ScanLeftToRemoteMode,
104                                 Remote:      "origin",
105                                 SkippedRefs: []string{"a", "b", "c"},
106                         },
107                         ExpectedArgs:  []string{"rev-list", "--stdin", "--objects", "--"},
108                         ExpectedStdin: s1 + "\n^" + s2 + "\na\nb\nc",
109                 },
110                 "scan unknown type": {
111                         Include: []string{s1}, Exclude: []string{s2}, Opt: &ScanRefsOptions{
112                                 Mode: ScanningMode(-1),
113                         },
114                         ExpectedErr: "unknown scan type: -1",
115                 },
116                 "scan date order": {
117                         Include: []string{s1}, Exclude: []string{s2}, Opt: &ScanRefsOptions{
118                                 Mode:  ScanRefsMode,
119                                 Order: DateRevListOrder,
120                         },
121                         ExpectedStdin: fmt.Sprintf("%s\n^%s", s1, s2),
122                         ExpectedArgs:  []string{"rev-list", "--stdin", "--objects", "--date-order", "--do-walk", "--"},
123                 },
124                 "scan author date order": {
125                         Include: []string{s1}, Exclude: []string{s2}, Opt: &ScanRefsOptions{
126                                 Mode:  ScanRefsMode,
127                                 Order: AuthorDateRevListOrder,
128                         },
129                         ExpectedStdin: fmt.Sprintf("%s\n^%s", s1, s2),
130                         ExpectedArgs:  []string{"rev-list", "--stdin", "--objects", "--author-date-order", "--do-walk", "--"},
131                 },
132                 "scan topo order": {
133                         Include: []string{s1}, Exclude: []string{s2}, Opt: &ScanRefsOptions{
134                                 Mode:  ScanRefsMode,
135                                 Order: TopoRevListOrder,
136                         },
137                         ExpectedStdin: fmt.Sprintf("%s\n^%s", s1, s2),
138                         ExpectedArgs:  []string{"rev-list", "--stdin", "--objects", "--topo-order", "--do-walk", "--"},
139                 },
140                 "scan commits only": {
141                         Include: []string{s1}, Exclude: []string{s2}, Opt: &ScanRefsOptions{
142                                 Mode:        ScanRefsMode,
143                                 CommitsOnly: true,
144                         },
145                         ExpectedStdin: fmt.Sprintf("%s\n^%s", s1, s2),
146                         ExpectedArgs:  []string{"rev-list", "--stdin", "--do-walk", "--"},
147                 },
148                 "scan reverse": {
149                         Include: []string{s1}, Exclude: []string{s2}, Opt: &ScanRefsOptions{
150                                 Mode:    ScanRefsMode,
151                                 Reverse: true,
152                         },
153                         ExpectedStdin: fmt.Sprintf("%s\n^%s", s1, s2),
154                         ExpectedArgs:  []string{"rev-list", "--stdin", "--objects", "--reverse", "--do-walk", "--"},
155                 },
156         } {
157                 t.Run(desc, c.Assert)
158         }
159 }
160
161 func TestRevListScannerCallsClose(t *testing.T) {
162         var called uint32
163         err := errors.New("Hello world")
164
165         s := &RevListScanner{
166                 closeFn: func() error {
167                         atomic.AddUint32(&called, 1)
168                         return err
169                 },
170         }
171
172         got := s.Close()
173
174         assert.EqualValues(t, 1, atomic.LoadUint32(&called))
175         assert.Equal(t, err, got)
176 }
177
178 func TestRevListScannerTreatsCloseFnAsOptional(t *testing.T) {
179         s := &RevListScanner{
180                 closeFn: nil,
181         }
182
183         defer func() { assert.Nil(t, recover()) }()
184
185         assert.Nil(t, s.Close())
186 }
187
188 func TestRevListScannerParsesLinesWithNames(t *testing.T) {
189         given := "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa name.dat"
190         s := &RevListScanner{
191                 s: bufio.NewScanner(strings.NewReader(given)),
192         }
193
194         assert.True(t, s.Scan())
195         assert.Equal(t, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", hex.EncodeToString(s.OID()))
196         assert.Equal(t, "name.dat", s.Name())
197         assert.Nil(t, s.Err())
198
199         assert.False(t, s.Scan())
200         assert.Equal(t, "", s.Name())
201         assert.Nil(t, s.OID())
202         assert.Nil(t, s.Err())
203 }
204
205 func TestRevListScannerParsesLinesWithoutName(t *testing.T) {
206         given := "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
207         s := &RevListScanner{
208                 s: bufio.NewScanner(strings.NewReader(given)),
209         }
210
211         assert.True(t, s.Scan())
212         assert.Equal(t, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", hex.EncodeToString(s.OID()))
213         assert.Nil(t, s.Err())
214
215         assert.False(t, s.Scan())
216         assert.Equal(t, "", s.Name())
217         assert.Nil(t, s.OID())
218         assert.Nil(t, s.Err())
219 }