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.
Files changed (76) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/multi-ruby-tests.yml +33 -0
  3. data/.rubocop.yml +2 -0
  4. data/.ruby-version +1 -1
  5. data/Appraisals +1 -6
  6. data/CHANGELOG.md +466 -348
  7. data/Gemfile.lock +100 -70
  8. data/LICENSE +20 -20
  9. data/README.md +36 -12
  10. data/Rakefile +15 -8
  11. data/Workflow +3 -0
  12. data/bin/console +7 -7
  13. data/bin/setup +6 -6
  14. data/exe/git-reflow +14 -30
  15. data/git_reflow.gemspec +25 -24
  16. data/lib/git_reflow.rb +3 -14
  17. data/lib/git_reflow/config.rb +52 -17
  18. data/lib/git_reflow/git_helpers.rb +69 -22
  19. data/lib/git_reflow/git_server/base.rb +68 -68
  20. data/lib/git_reflow/git_server/git_hub.rb +53 -40
  21. data/lib/git_reflow/git_server/git_hub/pull_request.rb +25 -17
  22. data/lib/git_reflow/git_server/pull_request.rb +19 -3
  23. data/lib/git_reflow/merge_error.rb +9 -9
  24. data/lib/git_reflow/rspec.rb +1 -0
  25. data/lib/git_reflow/rspec/command_line_helpers.rb +23 -6
  26. data/lib/git_reflow/rspec/stub_helpers.rb +13 -13
  27. data/lib/git_reflow/rspec/workflow_helpers.rb +18 -0
  28. data/lib/git_reflow/sandbox.rb +16 -6
  29. data/lib/git_reflow/version.rb +1 -1
  30. data/lib/git_reflow/workflow.rb +305 -10
  31. data/lib/git_reflow/workflows/FlatMergeWorkflow +38 -0
  32. data/lib/git_reflow/workflows/core.rb +208 -79
  33. data/spec/fixtures/authentication_failure.json +3 -0
  34. data/spec/fixtures/awesome_workflow.rb +2 -6
  35. data/spec/fixtures/git/git_config +7 -7
  36. data/spec/fixtures/issues/comment.json.erb +27 -27
  37. data/spec/fixtures/issues/comments.json +29 -29
  38. data/spec/fixtures/issues/comments.json.erb +15 -15
  39. data/spec/fixtures/pull_requests/comment.json.erb +45 -45
  40. data/spec/fixtures/pull_requests/comments.json +47 -47
  41. data/spec/fixtures/pull_requests/comments.json.erb +15 -15
  42. data/spec/fixtures/pull_requests/commits.json +29 -29
  43. data/spec/fixtures/pull_requests/external_pull_request.json +145 -145
  44. data/spec/fixtures/pull_requests/pull_request.json +142 -142
  45. data/spec/fixtures/pull_requests/pull_request.json.erb +142 -142
  46. data/spec/fixtures/pull_requests/pull_request_branch_nonexistent_error.json +32 -0
  47. data/spec/fixtures/pull_requests/pull_request_exists_error.json +32 -32
  48. data/spec/fixtures/pull_requests/pull_requests.json +136 -136
  49. data/spec/fixtures/repositories/commit.json +53 -53
  50. data/spec/fixtures/repositories/commit.json.erb +53 -53
  51. data/spec/fixtures/repositories/commits.json.erb +13 -13
  52. data/spec/fixtures/repositories/statuses.json +31 -31
  53. data/spec/fixtures/users/user.json +32 -0
  54. data/spec/lib/git_reflow/git_helpers_spec.rb +115 -12
  55. data/spec/lib/git_reflow/git_server/git_hub/pull_request_spec.rb +6 -6
  56. data/spec/lib/git_reflow/git_server/git_hub_spec.rb +77 -3
  57. data/spec/lib/git_reflow/git_server/pull_request_spec.rb +41 -7
  58. data/spec/lib/git_reflow/workflow_spec.rb +259 -14
  59. data/spec/lib/git_reflow/workflows/core_spec.rb +224 -65
  60. data/spec/lib/git_reflow/workflows/flat_merge_spec.rb +17 -6
  61. data/spec/lib/git_reflow_spec.rb +2 -25
  62. data/spec/spec_helper.rb +3 -0
  63. data/spec/support/github_helpers.rb +1 -1
  64. data/spec/support/mock_pull_request.rb +17 -17
  65. data/spec/support/web_mocks.rb +39 -39
  66. metadata +52 -53
  67. data/circle.yml +0 -26
  68. data/lib/git_reflow/commands/deliver.rb +0 -10
  69. data/lib/git_reflow/commands/refresh.rb +0 -20
  70. data/lib/git_reflow/commands/review.rb +0 -13
  71. data/lib/git_reflow/commands/setup.rb +0 -11
  72. data/lib/git_reflow/commands/stage.rb +0 -9
  73. data/lib/git_reflow/commands/start.rb +0 -18
  74. data/lib/git_reflow/commands/status.rb +0 -7
  75. data/lib/git_reflow/workflows/flat_merge.rb +0 -10
  76. 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.15.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(:append_to_squashed_commit_message).and_return(true)
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('reenhanced')
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 "notifies user of invalid login details" do
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(:append_to_squashed_commit_message)
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(:append_to_squashed_commit_message).with(pr.commit_message_for_merge)
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 user chooses to cleanup" do
489
- before { expect(pr).to receive(:ask).with('Would you like to push this branch to your remote repo and cleanup your feature branch? ').and_return('yes') }
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 choose not to cleanup" do
494
- before { expect(pr).to receive(:ask).with('Would you like to push this branch to your remote repo and cleanup your feature branch? ').and_return('no') }
495
- it { should be_falsy }
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::Workflow::AwesomeWorkflow) }
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(DummyWorkflow.bogus).to eql("Woohoo")
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: [:feature_branch] do |**params|
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(DummyWorkflow.bogus(feature_branch: "donuts")).to eql("Woohoo donuts!")
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 options" do
49
- workflow.command :bogus, arguments: [:feature_branch], defaults: {decoration: 'sprinkles'} do |**params|
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(DummyWorkflow.bogus(feature_branch: "donuts")).to eql("Woohoo donuts with sprinkles!")
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