git_reflow 0.8.10 → 0.9.4
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.
- checksums.yaml +4 -4
- data/.github/workflows/multi-ruby-tests.yml +33 -0
- data/.rubocop.yml +2 -0
- data/.ruby-version +1 -1
- data/Appraisals +1 -6
- data/CHANGELOG.md +466 -348
- data/Gemfile.lock +100 -70
- data/LICENSE +20 -20
- data/README.md +36 -12
- data/Rakefile +15 -8
- data/Workflow +3 -0
- data/bin/console +7 -7
- data/bin/setup +6 -6
- data/exe/git-reflow +14 -30
- data/git_reflow.gemspec +25 -24
- data/lib/git_reflow.rb +3 -14
- data/lib/git_reflow/config.rb +52 -17
- data/lib/git_reflow/git_helpers.rb +69 -22
- data/lib/git_reflow/git_server/base.rb +68 -68
- data/lib/git_reflow/git_server/git_hub.rb +53 -40
- data/lib/git_reflow/git_server/git_hub/pull_request.rb +25 -17
- data/lib/git_reflow/git_server/pull_request.rb +19 -3
- data/lib/git_reflow/merge_error.rb +9 -9
- data/lib/git_reflow/rspec.rb +1 -0
- data/lib/git_reflow/rspec/command_line_helpers.rb +23 -6
- data/lib/git_reflow/rspec/stub_helpers.rb +13 -13
- data/lib/git_reflow/rspec/workflow_helpers.rb +18 -0
- data/lib/git_reflow/sandbox.rb +16 -6
- data/lib/git_reflow/version.rb +1 -1
- data/lib/git_reflow/workflow.rb +305 -10
- data/lib/git_reflow/workflows/FlatMergeWorkflow +38 -0
- data/lib/git_reflow/workflows/core.rb +208 -79
- data/spec/fixtures/authentication_failure.json +3 -0
- data/spec/fixtures/awesome_workflow.rb +2 -6
- data/spec/fixtures/git/git_config +7 -7
- data/spec/fixtures/issues/comment.json.erb +27 -27
- data/spec/fixtures/issues/comments.json +29 -29
- data/spec/fixtures/issues/comments.json.erb +15 -15
- data/spec/fixtures/pull_requests/comment.json.erb +45 -45
- data/spec/fixtures/pull_requests/comments.json +47 -47
- data/spec/fixtures/pull_requests/comments.json.erb +15 -15
- data/spec/fixtures/pull_requests/commits.json +29 -29
- data/spec/fixtures/pull_requests/external_pull_request.json +145 -145
- data/spec/fixtures/pull_requests/pull_request.json +142 -142
- data/spec/fixtures/pull_requests/pull_request.json.erb +142 -142
- data/spec/fixtures/pull_requests/pull_request_branch_nonexistent_error.json +32 -0
- data/spec/fixtures/pull_requests/pull_request_exists_error.json +32 -32
- data/spec/fixtures/pull_requests/pull_requests.json +136 -136
- data/spec/fixtures/repositories/commit.json +53 -53
- data/spec/fixtures/repositories/commit.json.erb +53 -53
- data/spec/fixtures/repositories/commits.json.erb +13 -13
- data/spec/fixtures/repositories/statuses.json +31 -31
- data/spec/fixtures/users/user.json +32 -0
- data/spec/lib/git_reflow/git_helpers_spec.rb +115 -12
- data/spec/lib/git_reflow/git_server/git_hub/pull_request_spec.rb +6 -6
- data/spec/lib/git_reflow/git_server/git_hub_spec.rb +77 -3
- data/spec/lib/git_reflow/git_server/pull_request_spec.rb +41 -7
- data/spec/lib/git_reflow/workflow_spec.rb +259 -14
- data/spec/lib/git_reflow/workflows/core_spec.rb +224 -65
- data/spec/lib/git_reflow/workflows/flat_merge_spec.rb +17 -6
- data/spec/lib/git_reflow_spec.rb +2 -25
- data/spec/spec_helper.rb +3 -0
- data/spec/support/github_helpers.rb +1 -1
- data/spec/support/mock_pull_request.rb +17 -17
- data/spec/support/web_mocks.rb +39 -39
- metadata +52 -53
- data/circle.yml +0 -26
- data/lib/git_reflow/commands/deliver.rb +0 -10
- data/lib/git_reflow/commands/refresh.rb +0 -20
- data/lib/git_reflow/commands/review.rb +0 -13
- data/lib/git_reflow/commands/setup.rb +0 -11
- data/lib/git_reflow/commands/stage.rb +0 -9
- data/lib/git_reflow/commands/start.rb +0 -18
- data/lib/git_reflow/commands/status.rb +0 -7
- data/lib/git_reflow/workflows/flat_merge.rb +0 -10
- data/spec/fixtures/workflow_with_super.rb +0 -8
@@ -86,21 +86,21 @@ describe GitReflow::GitServer::GitHub::PullRequest do
|
|
86
86
|
pull_request: {
|
87
87
|
number: existing_pull_request.number,
|
88
88
|
comments: [{author: comment_author}],
|
89
|
-
reviews: []
|
89
|
+
reviews: [{author: existing_pull_request.user.login}]
|
90
90
|
},
|
91
91
|
issue: {
|
92
92
|
number: existing_pull_request.number,
|
93
|
-
comments: [{author: comment_author}]
|
93
|
+
comments: [{author: comment_author}, {author: existing_pull_request.user.login}]
|
94
94
|
}
|
95
95
|
)
|
96
96
|
end
|
97
|
-
specify { expect(subject).to eql(existing_pull_comments.to_a + existing_issue_comments.to_a) }
|
97
|
+
specify { expect(subject).to eql(existing_pull_comments.to_a + existing_issue_comments.to_a - [existing_pull_request.user.login]) }
|
98
98
|
end
|
99
99
|
|
100
100
|
context "Testing Nil Comments" do
|
101
101
|
before do
|
102
102
|
stub_request(:get, "https://api.github.com/repos/reenhanced/repo/pulls/2/comments?access_token=a1b2c3d4e5f6g7h8i9j0").
|
103
|
-
with(:headers => {'Accept'=>'application/vnd.github.v3+json,application/vnd.github.beta+json;q=0.5,application/json;q=0.1', 'Accept-Charset'=>'utf-8', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Authorization'=>'token a1b2c3d4e5f6g7h8i9j0', 'User-Agent'=>'Github API Ruby Gem 0.
|
103
|
+
with(:headers => {'Accept'=>'application/vnd.github.v3+json,application/vnd.github.beta+json;q=0.5,application/json;q=0.1', 'Accept-Charset'=>'utf-8', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Authorization'=>'token a1b2c3d4e5f6g7h8i9j0', 'User-Agent'=>'Github API Ruby Gem 0.19.0'}).
|
104
104
|
to_return(:status => 200, :body => "", :headers => {})
|
105
105
|
|
106
106
|
FakeGitHub.new(
|
@@ -133,7 +133,7 @@ describe GitReflow::GitServer::GitHub::PullRequest do
|
|
133
133
|
number: existing_pull_request.number,
|
134
134
|
owner: existing_pull_request.user.login,
|
135
135
|
comments: [{author: 'tito'}, {author: 'bobby'}, {author: 'ringo'}],
|
136
|
-
reviews: [{author: 'nature-boy'}]
|
136
|
+
reviews: [{author: 'ringo'}, {author: 'nature-boy'}]
|
137
137
|
},
|
138
138
|
issue: {
|
139
139
|
number: existing_pull_request.number,
|
@@ -484,7 +484,7 @@ describe GitReflow::GitServer::GitHub::PullRequest do
|
|
484
484
|
allow(GitReflow.git_server).to receive(:connection).and_return(github_api)
|
485
485
|
allow(GitReflow.git_server).to receive(:get_build_status).and_return(Struct.new(:state, :description, :target_url).new())
|
486
486
|
allow_any_instance_of(GitReflow::GitServer::PullRequest).to receive(:commit_message_for_merge).and_return('Bingo')
|
487
|
-
allow_any_instance_of(GitReflow).to receive(:
|
487
|
+
allow_any_instance_of(GitReflow).to receive(:append_to_merge_commit_message).and_return(true)
|
488
488
|
end
|
489
489
|
|
490
490
|
context "and force-merging" do
|
@@ -78,7 +78,7 @@ describe GitReflow::GitServer::GitHub do
|
|
78
78
|
subject { github.authenticate }
|
79
79
|
|
80
80
|
before do
|
81
|
-
allow(GitReflow::GitServer::GitHub).to receive(:user).and_return(
|
81
|
+
allow(GitReflow::GitServer::GitHub).to receive(:user).and_return(user)
|
82
82
|
allow(github_api).to receive(:oauth).and_return(github_authorizations)
|
83
83
|
allow(github_api).to receive_message_chain(:oauth, :all).and_return([])
|
84
84
|
allow(github).to receive(:run).with('hostname', loud: false).and_return(hostname)
|
@@ -151,12 +151,86 @@ describe GitReflow::GitServer::GitHub do
|
|
151
151
|
body: { error: "GET https://api.github.com/authorizations: 401 Bad credentials" }
|
152
152
|
}}
|
153
153
|
|
154
|
+
before do
|
155
|
+
allow(GitReflow::Config).to receive(:get).and_call_original
|
156
|
+
allow(GitReflow::Config).to receive(:get).with('github.oauth-token').and_return(oauth_token_hash[:token])
|
157
|
+
allow(Github::Client).to receive(:new).and_return(github_api)
|
158
|
+
allow(github_authorizations).to receive(:authenticated?).and_return(true)
|
159
|
+
allow(github_api.oauth).to receive(:create).with({ scopes: ['repo'], note: "git-reflow (#{hostname})" }).and_return(oauth_token_hash)
|
160
|
+
|
161
|
+
stub_request(:get, %r{/user}).
|
162
|
+
to_return(
|
163
|
+
body: Fixture.new('authentication_failure.json').to_s,
|
164
|
+
status: 401,
|
165
|
+
headers: {'content-type' => 'application/json; charset=utf-8', status: 'Unauthorized'},
|
166
|
+
)
|
167
|
+
end
|
168
|
+
|
169
|
+
it "notifies the user of successful setup" do
|
170
|
+
expect { subject }.to have_said "Your GitHub account was successfully setup!", :success
|
171
|
+
end
|
172
|
+
|
173
|
+
it "creates a new GitHub oauth token" do
|
174
|
+
expect(github_api.oauth).to receive(:create).and_return(oauth_token_hash)
|
175
|
+
subject
|
176
|
+
end
|
177
|
+
|
178
|
+
it "creates git config keys for github connections" do
|
179
|
+
expect{ subject }.to have_run_command_silently "git config -f #{GitReflow::Config::CONFIG_FILE_PATH} --replace-all github.site \"#{github_site}\"", blocking: false
|
180
|
+
expect{ subject }.to have_run_command_silently "git config -f #{GitReflow::Config::CONFIG_FILE_PATH} --replace-all github.endpoint \"#{github_api_endpoint}\"", blocking: false
|
181
|
+
expect{ subject }.to have_run_command_silently "git config -f #{GitReflow::Config::CONFIG_FILE_PATH} --replace-all github.oauth-token \"#{oauth_token_hash[:token]}\"", blocking: false
|
182
|
+
expect{ subject }.to have_run_command_silently "git config -f #{GitReflow::Config::CONFIG_FILE_PATH} --replace-all reflow.git-server \"GitHub\"", blocking: false
|
183
|
+
end
|
184
|
+
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
context 'already authenticated' do
|
189
|
+
let(:oauth_token) { "abc123" }
|
190
|
+
|
191
|
+
before do
|
192
|
+
allow(GitReflow::Config).to receive(:get).and_call_original
|
193
|
+
allow(GitReflow::Config).to receive(:get).with('github.oauth-token').and_return(oauth_token)
|
194
|
+
end
|
195
|
+
|
196
|
+
context "and authentication token is still valid" do
|
197
|
+
before do
|
198
|
+
stub_request(:get, %r{/user}).
|
199
|
+
to_return(
|
200
|
+
body: Fixture.new('users/user.json').to_s,
|
201
|
+
status: 200,
|
202
|
+
headers: { content_type: "application/json; charset=utf-8" }
|
203
|
+
)
|
204
|
+
|
205
|
+
allow(Github::Client).to receive(:new).and_return(github_api)
|
206
|
+
allow(github_api).to receive(:oauth).and_return(github_authorizations)
|
207
|
+
allow(github_authorizations).to receive(:authenticated?).and_return(true)
|
208
|
+
allow(github_api.oauth).to receive(:create).with({ scopes: ['repo'], note: "git-reflow (#{hostname})" }).and_return(oauth_token_hash)
|
209
|
+
end
|
210
|
+
|
211
|
+
it "resolves all missing git-reflow configurations" do
|
212
|
+
expect{ subject }.to have_run_command_silently "git config -f #{GitReflow::Config::CONFIG_FILE_PATH} --replace-all github.site \"#{github_site}\"", blocking: false
|
213
|
+
expect{ subject }.to have_run_command_silently "git config -f #{GitReflow::Config::CONFIG_FILE_PATH} --replace-all github.endpoint \"#{github_api_endpoint}\"", blocking: false
|
214
|
+
expect{ subject }.to have_run_command_silently "git config -f #{GitReflow::Config::CONFIG_FILE_PATH} --replace-all reflow.git-server \"GitHub\"", blocking: false
|
215
|
+
expect { subject }.to have_said "Your GitHub account was already setup with: "
|
216
|
+
expect { subject }.to have_said "\tUser Name: #{user}"
|
217
|
+
expect { subject }.to have_said "\tEndpoint: #{github_api_endpoint}"
|
218
|
+
end
|
219
|
+
end
|
220
|
+
|
221
|
+
context "and authentication token is expired" do
|
222
|
+
let(:unauthorized_error_response) {{
|
223
|
+
response_headers: {'content-type' => 'application/json; charset=utf-8', status: 'Unauthorized'},
|
224
|
+
method: 'GET',
|
225
|
+
status: '401',
|
226
|
+
body: { error: "GET https://api.github.com/authorizations: 401 Bad credentials" }
|
227
|
+
}}
|
228
|
+
|
154
229
|
before do
|
155
230
|
allow(Github::Client).to receive(:new).and_raise Github::Error::Unauthorized.new(unauthorized_error_response)
|
156
231
|
end
|
157
232
|
|
158
|
-
it "
|
159
|
-
expect { subject }.to have_said "Github Authentication Error: #{Github::Error::Unauthorized.new(unauthorized_error_response).inspect}", :error
|
233
|
+
it "requests a new oauth token" do
|
160
234
|
end
|
161
235
|
end
|
162
236
|
end
|
@@ -364,7 +364,7 @@ describe GitReflow::GitServer::PullRequest do
|
|
364
364
|
subject { pr.merge! inputs }
|
365
365
|
|
366
366
|
before do
|
367
|
-
allow(GitReflow).to receive(:
|
367
|
+
allow(GitReflow).to receive(:append_to_merge_commit_message)
|
368
368
|
allow(pr).to receive(:commit_message_for_merge).and_return(commit_message_for_merge)
|
369
369
|
end
|
370
370
|
|
@@ -376,7 +376,7 @@ describe GitReflow::GitServer::PullRequest do
|
|
376
376
|
it "updates both feature and destination branch and squash-merges feature into base branch" do
|
377
377
|
expect(GitReflow).to receive(:update_current_branch)
|
378
378
|
expect(GitReflow).to receive(:fetch_destination).with(pr.base_branch_name)
|
379
|
-
expect(GitReflow).to receive(:
|
379
|
+
expect(GitReflow).to receive(:append_to_merge_commit_message).with(pr.commit_message_for_merge)
|
380
380
|
expect { subject }.to have_run_commands_in_order [
|
381
381
|
"git checkout #{pr.base_branch_name}",
|
382
382
|
"git pull origin #{pr.base_branch_name}",
|
@@ -470,6 +470,12 @@ describe GitReflow::GitServer::PullRequest do
|
|
470
470
|
before { allow(pr).to receive(:approvals).and_return(['sally', 'joey']) }
|
471
471
|
specify { expect(subject).to include "\nLGTM given by: @sally, @joey\n" }
|
472
472
|
end
|
473
|
+
|
474
|
+
context "with custom merge commit message template" do
|
475
|
+
before { allow(GitReflow).to receive(:merge_commit_template).and_return("Super cool changes") }
|
476
|
+
specify { expect(subject).to include "Super cool changes" }
|
477
|
+
specify { expect(subject).to_not include "\nMerges ##{pr.number}\n" }
|
478
|
+
end
|
473
479
|
end
|
474
480
|
|
475
481
|
context "#cleanup_feature_branch?" do
|
@@ -485,14 +491,42 @@ describe GitReflow::GitServer::PullRequest do
|
|
485
491
|
allow(GitReflow::Config).to receive(:get).with('reflow.always-cleanup').and_return('false')
|
486
492
|
end
|
487
493
|
|
488
|
-
context "and
|
489
|
-
|
494
|
+
context "and always cleanup local config is set" do
|
495
|
+
end
|
496
|
+
|
497
|
+
context "and always cleanup remote config is set" do
|
498
|
+
end
|
499
|
+
|
500
|
+
context "and user chooses to cleanup local only" do
|
501
|
+
before do
|
502
|
+
expect(pr).to receive(:ask).with('Would you like to cleanup your local feature branch? ').and_return('yes')
|
503
|
+
allow(pr).to receive(:ask).with('Would you like to cleanup your remote feature branch? ').and_return('no')
|
504
|
+
end
|
505
|
+
it { should be_truthy }
|
506
|
+
end
|
507
|
+
|
508
|
+
context "and user chooses to cleanup remote only" do
|
509
|
+
before do
|
510
|
+
expect(pr).to receive(:ask).with('Would you like to cleanup your local feature branch? ').and_return('no')
|
511
|
+
expect(pr).to receive(:ask).with('Would you like to cleanup your remote feature branch? ').and_return('yes')
|
512
|
+
end
|
490
513
|
it { should be_truthy }
|
491
514
|
end
|
492
515
|
|
493
|
-
context "and user
|
494
|
-
before
|
495
|
-
|
516
|
+
context "and user chooses to cleanup local and remote" do
|
517
|
+
before do
|
518
|
+
allow(pr).to receive(:ask).with('Would you like to cleanup your local feature branch? ').and_return('yes')
|
519
|
+
allow(pr).to receive(:ask).with('Would you like to cleanup your remote feature branch? ').and_return('yes')
|
520
|
+
end
|
521
|
+
it { should be_truthy }
|
522
|
+
end
|
523
|
+
|
524
|
+
context "and user chooses to cleanup neither local nor remote" do
|
525
|
+
before do
|
526
|
+
expect(pr).to receive(:ask).with('Would you like to cleanup your local feature branch? ').and_return('no')
|
527
|
+
allow(pr).to receive(:ask).with('Would you like to cleanup your remote feature branch? ').and_return('no')
|
528
|
+
end
|
529
|
+
it { should be_falsey }
|
496
530
|
end
|
497
531
|
end
|
498
532
|
end
|
@@ -6,54 +6,299 @@ describe GitReflow::Workflow do
|
|
6
6
|
include GitReflow::Workflow
|
7
7
|
end
|
8
8
|
|
9
|
+
class DummyBundler
|
10
|
+
def gemfile(&block)
|
11
|
+
instance_eval &block
|
12
|
+
end
|
13
|
+
|
14
|
+
def source(name); end
|
15
|
+
def gem(name, *args); end
|
16
|
+
end
|
17
|
+
|
18
|
+
class DummyGemifiedWorkflow
|
19
|
+
include GitReflow::Workflow
|
20
|
+
|
21
|
+
command :whirl do
|
22
|
+
puts "whirl"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
9
26
|
let(:workflow) { DummyWorkflow }
|
10
27
|
let(:loader) { double() }
|
11
28
|
|
12
29
|
describe ".current" do
|
13
30
|
subject { GitReflow::Workflow.current }
|
14
31
|
|
32
|
+
before do
|
33
|
+
allow(GitReflow::Workflows::Core).to receive(:load_raw_workflow)
|
34
|
+
end
|
35
|
+
|
15
36
|
context "when no workflow is set" do
|
16
37
|
before { allow(GitReflow::Config).to receive(:get).with("reflow.workflow").and_return('') }
|
17
38
|
specify { expect( subject ).to eql(GitReflow::Workflows::Core) }
|
18
39
|
end
|
19
40
|
|
20
|
-
context "when a workflow is set" do
|
41
|
+
context "when a global workflow is set" do
|
21
42
|
let(:workflow_path) { File.join(File.expand_path("../../../fixtures", __FILE__), "/awesome_workflow.rb") }
|
22
43
|
|
23
44
|
before { allow(GitReflow::Config).to receive(:get).with("reflow.workflow").and_return(workflow_path) }
|
24
|
-
specify { expect( subject ).to eql(GitReflow::
|
45
|
+
specify { expect( subject ).to eql(GitReflow::Workflows::Core) }
|
46
|
+
end
|
47
|
+
|
48
|
+
context "when a local workflow is set" do
|
49
|
+
let(:workflow_content) do
|
50
|
+
<<~WORKFLOW_CONTENT
|
51
|
+
command :dummy do
|
52
|
+
GitReflow.say "derp"
|
53
|
+
end
|
54
|
+
WORKFLOW_CONTENT
|
55
|
+
end
|
56
|
+
|
57
|
+
before do
|
58
|
+
allow(File).to receive(:exists?).with("#{GitReflow.git_root_dir}/Workflow").and_return(true)
|
59
|
+
allow(File).to receive(:read).with("#{GitReflow.git_root_dir}/Workflow").and_return(workflow_content)
|
60
|
+
expect(GitReflow::Workflows::Core).to receive(:load_raw_workflow).with(workflow_content).and_call_original
|
61
|
+
end
|
62
|
+
|
63
|
+
specify { expect( subject ).to respond_to(:dummy) }
|
64
|
+
specify { expect( subject ).to eql(GitReflow::Workflows::Core) }
|
65
|
+
end
|
66
|
+
|
67
|
+
context "when both a local and a global workflow are set" do
|
68
|
+
let(:workflow_path) { File.join(File.expand_path("../../../fixtures", __FILE__), "/awesome_workflow.rb") }
|
69
|
+
let(:workflow_content) do
|
70
|
+
<<~WORKFLOW_CONTENT
|
71
|
+
command :dummy do
|
72
|
+
GitReflow.say "derp"
|
73
|
+
end
|
74
|
+
WORKFLOW_CONTENT
|
75
|
+
end
|
76
|
+
|
77
|
+
before do
|
78
|
+
allow(File).to receive(:exists?).with("#{GitReflow.git_root_dir}/Workflow").and_return(true)
|
79
|
+
allow(File).to receive(:read).with("#{GitReflow.git_root_dir}/Workflow").and_return(workflow_content)
|
80
|
+
allow(GitReflow::Config).to receive(:get).with("reflow.workflow").and_return(workflow_path)
|
81
|
+
allow(GitReflow::Workflows::Core).to receive(:load_raw_workflow).and_call_original
|
82
|
+
end
|
83
|
+
|
84
|
+
specify { expect(subject).to respond_to(:dummy) }
|
85
|
+
specify { expect(subject).to eql(GitReflow::Workflows::Core) }
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
describe ".before" do
|
90
|
+
it "executes the block before the command" do
|
91
|
+
GitReflow::Workflows::Core.load_raw_workflow <<~WORKFLOW_CONTENT
|
92
|
+
command :yips do
|
93
|
+
puts "Yips."
|
94
|
+
end
|
95
|
+
|
96
|
+
before :yips do
|
97
|
+
puts "Would you like a donut?"
|
98
|
+
end
|
99
|
+
WORKFLOW_CONTENT
|
100
|
+
|
101
|
+
allow(GitReflow::Workflows::Core).to receive(:load_workflow).and_return(true)
|
102
|
+
|
103
|
+
expect { GitReflow.workflow.yips }.to have_output "Would you like a donut?\nYips."
|
104
|
+
end
|
105
|
+
|
106
|
+
it "executes blocks sequentially by order of appearance" do
|
107
|
+
GitReflow::Workflows::Core.load_raw_workflow <<~WORKFLOW_CONTENT
|
108
|
+
command :yips do
|
109
|
+
puts "Yips."
|
110
|
+
end
|
111
|
+
|
112
|
+
before :yips do
|
113
|
+
puts "Cupcake?"
|
114
|
+
end
|
115
|
+
|
116
|
+
before :yips do
|
117
|
+
puts "Would you like a donut?"
|
118
|
+
end
|
119
|
+
WORKFLOW_CONTENT
|
120
|
+
|
121
|
+
allow(GitReflow::Workflows::Core).to receive(:load_workflow).and_return(true)
|
122
|
+
|
123
|
+
expect { GitReflow.workflow.yips }.to have_output "Cupcake?\nWould you like a donut?\nYips."
|
124
|
+
end
|
125
|
+
|
126
|
+
it "proxies any arguments returned to the command" do
|
127
|
+
GitReflow::Workflows::Core.load_raw_workflow <<~WORKFLOW_CONTENT
|
128
|
+
command :yips, arguments: { spiced: false } do |**params|
|
129
|
+
puts params[:spiced] ? "Too spicy." : "Yips."
|
130
|
+
end
|
131
|
+
|
132
|
+
before :yips do
|
133
|
+
puts "Wasabe?"
|
134
|
+
{ spiced: true }
|
135
|
+
end
|
136
|
+
WORKFLOW_CONTENT
|
137
|
+
|
138
|
+
allow(GitReflow::Workflows::Core).to receive(:load_workflow).and_return(true)
|
139
|
+
|
140
|
+
expect { GitReflow.workflow.yips }.to have_output "Wasabe?\nToo spicy."
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
describe ".after" do
|
145
|
+
it "executes the block after the command" do
|
146
|
+
GitReflow::Workflows::Core.load_raw_workflow <<~WORKFLOW_CONTENT
|
147
|
+
command :vroom do
|
148
|
+
puts "Vroom"
|
149
|
+
end
|
150
|
+
|
151
|
+
after :vroom do
|
152
|
+
puts "VROOOOM"
|
153
|
+
end
|
154
|
+
WORKFLOW_CONTENT
|
155
|
+
|
156
|
+
allow(GitReflow::Workflows::Core).to receive(:load_workflow).and_return(true)
|
157
|
+
|
158
|
+
expect { GitReflow.workflow.vroom }.to have_output "Vroom\nVROOOOM"
|
159
|
+
end
|
160
|
+
|
161
|
+
it "executes blocks sequentially by order of appearance" do
|
162
|
+
GitReflow::Workflows::Core.load_raw_workflow <<~WORKFLOW_CONTENT
|
163
|
+
command :vroom do
|
164
|
+
puts "Vroom"
|
165
|
+
end
|
166
|
+
|
167
|
+
after :vroom do
|
168
|
+
puts "Vrooom"
|
169
|
+
end
|
170
|
+
|
171
|
+
after :vroom do
|
172
|
+
puts "VROOOOM"
|
173
|
+
end
|
174
|
+
WORKFLOW_CONTENT
|
175
|
+
|
176
|
+
allow(GitReflow::Workflows::Core).to receive(:load_workflow).and_return(true)
|
177
|
+
|
178
|
+
expect { GitReflow.workflow.vroom }.to have_output "Vroom\nVrooom\nVROOOOM"
|
25
179
|
end
|
26
180
|
end
|
27
181
|
|
28
182
|
describe ".command" do
|
29
183
|
it "creates a class method for a bogus command" do
|
30
|
-
class DummyWorkflow
|
31
|
-
include GitReflow::Workflow
|
32
|
-
end
|
33
184
|
workflow.command :bogus do
|
34
|
-
"Woohoo"
|
185
|
+
GitReflow.say "Woohoo"
|
35
186
|
end
|
36
187
|
|
37
|
-
expect
|
188
|
+
expect { DummyWorkflow.bogus }.to have_said("Woohoo")
|
38
189
|
end
|
39
190
|
|
40
191
|
it "creates a method for a bogus command with arguments" do
|
41
|
-
workflow.command :bogus, arguments:
|
42
|
-
"Woohoo #{params[:feature_branch]}!"
|
192
|
+
workflow.command :bogus, arguments: { feature_branch: nil } do |**params|
|
193
|
+
GitReflow.say "Woohoo #{params[:feature_branch]}!"
|
43
194
|
end
|
44
195
|
|
45
|
-
expect
|
196
|
+
expect { DummyWorkflow.bogus(feature_branch: "arguments") }.to have_said("Woohoo arguments!")
|
46
197
|
end
|
47
198
|
|
48
|
-
it "creates a class method for a bogus command with default
|
49
|
-
workflow.command :bogus, arguments:
|
199
|
+
it "creates a class method for a bogus command with default arguments" do
|
200
|
+
workflow.command :bogus, arguments: { feature_branch: nil, decoration: "sprinkles" } do |**params|
|
50
201
|
donut_excitement = "Woohoo #{params[:feature_branch]}"
|
51
202
|
donut_excitement += " with #{params[:decoration]}" if params[:decoration]
|
52
|
-
"#{donut_excitement}!"
|
203
|
+
GitReflow.say "#{donut_excitement}!"
|
204
|
+
end
|
205
|
+
|
206
|
+
expect { DummyWorkflow.bogus(feature_branch: "donuts") }.to have_said("Woohoo donuts with sprinkles!")
|
207
|
+
end
|
208
|
+
|
209
|
+
it "creates a class method for a bogus command with flags" do
|
210
|
+
workflow.command :bogus, flags: { feature_branch: nil } do |**params|
|
211
|
+
GitReflow.say "Woohoo #{params[:feature_branch]}!"
|
212
|
+
end
|
213
|
+
|
214
|
+
expect { DummyWorkflow.bogus(feature_branch: "flags") }.to have_said("Woohoo flags!")
|
215
|
+
end
|
216
|
+
|
217
|
+
it "creates a class method for a bogus command with default flags" do
|
218
|
+
workflow.command :bogus, flags: { feature_branch: "donuts" } do |**params|
|
219
|
+
GitReflow.say "Woohoo #{params[:feature_branch]}!"
|
220
|
+
end
|
221
|
+
|
222
|
+
expect { DummyWorkflow.bogus }.to have_said("Woohoo donuts!")
|
223
|
+
end
|
224
|
+
|
225
|
+
it "creates a class method for a bogus command with switches" do
|
226
|
+
workflow.command :bogus, switches: { feature_branch: nil } do |**params|
|
227
|
+
GitReflow.say "Woohoo #{params[:feature_branch]}!"
|
228
|
+
end
|
229
|
+
|
230
|
+
expect { DummyWorkflow.bogus(feature_branch: "switches") }.to have_said("Woohoo switches!")
|
231
|
+
end
|
232
|
+
|
233
|
+
it "creates a class method for a bogus command with default switches" do
|
234
|
+
workflow.command :bogus, switches: { feature_branch: "donuts" } do |**params|
|
235
|
+
GitReflow.say "Woohoo #{params[:feature_branch]}!"
|
53
236
|
end
|
54
237
|
|
55
|
-
expect
|
238
|
+
expect { DummyWorkflow.bogus }.to have_said("Woohoo donuts!")
|
56
239
|
end
|
57
240
|
end
|
58
241
|
|
242
|
+
describe ".use(workflow_name)" do
|
243
|
+
it "Uses a pre-existing workflow as a basis" do
|
244
|
+
allow(GitReflow::Workflows::Core).to receive(:load_workflow)
|
245
|
+
expect(GitReflow::Workflows::Core).to receive(:load_workflow)
|
246
|
+
.with(workflow.workflows["FlatMergeWorkflow"])
|
247
|
+
.and_return(true)
|
248
|
+
workflow.use "FlatMergeWorkflow"
|
249
|
+
end
|
250
|
+
end
|
251
|
+
|
252
|
+
describe ".use_gem(name, *ags)" do
|
253
|
+
let(:mock_bundler) { DummyBundler.new }
|
254
|
+
|
255
|
+
before do
|
256
|
+
allow(DummyGemifiedWorkflow).to receive(:gemfile) do |&block|
|
257
|
+
mock_bundler.gemfile(&block)
|
258
|
+
end
|
259
|
+
stub_run_for(DummyGemifiedWorkflow)
|
260
|
+
end
|
261
|
+
|
262
|
+
it "Installs a gem using Bundler's inline gemfile" do
|
263
|
+
stub_command(command: "gem list -ie whirly", options: { loud: false, raise: true }, return_value: "false")
|
264
|
+
expect(mock_bundler).to receive(:source).with("https://rubygems.org")
|
265
|
+
expect(mock_bundler).to receive(:gem).with("whirly", "0.2.6")
|
266
|
+
|
267
|
+
DummyGemifiedWorkflow.class_eval do
|
268
|
+
use_gem "whirly", "0.2.6"
|
269
|
+
end
|
270
|
+
end
|
271
|
+
|
272
|
+
it "Uses an existing gem if it's already installed" do
|
273
|
+
stub_command(command: "gem list -ie whirly", options: { loud: false, raise: false }, return_value: "true")
|
274
|
+
expect(DummyGemifiedWorkflow).to_not receive(:gemfile)
|
275
|
+
|
276
|
+
DummyGemifiedWorkflow.class_eval do
|
277
|
+
use_gem "whirly", "0.2.6"
|
278
|
+
end
|
279
|
+
end
|
280
|
+
end
|
281
|
+
|
282
|
+
describe ".use_gemfile(&block)" do
|
283
|
+
let(:mock_bundler) { DummyBundler.new }
|
284
|
+
|
285
|
+
before do
|
286
|
+
allow(DummyGemifiedWorkflow).to receive(:gemfile) do |&block|
|
287
|
+
mock_bundler.gemfile(&block)
|
288
|
+
end
|
289
|
+
stub_run_for(DummyGemifiedWorkflow)
|
290
|
+
end
|
291
|
+
|
292
|
+
it "runs bundler's inline gemfile with the provided block" do
|
293
|
+
expect(mock_bundler).to receive(:source).with("https://rubygems.org")
|
294
|
+
expect(mock_bundler).to receive(:gem).with("standard")
|
295
|
+
|
296
|
+
DummyGemifiedWorkflow.class_eval do
|
297
|
+
use_gemfile do
|
298
|
+
source "https://rubygems.org"
|
299
|
+
gem "standard"
|
300
|
+
end
|
301
|
+
end
|
302
|
+
end
|
303
|
+
end
|
59
304
|
end
|