git_helper 1.1.0 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,13 +1,23 @@
1
1
  require_relative './octokit_client.rb'
2
2
  require_relative './highline_cli.rb'
3
+ require_relative './local_code.rb'
3
4
 
4
5
  module GitHelper
5
6
  class GitHubPullRequest
6
- def create
7
+ attr_accessor :local_repo, :local_branch, :local_code, :cli, :base_branch, :new_pr_title
8
+
9
+ def initialize(options)
10
+ @local_repo = options[:local_project]
11
+ @local_branch = options[:local_branch]
12
+ @local_code = options[:local_code]
13
+ @cli = options[:cli]
14
+ end
15
+
16
+ def create(options)
17
+ @base_branch = options[:base_branch]
18
+ @new_pr_title = options[:new_title]
19
+
7
20
  begin
8
- # Ask these questions right away
9
- base_branch
10
- new_pr_title
11
21
  new_pr_body
12
22
 
13
23
  puts "Creating pull request: #{new_pr_title}"
@@ -30,12 +40,11 @@ module GitHelper
30
40
 
31
41
  def merge
32
42
  begin
33
- # Ask these questions right away
34
43
  pr_id
35
44
  merge_method
36
45
 
37
46
  puts "Merging pull request: #{pr_id}"
38
- merge = octokit_client.merge_pull_request(local_repo, pr_id, existing_pr_title, { merge_method: merge_method })
47
+ merge = octokit_client.merge_pull_request(local_repo, pr_id, existing_pr.title, { merge_method: merge_method })
39
48
  puts "Pull request successfully merged: #{merge.sha}"
40
49
  rescue Octokit::UnprocessableEntity => e
41
50
  puts 'Could not merge pull request:'
@@ -66,100 +75,61 @@ module GitHelper
66
75
  end
67
76
  end
68
77
 
69
- private def local_repo
70
- # Get the repository by looking in the remote URLs for the full repository name
71
- remotes = `git remote -v`
72
- return remotes.scan(/\S[\s]*[\S]+.com[\S]{1}([\S]*).git/).first.first
78
+ private def new_pr_body
79
+ @new_pr_body ||= template_name_to_apply ? local_code.read_template(template_name_to_apply) : ''
73
80
  end
74
81
 
75
- private def local_branch
76
- # Get the current branch by looking in the list of branches for the *
77
- branches = `git branch`
78
- return branches.scan(/\*\s([\S]*)/).first.first
79
- end
82
+ private def template_name_to_apply
83
+ return @template_name_to_apply if @template_name_to_apply
84
+ @template_name_to_apply = nil
80
85
 
81
- private def read_template
82
- if pr_template_options.count == 1
83
- apply_template?(pr_template_options.first) ? File.open(pr_template_options.first).read : ''
84
- else
85
- template_file_name_to_apply = template_to_apply
86
- template_file_name_to_apply == "None" ? '' : File.open(template_file_name_to_apply).read
86
+ unless pr_template_options.empty?
87
+ if pr_template_options.count == 1
88
+ apply_single_template = cli.apply_template?(pr_template_options.first, 'pull')
89
+ @template_name_to_apply = pr_template_options.first if apply_single_template
90
+ else
91
+ response = cli.template_to_apply(pr_template_options, 'pull')
92
+ @template_name_to_apply = response unless response == 'None'
93
+ end
87
94
  end
88
- end
89
-
90
- private def merge_options
91
- [ 'merge', 'squash', 'rebase' ]
92
- end
93
-
94
- private def pr_id
95
- @pr_id ||= cli.ask('Pull Request ID?')
96
- end
97
-
98
- private def existing_pr_title
99
- @existing_pr_title ||= octokit_client.pull_request(local_repo, pr_id).title
100
- end
101
-
102
- private def new_pr_title
103
- @new_pr_title ||= accept_autogenerated_title? ? autogenerated_title : cli.ask('Title?')
104
- end
105
-
106
- private def new_pr_body
107
- @new_pr_body ||= pr_template_options.empty? ? '' : read_template
108
- end
109
95
 
110
- private def base_branch
111
- @base_branch ||= base_branch_default? ? default_branch : cli.ask('Base branch?')
96
+ @template_name_to_apply
112
97
  end
113
98
 
114
- private def autogenerated_title
115
- @autogenerated_title ||= local_branch.split('_')[0..-1].join(' ').capitalize
99
+ private def pr_template_options
100
+ @pr_template_options ||= local_code.template_options({
101
+ nested_directory_name: 'PULL_REQUEST_TEMPLATE',
102
+ non_nested_file_name: 'pull_request_template'
103
+ })
116
104
  end
