1package random_bugs
2
3import (
4 "math/rand"
5 "strings"
6 "time"
7
8 "github.com/MichaelMure/git-bug/bug"
9 "github.com/MichaelMure/git-bug/identity"
10 "github.com/MichaelMure/git-bug/repository"
11 "github.com/icrowley/fake"
12)
13
14type opsGenerator func(bug.Interface, identity.Interface)
15
16type Options struct {
17 BugNumber int
18 PersonNumber int
19 MinOp int
20 MaxOp int
21}
22
23func DefaultOptions() Options {
24 return Options{
25 BugNumber: 15,
26 PersonNumber: 5,
27 MinOp: 3,
28 MaxOp: 20,
29 }
30}
31
32func CommitRandomBugs(repo repository.ClockedRepo, opts Options) {
33 CommitRandomBugsWithSeed(repo, opts, time.Now().UnixNano())
34}
35
36func CommitRandomBugsWithSeed(repo repository.ClockedRepo, opts Options, seed int64) {
37 generateRandomPersons(repo, opts.PersonNumber)
38
39 bugs := generateRandomBugsWithSeed(opts, seed)
40
41 for _, b := range bugs {
42 err := b.Commit(repo)
43 if err != nil {
44 panic(err)
45 }
46 }
47}
48
49func generateRandomBugsWithSeed(opts Options, seed int64) []*bug.Bug {
50 rand.Seed(seed)
51 fake.Seed(seed)
52
53 opsGenerators := []opsGenerator{
54 comment,
55 comment,
56 title,
57 labels,
58 open,
59 close,
60 }
61
62 result := make([]*bug.Bug, opts.BugNumber)
63
64 for i := 0; i < opts.BugNumber; i++ {
65 addedLabels = []string{}
66
67 b, _, err := bug.Create(
68 randomPerson(),
69 time.Now().Unix(),
70 fake.Sentence(),
71 paragraphs(),
72 )
73
74 if err != nil {
75 panic(err)
76 }
77
78 nOps := opts.MinOp
79
80 if opts.MaxOp > opts.MinOp {
81 nOps += rand.Intn(opts.MaxOp - opts.MinOp)
82 }
83
84 for j := 0; j < nOps; j++ {
85 index := rand.Intn(len(opsGenerators))
86 opsGenerators[index](b, randomPerson())
87 }
88
89 result[i] = b
90 }
91
92 return result
93}
94
95func GenerateRandomOperationPacks(packNumber int, opNumber int) []*bug.OperationPack {
96 return GenerateRandomOperationPacksWithSeed(packNumber, opNumber, time.Now().UnixNano())
97}
98
99func GenerateRandomOperationPacksWithSeed(packNumber int, opNumber int, seed int64) []*bug.OperationPack {
100 // Note: this is a bit crude, only generate a Create + Comments
101
102 panic("this piece of code needs to be updated to make sure that the identities " +
103 "are properly commit before usage. That is, generateRandomPersons() need to be called.")
104
105 rand.Seed(seed)
106 fake.Seed(seed)
107
108 result := make([]*bug.OperationPack, packNumber)
109
110 for i := 0; i < packNumber; i++ {
111 opp := &bug.OperationPack{}
112
113 var op bug.Operation
114
115 op = bug.NewCreateOp(
116 randomPerson(),
117 time.Now().Unix(),
118 fake.Sentence(),
119 paragraphs(),
120 nil,
121 )
122
123 opp.Append(op)
124
125 for j := 0; j < opNumber-1; j++ {
126 op = bug.NewAddCommentOp(
127 randomPerson(),
128 time.Now().Unix(),
129 paragraphs(),
130 nil,
131 )
132 opp.Append(op)
133 }
134
135 result[i] = opp
136 }
137
138 return result
139}
140
141func person() identity.Interface {
142 return identity.NewIdentity(fake.FullName(), fake.EmailAddress())
143}
144
145var persons []identity.Interface
146
147func generateRandomPersons(repo repository.ClockedRepo, n int) {
148 persons = make([]identity.Interface, n)
149 for i := range persons {
150 p := person()
151 err := p.Commit(repo)
152 if err != nil {
153 panic(err)
154 }
155 persons[i] = p
156 }
157}
158
159func randomPerson() identity.Interface {
160 index := rand.Intn(len(persons))
161 return persons[index]
162}
163
164func paragraphs() string {
165 p := fake.Paragraphs()
166 return strings.Replace(p, "\t", "\n\n", -1)
167}
168
169func comment(b bug.Interface, p identity.Interface) {
170 _, _ = bug.AddComment(b, p, time.Now().Unix(), paragraphs())
171}
172
173func title(b bug.Interface, p identity.Interface) {
174 _, _ = bug.SetTitle(b, p, time.Now().Unix(), fake.Sentence())
175}
176
177func open(b bug.Interface, p identity.Interface) {
178 _, _ = bug.Open(b, p, time.Now().Unix())
179}
180
181func close(b bug.Interface, p identity.Interface) {
182 _, _ = bug.Close(b, p, time.Now().Unix())
183}
184
185var addedLabels []string
186
187func labels(b bug.Interface, p identity.Interface) {
188 var removed []string
189 nbRemoved := rand.Intn(3)
190 for nbRemoved > 0 && len(addedLabels) > 0 {
191 index := rand.Intn(len(addedLabels))
192 removed = append(removed, addedLabels[index])
193 addedLabels[index] = addedLabels[len(addedLabels)-1]
194 addedLabels = addedLabels[:len(addedLabels)-1]
195 nbRemoved--
196 }
197
198 var added []string
199 nbAdded := rand.Intn(3)
200 for i := 0; i < nbAdded; i++ {
201 label := fake.Word()
202 added = append(added, label)
203 addedLabels = append(addedLabels, label)
204 }
205
206 // ignore error
207 // if the randomisation produce no changes, no op
208 // is added to the bug
209 _, _, _ = bug.ChangeLabels(b, p, time.Now().Unix(), added, removed)
210}