octopolo 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (108) hide show
  1. checksums.yaml +15 -0
  2. data/.gitignore +21 -0
  3. data/.ruby-gemset +1 -0
  4. data/.ruby-version +1 -0
  5. data/.travis.yml +6 -0
  6. data/Gemfile +3 -0
  7. data/Guardfile +5 -0
  8. data/MIT-LICENSE +20 -0
  9. data/README.markdown +55 -0
  10. data/Rakefile +38 -0
  11. data/bash_completion.sh +13 -0
  12. data/bin/octopolo +21 -0
  13. data/bin/op +21 -0
  14. data/lib/octopolo.rb +15 -0
  15. data/lib/octopolo/changelog.rb +27 -0
  16. data/lib/octopolo/cli.rb +210 -0
  17. data/lib/octopolo/commands/accept_pull.rb +8 -0
  18. data/lib/octopolo/commands/compare_release.rb +9 -0
  19. data/lib/octopolo/commands/deployable.rb +8 -0
  20. data/lib/octopolo/commands/github_auth.rb +5 -0
  21. data/lib/octopolo/commands/new_branch.rb +9 -0
  22. data/lib/octopolo/commands/new_deployable.rb +8 -0
  23. data/lib/octopolo/commands/new_staging.rb +8 -0
  24. data/lib/octopolo/commands/octopolo_setup.rb +5 -0
  25. data/lib/octopolo/commands/pivotal_auth.rb +5 -0
  26. data/lib/octopolo/commands/pull_request.rb +13 -0
  27. data/lib/octopolo/commands/signoff.rb +10 -0
  28. data/lib/octopolo/commands/stage_up.rb +8 -0
  29. data/lib/octopolo/commands/stale_branches.rb +11 -0
  30. data/lib/octopolo/commands/sync_branch.rb +11 -0
  31. data/lib/octopolo/commands/tag_release.rb +13 -0
  32. data/lib/octopolo/config.rb +146 -0
  33. data/lib/octopolo/convenience_wrappers.rb +46 -0
  34. data/lib/octopolo/dated_branch_creator.rb +81 -0
  35. data/lib/octopolo/git.rb +262 -0
  36. data/lib/octopolo/github.rb +95 -0
  37. data/lib/octopolo/github/commit.rb +45 -0
  38. data/lib/octopolo/github/pull_request.rb +126 -0
  39. data/lib/octopolo/github/pull_request_creator.rb +127 -0
  40. data/lib/octopolo/github/user.rb +40 -0
  41. data/lib/octopolo/jira/story_commenter.rb +26 -0
  42. data/lib/octopolo/pivotal.rb +44 -0
  43. data/lib/octopolo/pivotal/story_commenter.rb +19 -0
  44. data/lib/octopolo/pull_request_merger.rb +99 -0
  45. data/lib/octopolo/renderer.rb +37 -0
  46. data/lib/octopolo/reports.rb +18 -0
  47. data/lib/octopolo/scripts.rb +23 -0
  48. data/lib/octopolo/scripts/accept_pull.rb +67 -0
  49. data/lib/octopolo/scripts/compare_release.rb +52 -0
  50. data/lib/octopolo/scripts/deployable.rb +27 -0
  51. data/lib/octopolo/scripts/github_auth.rb +87 -0
  52. data/lib/octopolo/scripts/new_branch.rb +34 -0
  53. data/lib/octopolo/scripts/new_deployable.rb +14 -0
  54. data/lib/octopolo/scripts/new_staging.rb +15 -0
  55. data/lib/octopolo/scripts/octopolo_setup.rb +55 -0
  56. data/lib/octopolo/scripts/pivotal_auth.rb +44 -0
  57. data/lib/octopolo/scripts/pull_request.rb +127 -0
  58. data/lib/octopolo/scripts/signoff.rb +85 -0
  59. data/lib/octopolo/scripts/stage_up.rb +26 -0
  60. data/lib/octopolo/scripts/stale_branches.rb +54 -0
  61. data/lib/octopolo/scripts/sync_branch.rb +37 -0
  62. data/lib/octopolo/scripts/tag_release.rb +70 -0
  63. data/lib/octopolo/templates/pull_request_body.erb +24 -0
  64. data/lib/octopolo/user_config.rb +112 -0
  65. data/lib/octopolo/version.rb +3 -0
  66. data/lib/octopolo/week.rb +130 -0
  67. data/octopolo.gemspec +31 -0
  68. data/spec/.DS_Store +0 -0
  69. data/spec/octopolo/cli_spec.rb +310 -0
  70. data/spec/octopolo/config_spec.rb +344 -0
  71. data/spec/octopolo/convenience_wrappers_spec.rb +80 -0
  72. data/spec/octopolo/dated_branch_creator_spec.rb +143 -0
  73. data/spec/octopolo/git_spec.rb +419 -0
  74. data/spec/octopolo/github/commit_spec.rb +59 -0
  75. data/spec/octopolo/github/pull_request_creator_spec.rb +174 -0
  76. data/spec/octopolo/github/pull_request_spec.rb +291 -0
  77. data/spec/octopolo/github/user_spec.rb +65 -0
  78. data/spec/octopolo/github_spec.rb +169 -0
  79. data/spec/octopolo/jira/stor_commenter_spec.rb +30 -0
  80. data/spec/octopolo/pivotal/story_commenter_spec.rb +34 -0
  81. data/spec/octopolo/pivotal_spec.rb +61 -0
  82. data/spec/octopolo/pull_request_merger_spec.rb +144 -0
  83. data/spec/octopolo/renderer_spec.rb +35 -0
  84. data/spec/octopolo/scripts/accept_pull_spec.rb +76 -0
  85. data/spec/octopolo/scripts/compare_release_spec.rb +115 -0
  86. data/spec/octopolo/scripts/deployable_spec.rb +52 -0
  87. data/spec/octopolo/scripts/github_auth_spec.rb +156 -0
  88. data/spec/octopolo/scripts/new_branch_spec.rb +41 -0
  89. data/spec/octopolo/scripts/new_deployable_spec.rb +18 -0
  90. data/spec/octopolo/scripts/new_staging_spec.rb +18 -0
  91. data/spec/octopolo/scripts/octopolo_setup_spec.rb +120 -0
  92. data/spec/octopolo/scripts/pivotal_auth_spec.rb +77 -0
  93. data/spec/octopolo/scripts/pull_request_spec.rb +217 -0
  94. data/spec/octopolo/scripts/signoff_spec.rb +139 -0
  95. data/spec/octopolo/scripts/stage_up_spec.rb +52 -0
  96. data/spec/octopolo/scripts/stale_branches_spec.rb +81 -0
  97. data/spec/octopolo/scripts/sync_branch_spec.rb +57 -0
  98. data/spec/octopolo/scripts/tag_release_spec.rb +108 -0
  99. data/spec/octopolo/user_config_spec.rb +167 -0
  100. data/spec/octopolo_spec.rb +7 -0
  101. data/spec/spec_helper.rb +29 -0
  102. data/spec/support/engine_yard.cache +0 -0
  103. data/spec/support/sample_octopolo.yml +2 -0
  104. data/spec/support/sample_user.yml +2 -0
  105. data/templates/lib.erb +23 -0
  106. data/templates/script.erb +7 -0
  107. data/templates/spec.erb +29 -0
  108. metadata +344 -0