117
105
 
118
- private def default_branch
119
- @default_branch ||= octokit_client.repository(local_repo).default_branch
106
+ private def pr_id
107
+ @pr_id ||= cli.code_request_id('Pull')
120
108
  end
121
109
 
122
110
  private def merge_method
123
- return @merge_method if @merge_method
124
- index = cli.ask_options("Merge method?", merge_options)
125
- @merge_method = merge_options[index]
111
+ @merge_method ||= merge_options.length == 1 ? merge_options.first : cli.merge_method(merge_options)
126
112
  end
127
113
 
128
- private def template_to_apply
129
- return @template_to_apply if @template_to_apply
130
- complete_options = pr_template_options << 'None'
131
- index = cli.ask_options("Which pull request template should be applied?", complete_options)
132
- @template_to_apply = complete_options[index]
133
- end
134
-
135
- private def pr_template_options
136
- return @pr_template_options if @pr_template_options
137
- nested_templates = Dir.glob(File.join("**/PULL_REQUEST_TEMPLATE", "*.md"), File::FNM_DOTMATCH | File::FNM_CASEFOLD)
138
- non_nested_templates = Dir.glob(File.join("**", "pull_request_template.md"), File::FNM_DOTMATCH | File::FNM_CASEFOLD)
139
- @pr_template_options = nested_templates.concat(non_nested_templates)
140
- end
141
-
142
- private def base_branch_default?
143
- answer = cli.ask("Is '#{default_branch}' the correct base branch for your new pull request? (y/n)")
144
- !!(answer =~ /^y/i)
114
+ private def merge_options
115
+ return @merge_options if @merge_options
116
+ merge_options = []
117
+ merge_options << 'merge' if existing_project.allow_merge_commit
118
+ merge_options << 'squash' if existing_project.allow_squash_merge
119
+ merge_options << 'rebase' if existing_project.allow_rebase_merge
120
+ @merge_options = merge_options
145
121
  end
146
122
 
147
- private def accept_autogenerated_title?
148
- answer = cli.ask("Accept the autogenerated pull request title '#{autogenerated_title}'? (y/n)")
149
- !!(answer =~ /^y/i)
123
+ private def existing_project
124
+ @existing_project ||= octokit_client.repository(local_repo)
150
125
  end
151
126
 
152
- private def apply_template?(template_file_name)
153
- answer = cli.ask("Apply the pull request template from #{template_file_name}? (y/n)")
154
- !!(answer =~ /^y/i)
127
+ private def existing_pr
128
+ @existing_pr ||= octokit_client.pull_request(local_repo, pr_id)
155
129
  end
156
130
 
157
131
  private def octokit_client
158
132
  @octokit_client ||= GitHelper::OctokitClient.new.client
159
133
  end
160
-
161
- private def cli
162
- @cli ||= GitHelper::HighlineCli.new
163
- end
164
134
  end
165
135
  end
@@ -1,3 +1,3 @@
1
1
  module GitHelper
2
- VERSION = '1.1.0'
2
+ VERSION = '2.0.0'
3
3
  end
