zenflow 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +6 -0
- data/.rspec +2 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/.zenflow +10 -0
- data/CHANGELOG.md +0 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +95 -0
- data/Guardfile +6 -0
- data/LICENSE.md +22 -0
- data/README.markdown +92 -0
- data/VERSION.yml +5 -0
- data/bin/zenflow +17 -0
- data/lib/zenflow.rb +35 -0
- data/lib/zenflow/cli.rb +130 -0
- data/lib/zenflow/commands/deploy.rb +33 -0
- data/lib/zenflow/commands/feature.rb +10 -0
- data/lib/zenflow/commands/hotfix.rb +15 -0
- data/lib/zenflow/commands/release.rb +16 -0
- data/lib/zenflow/commands/reviews.rb +12 -0
- data/lib/zenflow/helpers/ask.rb +66 -0
- data/lib/zenflow/helpers/branch.rb +80 -0
- data/lib/zenflow/helpers/branch_command.rb +95 -0
- data/lib/zenflow/helpers/branch_commands/abort.rb +21 -0
- data/lib/zenflow/helpers/branch_commands/branches.rb +21 -0
- data/lib/zenflow/helpers/branch_commands/compare.rb +20 -0
- data/lib/zenflow/helpers/branch_commands/deploy.rb +29 -0
- data/lib/zenflow/helpers/branch_commands/diff.rb +19 -0
- data/lib/zenflow/helpers/branch_commands/finish.rb +68 -0
- data/lib/zenflow/helpers/branch_commands/review.rb +58 -0
- data/lib/zenflow/helpers/branch_commands/start.rb +39 -0
- data/lib/zenflow/helpers/branch_commands/update.rb +22 -0
- data/lib/zenflow/helpers/changelog.rb +100 -0
- data/lib/zenflow/helpers/config.rb +36 -0
- data/lib/zenflow/helpers/github.rb +40 -0
- data/lib/zenflow/helpers/help.rb +37 -0
- data/lib/zenflow/helpers/log.rb +21 -0
- data/lib/zenflow/helpers/pull_request.rb +68 -0
- data/lib/zenflow/helpers/repo.rb +13 -0
- data/lib/zenflow/helpers/shell.rb +89 -0
- data/lib/zenflow/helpers/version.rb +87 -0
- data/lib/zenflow/version.rb +3 -0
- data/spec/fixtures/VERSION.yml +5 -0
- data/spec/fixtures/cassettes/create_bad_pull_request.yml +57 -0
- data/spec/fixtures/cassettes/create_pull_request.yml +68 -0
- data/spec/fixtures/cassettes/existing_pull_request.yml +145 -0
- data/spec/fixtures/cassettes/pull_request_by_ref.yml +145 -0
- data/spec/fixtures/cassettes/pull_request_find.yml +70 -0
- data/spec/fixtures/cassettes/pull_request_for_non-existent_ref.yml +145 -0
- data/spec/fixtures/cassettes/pull_request_list.yml +74 -0
- data/spec/fixtures/cassettes/unexisting_pull_request.yml +145 -0
- data/spec/spec_helper.rb +36 -0
- data/spec/support/shared_examples_for_version_number.rb +19 -0
- data/spec/zenflow/commands/deploy_spec.rb +48 -0
- data/spec/zenflow/commands/feature_spec.rb +11 -0
- data/spec/zenflow/commands/hotfix_spec.rb +14 -0
- data/spec/zenflow/commands/release_spec.rb +15 -0
- data/spec/zenflow/commands/reviews_spec.rb +15 -0
- data/spec/zenflow/helpers/ask_spec.rb +115 -0
- data/spec/zenflow/helpers/branch_command_spec.rb +310 -0
- data/spec/zenflow/helpers/branch_spec.rb +300 -0
- data/spec/zenflow/helpers/changelog_spec.rb +188 -0
- data/spec/zenflow/helpers/cli_spec.rb +277 -0
- data/spec/zenflow/helpers/github_spec.rb +45 -0
- data/spec/zenflow/helpers/help_spec.rb +36 -0
- data/spec/zenflow/helpers/log_spec.rb +31 -0
- data/spec/zenflow/helpers/pull_request_spec.rb +108 -0
- data/spec/zenflow/helpers/shell_spec.rb +135 -0
- data/spec/zenflow/helpers/version_spec.rb +111 -0
- data/zenflow.gemspec +33 -0
- metadata +273 -0
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'simplecov'
|
2
|
+
SimpleCov.start do
|
3
|
+
add_filter '/spec/'
|
4
|
+
end
|
5
|
+
|
6
|
+
Dir["./spec/support/**/*.rb"].sort.each {|f| require f}
|
7
|
+
require 'zenflow'
|
8
|
+
require 'vcr'
|
9
|
+
|
10
|
+
VCR.configure do |c|
|
11
|
+
c.configure_rspec_metadata!
|
12
|
+
c.cassette_library_dir = 'spec/fixtures/cassettes'
|
13
|
+
c.hook_into :webmock
|
14
|
+
c.default_cassette_options = { :record => :new_episodes }
|
15
|
+
c.filter_sensitive_data('<GITHUB-USER>'){ Zenflow::Github.user }
|
16
|
+
c.filter_sensitive_data('<ZENFLOW-TOKEN>'){ Zenflow::Github.zenflow_token }
|
17
|
+
end
|
18
|
+
|
19
|
+
RSpec.configure do |config|
|
20
|
+
config.order = "random"
|
21
|
+
config.treat_symbols_as_metadata_keys_with_true_values = true
|
22
|
+
config.run_all_when_everything_filtered = true
|
23
|
+
config.filter_run :focus => true
|
24
|
+
|
25
|
+
def capture(stream)
|
26
|
+
begin
|
27
|
+
stream = stream.to_s
|
28
|
+
eval "$#{stream} = StringIO.new"
|
29
|
+
yield
|
30
|
+
result = eval("$#{stream}").string
|
31
|
+
ensure
|
32
|
+
eval("$#{stream} = #{stream.upcase}")
|
33
|
+
end
|
34
|
+
result
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
shared_examples_for "a version" do |version_array|
|
2
|
+
it{expect(subject.instance_variable_get('@version')).to(have_key('major'))}
|
3
|
+
it{expect(subject.instance_variable_get('@version')).to(have_key('minor'))}
|
4
|
+
it{expect(subject.instance_variable_get('@version')).to(have_key('patch'))}
|
5
|
+
it{expect(subject.instance_variable_get('@version')).to(have_key('pre'))}
|
6
|
+
|
7
|
+
it{
|
8
|
+
expect(
|
9
|
+
subject.instance_variable_get('@version')
|
10
|
+
).to(eq(
|
11
|
+
{
|
12
|
+
'major' => version_array[0],
|
13
|
+
'minor' => version_array[1],
|
14
|
+
'patch' => version_array[2],
|
15
|
+
'pre' => version_array[3]
|
16
|
+
}
|
17
|
+
) )
|
18
|
+
}
|
19
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Zenflow::Deploy do
|
4
|
+
|
5
|
+
describe "Zenflow.Deploy" do
|
6
|
+
context 'with migrations' do
|
7
|
+
it 'deploys with migrations' do
|
8
|
+
Zenflow::Branch.should_receive(:push).with('some-server')
|
9
|
+
Zenflow.should_receive(:Log).with("Deploying with migrations to some-server")
|
10
|
+
Zenflow::Shell.should_receive(:run).with("cap some-server deploy:migrations")
|
11
|
+
Zenflow::Deploy('some-server', :migrations => true)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
context 'without migrations' do
|
16
|
+
it 'deploys without migrations' do
|
17
|
+
Zenflow::Branch.should_receive(:push).with('some-server')
|
18
|
+
Zenflow.should_receive(:Log).with("Deploying to some-server")
|
19
|
+
Zenflow::Shell.should_receive(:run).with("cap some-server deploy")
|
20
|
+
Zenflow::Deploy('some-server')
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
subject {Zenflow::Deploy.new}
|
26
|
+
|
27
|
+
describe '#qa' do
|
28
|
+
it 'Deploys to QA' do
|
29
|
+
Zenflow.should_receive(:Deploy).with('qa', {})
|
30
|
+
subject.qa
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe '#staging' do
|
35
|
+
it 'Deploys to staging' do
|
36
|
+
Zenflow.should_receive(:Deploy).with('staging', {})
|
37
|
+
subject.staging
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
describe '#staging' do
|
42
|
+
it 'Deploys to production' do
|
43
|
+
Zenflow.should_receive(:Deploy).with('production', {})
|
44
|
+
subject.production
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Zenflow::Feature do
|
4
|
+
|
5
|
+
subject { Zenflow::Feature.new }
|
6
|
+
|
7
|
+
it { expect(subject.flow).to eq("feature") }
|
8
|
+
it { expect(subject.branch(:source)).to eq("master") }
|
9
|
+
it { expect(subject.branch(:deploy)).to eq("qa") }
|
10
|
+
|
11
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Zenflow::Hotfix do
|
4
|
+
|
5
|
+
subject { Zenflow::Hotfix.new }
|
6
|
+
|
7
|
+
it { expect(subject.flow).to eq("hotfix") }
|
8
|
+
it { expect(subject.branch(:source)).to eq("production") }
|
9
|
+
it { expect(subject.branch(:deploy)).to match_array(["staging", "qa"]) }
|
10
|
+
it { expect(subject.changelog).to eq(:rotate) }
|
11
|
+
it { expect(subject.version).to eq(:patch) }
|
12
|
+
it { expect(subject.tag).to be_true }
|
13
|
+
|
14
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Zenflow::Release do
|
4
|
+
|
5
|
+
subject { Zenflow::Release.new }
|
6
|
+
|
7
|
+
it { expect(subject.flow).to eq("release") }
|
8
|
+
it { expect(subject.branch(:source)).to eq("master") }
|
9
|
+
it { expect(subject.branch(:destination)).to eq("production") }
|
10
|
+
it { expect(subject.branch(:deploy)).to match_array(["staging", "qa"]) }
|
11
|
+
it { expect(subject.changelog).to eq(:rotate) }
|
12
|
+
it { expect(subject.version).to eq(:minor) }
|
13
|
+
it { expect(subject.tag).to be_true }
|
14
|
+
|
15
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Zenflow::Reviews do
|
4
|
+
|
5
|
+
describe "#list" do
|
6
|
+
before do
|
7
|
+
pull = double
|
8
|
+
pull.stub(:[]).with("number").and_return(1)
|
9
|
+
pull.stub(:[]).with("head").and_return({ "ref" => "URL" })
|
10
|
+
Zenflow::PullRequest.should_receive(:list).and_return([pull])
|
11
|
+
end
|
12
|
+
it { capture(:stdout) { Zenflow::Reviews.new.invoke(:list) } }
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
@@ -0,0 +1,115 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Zenflow do
|
4
|
+
|
5
|
+
describe "prompt" do
|
6
|
+
before do
|
7
|
+
Zenflow.stub(:LogToFile)
|
8
|
+
$stdin.stub(:gets).and_return("good")
|
9
|
+
end
|
10
|
+
|
11
|
+
it "displays a prompt" do
|
12
|
+
Zenflow::Query.should_receive(:print).with(">> How are you? ")
|
13
|
+
Zenflow::Ask("How are you?")
|
14
|
+
end
|
15
|
+
|
16
|
+
it "displays a prompt with options" do
|
17
|
+
Zenflow::Query.should_receive(:print).with(">> How are you? [good/bad] ")
|
18
|
+
Zenflow::Ask("How are you?", options: ["good", "bad"])
|
19
|
+
end
|
20
|
+
|
21
|
+
it "displays a prompt with default" do
|
22
|
+
Zenflow::Query.should_receive(:print).with(">> How are you? [good] ")
|
23
|
+
Zenflow::Ask("How are you?", default: "good")
|
24
|
+
end
|
25
|
+
|
26
|
+
it "displays a prompt with options and default" do
|
27
|
+
Zenflow::Query.should_receive(:print).with(">> How are you? [good/bad] ")
|
28
|
+
Zenflow::Ask("How are you?", options: ["good", "bad"], default: "good")
|
29
|
+
end
|
30
|
+
|
31
|
+
context "on error" do
|
32
|
+
before(:each) do
|
33
|
+
Zenflow::Query.should_receive(:ask_question).at_least(:once).and_return('foo')
|
34
|
+
Zenflow::Query.should_receive(:handle_response).once.and_raise('something failed')
|
35
|
+
$stdout.should_receive(:puts).once
|
36
|
+
end
|
37
|
+
|
38
|
+
it{expect{Zenflow::Ask('howdy', response: 'foo', error_message: 'something failed')}.to raise_error(/something failed/)}
|
39
|
+
end
|
40
|
+
|
41
|
+
context "on interrupt" do
|
42
|
+
before(:each) do
|
43
|
+
Zenflow::Query.should_receive(:ask_question).once.and_return('foo')
|
44
|
+
Zenflow::Query.should_receive(:handle_response).once.and_raise(Interrupt)
|
45
|
+
Zenflow.should_receive(:LogToFile)
|
46
|
+
$stdout.should_receive(:puts).at_least(:once)
|
47
|
+
end
|
48
|
+
|
49
|
+
it{expect{Zenflow::Ask('howdy')}.to raise_error(SystemExit)}
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
describe Zenflow::Query do
|
54
|
+
describe '.get_response' do
|
55
|
+
context 'with a response' do
|
56
|
+
it{expect(
|
57
|
+
Zenflow::Query.ask_question('foo?', response: 'bar')).to eq('bar')
|
58
|
+
}
|
59
|
+
end
|
60
|
+
|
61
|
+
context 'with a response' do
|
62
|
+
before(:each) do
|
63
|
+
Zenflow::Query.should_receive(:prompt_for_answer).with('foo?',{}).and_return('bar')
|
64
|
+
end
|
65
|
+
|
66
|
+
it{expect(Zenflow::Query.ask_question('foo?')).to eq('bar')}
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
describe '.prompt_for_answer' do
|
71
|
+
before(:each) do
|
72
|
+
Zenflow::Query.should_receive(:print).with(">> Hi? [yes/bye] ")
|
73
|
+
STDIN.should_receive(:gets).and_return("bye")
|
74
|
+
end
|
75
|
+
|
76
|
+
it{expect(
|
77
|
+
Zenflow::Query.prompt_for_answer('Hi?', options: ['yes','bye'])
|
78
|
+
).to(
|
79
|
+
eq('bye')
|
80
|
+
) }
|
81
|
+
end
|
82
|
+
|
83
|
+
describe '.handle_response' do
|
84
|
+
context 'invalid response' do
|
85
|
+
before(:each){Zenflow::Query.should_receive(:valid_response?).and_return(false)}
|
86
|
+
it{expect{Zenflow::Query.handle_response('foo')}.to raise_error}
|
87
|
+
end
|
88
|
+
|
89
|
+
context 'valid response' do
|
90
|
+
before(:each){Zenflow::Query.should_receive(:valid_response?).and_return(true)}
|
91
|
+
it{expect(Zenflow::Query.handle_response('foo')).to eq('foo')}
|
92
|
+
it{expect(Zenflow::Query.handle_response('Y')).to eq('y')}
|
93
|
+
it{expect(Zenflow::Query.handle_response('N')).to eq('n')}
|
94
|
+
it{expect(Zenflow::Query.handle_response('', default: 'foo')).to eq('foo')}
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
describe '.valid_response?' do
|
99
|
+
it{expect(Zenflow::Query.valid_response?('foo', options: ['foo'])).to eq(true)}
|
100
|
+
it{expect(Zenflow::Query.valid_response?('foo', options: ['bar'])).to eq(false)}
|
101
|
+
it{expect(Zenflow::Query.valid_response?('foo', validate: /foo/)).to eq(true)}
|
102
|
+
it{expect(Zenflow::Query.valid_response?('foo', validate: /bar/)).to eq(false)}
|
103
|
+
it{expect(Zenflow::Query.valid_response?('', required: true)).to eq(false)}
|
104
|
+
it{expect(Zenflow::Query.valid_response?('foo', required: true)).to eq(true)}
|
105
|
+
it{expect(Zenflow::Query.valid_response?('foo', required: false)).to eq(true)}
|
106
|
+
it{expect(Zenflow::Query.valid_response?('', required: false)).to eq(true)}
|
107
|
+
end
|
108
|
+
|
109
|
+
describe '.build_error_message' do
|
110
|
+
it{expect(Zenflow::Query.build_error_message('foo')).to match(/not a valid response/)}
|
111
|
+
it{expect(Zenflow::Query.build_error_message('foo', error_message: 'stupid response.')).to match(/stupid response/)}
|
112
|
+
it{expect(Zenflow::Query.build_error_message('foo', required: true)).to match(/must respond/)}
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
@@ -0,0 +1,310 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module BranchCommandSpec
|
4
|
+
|
5
|
+
class TestCommand < Zenflow::BranchCommand
|
6
|
+
flow "test"
|
7
|
+
branch source: "master"
|
8
|
+
branch destination: "production"
|
9
|
+
branch deploy: "deploy1"
|
10
|
+
branch deploy: "deploy2"
|
11
|
+
version :patch
|
12
|
+
changelog :rotate
|
13
|
+
tag true
|
14
|
+
end
|
15
|
+
|
16
|
+
describe "Zenflow::BranchCommand" do
|
17
|
+
describe "#branches" do
|
18
|
+
before do
|
19
|
+
Zenflow.should_receive(:Log).with("Available test branches:")
|
20
|
+
Zenflow::Branch.should_receive(:list).with("test").and_return(["YES"])
|
21
|
+
Zenflow.should_receive(:Log).with("* YES", indent: true, color: false)
|
22
|
+
end
|
23
|
+
it { TestCommand.new.invoke(:branches) }
|
24
|
+
end
|
25
|
+
|
26
|
+
describe "#start" do
|
27
|
+
context "when online" do
|
28
|
+
before do
|
29
|
+
Zenflow.should_receive(:Ask).and_return("new-test-branch")
|
30
|
+
Zenflow::Branch.should_receive(:update).with("master")
|
31
|
+
Zenflow::Branch.should_receive(:create).with("test/new-test-branch", "master")
|
32
|
+
Zenflow::Branch.should_receive(:push).with("test/new-test-branch")
|
33
|
+
Zenflow::Branch.should_receive(:track).with("test/new-test-branch")
|
34
|
+
end
|
35
|
+
it { TestCommand.new.invoke(:start) }
|
36
|
+
end
|
37
|
+
|
38
|
+
context "when offline" do
|
39
|
+
before do
|
40
|
+
Zenflow.should_receive(:Ask).and_return("new-test-branch")
|
41
|
+
Zenflow::Branch.should_receive(:checkout).with("master")
|
42
|
+
Zenflow::Branch.should_receive(:create).with("test/new-test-branch", "master")
|
43
|
+
end
|
44
|
+
it { TestCommand.new.invoke(:start, nil, offline: true) }
|
45
|
+
end
|
46
|
+
|
47
|
+
context "when supplying a name" do
|
48
|
+
before do
|
49
|
+
Zenflow::Branch.should_receive(:update).with("master")
|
50
|
+
Zenflow::Branch.should_receive(:create).with("test/new-test-branch", "master")
|
51
|
+
Zenflow::Branch.should_receive(:push).with("test/new-test-branch")
|
52
|
+
Zenflow::Branch.should_receive(:track).with("test/new-test-branch")
|
53
|
+
end
|
54
|
+
it { TestCommand.new.invoke(:start, ["new-test-branch"]) }
|
55
|
+
end
|
56
|
+
|
57
|
+
context "when asking for a name" do
|
58
|
+
before do
|
59
|
+
$stdin.should_receive(:gets).and_return("new-test-branch\n")
|
60
|
+
Zenflow::Branch.should_receive(:update).with("master")
|
61
|
+
Zenflow::Branch.should_receive(:create).with("test/new-test-branch", "master")
|
62
|
+
Zenflow::Branch.should_receive(:push).with("test/new-test-branch")
|
63
|
+
Zenflow::Branch.should_receive(:track).with("test/new-test-branch")
|
64
|
+
end
|
65
|
+
it { expect(capture(:stdout){ TestCommand.new.invoke(:start) }).to eq(">> Name of the test: ") }
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
describe "#deploy" do
|
70
|
+
context "when a project is not deployable" do
|
71
|
+
before do
|
72
|
+
Zenflow::Branch.should_receive(:current).with("test").and_return("new-test-branch")
|
73
|
+
Zenflow::Config.should_receive(:[]).with(:deployable).and_return(false)
|
74
|
+
Zenflow.should_receive(:Log).with("This project is not deployable right now", color: :red)
|
75
|
+
end
|
76
|
+
it { expect{TestCommand.new.invoke(:deploy)}.to raise_error(SystemExit) }
|
77
|
+
end
|
78
|
+
|
79
|
+
context "without running migrations" do
|
80
|
+
before do
|
81
|
+
Zenflow::Branch.should_receive(:current).with("test").and_return("new-test-branch")
|
82
|
+
Zenflow::Config.should_receive(:[]).with(:deployable).and_return(true)
|
83
|
+
Zenflow::Branch.should_receive(:update).with("deploy1")
|
84
|
+
Zenflow::Branch.should_receive(:update).with("deploy2")
|
85
|
+
Zenflow::Branch.should_receive(:merge).with("test/new-test-branch").twice
|
86
|
+
Zenflow.should_receive(:Deploy).with("deploy1", {})
|
87
|
+
Zenflow.should_receive(:Deploy).with("deploy2", {})
|
88
|
+
Zenflow::Branch.should_receive(:checkout).with("test/new-test-branch")
|
89
|
+
end
|
90
|
+
it { TestCommand.new.invoke(:deploy) }
|
91
|
+
end
|
92
|
+
|
93
|
+
context "when running migrations" do
|
94
|
+
before do
|
95
|
+
Zenflow::Branch.should_receive(:current).with("test").and_return("new-test-branch")
|
96
|
+
Zenflow::Config.should_receive(:[]).with(:deployable).and_return(true)
|
97
|
+
Zenflow::Branch.should_receive(:update).with("deploy1")
|
98
|
+
Zenflow::Branch.should_receive(:update).with("deploy2")
|
99
|
+
Zenflow::Branch.should_receive(:merge).with("test/new-test-branch").twice
|
100
|
+
Zenflow.should_receive(:Deploy).with("deploy1", { "migrations" => true })
|
101
|
+
Zenflow.should_receive(:Deploy).with("deploy2", { "migrations" => true })
|
102
|
+
Zenflow::Branch.should_receive(:checkout).with("test/new-test-branch")
|
103
|
+
end
|
104
|
+
it { TestCommand.new.invoke(:deploy, [], "migrations" => true) }
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
describe "#update" do
|
109
|
+
before do
|
110
|
+
Zenflow::Branch.should_receive(:current).with("test").and_return("new-test-branch")
|
111
|
+
Zenflow::Branch.should_receive(:update).with("master")
|
112
|
+
Zenflow::Branch.should_receive(:checkout).with("test/new-test-branch")
|
113
|
+
Zenflow::Branch.should_receive(:merge).with("master")
|
114
|
+
end
|
115
|
+
it { TestCommand.new.invoke(:update) }
|
116
|
+
end
|
117
|
+
|
118
|
+
describe "#diff" do
|
119
|
+
before do
|
120
|
+
Zenflow.should_receive(:Log).with("Displaying diff with master")
|
121
|
+
Zenflow::Shell.should_receive(:[]).with("git difftool master")
|
122
|
+
end
|
123
|
+
it { TestCommand.new.invoke(:diff) }
|
124
|
+
end
|
125
|
+
|
126
|
+
describe "#compare" do
|
127
|
+
before do
|
128
|
+
Zenflow::Branch.should_receive(:current).with("test").and_return("new-test-branch")
|
129
|
+
Zenflow.should_receive(:Log).with("Opening GitHub compare view for master...test/new-test-branch")
|
130
|
+
Zenflow::Repo.should_receive(:slug).and_return("test-repo")
|
131
|
+
Zenflow::Shell.should_receive(:[]).with("open https://github.com/test-repo/compare/master...test/new-test-branch")
|
132
|
+
end
|
133
|
+
it { TestCommand.new.invoke(:compare) }
|
134
|
+
end
|
135
|
+
|
136
|
+
describe "#review" do
|
137
|
+
context "when pull request is found" do
|
138
|
+
before do
|
139
|
+
Zenflow::Branch.should_receive(:current).with("test").and_return("new-test-branch")
|
140
|
+
Zenflow::PullRequest.should_receive(:find_by_ref).with("test/new-test-branch").and_return({ html_url: "URL"})
|
141
|
+
Zenflow.should_receive(:Log).with("A pull request for test/new-test-branch already exists", color: :red)
|
142
|
+
Zenflow.should_receive(:Log).with("URL", indent: true, color: false)
|
143
|
+
end
|
144
|
+
it { expect{TestCommand.new.invoke(:review)}.to raise_error(SystemExit) }
|
145
|
+
end
|
146
|
+
|
147
|
+
context "with new pull request" do
|
148
|
+
before do
|
149
|
+
Zenflow::Branch.should_receive(:current).with("test").and_return("new-test-branch")
|
150
|
+
Zenflow::PullRequest.should_receive(:find_by_ref).with("test/new-test-branch").and_return(false)
|
151
|
+
end
|
152
|
+
|
153
|
+
context "with valid request" do
|
154
|
+
before do
|
155
|
+
Zenflow.should_receive(:Ask).with("Describe this test:", required: true).and_return("A great test")
|
156
|
+
pull = double(valid?: true)
|
157
|
+
pull.stub(:[]).with("html_url").and_return("URL")
|
158
|
+
Zenflow::PullRequest.should_receive(:create).with(
|
159
|
+
base: "master",
|
160
|
+
head: "test/new-test-branch",
|
161
|
+
title: "test: new-test-branch",
|
162
|
+
body: "A great test"
|
163
|
+
).and_return(pull)
|
164
|
+
Zenflow.should_receive(:Log).with("Pull request was created!")
|
165
|
+
Zenflow.should_receive(:Log).with("URL", indent: true, color: false)
|
166
|
+
Zenflow::Shell.should_receive(:[]).with("open URL")
|
167
|
+
end
|
168
|
+
it { TestCommand.new.invoke(:review) }
|
169
|
+
end
|
170
|
+
|
171
|
+
context "with invalid request" do
|
172
|
+
let(:pull){ double(valid?: false) }
|
173
|
+
|
174
|
+
before do
|
175
|
+
Zenflow.should_receive(:Ask).with("Describe this test:", required: true).and_return("A great test")
|
176
|
+
Zenflow::PullRequest.should_receive(:create).with(
|
177
|
+
base: "master",
|
178
|
+
head: "test/new-test-branch",
|
179
|
+
title: "test: new-test-branch",
|
180
|
+
body: "A great test"
|
181
|
+
).and_return(pull)
|
182
|
+
Zenflow.should_receive(:Log).with("There was a problem creating the pull request:", color: :red)
|
183
|
+
end
|
184
|
+
|
185
|
+
it "displays errors" do
|
186
|
+
pull.stub(:[]).with("errors").and_return([{"message" => "ERROR"},{"message" => "ERROR"}])
|
187
|
+
Zenflow.should_receive(:Log).with("* ERROR", indent: true, color: :red).twice
|
188
|
+
TestCommand.new.invoke(:review)
|
189
|
+
end
|
190
|
+
|
191
|
+
it "displays an error message" do
|
192
|
+
pull.stub(:[]).with("errors")
|
193
|
+
pull.stub(:[]).with("message").and_return("ERROR")
|
194
|
+
Zenflow.should_receive(:Log).with("* ERROR", indent: true, color: :red)
|
195
|
+
TestCommand.new.invoke(:review)
|
196
|
+
end
|
197
|
+
|
198
|
+
it "handles unexpected failure" do
|
199
|
+
pull.stub(:[]).with("errors")
|
200
|
+
pull.stub(:[]).with("message")
|
201
|
+
Zenflow.should_receive(:Log).with(" * unexpected failure, both 'errors' and 'message' were empty in the response")
|
202
|
+
TestCommand.new.invoke(:review)
|
203
|
+
end
|
204
|
+
end
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
208
|
+
describe "#abort" do
|
209
|
+
let(:branch_name){"test/new-test-branch"}
|
210
|
+
before {
|
211
|
+
Zenflow::Branch.should_receive(:current).with("test").and_return("new-test-branch")
|
212
|
+
Zenflow::Branch.should_receive(:checkout).with("master")
|
213
|
+
}
|
214
|
+
|
215
|
+
context "when online" do
|
216
|
+
before do
|
217
|
+
Zenflow::Branch.should_receive(:delete_remote).with(branch_name)
|
218
|
+
Zenflow::Branch.should_receive(:delete_local).with(branch_name, force: true)
|
219
|
+
end
|
220
|
+
it { TestCommand.new.invoke(:abort) }
|
221
|
+
end
|
222
|
+
|
223
|
+
context "when offline" do
|
224
|
+
before do
|
225
|
+
Zenflow::Branch.should_receive(:delete_local).with(branch_name, force: true)
|
226
|
+
end
|
227
|
+
it { TestCommand.new.invoke(:abort, [], offline: true) }
|
228
|
+
end
|
229
|
+
end
|
230
|
+
|
231
|
+
describe "#finish" do
|
232
|
+
before do
|
233
|
+
Zenflow::Branch.should_receive(:current).with("test").and_return("new-test-branch")
|
234
|
+
end
|
235
|
+
|
236
|
+
context "with confirmations" do
|
237
|
+
it "without deployment to staging" do
|
238
|
+
Zenflow::Config.should_receive(:[]).with(:confirm_staging).and_return(true)
|
239
|
+
Zenflow.should_receive(:Ask).with("Has this been tested in a staging environment first?", options: ["Y", "n"], default: "Y").and_return("n")
|
240
|
+
Zenflow.should_receive(:Log).with("Sorry, deploy to a staging environment first", color: :red)
|
241
|
+
expect{TestCommand.new.invoke(:finish)}.to raise_error(SystemExit)
|
242
|
+
end
|
243
|
+
|
244
|
+
it "without review" do
|
245
|
+
Zenflow::Config.should_receive(:[]).with(:confirm_staging).and_return(true)
|
246
|
+
Zenflow::Config.should_receive(:[]).with(:confirm_review).and_return(true)
|
247
|
+
Zenflow.should_receive(:Ask).with("Has this been tested in a staging environment first?", options: ["Y", "n"], default: "Y").and_return("y")
|
248
|
+
Zenflow.should_receive(:Ask).with("Has this been code reviewed yet?", options: ["Y", "n"], default: "Y").and_return("n")
|
249
|
+
Zenflow.should_receive(:Log).with("Please have someone look at this first", color: :red)
|
250
|
+
expect{TestCommand.new.invoke(:finish)}.to raise_error(SystemExit)
|
251
|
+
end
|
252
|
+
end
|
253
|
+
|
254
|
+
context "without confirmations" do
|
255
|
+
before do
|
256
|
+
Zenflow::Config.should_receive(:[]).with(:confirm_staging).and_return(false)
|
257
|
+
Zenflow::Config.should_receive(:[]).with(:confirm_review).and_return(false)
|
258
|
+
end
|
259
|
+
|
260
|
+
context "when online" do
|
261
|
+
before do
|
262
|
+
Zenflow::Branch.should_receive(:update).with("production")
|
263
|
+
Zenflow::Branch.should_receive(:checkout).with("test/new-test-branch")
|
264
|
+
Zenflow::Branch.should_receive(:merge).with("production")
|
265
|
+
|
266
|
+
Zenflow::Version.should_receive(:update).with(:patch)
|
267
|
+
|
268
|
+
Zenflow::Changelog.should_receive(:update).with(rotate: true, name: "new-test-branch").and_return("YES")
|
269
|
+
|
270
|
+
Zenflow::Branch.should_receive(:checkout).with("master")
|
271
|
+
Zenflow::Branch.should_receive(:merge).with("test/new-test-branch")
|
272
|
+
Zenflow::Branch.should_receive(:push).with("master")
|
273
|
+
Zenflow::Branch.should_receive(:checkout).with("production")
|
274
|
+
Zenflow::Branch.should_receive(:merge).with("test/new-test-branch")
|
275
|
+
Zenflow::Branch.should_receive(:push).with("production")
|
276
|
+
|
277
|
+
Zenflow::Branch.should_receive(:tag).with(Zenflow::Version.current.to_s, "YES")
|
278
|
+
Zenflow::Branch.should_receive(:push).with(:tags)
|
279
|
+
|
280
|
+
Zenflow::Branch.should_receive(:delete_remote).with("test/new-test-branch")
|
281
|
+
Zenflow::Branch.should_receive(:delete_local).with("test/new-test-branch", force: true)
|
282
|
+
end
|
283
|
+
it { TestCommand.new.invoke(:finish) }
|
284
|
+
end
|
285
|
+
|
286
|
+
context "when offline" do
|
287
|
+
before do
|
288
|
+
Zenflow::Branch.should_receive(:checkout).with("test/new-test-branch")
|
289
|
+
Zenflow::Branch.should_receive(:merge).with("production")
|
290
|
+
|
291
|
+
Zenflow::Version.should_receive(:update).with(:patch)
|
292
|
+
|
293
|
+
Zenflow::Changelog.should_receive(:update).with(rotate: true, name: "new-test-branch").and_return("YES")
|
294
|
+
|
295
|
+
Zenflow::Branch.should_receive(:checkout).with("master")
|
296
|
+
Zenflow::Branch.should_receive(:merge).with("test/new-test-branch")
|
297
|
+
Zenflow::Branch.should_receive(:checkout).with("production")
|
298
|
+
Zenflow::Branch.should_receive(:merge).with("test/new-test-branch")
|
299
|
+
|
300
|
+
Zenflow::Branch.should_receive(:tag).with(Zenflow::Version.current.to_s, "YES")
|
301
|
+
|
302
|
+
Zenflow::Branch.should_receive(:delete_local).with("test/new-test-branch", force: true)
|
303
|
+
end
|
304
|
+
it { TestCommand.new.invoke(:finish, [], offline: true) }
|
305
|
+
end
|
306
|
+
end
|
307
|
+
end
|
308
|
+
end
|
309
|
+
|
310
|
+
end
|