git_helper 1.3.1 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,233 @@
1
+ require_relative '../../lib/git_helper/merge_request.rb'
2
+
3
+ describe GitHelper::GitLabMergeRequest do
4
+ let(:local_code) { double(:local_code, read_template: 'template') }
5
+ let(:highline_cli) { double(:highline_cli) }
6
+ let(:gitlab_client_client) { double(:gitlab_client_client, project: :project, merge_request: :merge_request, create_merge_request: :created) }
7
+ let(:gitlab_client) { double(:gitlab_client, client: gitlab_client_client) }
8
+ let(:options) do
9
+ {
10
+ local_project: 'emmasax4/git_helper',
11
+ local_branch: 'main',
12
+ local_code: local_code,
13
+ cli: highline_cli
14
+ }
15
+ end
16
+
17
+ subject { GitHelper::GitLabMergeRequest.new(options) }
18
+
19
+ before do
20
+ allow(GitHelper::GitLabClient).to receive(:new).and_return(gitlab_client)
21
+ end
22
+
23
+ describe '#create' do
24
+ it 'should call the gitlab client to create' do
25
+ allow(subject).to receive(:squash_merge_request).and_return(true)
26
+ allow(subject).to receive(:remove_source_branch).and_return(false)
27
+ allow(subject).to receive(:new_mr_body).and_return('')
28
+ expect(gitlab_client_client).to receive(:create_merge_request)
29
+ subject.create({base_branch: 'base', new_title: 'title'})
30
+ end
31
+
32
+ it 'should call various other methods' do
33
+ expect(subject).to receive(:squash_merge_request).and_return(true)
34
+ expect(subject).to receive(:remove_source_branch).and_return(false)
35
+ expect(subject).to receive(:new_mr_body).and_return('')
36
+ allow(gitlab_client_client).to receive(:create_merge_request)
37
+ subject.create({base_branch: 'base', new_title: 'title'})
38
+ end
39
+
40
+ it 'should catch the raised error if the creation does not work' do
41
+ allow(subject).to receive(:squash_merge_request).and_return(true)
42
+ allow(subject).to receive(:remove_source_branch).and_return(false)
43
+ allow(subject).to receive(:new_mr_body).and_return('')
44
+ allow(gitlab_client_client).to receive(:create_merge_request).and_raise(StandardError)
45
+ expect(subject.create({base_branch: 'base', new_title: 'title'})).to eq(nil)
46
+ end
47
+ end
48
+
49
+ describe '#merge' do
50
+ it 'should call the gitlab client to merge' do
51
+ allow(subject).to receive(:existing_mr).and_return(double(should_remove_source_branch: true, squash: false, title: 'title'))
52
+ allow(subject).to receive(:mr_id).and_return(123)
53
+ expect(gitlab_client_client).to receive(:accept_merge_request)
54
+ subject.merge
55
+ end
56
+
57
+ it 'should call various other methods' do
58
+ expect(subject).to receive(:existing_mr).and_return(double(should_remove_source_branch: true, squash: false, title: 'title')).at_least(:once)
59
+ expect(subject).to receive(:mr_id).and_return(123).at_least(:once)
60
+ allow(gitlab_client_client).to receive(:accept_merge_request)
61
+ subject.merge
62
+ end
63
+
64
+ it 'should catch the raised error if the merge does not work' do
65
+ allow(subject).to receive(:existing_mr).and_return(double(should_remove_source_branch: true, squash: false, title: 'title'))
66
+ allow(subject).to receive(:mr_id).and_return(123)
67
+ allow(gitlab_client_client).to receive(:accept_merge_request).and_raise(StandardError)
68
+ expect(subject.merge).to eq(nil)
69
+ end
70
+
71
+ it 'should try to merge multiple times if the first merge errors' do
72
+ allow(subject).to receive(:existing_mr).and_return(double(should_remove_source_branch: true, squash: false, title: 'title'))
73
+ allow(subject).to receive(:mr_id).and_return(123)
74
+ expect(gitlab_client_client).to receive(:accept_merge_request).and_return(double(merge_commit_sha: nil)).exactly(2).times
75
+ expect(subject.merge).to eq(nil)
76
+ end
77
+ end
78
+
79
+ describe '#new_mr_body' do
80
+ it 'should call the local code if the template to apply exists' do
81
+ allow(subject).to receive(:template_name_to_apply).and_return('')
82
+ expect(local_code).to receive(:read_template)
83
+ subject.send(:new_mr_body)
84
+ end
85
+
86
+ it 'should not call the local code if the template is nil' do
87
+ allow(subject).to receive(:template_name_to_apply).and_return(nil)
88
+ expect(local_code).not_to receive(:read_template)
89
+ subject.send(:new_mr_body)
90
+ end
91
+
92
+ it 'should return an empty string if the template is nil' do
93
+ allow(subject).to receive(:template_name_to_apply).and_return(nil)
94
+ expect(subject.send(:new_mr_body)).to eq('')
95
+ end
96
+ end
97
+
98
+ describe '#template_name_to_apply' do
99
+ context 'if MR template options are empty' do
100
+ it 'should return nil' do
101
+ allow(subject).to receive(:mr_template_options).and_return([])
102
+ expect(subject.send(:template_name_to_apply)).to eq(nil)
103
+ end
104
+ end
105
+
106
+ context 'if there is one template option' do
107
+ it 'should call the CLI to ask about a single template' do
108
+ allow(subject).to receive(:mr_template_options).and_return(['template1'])
109
+ expect(highline_cli).to receive(:apply_template?).and_return(true)
110
+ subject.send(:template_name_to_apply)
111
+ end
112
+
113
+ it 'should return the single template if the user says yes' do
114
+ allow(subject).to receive(:mr_template_options).and_return(['template1'])
115
+ allow(highline_cli).to receive(:apply_template?).and_return(true)
116
+ expect(subject.send(:template_name_to_apply)).to eq('template1')
117
+ end
118
+
119
+ it 'should return nil if the user says no' do
120
+ allow(subject).to receive(:mr_template_options).and_return(['template1'])
121
+ allow(highline_cli).to receive(:apply_template?).and_return(false)
122
+ expect(subject.send(:template_name_to_apply)).to eq(nil)
123
+ end
124
+ end
125
+
126
+ context 'if there are multiple template options' do
127
+ it 'should call the CLI to ask which of multiple templates to apply' do
128
+ allow(subject).to receive(:mr_template_options).and_return(['template1', 'template2'])
129
+ expect(highline_cli).to receive(:template_to_apply).and_return('template1')
130
+ subject.send(:template_name_to_apply)
131
+ end
132
+
133
+ it 'should return the answer template if the user says yes' do
134
+ allow(subject).to receive(:mr_template_options).and_return(['template1', 'template2'])
135
+ allow(highline_cli).to receive(:template_to_apply).and_return('template1')
136
+ expect(subject.send(:template_name_to_apply)).to eq('template1')
137
+ end
138
+
139
+ it 'should return nil if the user says no' do
140
+ allow(subject).to receive(:mr_template_options).and_return(['template1', 'template2'])
141
+ allow(highline_cli).to receive(:template_to_apply).and_return('None')
142
+ expect(subject.send(:template_name_to_apply)).to eq(nil)
143
+ end
144
+ end
145
+ end
146
+
147
+ describe '#mr_template_options' do
148
+ it 'should call the local code' do
149
+ expect(local_code).to receive(:template_options)
150
+ subject.send(:mr_template_options)
151
+ end
152
+ end
153
+
154
+ describe '#mr_id' do
155
+ it 'should ask the CLI for the code request ID' do
156
+ expect(highline_cli).to receive(:code_request_id).and_return(123)
157
+ subject.send(:mr_id)
158
+ end
159
+
160
+ it 'should equal an integer' do
161
+ expect(highline_cli).to receive(:code_request_id).and_return(123)
162
+ expect(subject.send(:mr_id)).to eq(123)
163
+ end
164
+ end
165
+
166
+ describe '#squash_merge_request' do
167
+ it 'should ask the CLI for the code request ID' do
168
+ expect(highline_cli).to receive(:squash_merge_request?).and_return(true)
169
+ subject.send(:squash_merge_request)
170
+ end
171
+
172
+ it 'should be a boolean' do
173
+ expect(highline_cli).to receive(:squash_merge_request?).and_return(false)
174
+ expect([true, false]).to include(subject.send(:squash_merge_request))
175
+ end
176
+ end
177
+
178
+ describe '#remove_source_branch' do
179
+ before do
180
+ allow(subject).to receive(:existing_project).and_return(double(remove_source_branch_after_merge: nil))
181
+ end
182
+
183
+ context 'when the existing project has no setting' do
184
+ it 'should ask the CLI for the code request ID' do
185
+ expect(highline_cli).to receive(:remove_source_branch?).and_return(true)
186
+ subject.send(:remove_source_branch)
187
+ end
188
+
189
+ it 'should be a boolean' do
190
+ allow(highline_cli).to receive(:remove_source_branch?).and_return(false)
191
+ expect([true, false]).to include(subject.send(:remove_source_branch))
192
+ end
193
+ end
194
+
195
+ it 'should ask the existing project' do
196
+ expect(subject).to receive(:existing_project).and_return(double(remove_source_branch_after_merge: true))
197
+ subject.send(:remove_source_branch)
198
+ end
199
+
200
+ it "should return the existing project's setting if it exists" do
201
+ allow(subject).to receive(:existing_project).and_return(double(remove_source_branch_after_merge: true))
202
+ expect(subject.send(:remove_source_branch)).to eq(true)
203
+ end
204
+
205
+ it "should return the existing project's setting if it exists" do
206
+ allow(subject).to receive(:existing_project).and_return(double(remove_source_branch_after_merge: false))
207
+ allow(highline_cli).to receive(:remove_source_branch?).and_return(true)
208
+ expect(subject.send(:remove_source_branch)).to eq(true)
209
+ end
210
+ end
211
+
212
+ describe '#existing_project' do
213
+ it 'should call the gitlab client' do
214
+ expect(gitlab_client_client).to receive(:project).and_return(:project)
215
+ subject.send(:existing_project)
216
+ end
217
+ end
218
+
219
+ describe '#existing_mr' do
220
+ it 'should call the gitlab client' do
221
+ allow(highline_cli).to receive(:code_request_id).and_return(123)
222
+ expect(gitlab_client_client).to receive(:merge_request).and_return(:merge_request)
223
+ subject.send(:existing_mr)
224
+ end
225
+ end
226
+
227
+ describe '#gitlab_client' do
228
+ it 'should call the gitlab client' do
229
+ expect(GitHelper::GitLabClient).to receive(:new).and_return(gitlab_client)
230
+ subject.send(:gitlab_client)
231
+ end
232
+ end
233
+ end
@@ -0,0 +1,43 @@
1
+ require_relative '../../lib/git_helper/new_branch.rb'
2
+
3
+ describe GitHelper::NewBranch do
4
+ let(:new_branch_name) { 'new-branch-name' }
5
+ let(:local_code) { double(:local_code, new_branch: :commit) }
6
+ let(:cli) { double(:highline_cli, new_branch_name: new_branch_name) }
7
+
8
+ subject { GitHelper::NewBranch.new }
9
+
10
+ before do
11
+ allow(GitHelper::LocalCode).to receive(:new).and_return(local_code)
12
+ allow(GitHelper::HighlineCli).to receive(:new).and_return(cli)
13
+ end
14
+
15
+ it 'should call GitHelper::LocalCode' do
16
+ expect(GitHelper::LocalCode).to receive(:new).and_return(local_code)
17
+ subject.execute
18
+ end
19
+
20
+ it 'should call the new_branch method from the local code class' do
21
+ expect(local_code).to receive(:new_branch)
22
+ subject.execute
23
+ end
24
+
25
+ context 'when no branch name is passed in' do
26
+ it 'should call the highline cli' do
27
+ expect(GitHelper::HighlineCli).to receive(:new).and_return(cli)
28
+ subject.execute
29
+ end
30
+
31
+ it 'should ask the highline cli what the new branch name should be' do
32
+ expect(cli).to receive(:new_branch_name)
33
+ subject.execute
34
+ end
35
+ end
36
+
37
+ context 'when there is a branch name passed in' do
38
+ it 'should not create a highline cli' do
39
+ expect(GitHelper::HighlineCli).not_to receive(:new)
40
+ subject.execute(new_branch_name)
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,25 @@
1
+ require_relative '../../lib/git_helper/octokit_client.rb'
2
+
3
+ describe GitHelper::OctokitClient do
4
+ let(:git_config_reader) { double(:git_config_reader, github_token: :token) }
5
+
6
+ subject { GitHelper::OctokitClient.new }
7
+
8
+ before do
9
+ allow(GitHelper::GitConfigReader).to receive(:new).and_return(git_config_reader)
10
+ end
11
+
12
+ describe '#client' do
13
+ it 'should call the GitLab client to make a new client' do
14
+ expect(Octokit::Client).to receive(:new)
15
+ subject.client
16
+ end
17
+ end
18
+
19
+ describe '#git_config_reader' do
20
+ it 'should make a new git config reader' do
21
+ expect(GitHelper::GitConfigReader).to receive(:new)
22
+ subject.send(:git_config_reader)
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,245 @@
1
+ require_relative '../../lib/git_helper/pull_request.rb'
2
+
3
+ describe GitHelper::GitHubPullRequest do
4
+ let(:local_code) { double(:local_code, read_template: 'template') }
5
+ let(:highline_cli) { double(:highline_cli) }
6
+ let(:octokit_client_client) { double(:octokit_client_client, project: :project, merge_request: :merge_request, create_merge_request: :created) }
7
+ let(:octokit_client) { double(:octokit_client, client: octokit_client_client) }
8
+ let(:options) do
9
+ {
10
+ local_project: 'emmasax4/git_helper',
11
+ local_branch: 'main',
12
+ local_code: local_code,
13
+ cli: highline_cli
14
+ }
15
+ end
16
+
17
+ subject { GitHelper::GitHubPullRequest.new(options) }
18
+
19
+ before do
20
+ allow(GitHelper::OctokitClient).to receive(:new).and_return(octokit_client)
21
+ end
22
+
23
+ describe '#create' do
24
+ it 'should call the octokit client to create' do
25
+ allow(subject).to receive(:new_pr_body).and_return('')
26
+ expect(octokit_client_client).to receive(:create_pull_request)
27
+ subject.create({base_branch: 'base', new_title: 'title'})
28
+ end
29
+
30
+ it 'should call various other methods' do
31
+ expect(subject).to receive(:new_pr_body).and_return('').at_least(:once)
32
+ allow(octokit_client_client).to receive(:create_pull_request)
33
+ subject.create({base_branch: 'base', new_title: 'title'})
34
+ end
35
+
36
+ it 'should catch the raised error if the creation does not work' do
37
+ allow(subject).to receive(:new_pr_body).and_return('')
38
+ allow(octokit_client_client).to receive(:create_pull_request).and_raise(StandardError)
39
+ expect(subject.create({base_branch: 'base', new_title: 'title'})).to eq(nil)
40
+ end
41
+ end
42
+
43
+ describe '#merge' do
44
+ it 'should call the octokit client to merge' do
45
+ allow(subject).to receive(:existing_pr).and_return(double(title: 'title'))
46
+ allow(subject).to receive(:merge_method).and_return('rebase')
47
+ allow(subject).to receive(:pr_id).and_return(123)
48
+ expect(octokit_client_client).to receive(:merge_pull_request)
49
+ subject.merge
50
+ end
51
+
52
+ it 'should call various other methods' do
53
+ expect(subject).to receive(:existing_pr).and_return(double(title: 'title')).at_least(:once)
54
+ expect(subject).to receive(:merge_method).and_return('rebase').at_least(:once)
55
+ expect(subject).to receive(:pr_id).and_return(123).at_least(:once)
56
+ allow(octokit_client_client).to receive(:merge_pull_request)
57
+ subject.merge
58
+ end
59
+
60
+ it 'should catch the raised error if the merge does not work' do
61
+ allow(subject).to receive(:existing_pr).and_return(double(title: 'title'))
62
+ allow(subject).to receive(:merge_method).and_return('rebase')
63
+ allow(subject).to receive(:pr_id).and_return(123)
64
+ allow(octokit_client_client).to receive(:merge_pull_request).and_raise(StandardError)
65
+ expect(subject.merge).to eq(nil)
66
+ end
67
+ end
68
+
69
+ describe '#new_pr_body' do
70
+ it 'should call the local code if the template to apply exists' do
71
+ allow(subject).to receive(:template_name_to_apply).and_return('')
72
+ expect(local_code).to receive(:read_template)
73
+ subject.send(:new_pr_body)
74
+ end
75
+
76
+ it 'should not call the local code if the template is nil' do
77
+ allow(subject).to receive(:template_name_to_apply).and_return(nil)
78
+ expect(local_code).not_to receive(:read_template)
79
+ subject.send(:new_pr_body)
80
+ end
81
+
82
+ it 'should return an empty string if the template is nil' do
83
+ allow(subject).to receive(:template_name_to_apply).and_return(nil)
84
+ expect(subject.send(:new_pr_body)).to eq('')
85
+ end
86
+ end
87
+
88
+ describe '#template_name_to_apply' do
89
+ context 'if PR template options are empty' do
90
+ it 'should return nil' do
91
+ allow(subject).to receive(:pr_template_options).and_return([])
92
+ expect(subject.send(:template_name_to_apply)).to eq(nil)
93
+ end
94
+ end
95
+
96
+ context 'if there is one template option' do
97
+ it 'should call the CLI to ask about a single template' do
98
+ allow(subject).to receive(:pr_template_options).and_return(['template1'])
99
+ expect(highline_cli).to receive(:apply_template?).and_return(true)
100
+ subject.send(:template_name_to_apply)
101
+ end
102
+
103
+ it 'should return the single template if the user says yes' do
104
+ allow(subject).to receive(:pr_template_options).and_return(['template1'])
105
+ allow(highline_cli).to receive(:apply_template?).and_return(true)
106
+ expect(subject.send(:template_name_to_apply)).to eq('template1')
107
+ end
108
+
109
+ it 'should return nil if the user says no' do
110
+ allow(subject).to receive(:pr_template_options).and_return(['template1'])
111
+ allow(highline_cli).to receive(:apply_template?).and_return(false)
112
+ expect(subject.send(:template_name_to_apply)).to eq(nil)
113
+ end
114
+ end
115
+
116
+ context 'if there are multiple template options' do
117
+ it 'should call the CLI to ask which of multiple templates to apply' do
118
+ allow(subject).to receive(:pr_template_options).and_return(['template1', 'template2'])
119
+ expect(highline_cli).to receive(:template_to_apply).and_return('template1')
120
+ subject.send(:template_name_to_apply)
121
+ end
122
+
123
+ it 'should return the answer template if the user says yes' do
124
+ allow(subject).to receive(:pr_template_options).and_return(['template1', 'template2'])
125
+ allow(highline_cli).to receive(:template_to_apply).and_return('template1')
126
+ expect(subject.send(:template_name_to_apply)).to eq('template1')
127
+ end
128
+
129
+ it 'should return nil if the user says no' do
130
+ allow(subject).to receive(:pr_template_options).and_return(['template1', 'template2'])
131
+ allow(highline_cli).to receive(:template_to_apply).and_return('None')
132
+ expect(subject.send(:template_name_to_apply)).to eq(nil)
133
+ end
134
+ end
135
+ end
136
+
137
+ describe '#pr_template_options' do
138
+ it 'should call the local code' do
139
+ expect(local_code).to receive(:template_options)
140
+ subject.send(:pr_template_options)
141
+ end
142
+ end
143
+
144
+ describe '#pr_id' do
145
+ it 'should ask the CLI for the code request ID' do
146
+ expect(highline_cli).to receive(:code_request_id).and_return(123)
147
+ subject.send(:pr_id)
148
+ end
149
+
150
+ it 'should equal an integer' do
151
+ expect(highline_cli).to receive(:code_request_id).and_return(123)
152
+ expect(subject.send(:pr_id)).to eq(123)
153
+ end
154
+ end
155
+
156
+ describe '#merge_method' do
157
+ let(:project) { double(:project, allow_merge_commit: true, allow_squash_merge: true, allow_rebase_merge: true) }
158
+
159
+ before do
160
+ allow(subject).to receive(:existing_project).and_return(project)
161
+ allow(highline_cli).to receive(:merge_method)
162
+ end
163
+
164
+ it 'should ask the CLI for the merge_method' do
165
+ expect(highline_cli).to receive(:merge_method).and_return('merge')
166
+ subject.send(:merge_method)
167
+ end
168
+
169
+ it 'should be a string' do
170
+ allow(highline_cli).to receive(:merge_method).and_return('merge')
171
+ expect(subject.send(:merge_method)).to be_a(String)
172
+ end
173
+
174
+ context "if there's only one item" do
175
+ let(:project) { double(:project, allow_merge_commit: true, allow_squash_merge: false, allow_rebase_merge: false) }
176
+
177
+ it 'should not ask the CLI anything' do
178
+ expect(highline_cli).not_to receive(:merge_method)
179
+ subject.send(:merge_method)
180
+ end
181
+ end
182
+ end
183
+
184
+ describe '#merge_options' do
185
+ let(:project) { double(:project, allow_merge_commit: true, allow_squash_merge: true, allow_rebase_merge: true) }
186
+
187
+ before do
188
+ allow(subject).to receive(:existing_project).and_return(project)
189
+ end
190
+
191
+ it 'should return an array' do
192
+ expect(subject.send(:merge_options)).to be_a(Array)
193
+ end
194
+
195
+ it 'should have three items' do
196
+ expect(subject.send(:merge_options).length).to eq(3)
197
+ end
198
+
199
+ context 'when two options are present' do
200
+ let(:project) { double(:project, allow_merge_commit: false, allow_squash_merge: true, allow_rebase_merge: true) }
201
+
202
+ it 'should have two items' do
203
+ expect(subject.send(:merge_options).length).to eq(2)
204
+ end
205
+ end
206
+
207
+ context 'when one option is present' do
208
+ let(:project) { double(:project, allow_merge_commit: false, allow_squash_merge: false, allow_rebase_merge: true) }
209
+
210
+ it 'should have one item' do
211
+ expect(subject.send(:merge_options).length).to eq(1)
212
+ end
213
+ end
214
+
215
+ context 'when no options are present' do
216
+ let(:project) { double(:project, allow_merge_commit: false, allow_squash_merge: false, allow_rebase_merge: false) }
217
+
218
+ it 'should have no items' do
219
+ expect(subject.send(:merge_options).length).to eq(0)
220
+ end
221
+ end
222
+ end
223
+
224
+ describe '#existing_project' do
225
+ it 'should call the octokit client' do
226
+ expect(octokit_client_client).to receive(:repository).and_return(:repository)
227
+ subject.send(:existing_project)
228
+ end
229
+ end
230
+
231
+ describe '#existing_pr' do
232
+ it 'should call the octokit client' do
233
+ allow(highline_cli).to receive(:code_request_id).and_return(123)
234
+ expect(octokit_client_client).to receive(:pull_request).and_return(:pull_request)
235
+ subject.send(:existing_pr)
236
+ end
237
+ end
238
+
239
+ describe '#octokit_client' do
240
+ it 'should call the octokit client' do
241
+ expect(GitHelper::OctokitClient).to receive(:new).and_return(octokit_client)
242
+ subject.send(:octokit_client)
243
+ end
244
+ end
245
+ end