@@ -0,0 +1,172 @@
1
+ require_relative '../../lib/git_helper/change_remote.rb'
2
+
3
+ describe GitHelper::ChangeRemote do
4
+ let(:remote1) { 'git@github.com:github-username-old/project-1.git' }
5
+ let(:local_code) do
6
+ double(:local_code,
7
+ remotes: [remote1],
8
+ remote_name: 'origin',
9
+ ssh_remote?: true,
10
+ https_remote?: false,
11
+ remote_project: 'project-1',
12
+ remote_source: 'github.com',
13
+ change_remote: true
14
+ )
15
+ end
16
+ let(:cli) { double(:highline_cli, process_directory_remotes?: true) }
17
+ let(:old_owner) { 'github-username-old' }
18
+ let(:new_owner) { 'github-username-new' }
19
+ let(:directory_entries) { [ '.', '..', 'project-1', 'project-2', 'project-3' ] }
20
+
21
+ subject { GitHelper::ChangeRemote.new(old_owner, new_owner) }
22
+
23
+ before do
24
+ allow(GitHelper::HighlineCli).to receive(:new).and_return(cli)
25
+ allow(GitHelper::LocalCode).to receive(:new).and_return(local_code)
26
+ end
27
+
28
+ describe '#execute' do
29
+ before do
30
+ allow(Dir).to receive(:pwd).and_return('/Users/firstname/lastname/path/to/project')
31
+ allow(Dir).to receive(:entries).and_return(directory_entries)
32
+ allow(File).to receive(:join).and_return('/Users/firstname/lastname/path/to/project/project-1')
33
+ allow(File).to receive(:directory?).and_return(true)
34
+ allow(subject).to receive(:process_dir)
35
+ end
36
+
37
+ it 'should call to process at least one directory' do
38
+ expect(subject).to receive(:process_dir).at_least(:once)
39
+ subject.execute
40
+ end
41
+
42
+ it 'should definitely look in the file structure' do
43
+ expect(Dir).to receive(:pwd)
44
+ expect(Dir).to receive(:entries)
45
+ expect(File).to receive(:join)
46
+ expect(File).to receive(:directory?)
47
+ subject.execute
48
+ end
49
+ end
50
+
51
+ describe '#process_dir' do
52
+ before do
53
+ allow(Dir).to receive(:chdir).and_return(nil)
54
+ allow(File).to receive(:exist?).and_return(true)
55
+ allow(subject).to receive(:process_git_repository)
56
+ end
57
+
58
+ it 'should definitely look in the file structure' do
59
+ expect(Dir).to receive(:chdir)
60
+ expect(File).to receive(:exist?)
61
+ subject.send(:process_dir, '/Users/firstname/lastname/path/to/project', '/Users/firstname/lastname/path/to/project/project-1')
62
+ end
63
+
64
+ context 'when the user says to process the directory' do
65
+ it 'should call to process the git repository at least once' do
66
+ expect(subject).to receive(:process_git_repository).at_least(:once)
67
+ subject.send(:process_dir, '/Users/firstname/lastname/path/to/project', '/Users/firstname/lastname/path/to/project/project-1')
68
+ end
69
+ end
70
+
71
+ context 'when the user says not to process the directory' do
72
+ let(:cli) { double(:highline_cli, process_directory_remotes?: false) }
73
+
74
+ it 'should not call to process the directory' do
75
+ expect(subject).not_to receive(:process_git_repository)
76
+ subject.send(:process_dir, '/Users/firstname/lastname/path/to/project', '/Users/firstname/lastname/path/to/project/project-1')
77
+ end
78
+ end
79
+ end
80
+
81
+ describe '#process_git_repository' do
82
+ before do
83
+ allow(subject).to receive(:process_remote).and_return(nil)
84
+ end
85
+
86
+ it 'should call local_code' do
87
+ expect(GitHelper::LocalCode).to receive(:new)
88
+ subject.send(:process_git_repository)
89
+ end
90
+
91
+ context 'when the remote includes the old owner' do
92
+ it 'should call to process the remote' do
93
+ expect(subject).to receive(:process_remote)
94
+ subject.send(:process_git_repository)
95
+ end
96
+ end
97
+
98
+ context 'when the remote does not include the old owner' do
99
+ let(:remote1) { 'git@github.com:github-username-new/project-1.git' }
100
+
101
+ it 'should not call to process the remote' do
102
+ expect(subject).not_to receive(:process_remote)
103
+ subject.send(:process_git_repository)
104
+ end
105
+ end
106
+ end
107
+
108
+ describe '#process_remote' do
109
+ it 'should always get the remote name' do
110
+ expect(local_code).to receive(:remote_name)
111
+ subject.send(:process_remote, remote1)
112
+ end
113
+
114
+ it 'should always attempt to change the remote' do
115
+ expect(local_code).to receive(:change_remote)
116
+ subject.send(:process_remote, remote1)
117
+ end
118
+
119
+ it 'should attempt to get the remote repo exactly once' do
120
+ expect(local_code).to receive(:remote_project).exactly(:once)
121
+ subject.send(:process_remote, remote1)
122
+ end
123
+
124
+ it 'should attempt to get the remote source exactly once' do
125
+ expect(local_code).to receive(:remote_source).exactly(:once)
126
+ subject.send(:process_remote, remote1)
127
+ end
128
+
129
+ it 'should ask if the remote is SSH' do
130
+ expect(local_code).to receive(:ssh_remote?)
131
+ subject.send(:process_remote, remote1)
132
+ end
133
+
134
+ context 'https remote' do
135
+ let(:local_code) do
136
+ double(:local_code,
137
+ remotes: [remote1],
138
+ remote_name: 'origin',
139
+ ssh_remote?: false,
140
+ https_remote?: false,
141
+ remote_project: 'project-1',
142
+ remote_source: 'github.com',
143
+ change_remote: true
144
+ )
145
+ end
146
+
147
+ it 'should ask if the remote is SSH' do
148
+ expect(local_code).to receive(:ssh_remote?)
149
+ subject.send(:process_remote, remote1)
150
+ end
151
+
152
+ it 'should ask if the remote is https' do
153
+ expect(local_code).to receive(:https_remote?)
154
+ subject.send(:process_remote, remote1)
155
+ end
156
+ end
157
+ end
158
+
159
+ describe '#local_code' do
160
+ it 'should create a new local code instance' do
161
+ expect(GitHelper::LocalCode).to receive(:new)
162
+ subject.send(:local_code)
163
+ end
164
+ end
165
+
166
+ describe '#cli' do
167
+ it 'should create a new highline CLI instance' do
168
+ expect(GitHelper::HighlineCli).to receive(:new)
169
+ subject.send(:cli)
170
+ end
171
+ end
172
+ end
@@ -0,0 +1,18 @@
1
+ require_relative '../../lib/git_helper/checkout_default.rb'
2
+
3
+ describe GitHelper::CheckoutDefault do
4
+ let(:local_code) { double(:local_code, checkout_default: :done) }
5
+
6
+ subject { GitHelper::CheckoutDefault.new }
7
+
8
+ it 'should call GitHelper::LocalCode' do
9
+ expect(GitHelper::LocalCode).to receive(:new).and_return(local_code)
10
+ subject.execute
11
+ end
12
+
13
+ it 'should call the checkout_default method from the local code class' do
14
+ allow(GitHelper::LocalCode).to receive(:new).and_return(local_code)
15
+ expect(local_code).to receive(:checkout_default)
16
+ subject.execute
17
+ end
18
+ end
@@ -0,0 +1,18 @@
1
+ require_relative '../../lib/git_helper/clean_branches.rb'
2
+
3
+ describe GitHelper::CleanBranches do
4
+ let(:local_code) { double(:local_code, clean_branches: :commit) }
5
+
6
+ subject { GitHelper::CleanBranches.new }
7
+
8
+ it 'should call GitHelper::LocalCode' do
9
+ expect(GitHelper::LocalCode).to receive(:new).and_return(local_code)
10
+ subject.execute
11
+ end
12
+
13
+ it 'should call the clean_branches method from the local code class' do
14
+ allow(GitHelper::LocalCode).to receive(:new).and_return(local_code)
15
+ expect(local_code).to receive(:clean_branches)
16
+ subject.execute
17
+ end
18
+ end
@@ -0,0 +1,258 @@
1
+ require_relative '../../lib/git_helper/code_request.rb'
2
+
3
+ describe GitHelper::CodeRequest do
4
+ let(:highline_cli) { double(:highline_cli) }
5
+ let(:local_code) { double(:local_code, project_name: 'name', branch: 'branch') }
6
+ let(:process_project) { double(:process_project, create: :created, merge: :merged) }
7
+
8
+ subject { GitHelper::CodeRequest.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(highline_cli)
13
+ end
14
+
15
+ describe '#create' do
16
+ before do
17
+ allow(subject).to receive(:base_branch).and_return('base')
18
+ allow(subject).to receive(:new_code_request_title).and_return('Title')
19
+ end
20
+
21
+ it 'should call to process the project' do
22
+ expect(subject).to receive(:process_project).and_return(process_project)
23
+ subject.create
24
+ end
25
+
26
+ it 'should call create' do
27
+ allow(subject).to receive(:process_project).and_return(process_project)
28
+ expect(process_project).to receive(:create)
29
+ subject.create
30
+ end
31
+
32
+ it 'should call base_branch and new_code_request_title' do
33
+ expect(subject).to receive(:base_branch).and_return('base')
34
+ expect(subject).to receive(:new_code_request_title).and_return('Title')
35
+ allow(subject).to receive(:process_project).and_return(process_project)
36
+ allow(process_project).to receive(:create)
37
+ subject.create
38
+ end
39
+ end
40
+
41
+ describe '#merge' do
42
+ it 'should call to process the project' do
43
+ expect(subject).to receive(:process_project).and_return(process_project)
44
+ subject.merge
45
+ end
46
+
47
+ it 'should call merge' do
48
+ allow(subject).to receive(:process_project).and_return(process_project)
49
+ expect(process_project).to receive(:merge)
50
+ subject.merge
51
+ end
52
+ end
53
+
54
+ describe '#process_project' do
55
+ it 'should call the local code to see if it is a github or gitlab project' do
56
+ expect(local_code).to receive(:gitlab_project?).and_return(false)
57
+ expect(local_code).to receive(:github_repo?).and_return(true)
58
+ subject.send(:process_project)
59
+ end
60
+
61
+ context 'when github and gitlab remotes are found' do
62
+ it 'should ask for clarification' do
63
+ allow(local_code).to receive(:gitlab_project?).and_return(true)
64
+ allow(local_code).to receive(:github_repo?).and_return(true)
65
+ expect(subject).to receive(:ask_for_clarification)
66
+ subject.send(:process_project)
67
+ end
68
+ end
69
+
70
+ context 'when github' do
71
+ it 'should call the github_pull_request' do
72
+ allow(local_code).to receive(:gitlab_project?).and_return(false)
73
+ allow(local_code).to receive(:github_repo?).and_return(true)
74
+ expect(subject).to receive(:github_pull_request)
75
+ subject.send(:process_project)
76
+ end
77
+ end
78
+
79
+ context 'when gitlab' do
80
+ it 'should call the gitlab_merge_request' do
81
+ allow(local_code).to receive(:gitlab_project?).and_return(true)
82
+ allow(local_code).to receive(:github_repo?).and_return(false)
83
+ expect(subject).to receive(:gitlab_merge_request)
84
+ subject.send(:process_project)
85
+ end
86
+ end
87
+
88
+ context 'when no github or gitlab remotes are found' do
89
+ it 'should raise error' do
90
+ allow(local_code).to receive(:gitlab_project?).and_return(false)
91
+ allow(local_code).to receive(:github_repo?).and_return(false)
92
+ expect(subject).to receive(:exit)
93
+ subject.send(:process_project)
94
+ end
95
+ end
96
+ end
97
+
98
+ describe '#ask_for_clarification' do
99
+ it 'should ask the CLI' do
100
+ expect(highline_cli).to receive(:conflicting_remote_clarification).and_return('github')
101
+ subject.send(:ask_for_clarification)
102
+ end
103
+
104
+ context 'when response is github' do
105
+ it 'should return github_pull_request' do
106
+ allow(highline_cli).to receive(:conflicting_remote_clarification).and_return('github')
107
+ expect(subject).to receive(:github_pull_request)
108
+ subject.send(:ask_for_clarification)
109
+ end
110
+
111
+ it 'should return github_pull_request' do
112
+ allow(highline_cli).to receive(:conflicting_remote_clarification).and_return('Github')
113
+ expect(subject).to receive(:github_pull_request)
114
+ subject.send(:ask_for_clarification)
115
+ end
116
+ end
117
+
118
+ context 'when response is gitlab' do
119
+ it 'should return gitlab_merge_request' do
120
+ allow(highline_cli).to receive(:conflicting_remote_clarification).and_return('gitlab')
121
+ expect(subject).to receive(:gitlab_merge_request)
122
+ subject.send(:ask_for_clarification)
123
+ end
124
+
125
+ it 'should return gitlab_merge_request' do
126
+ allow(highline_cli).to receive(:conflicting_remote_clarification).and_return('Gitlab')
127
+ expect(subject).to receive(:gitlab_merge_request)
128
+ subject.send(:ask_for_clarification)
129
+ end
130
+ end
131
+
132
+ context 'when response is neither' do
133
+ it 'should raise an error' do
134
+ allow(highline_cli).to receive(:conflicting_remote_clarification).and_return('huh?')
135
+ expect(subject).to receive(:exit)
136
+ subject.send(:ask_for_clarification)
137
+ end
138
+ end
139
+ end
140
+
141
+ describe '#github_pull_request' do
142
+ it 'should call the GitHelper::GitHubPullRequest' do
143
+ expect(GitHelper::GitHubPullRequest).to receive(:new)
144
+ subject.send(:github_pull_request)
145
+ end
146
+ end
147
+
148
+ describe '#gitlab_merge_request' do
149
+ it 'should call the GitHelper::GitLabMergeRequest' do
150
+ expect(GitHelper::GitLabMergeRequest).to receive(:new)
151
+ subject.send(:gitlab_merge_request)
152
+ end
153
+ end
154
+
155
+ describe '#local_project' do
156
+ it 'should call the name of the local_code' do
157
+ expect(local_code).to receive(:project_name)
158
+ subject.send(:local_project)
159
+ end
160
+ end
161
+
162
+ describe '#default_branch' do
163
+ it 'should call the name of the local_code' do
164
+ expect(local_code).to receive(:default_branch)
165
+ subject.send(:default_branch)
166
+ end
167
+ end
168
+
169
+ describe '#base_branch' do
170
+ it 'should call the default branch' do
171
+ expect(subject).to receive(:default_branch)
172
+ allow(highline_cli).to receive(:base_branch_default?).at_least(:once)
173
+ allow(highline_cli).to receive(:base_branch).at_least(:once).and_return('base')
174
+ subject.send(:base_branch)
175
+ end
176
+
177
+ it 'should ask the CLI to ask the user' do
178
+ allow(subject).to receive(:default_branch)
179
+ expect(highline_cli).to receive(:base_branch_default?).at_least(:once)
180
+ allow(highline_cli).to receive(:base_branch).at_least(:once).and_return('base')
181
+ subject.send(:base_branch)
182
+ end
183
+
184
+ context 'if the user says no' do
185
+ it "definitely asks for the user's base branch" do
186
+ allow(subject).to receive(:default_branch)
187
+ expect(highline_cli).to receive(:base_branch_default?).at_least(:once).and_return(false)
188
+ expect(highline_cli).to receive(:base_branch).at_least(:once).and_return('base')
189
+ subject.send(:base_branch)
190
+ end
191
+ end
192
+
193
+ context 'if the user says yes' do
194
+ it "does not ask for the user's base branch" do
195
+ allow(subject).to receive(:default_branch)
196
+ expect(highline_cli).to receive(:base_branch_default?).at_least(:once).and_return(true)
197
+ expect(highline_cli).not_to receive(:base_branch)
198
+ subject.send(:base_branch)
199
+ end
200
+ end
201
+ end
202
+
203
+ describe '#autogenerated_title' do
204
+ it 'should generate a title based on the branch' do
205
+ expect(subject).to receive(:local_branch).and_return('branch')
206
+ expect(local_code).to receive(:generate_title)
207
+ subject.send(:autogenerated_title)
208
+ end
209
+ end
210
+
211
+ describe '#new_code_request_title' do
212
+ it 'should call autogenerated title method' do
213
+ expect(subject).to receive(:autogenerated_title)
214
+ allow(highline_cli).to receive(:accept_autogenerated_title?).at_least(:once)
215
+ allow(highline_cli).to receive(:title).at_least(:once).and_return('Title')
216
+ subject.send(:new_code_request_title)
217
+ end
218
+
219
+ it 'should ask the CLI to ask the user' do
220
+ allow(subject).to receive(:autogenerated_title)
221
+ expect(highline_cli).to receive(:accept_autogenerated_title?).at_least(:once)
222
+ allow(highline_cli).to receive(:title).at_least(:once).and_return('Title')
223
+ subject.send(:new_code_request_title)
224
+ end
225
+
226
+ context 'if the user says no' do
227
+ it "definitely asks for the user's title" do
228
+ allow(subject).to receive(:autogenerated_title)
229
+ expect(highline_cli).to receive(:accept_autogenerated_title?).at_least(:once).and_return(false)
230
+ expect(highline_cli).to receive(:title).at_least(:once).and_return('Title')
231
+ subject.send(:new_code_request_title)
232
+ end
233
+ end
234
+
235
+ context 'if the user says yes to original title' do
236
+ it "does not ask for the user's chosen title" do
237
+ allow(subject).to receive(:autogenerated_title)
238
+ expect(highline_cli).to receive(:accept_autogenerated_title?).at_least(:once).and_return(true)
239
+ expect(highline_cli).not_to receive(:title)
240
+ subject.send(:new_code_request_title)
241
+ end
242
+ end
243
+ end
244
+
245
+ describe '#local_code' do
246
+ it 'should call the octokit client' do
247
+ expect(GitHelper::LocalCode).to receive(:new).and_return(local_code)
248
+ subject.send(:local_code)
249
+ end
250
+ end
251
+
252
+ describe '#cli' do
253
+ it 'should call the octokit client' do
254
+ expect(GitHelper::HighlineCli).to receive(:new).and_return(highline_cli)
255
+ subject.send(:cli)
256
+ end
257
+ end
258
+ end