@@ -0,0 +1,344 @@
1
+ require "spec_helper"
2
+ require "fileutils"
3
+
4
+ module Octopolo
5
+ describe Config do
6
+ let(:cli) { mock("cli") }
7
+
8
+ context "#initialize" do
9
+ subject { Config }
10
+
11
+ it "loads plugins" do
12
+ subject.any_instance.should_receive(:load_plugins)
13
+ subject.new(deploy_branch: "foo", branches_to_keep: ["a", "b"])
14
+ end
15
+
16
+ it "sets up methods for all the attributes it receives" do
17
+ config = subject.new(deploy_branch: "foo", branches_to_keep: ["a", "b"])
18
+
19
+ config.deploy_branch.should == "foo"
20
+ config.branches_to_keep.should == ["a", "b"]
21
+ end
22
+ end
23
+
24
+ context "default cuzomizable methods" do
25
+ context "#deploy_branch" do
26
+ it "is master by default" do
27
+ Config.new.deploy_branch.should == "master"
28
+ end
29
+
30
+ it "is the specified branch otherwise" do
31
+ Config.new(deploy_branch: "production").deploy_branch.should == "production"
32
+ end
33
+ end
34
+
35
+ context "#branches_to_keep" do
36
+ it "is an empty array by default" do
37
+ Config.new.branches_to_keep.should == []
38
+ end
39
+
40
+ it "is the specified values otherwise" do
41
+ Config.new(branches_to_keep: ["a", "b"]).branches_to_keep.should == ["a", "b"]
42
+ end
43
+ end
44
+
45
+ context "#deploy_methods" do
46
+ it "is an empty array by default" do
47
+ Config.new.deploy_methods.should == []
48
+ end
49
+
50
+ it "is the specified values otherwise" do
51
+ Config.new(deploy_methods: ["a", "b"]).deploy_methods.should == ["a", "b"]
52
+ end
53
+ end
54
+
55
+ context "#deploy_environments" do
56
+ it "is an empty array by default" do
57
+ Config.new.deploy_environments.should == []
58
+ end
59
+
60
+ it "is the specified values otherwise" do
61
+ Config.new(deploy_environments: ["a", "b"]).deploy_environments.should == ["a", "b"]
62
+ end
63
+ end
64
+
65
+ context "#github_repo" do
66
+ it "raises an exception if not given" do
67
+ expect { Config.new.github_repo }.to raise_error(Config::MissingRequiredAttribute)
68
+ end
69
+
70
+ it "returns the specified value otherwise" do
71
+ Config.new(github_repo: "tstmedia/ngin").github_repo.should == "tstmedia/ngin"
72
+ end
73
+ end
74
+
75
+ context "#user_notifications" do
76
+ it "is nil by default" do
77
+ Config.new.user_notifications.should == nil
78
+ end
79
+
80
+ it "raise an error if it is not an array" do
81
+ expect { Config.new(user_notifications: {:user => "NickLaMuro"}).user_notifications }.to raise_error(Config::InvalidAttributeSupplied)
82
+ end
83
+
84
+ it "returns the specified value if an array" do
85
+ Config.new(user_notifications: ["NickLaMuro"]).user_notifications.should == ["NickLaMuro"]
86
+ end
87
+
88
+ it "returns the specified value if as an array if a string" do
89
+ Config.new(user_notifications: "NickLaMuro").user_notifications.should == ["NickLaMuro"]
90
+ end
91
+ end
92
+
93
+ context "#plugins" do
94
+ before { Config.any_instance.stub(:load_plugins) }
95
+
96
+ it "defaults to an empty array" do
97
+ Config.new.plugins.should == []
98
+ end
99
+
100
+ it "raise an error if it is not a string or array" do
101
+ expect { Config.new(plugins: {:user => "foo-plugin"}).plugins }.to raise_error(Config::InvalidAttributeSupplied)
102
+ end
103
+
104
+ it "returns the specified single plugin as an array" do
105
+ Config.new(plugins: "octopolo-templates").plugins.should == ["octopolo-templates"]
106
+ end
107
+
108
+ it "returns the specified plugins as an array" do
109
+ Config.new(plugins: ["op-templates", "op-pivotal"]).plugins.should == ["op-templates", "op-pivotal"]
110
+ end
111
+ end
112
+
113
+ context "#use_pivotal_tracker" do
114
+ it "defaults to false" do
115
+ expect(Config.new.use_pivotal_tracker).to be_false
116
+ end
117
+
118
+ it "forces a truthy value to be true" do
119
+ expect(Config.new(use_pivotal_tracker: "true").use_pivotal_tracker).to be_true
120
+ end
121
+ end
122
+
123
+ context "#use_jira" do
124
+ it "defaults to false" do
125
+ expect(Config.new.use_jira).to be_false
126
+ end
127
+
128
+ it "forces a truthy value to be true" do
129
+ expect(Config.new(use_jira: "true").use_jira).to be_true
130
+ end
131
+ end
132
+
133
+ context "#jira_user" do
134
+ it "does not raise an exception if jira isn't enabled" do
135
+ expect { Config.new.jira_user }.to_not raise_error(Config::MissingRequiredAttribute)
136
+ end
137
+
138
+ it "raises an exception if not given" do
139
+ expect { Config.new(use_jira: true).jira_user }.to raise_error(Config::MissingRequiredAttribute)
140
+ end
141
+
142
+ it "returns the specified value otherwise" do
143
+ expect(Config.new(use_jira: true, jira_user: "jira-user").jira_user).to eq("jira-user")
144
+ end
145
+ end
146
+
147
+ context "#jira_password" do
148
+ it "does not raise an exception if jira isn't enabled" do
149
+ expect { Config.new.jira_password }.to_not raise_error(Config::MissingRequiredAttribute)
150
+ end
151
+
152
+ it "raises an exception if not given" do
153
+ expect { Config.new(use_jira: true).jira_password }.to raise_error(Config::MissingRequiredAttribute)
154
+ end
155
+
156
+ it "returns the specified value otherwise" do
157
+ expect(Config.new(use_jira: true, jira_password: "jira-password").jira_password).to eq("jira-password")
158
+ end
159
+ end
160
+ context "#jira_url" do
161
+ it "does not raise an exception if jira isn't enabled" do
162
+ expect { Config.new.jira_url }.to_not raise_error(Config::MissingRequiredAttribute)
163
+ end
164
+
165
+ it "raises an exception if not given" do
166
+ expect { Config.new(use_jira: true).jira_url }.to raise_error(Config::MissingRequiredAttribute)
167
+ end
168
+
169
+ it "returns the specified value otherwise" do
170
+ expect(Config.new(use_jira: true, jira_url: "jira-url").jira_url).to eq("jira-url")
171
+ end
172
+ end
173
+ end
174
+
175
+ context "loading in plugins" do
176
+ context "in a seperate state" do
177
+ fork {
178
+ before { Config.new(:plugins => "octopolo_plugin_example") }
179
+
180
+ it "include the plugin in the object space" do
181
+ expect{ ExamplePlugin.new.example_method }.not_to raise_error
182
+ end
183
+
184
+ it "includes any monkey patching" do
185
+ subject.example_var.should == ExamplePlugin::EXAMPLE_CONSTANT
186
+ end
187
+ }
188
+ end
189
+
190
+ context "in a clean state" do
191
+ it "not include the plugin in the object space" do
192
+ expect{ ExamplePlugin.new.example_method }.to raise_error NameError
193
+ end
194
+
195
+ it "not include any monkey patching" do
196
+ expect{ subject.example_var.should }.to raise_error NoMethodError
197
+ end
198
+ end
199
+ end
200
+
201
+ context ".parse" do
202
+ let(:parsed_attributes) { { :foo => "bar" }}
203
+ subject { Config }
204
+
205
+ it "reads from the .octopolo.yml file and creates a new config instance" do
206
+ subject.should_receive(:attributes_from_file).and_return(parsed_attributes)
207
+ subject.should_receive(:new).with(parsed_attributes)
208
+
209
+ subject.parse
210
+ end
211
+ end
212
+
213
+ context ".attributes_from_file" do
214
+ let(:stub_path) { File.join(Dir.pwd, 'spec', 'support', 'sample_octopolo.yml') }
215
+ subject { Config }
216
+
217
+ it "parses the YAML in the octopolo_config_path" do
218
+ subject.stub(:octopolo_config_path).and_return(stub_path)
219
+ subject.attributes_from_file.should == YAML.load_file(stub_path)
220
+ end
221
+ end
222
+
223
+ context ".octopolo_config_path" do
224
+ let(:project_working_dir) { Dir.pwd }
225
+ subject { Config }
226
+ before { project_working_dir }
227
+
228
+ it "gives up if it can't find a config file" do
229
+ File.stub(:exists?) { false }
230
+ Octopolo::CLI.should_receive(:say).with("Could not find .octopolo.yml or .automation.yml")
231
+ lambda { subject.octopolo_config_path }.should raise_error(SystemExit)
232
+ Dir.chdir project_working_dir
233
+ end
234
+
235
+ context "with a .octopolo.yml file" do
236
+ before do
237
+ FileUtils.cp "spec/support/sample_octopolo.yml", "spec/support/.octopolo.yml"
238
+ end
239
+
240
+ it "is the .octopolo.yml file in the project directory" do
241
+ Dir.chdir "spec/support"
242
+ subject.octopolo_config_path.should == File.join(Dir.pwd, '.octopolo.yml')
243
+ end
244
+
245
+ it "is the .octopolo.yml file in the project directory, two directories up" do
246
+ FileUtils.mkdir_p "spec/support/tmp/foo"
247
+ Dir.chdir "spec/support/tmp/foo"
248
+ subject.octopolo_config_path.should == File.join(Dir.pwd, '.octopolo.yml')
249
+ end
250
+
251
+ after do
252
+ Dir.chdir project_working_dir
253
+ FileUtils.rm "spec/support/.octopolo.yml"
254
+ FileUtils.rm_f "spec/support/tmp"
255
+ end
256
+ end
257
+
258
+ context "with a .automation.yml file" do
259
+ before do
260
+ FileUtils.cp "spec/support/sample_octopolo.yml", "spec/support/.automation.yml"
261
+ end
262
+
263
+ it "is the .octopolo.yml file in the project directory" do
264
+ Dir.chdir "spec/support"
265
+ subject.octopolo_config_path.should == File.join(Dir.pwd, '.automation.yml')
266
+ end
267
+
268
+ it "is the .octopolo.yml file in the project directory, two directories up" do
269
+ FileUtils.mkdir_p "spec/support/tmp/foo"
270
+ Dir.chdir "spec/support/tmp/foo"
271
+ subject.octopolo_config_path.should == File.join(Dir.pwd, '.automation.yml')
272
+ end
273
+
274
+ after do
275
+ Dir.chdir project_working_dir
276
+ FileUtils.rm "spec/support/.automation.yml"
277
+ FileUtils.rm_f "spec/support/tmp"
278
+ end
279
+ end
280
+
281
+ end
282
+
283
+ context "#load_plugins" do
284
+ context "with valid plugins" do
285
+ subject { Config.new(:plugins => "rspec") }
286
+
287
+ it "loads the plugins" do
288
+ subject.load_plugins
289
+ end
290
+ end
291
+
292
+ context "with invalid plugins" do
293
+ subject { Config.new }
294
+
295
+ it "skips loading the plugin and displays a message" do
296
+ subject.instance_variable_set(:@plugins, "not-a-real-plugin")
297
+ subject.should_receive(:puts)
298
+ .with("Plugin 'not-a-real-plugin' failed to load")
299
+
300
+ subject.load_plugins
301
+ end
302
+ end
303
+ end
304
+
305
+ context "#remote_branch_exists?" do
306
+ before do
307
+ Octopolo::CLI.stub(:perform => <<-BR
308
+ * origin/production
309
+ origin/test
310
+ origin/asdf
311
+ BR
312
+ )
313
+ end
314
+
315
+ it "should find production" do
316
+ subject.remote_branch_exists?("production").should == true
317
+ end
318
+
319
+ it "shouldn't production" do
320
+ subject.remote_branch_exists?("not-there").should == false
321
+ end
322
+ end
323
+
324
+ context "#basedir" do
325
+ let(:project_working_dir) { Dir.pwd }
326
+ before do
327
+ project_working_dir
328
+ FileUtils.cp "spec/support/sample_octopolo.yml", "spec/support/.octopolo.yml"
329
+ end
330
+
331
+ it "returns the name of the directory containing the .octopolo.yml file" do
332
+ Dir.chdir "spec/support"
333
+ config = Config.new
334
+ expected_value = File.basename(File.dirname(Config.octopolo_config_path))
335
+ config.basedir.should == expected_value
336
+ end
337
+
338
+ after do
339
+ Dir.chdir project_working_dir
340
+ FileUtils.rm "spec/support/.octopolo.yml"
341
+ end
342
+ end
343
+ end
344
+ end
@@ -0,0 +1,80 @@
1
+ require "spec_helper"
2
+ require_relative "../../lib/octopolo/convenience_wrappers"
3
+ require_relative "../../lib/octopolo/git"
4
+
5
+ module Octopolo
6
+ class Foo
7
+ include CLIWrapper
8
+ include ConfigWrapper
9
+ include UserConfigWrapper
10
+ include GitWrapper
11
+ end
12
+
13
+ describe CLIWrapper do
14
+ let(:foo) { Foo.new }
15
+ let(:cli) { stub(:CLI) }
16
+
17
+ context "#cli" do
18
+ it "wraps around the CLI class" do
19
+ foo.cli.should == CLI
20
+ end
21
+
22
+ it "uses the given CLI class" do
23
+ foo.cli = cli
24
+ foo.cli.should == cli
25
+ end
26
+ end
27
+ end
28
+
29
+ describe ConfigWrapper do
30
+ let(:foo) { Foo.new }
31
+ let(:config) { stub(:config) }
32
+
33
+ context "#config" do
34
+ it "parses the current config" do
35
+ Octopolo.should_receive(:config) { config }
36
+ foo.config.should == config
37
+ end
38
+
39
+ it "uses the given parsed config" do
40
+ Config.should_not_receive(:parse)
41
+ foo.config = config
42
+ foo.config.should == config
43
+ end
44
+ end
45
+ end
46
+
47
+ describe UserConfigWrapper do
48
+ let(:foo) { Foo.new }
49
+ let(:user_config) { stub(:user_config) }
50
+
51
+ context "#user_config" do
52
+ it "parses the current user config" do
53
+ UserConfig.should_receive(:parse) { user_config }
54
+ foo.user_config.should == user_config
55
+ end
56
+
57
+ it "uses the given parsed config" do
58
+ foo.user_config = user_config
59
+ UserConfig.should_not_receive(:parse)
60
+ foo.user_config.should == user_config
61
+ end
62
+ end
63
+ end
64
+
65
+ describe GitWrapper do
66
+ subject { Foo.new }
67
+ let(:git) { stub(:Git) }
68
+
69
+ context "#git" do
70
+ it "wraps around the Git class" do
71
+ subject.git.should == Git
72
+ end
73
+
74
+ it "uses the given Git" do
75
+ subject.git = git
76
+ subject.git.should == git
77
+ end
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,143 @@
1
+ require "spec_helper"
2
+ require_relative "../../lib/octopolo/dated_branch_creator"
3
+
4
+ module Octopolo
5
+ describe DatedBranchCreator do
6
+ let(:type) { stub(:string) }
7
+ let(:branch_name) { stub(:string) }
8
+ let(:cli) { stub(:CLI) }
9
+ let(:config) { stub(:Config, app_name: "fooapp", deploy_branch: "somebranch") }
10
+ let(:git) { stub(:Git) }
11
+
12
+ subject { DatedBranchCreator.new type }
13
+
14
+ before do
15
+ subject.cli = cli
16
+ subject.config = config
17
+ subject.git = git
18
+ end
19
+
20
+ context ".perform(branch_type)" do
21
+ let(:creator) { stub(:DatedBranchCreator) }
22
+
23
+ it "instantiates a new creator and performs it" do
24
+ DatedBranchCreator.should_receive(:new).with(type) { creator }
25
+ creator.should_receive(:perform)
26
+ DatedBranchCreator.perform(type).should == creator
27
+ end
28
+ end
29
+
30
+ context ".new(branch_type)" do
31
+ it "remembers the branch_type" do
32
+ test = DatedBranchCreator.new(type)
33
+ test.branch_type.should == type
34
+ end
35
+ end
36
+
37
+ context "#perform" do
38
+ it "creates the branch and handles cleaning up and posting about it" do
39
+ subject.should_receive(:create_branch)
40
+ subject.should_receive(:delete_old_branches)
41
+
42
+ subject.perform
43
+ end
44
+ end
45
+
46
+ context "#create_branch" do
47
+ let(:runner) { stub("script::new_branch") }
48
+
49
+ before do
50
+ subject.stub(branch_name: branch_name)
51
+ end
52
+
53
+ it "creates a branch from its #branch_name" do
54
+ git.should_receive(:new_branch).with(branch_name, config.deploy_branch)
55
+ subject.create_branch
56
+ end
57
+ end
58
+
59
+ context "#date_suffix" do
60
+ it "uses today's date" do
61
+ subject.date_suffix.should == Date.today.strftime("%Y.%m.%d")
62
+ end
63
+ end
64
+
65
+ context "#branch_name" do
66
+ it "properly generates a name for staging branches" do
67
+ subject.branch_type = Git::STAGING_PREFIX
68
+ subject.branch_name.should == "#{Git::STAGING_PREFIX}.#{subject.date_suffix}"
69
+ end
70
+
71
+ it "properly generates a name for deployable branches" do
72
+ subject.branch_type = Git::DEPLOYABLE_PREFIX
73
+ subject.branch_name.should == "#{Git::DEPLOYABLE_PREFIX}.#{subject.date_suffix}"
74
+ end
75
+
76
+ it "properly generates a name for qaready branches" do
77
+ subject.branch_type = Git::QAREADY_PREFIX
78
+ subject.branch_name.should == "#{Git::QAREADY_PREFIX}.#{subject.date_suffix}"
79
+ end
80
+
81
+ it "raises an exception for other branch types" do
82
+ subject.branch_type = "asdfasdfasdf"
83
+ expect { subject.branch_name }.to raise_error(DatedBranchCreator::InvalidBranchType, "'#{subject.branch_type}' is not a valid branch type")
84
+ end
85
+ end
86
+
87
+ context "#delete_old_branches" do
88
+ it "does nothing if no extra branches" do
89
+ subject.stub(extra_branches: [])
90
+ cli.should_not_receive(:ask_boolean)
91
+ subject.delete_old_branches
92
+ end
93
+
94
+ context "having extra branches" do
95
+ let(:extras) { %w(foo bar) }
96
+ let(:message) { "Do you want to delete the old #{subject.branch_type} branch(es)? (#{extras.join(", ")})"}
97
+
98
+ before do
99
+ subject.stub(extra_branches: extras)
100
+ end
101
+
102
+ it "deletes these branches if user opts to" do
103
+ cli.should_receive(:ask_boolean).with(message) { true }
104
+ extras.each do |extra|
105
+ Git.should_receive(:delete_branch).with(extra)
106
+ end
107
+ subject.delete_old_branches
108
+ end
109
+
110
+ it "does nothing if user opts not to delete" do
111
+ cli.should_receive(:ask_boolean).with(message) { false }
112
+ cli.should_not_receive(:perform)
113
+ subject.delete_old_branches
114
+ end
115
+ end
116
+ end
117
+
118
+ context "#extra_branches" do
119
+ let(:extra_deployables) { %w(foo bar) }
120
+ let(:extra_stagings) { %w(bing bang) }
121
+
122
+ it "gets the correct list for staging branches" do
123
+ subject.branch_type = Git::STAGING_PREFIX
124
+ Git.stub(:branches_for).with(Git::STAGING_PREFIX) { extra_stagings + [subject.branch_name] }
125
+ subject.extra_branches.should_not include subject.branch_name
126
+ subject.extra_branches.should == extra_stagings
127
+ end
128
+
129
+ it "gets the correct list for deployable branches" do
130
+ subject.branch_type = Git::DEPLOYABLE_PREFIX
131
+ Git.stub(:branches_for).with(Git::DEPLOYABLE_PREFIX) { extra_deployables + [subject.branch_name] }
132
+ subject.extra_branches.should_not include subject.branch_name
133
+ subject.extra_branches.should == extra_deployables
134
+ end
135
+
136
+ it "raises an exception for any other branch type" do
137
+ subject.branch_type = "asdfasdfasdf"
138
+ expect { subject.extra_branches }.to raise_error(DatedBranchCreator::InvalidBranchType, "'#{subject.branch_type}' is not a valid branch type")
139
+ end
140
+ ; end
141
+
142
+ end
143
+ end