git_workflow 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
- data/README.markdown +77 -0
- data/Rakefile +33 -0
- data/bin/git-finish +4 -0
- data/bin/git-start +4 -0
- data/bin/git-workflow-setup +4 -0
- data/features/core_functionality/4049578_need_the_ability_to_start_a_new_branch.feature +15 -0
- data/features/core_functionality/4049611_need_the_ability_to_finish_a_specified_branch.feature +17 -0
- data/features/core_functionality/4056359_start_with_local_branch_already_present.feature +16 -0
- data/features/core_functionality/4056363_finish_the_current_branch.feature +17 -0
- data/features/core_functionality/4056389_changes_to_pt_story_name_cause_branch_issues.feature +25 -0
- data/features/core_functionality/4135658_control_output_verbosity_using_v_switch.feature +32 -0
- data/features/core_functionality/4468313_get_config_value_for_is_producing_an_error_log.feature +43 -0
- data/features/extensions/4058326_display_story_description_on_start.feature +14 -0
- data/features/git_branching/4135501_allow_branch_start_point_to_be_specified_from_command_line.feature +27 -0
- data/features/hooks/4069174_investigate_the_effort_required_to_add_pre_amp_post_hooks.feature +24 -0
- data/features/hooks/4199841_need_hooks_for_my_workflow.feature +51 -0
- data/features/hooks/4199845_need_hooks_for_sanger_workflow.feature +66 -0
- data/features/hooks/4205913_output_from_rake_tests_should_be_seen.feature +19 -0
- data/features/hooks/4424828_git_start_is_missing_pt_integration_for_my_hooks.feature +15 -0
- data/features/pivotal_tracker_api/4133291_chores_go_straight_to_accepted_not_to_finished.feature +15 -0
- data/features/release/4132264_fix_the_libxml_warnings_from_nokogiri.feature +20 -0
- data/features/step_definitions/aruba_extensions.rb +4 -0
- data/features/step_definitions/configuration_steps.rb +38 -0
- data/features/step_definitions/git_steps.rb +102 -0
- data/features/step_definitions/misc_steps.rb +3 -0
- data/features/step_definitions/pivotal_tracker_steps.rb +43 -0
- data/features/step_definitions/project_code_steps.rb +35 -0
- data/features/support/aruba.rb +1 -0
- data/features/support/hooks/configuration.rb +4 -0
- data/features/support/hooks/environment.rb +49 -0
- data/features/support/hooks/pivotal_tracker.rb +170 -0
- data/lib/git_workflow.rb +5 -0
- data/lib/git_workflow/callbacks.rb +16 -0
- data/lib/git_workflow/callbacks/pivotal_tracker_support.rb +64 -0
- data/lib/git_workflow/callbacks/remote_git_branch_support.rb +9 -0
- data/lib/git_workflow/callbacks/styles/debug.rb +58 -0
- data/lib/git_workflow/callbacks/styles/default.rb +43 -0
- data/lib/git_workflow/callbacks/styles/mine.rb +52 -0
- data/lib/git_workflow/callbacks/styles/sanger.rb +48 -0
- data/lib/git_workflow/callbacks/test_code_support.rb +29 -0
- data/lib/git_workflow/command_line.rb +46 -0
- data/lib/git_workflow/commands.rb +4 -0
- data/lib/git_workflow/commands/base.rb +31 -0
- data/lib/git_workflow/commands/finish.rb +36 -0
- data/lib/git_workflow/commands/setup.rb +157 -0
- data/lib/git_workflow/commands/start.rb +30 -0
- data/lib/git_workflow/configuration.rb +93 -0
- data/lib/git_workflow/core_ext.rb +106 -0
- data/lib/git_workflow/git.rb +143 -0
- data/lib/git_workflow/logger.yaml +27 -0
- data/lib/git_workflow/logging.rb +77 -0
- data/lib/git_workflow/story.rb +96 -0
- data/spec/core_functionality/4056539_support_http_proxy_spec.rb +68 -0
- data/spec/core_functionality/4058365_bad_request_on_story_update_spec.rb +13 -0
- data/spec/core_functionality/4058394_make_commands_more_verbose_spec.rb +41 -0
- data/spec/core_functionality/4058719_error_if_none_of_the_required_configuration_values_are_set_spec.rb +21 -0
- data/spec/core_functionality/4058861_git_config_returns_empty_strings_which_should_be_nil_spec.rb +59 -0
- data/spec/core_functionality/4172431_add_git_workflow_setup_command_to_make_setup_easier_spec.rb +148 -0
- data/spec/core_functionality/4199841_need_callbacks_for_my_workflow_spec.rb +97 -0
- data/spec/extensions/4199841_need_callbacks_for_my_workflow_spec.rb +167 -0
- data/spec/extensions/4205913_output_from_rake_tests_should_be_seen_spec.rb +34 -0
- data/spec/git_branching/4058723_branches_end_in_if_the_last_character_is_invalid_spec.rb +40 -0
- data/spec/git_branching/4059824_code_is_not_using_workflow_localbranchconvention_to_decode_branch_names_on_finish_spec.rb +115 -0
- data/spec/git_branching/4216087_support_pushing_branches_spec.rb +44 -0
- data/spec/hooks/4199845_need_hooks_for_sanger_workflow_spec.rb +27 -0
- data/spec/pivotal_tracker_api/4056381_pt_api_token_not_being_passed_in_headers_spec.rb +40 -0
- data/spec/pivotal_tracker_api/4056638_library_code_using_localhost_spec.rb +16 -0
- data/spec/pivotal_tracker_api/4056661_content_type_header_should_be_text_xml_on_updates_spec.rb +16 -0
- data/spec/pivotal_tracker_api/4058718_if_pt_username_is_not_set_use_user_name_spec.rb +26 -0
- data/spec/pivotal_tracker_api/4146016_decode_the_xml_encoded_text_of_description_and_name_spec.rb +63 -0
- data/spec/shared_examples/configuration.rb +10 -0
- data/spec/shared_examples/story.rb +17 -0
- data/spec/spec_helper.rb +18 -0
- metadata +220 -0
@@ -0,0 +1,97 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe GitWorkflow::Git do
|
4
|
+
before(:each) do
|
5
|
+
@git, @repository = Class.new, mock('Repository')
|
6
|
+
@git.send(:extend, GitWorkflow::Git)
|
7
|
+
@git.stub(:repository).and_return(@repository)
|
8
|
+
|
9
|
+
@git.stub(:info).with(anything)
|
10
|
+
end
|
11
|
+
|
12
|
+
describe '#in_git_branch' do
|
13
|
+
before(:each) do
|
14
|
+
@repository.should_receive(:current_branch).ordered.and_return('current')
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'does not switch back if an error occurs' do
|
18
|
+
@repository.should_receive(:checkout).with('new_branch').ordered
|
19
|
+
|
20
|
+
lambda do
|
21
|
+
@git.in_git_branch('new_branch') { raise StandardError, 'Failed' }
|
22
|
+
end.should raise_error(StandardError)
|
23
|
+
end
|
24
|
+
|
25
|
+
context 'with a successful block' do
|
26
|
+
before(:each) do
|
27
|
+
@callback = mock('callback')
|
28
|
+
@callback.should_receive(:called)
|
29
|
+
end
|
30
|
+
|
31
|
+
after(:each) do
|
32
|
+
@git.in_git_branch(@target_branch) { @callback.called }
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'simply yields if the current branch is the requested branch' do
|
36
|
+
@target_branch = 'current'
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'switches to the new branch and back again for success' do
|
40
|
+
@target_branch = 'new_branch'
|
41
|
+
|
42
|
+
@repository.should_receive(:checkout).with('new_branch').ordered
|
43
|
+
@repository.should_receive(:checkout).with('current').ordered
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
class GitWorkflow::Git::Repository
|
50
|
+
def self.for_testing
|
51
|
+
new
|
52
|
+
end
|
53
|
+
|
54
|
+
def internal_current_branch
|
55
|
+
@current_branch
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
describe GitWorkflow::Git::Repository do
|
60
|
+
before(:each) do
|
61
|
+
@repository = described_class.for_testing
|
62
|
+
end
|
63
|
+
|
64
|
+
describe '#current_branch' do
|
65
|
+
it 'finds the current branch from the list' do
|
66
|
+
@repository.should_receive(:execute_command).with('git branch').and_return([ ' branch_1', '* branch_2', ' branch_3' ].join("\n"))
|
67
|
+
@repository.current_branch.should == 'branch_2'
|
68
|
+
end
|
69
|
+
|
70
|
+
it 'raises if the current branch cannot be found in the list' do
|
71
|
+
@repository.should_receive(:execute_command).with('git branch').and_return([ ' branch_1', ' branch_2', ' branch_3' ].join("\n"))
|
72
|
+
lambda { @repository.current_branch }.should raise_error(GitWorkflow::Git::Repository::BranchError)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
describe '#checkout' do
|
77
|
+
it 'raises CheckoutError on command failure' do
|
78
|
+
@repository.should_receive(:execute_command).with(anything).and_raise(Execution::CommandFailure.new('command', :fail))
|
79
|
+
lambda { @repository.checkout('target') }.should raise_error(GitWorkflow::Git::Repository::CheckoutError)
|
80
|
+
end
|
81
|
+
|
82
|
+
context 'on successful checkout' do
|
83
|
+
before(:each) do
|
84
|
+
@repository.should_receive(:execute_command).with('git checkout target')
|
85
|
+
@repository.checkout('target')
|
86
|
+
end
|
87
|
+
|
88
|
+
it 'checks out the requested branch' do
|
89
|
+
# Nothing needed here
|
90
|
+
end
|
91
|
+
|
92
|
+
it 'maintains the current branch for performance' do
|
93
|
+
@repository.internal_current_branch.should == 'target'
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
@@ -0,0 +1,167 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'git_workflow/callbacks/styles/mine'
|
3
|
+
|
4
|
+
describe String do
|
5
|
+
describe '#camelize' do
|
6
|
+
it 'camelizes an underscored word' do
|
7
|
+
'foo_bar_baz'.camelize.should == 'FooBarBaz'
|
8
|
+
end
|
9
|
+
|
10
|
+
it 'modularizes a path' do
|
11
|
+
'foo/bar/baz'.camelize.should == 'Foo::Bar::Baz'
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
describe '#underscore' do
|
16
|
+
it 'underscores a modular string' do
|
17
|
+
'Foo::Bar::Baz'.underscore.should == 'foo/bar/baz'
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'underscores a camelized word' do
|
21
|
+
'FooBarBaz'.underscore.should == 'foo_bar_baz'
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe GitWorkflow::Callbacks::Styles::Mine::FinishBehaviour do
|
27
|
+
before(:each) do
|
28
|
+
@callbacks = Class.new
|
29
|
+
@callbacks.send(:extend, GitWorkflow::Callbacks::Styles::Mine::FinishBehaviour)
|
30
|
+
end
|
31
|
+
|
32
|
+
describe '#finish' do
|
33
|
+
before(:each) do
|
34
|
+
@story = mock('Story')
|
35
|
+
@story.stub(:branch_name).and_return('story_branch')
|
36
|
+
|
37
|
+
@callbacks.should_receive(:in_git_branch).with('story_branch').and_yield.ordered
|
38
|
+
@callbacks.should_receive(:run_tests!).with(:spec, :features).ordered
|
39
|
+
end
|
40
|
+
|
41
|
+
after(:each) do
|
42
|
+
@callbacks.finish(@story, @target_branch)
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'runs the tests but not the push if non-master branch' do
|
46
|
+
@target_branch = 'non-master'
|
47
|
+
|
48
|
+
@callbacks.should_receive(:in_git_branch).with(@target_branch).and_yield.ordered
|
49
|
+
@callbacks.should_receive(:merge_branch).with('story_branch', anything).ordered
|
50
|
+
@callbacks.should_receive(:run_tests_with_recovery!).with(:spec, :features).ordered
|
51
|
+
|
52
|
+
@callbacks.should_not_receive(:push_current_branch_to).with('non-master').ordered
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'runs the tests and the push if master branch' do
|
56
|
+
@target_branch = 'master'
|
57
|
+
|
58
|
+
@callbacks.should_receive(:in_git_branch).with(@target_branch).and_yield.ordered
|
59
|
+
@callbacks.should_receive(:merge_branch).with('story_branch', anything).ordered
|
60
|
+
@callbacks.should_receive(:run_tests_with_recovery!).with(:spec, :features).ordered
|
61
|
+
|
62
|
+
@callbacks.should_receive(:push_current_branch_to).with('master').ordered
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
describe GitWorkflow::Callbacks::Styles::Mine do
|
68
|
+
describe '.setup' do
|
69
|
+
before(:each) do
|
70
|
+
@start, @finish = Class.new, Class.new
|
71
|
+
|
72
|
+
GitWorkflow::Callbacks::Styles::Mine.setup(@start, @finish)
|
73
|
+
end
|
74
|
+
|
75
|
+
context 'configured start' do
|
76
|
+
it 'has my callbacks installed' do
|
77
|
+
@start.included_modules.should include(GitWorkflow::Callbacks::Styles::Mine::StartBehaviour)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
context 'configured finish' do
|
82
|
+
it 'has the Pivotal Tracker support' do
|
83
|
+
@finish.included_modules.should include(GitWorkflow::Callbacks::PivotalTrackerSupport)
|
84
|
+
end
|
85
|
+
|
86
|
+
it 'has the test code support' do
|
87
|
+
@finish.included_modules.should include(GitWorkflow::Callbacks::TestCodeSupport)
|
88
|
+
end
|
89
|
+
|
90
|
+
it 'has the remote git branch support' do
|
91
|
+
@finish.included_modules.should include(GitWorkflow::Callbacks::RemoteGitBranchSupport)
|
92
|
+
end
|
93
|
+
|
94
|
+
it 'has my callbacks installed' do
|
95
|
+
@finish.included_modules.should include(GitWorkflow::Callbacks::Styles::Mine::FinishBehaviour)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
describe GitWorkflow::Callbacks::TestCodeSupport do
|
102
|
+
before(:each) do
|
103
|
+
@callbacks = Class.new
|
104
|
+
@callbacks.send(:extend, GitWorkflow::Callbacks::TestCodeSupport)
|
105
|
+
end
|
106
|
+
|
107
|
+
describe '#run_tests!' do
|
108
|
+
it 'does nothing if the tests pass' do
|
109
|
+
@callbacks.should_receive(:run_tests).with(:task1, :task2).once.and_return(true)
|
110
|
+
|
111
|
+
@callbacks.run_tests!(:task1, :task2)
|
112
|
+
end
|
113
|
+
|
114
|
+
it 'raises if the tests fail' do
|
115
|
+
@callbacks.should_receive(:run_tests).with(:task1, :task2).once.and_return(false)
|
116
|
+
|
117
|
+
lambda { @callbacks.run_tests!(:task1, :task2) }.should raise_error(GitWorkflow::Callbacks::TestCodeSupport::Failure)
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
describe '#run_tests_with_recovery!' do
|
122
|
+
it 'does nothing if the tests pass' do
|
123
|
+
@callbacks.should_receive(:run_tests).with(:task1, :task2).once.and_return(true)
|
124
|
+
|
125
|
+
@callbacks.run_tests_with_recovery!(:task1, :task2)
|
126
|
+
end
|
127
|
+
|
128
|
+
it 'tries to recover from failing tests' do
|
129
|
+
@callbacks.should_receive(:run_tests).with(:task1, :task2).twice.and_return(false, true)
|
130
|
+
@callbacks.should_receive(:spawn_shell_for_recovery).once.and_return(true)
|
131
|
+
|
132
|
+
@callbacks.run_tests_with_recovery!(:task1, :task2)
|
133
|
+
end
|
134
|
+
|
135
|
+
it 'raises if the recovery is not possible' do
|
136
|
+
@callbacks.should_receive(:run_tests).with(:task1, :task2).once.and_return(false)
|
137
|
+
@callbacks.should_receive(:spawn_shell_for_recovery).once.and_return(false)
|
138
|
+
|
139
|
+
lambda { @callbacks.run_tests_with_recovery!(:task1, :task2) }.should raise_error(GitWorkflow::Callbacks::TestCodeSupport::Failure)
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
describe '#run_tests' do
|
144
|
+
it 'executes the given rake tasks' do
|
145
|
+
@callbacks.should_receive(:system).with('rake', 'task1', 'task2').and_return(true)
|
146
|
+
@callbacks.send(:run_tests, :task1, :task2).should == true
|
147
|
+
end
|
148
|
+
|
149
|
+
it 'returns the result of execution' do
|
150
|
+
@callbacks.should_receive(:system).with('rake', 'task1', 'task2').and_return(false)
|
151
|
+
@callbacks.send(:run_tests, :task1, :task2).should == false
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
describe '#spawn_shell_for_recovery' do
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
describe GitWorkflow::Callbacks::RemoteGitBranchSupport do
|
160
|
+
before(:each) do
|
161
|
+
@callbacks = Class.new
|
162
|
+
@callbacks.send(:extend, GitWorkflow::Callbacks::RemoteGitBranchSupport)
|
163
|
+
end
|
164
|
+
|
165
|
+
describe '#push_current_branch_to' do
|
166
|
+
end
|
167
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Execution do
|
4
|
+
before(:each) do
|
5
|
+
@executor = Class.new
|
6
|
+
@executor.send(:extend, Execution)
|
7
|
+
@executor.stub(:debug).with(anything).and_yield
|
8
|
+
end
|
9
|
+
|
10
|
+
before(:each) do
|
11
|
+
@stdin, @stdout, @stderr = mock('stdin'), mock('stdout'), mock('stderr')
|
12
|
+
@outputs = [ @stdout, @stderr, @stdin ]
|
13
|
+
end
|
14
|
+
|
15
|
+
describe '#execute_command' do
|
16
|
+
it 'returns the output from the command' do
|
17
|
+
@stdout.should_receive(:read).and_return('Hello World')
|
18
|
+
@executor.should_receive(:execute_command_with_output_handling).with(:command).and_yield(*@outputs)
|
19
|
+
@executor.execute_command(:command).should == 'Hello World'
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe '#execute_command_with_output_handling' do
|
24
|
+
it 'does not raise if the command succeeds' do
|
25
|
+
@executor.execute_command_with_output_handling('sh -c "exit 0"') { |*args| }
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'raises if the command fails' do
|
29
|
+
lambda do
|
30
|
+
@executor.execute_command_with_output_handling('sh -c "exit 1"') { |*args| }
|
31
|
+
end.should raise_error(Execution::CommandFailure)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
class GitWorkflow::Story
|
4
|
+
attr_writer :name
|
5
|
+
end
|
6
|
+
|
7
|
+
describe GitWorkflow::Story do
|
8
|
+
describe '#branch_name' do
|
9
|
+
it_should_behave_like 'it needs a working Story'
|
10
|
+
|
11
|
+
it 'delegates to the local branch convention' do
|
12
|
+
configuration, convention = mock('configuration'), mock('convention')
|
13
|
+
configuration.should_receive(:local_branch_convention).and_return(convention)
|
14
|
+
convention.should_receive(:to).with(@story).and_return(:ok)
|
15
|
+
GitWorkflow::Configuration.stub!(:instance).and_return(configuration)
|
16
|
+
|
17
|
+
@story.branch_name.should == :ok
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
describe GitWorkflow::Configuration::Convention do
|
23
|
+
describe '#to' do
|
24
|
+
before(:each) do
|
25
|
+
@convention = described_class.new('${number}_${name}')
|
26
|
+
end
|
27
|
+
|
28
|
+
after(:each) do
|
29
|
+
@convention.to(OpenStruct.new(:story_id => 12345, :name => @name)).should_not match(/_+$/)
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'does not end in underscore with invalid character at the end' do
|
33
|
+
@name = 'ends in invalid character!'
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'does not end in multiple underscores' do
|
37
|
+
@name = 'ends in invalid characters!!!!!!!'
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,115 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
class GitWorkflow::Configuration
|
4
|
+
def self.instance_for_testing
|
5
|
+
new
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
describe GitWorkflow::Configuration do
|
10
|
+
describe '#local_branch_convention' do
|
11
|
+
before(:each) do
|
12
|
+
@configuration = GitWorkflow::Configuration.instance_for_testing
|
13
|
+
@configuration.should_receive(:get_config_value_for!).with('workflow.localbranchconvention').once.and_return('${number}_${name}')
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'uses the workflow.localbranchconvention configuration value' do
|
17
|
+
@configuration.local_branch_convention
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'caches the value' do
|
21
|
+
@configuration.local_branch_convention # Gets the value ...
|
22
|
+
@configuration.local_branch_convention # ... that should now be cached
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
class GitWorkflow::Commands::Finish
|
28
|
+
public :extract_story_from_branch
|
29
|
+
end
|
30
|
+
|
31
|
+
describe GitWorkflow::Commands::Finish do
|
32
|
+
before(:each) do
|
33
|
+
@configuration = mock('configuration')
|
34
|
+
@configuration.stub(:ignore_git_global?).and_return(false)
|
35
|
+
GitWorkflow::Configuration.stub!(:instance).and_return(@configuration)
|
36
|
+
|
37
|
+
@command = described_class.new([])
|
38
|
+
end
|
39
|
+
|
40
|
+
describe '#extract_story_from_branch' do
|
41
|
+
before(:each) do
|
42
|
+
@convention = mock('convention')
|
43
|
+
@configuration.stub!(:local_branch_convention).and_return(@convention)
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'uses the branch convention' do
|
47
|
+
@convention.should_receive(:from).with('12345_this_branch_matches').and_return(12345)
|
48
|
+
@command.extract_story_from_branch('12345_this_branch_matches').should == 12345
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
describe GitWorkflow::Configuration::Convention do
|
54
|
+
describe '#initialize' do
|
55
|
+
it 'errors if the convention has no story_id' do
|
56
|
+
lambda { described_class.new('foo') }.should raise_error(StandardError)
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'does not error if story_id included' do
|
60
|
+
described_class.new('${number}_foo')
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
shared_examples_for 'branch convention behaviour' do
|
65
|
+
before(:each) do
|
66
|
+
@branches = { :start => '12345_works_for_me', :end => 'works_for_me_12345' }
|
67
|
+
end
|
68
|
+
|
69
|
+
describe '#to' do
|
70
|
+
before(:each) do
|
71
|
+
@decoder = described_class.new(@convention)
|
72
|
+
@decoder.stub!(:use_existing_for).with(anything).and_return(nil)
|
73
|
+
end
|
74
|
+
|
75
|
+
it 'evaluates the convention string' do
|
76
|
+
story = OpenStruct.new(:story_id => 12345, :name => 'works for me')
|
77
|
+
@decoder.to(story).should == @branches[ @to_result ]
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
describe '#from' do
|
82
|
+
before(:each) do
|
83
|
+
@decoder = described_class.new(@convention)
|
84
|
+
end
|
85
|
+
|
86
|
+
it 'decodes the same branch that #to produces' do
|
87
|
+
@decoder.from(@branches[ @to_result ]).should == 12345
|
88
|
+
end
|
89
|
+
|
90
|
+
it 'errors if the branch does not conform to the convention' do
|
91
|
+
lambda { @decoder.from(@branches[ @from_mismatch ]) }.should raise_error(StandardError)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
context 'after successful initialization' do
|
97
|
+
context 'with ${number}_${name}' do
|
98
|
+
it_should_behave_like 'branch convention behaviour'
|
99
|
+
|
100
|
+
before(:each) do
|
101
|
+
@convention = '${number}_${name}'
|
102
|
+
@to_result, @from_mismatch = :start, :end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
context 'with ${name}_${number}' do
|
107
|
+
it_should_behave_like 'branch convention behaviour'
|
108
|
+
|
109
|
+
before(:each) do
|
110
|
+
@convention = '${name}_${number}'
|
111
|
+
@to_result, @from_mismatch = :end, :start
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|