rubycut-babushka 0.10.8 → 0.15.6.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (142) hide show
  1. data/Gemfile +1 -0
  2. data/Gemfile.lock +17 -15
  3. data/README.markdown +163 -41
  4. data/Rakefile +1 -1
  5. data/bin/babushka +1 -1
  6. data/deps/apt.rb +44 -0
  7. data/deps/babushka.rb +54 -42
  8. data/deps/deprecated.rb +16 -0
  9. data/deps/dev.rb +28 -3
  10. data/deps/git.rb +27 -12
  11. data/deps/homebrew.rb +2 -2
  12. data/deps/packages.rb +14 -15
  13. data/deps/pkg_managers.rb +21 -75
  14. data/deps/ruby.rb +5 -19
  15. data/deps/rubygems.rb +3 -3
  16. data/deps/system.rb +2 -2
  17. data/deps/templates/app.rb +60 -41
  18. data/deps/templates/bin.rb +16 -0
  19. data/deps/templates/installer.rb +9 -9
  20. data/deps/templates/lib.rb +17 -0
  21. data/deps/templates/managed.rb +1 -38
  22. data/deps/templates/src.rb +16 -8
  23. data/deps/templates/task.rb +11 -0
  24. data/deps/templates/tmbundle.rb +16 -2
  25. data/lib/babushka.rb +2 -3
  26. data/lib/babushka/accepts_block_for.rb +5 -3
  27. data/lib/babushka/asset.rb +172 -0
  28. data/lib/babushka/base.rb +37 -8
  29. data/lib/babushka/bug_reporter.rb +6 -6
  30. data/lib/babushka/cmdline.rb +11 -10
  31. data/lib/babushka/cmdline/handler.rb +7 -3
  32. data/lib/babushka/cmdline/helpers.rb +15 -23
  33. data/lib/babushka/cmdline/parser.rb +1 -1
  34. data/lib/babushka/core_patches/object.rb +1 -1
  35. data/lib/babushka/core_patches/string.rb +8 -3
  36. data/lib/babushka/current_ruby.rb +44 -0
  37. data/lib/babushka/dep.rb +111 -185
  38. data/lib/babushka/dep_context.rb +8 -3
  39. data/lib/babushka/dep_definer.rb +45 -15
  40. data/lib/babushka/dep_pool.rb +5 -8
  41. data/lib/babushka/{meta_dep.rb → dep_template.rb} +21 -2
  42. data/lib/babushka/dsl.rb +3 -0
  43. data/lib/babushka/git_repo.rb +143 -49
  44. data/lib/babushka/helpers/git_helpers.rb +7 -6
  45. data/lib/babushka/helpers/log_helpers.rb +51 -13
  46. data/lib/babushka/helpers/path_helpers.rb +5 -7
  47. data/lib/babushka/helpers/run_helpers.rb +15 -55
  48. data/lib/babushka/helpers/shell_helpers.rb +18 -26
  49. data/lib/babushka/helpers/uri_helpers.rb +9 -18
  50. data/lib/babushka/lambda_chooser.rb +20 -13
  51. data/lib/babushka/parameter.rb +20 -4
  52. data/lib/babushka/path_checker.rb +72 -0
  53. data/lib/babushka/pkg_helper.rb +38 -13
  54. data/lib/babushka/pkg_helpers/apt_helper.rb +15 -8
  55. data/lib/babushka/pkg_helpers/binpkgsrc_helper.rb +15 -14
  56. data/lib/babushka/pkg_helpers/binports_helper.rb +7 -7
  57. data/lib/babushka/pkg_helpers/brew_helper.rb +17 -25
  58. data/lib/babushka/pkg_helpers/gem_helper.rb +36 -27
  59. data/lib/babushka/pkg_helpers/npm_helper.rb +9 -9
  60. data/lib/babushka/pkg_helpers/pacman_helper.rb +5 -4
  61. data/lib/babushka/pkg_helpers/pip_helper.rb +14 -10
  62. data/lib/babushka/pkg_helpers/unknown_pkg_helper.rb +19 -0
  63. data/lib/babushka/pkg_helpers/yum_helper.rb +1 -1
  64. data/lib/babushka/popen.rb +13 -10
  65. data/lib/babushka/prompt.rb +14 -1
  66. data/lib/babushka/renderable.rb +11 -9
  67. data/lib/babushka/resource.rb +5 -166
  68. data/lib/babushka/run_reporter.rb +12 -3
  69. data/lib/babushka/shell.rb +54 -44
  70. data/lib/babushka/source.rb +41 -20
  71. data/lib/babushka/source_pool.rb +20 -13
  72. data/lib/babushka/system_definitions.rb +11 -3
  73. data/lib/babushka/system_detector.rb +31 -0
  74. data/lib/babushka/system_matcher.rb +53 -0
  75. data/lib/babushka/system_profile.rb +67 -89
  76. data/lib/babushka/task.rb +36 -8
  77. data/lib/babushka/{meta_dep_context.rb → templated_dep_context.rb} +1 -1
  78. data/lib/babushka/vars.rb +46 -4
  79. data/lib/babushka/version_of.rb +35 -17
  80. data/lib/babushka/version_str.rb +12 -8
  81. data/lib/components.rb +9 -8
  82. data/lib/fancypath/fancypath.rb +109 -83
  83. data/lib/inkan/inkan.rb +14 -14
  84. data/lib/{babushka → levenshtein}/levenshtein.rb +0 -0
  85. data/spec/acceptance/acceptance.rb +4 -4
  86. data/spec/acceptance_helper.rb +10 -6
  87. data/spec/babushka/accepts_for_spec.rb +137 -142
  88. data/spec/babushka/accepts_for_support.rb +13 -6
  89. data/spec/babushka/asset_spec.rb +165 -0
  90. data/spec/babushka/cmdline/help_spec.rb +11 -9
  91. data/spec/babushka/cmdline/meet_spec.rb +15 -0
  92. data/spec/babushka/cmdline/version_spec.rb +1 -1
  93. data/spec/babushka/core_patches_spec.rb +9 -0
  94. data/spec/babushka/current_ruby_spec.rb +73 -0
  95. data/spec/babushka/dep_context_spec.rb +27 -13
  96. data/spec/babushka/dep_definer_spec.rb +108 -16
  97. data/spec/babushka/dep_spec.rb +87 -104
  98. data/spec/babushka/dep_template_spec.rb +176 -0
  99. data/spec/babushka/deps_spec.rb +48 -19
  100. data/spec/babushka/gem_helper_spec.rb +46 -59
  101. data/spec/babushka/git_repo_spec.rb +242 -51
  102. data/spec/babushka/ip_spec.rb +11 -11
  103. data/spec/babushka/lambda_chooser_spec.rb +47 -9
  104. data/spec/babushka/parameter_spec.rb +21 -0
  105. data/spec/babushka/path_checker_spec.rb +35 -0
  106. data/spec/babushka/path_helpers_spec.rb +51 -50
  107. data/spec/babushka/prompt_spec.rb +4 -4
  108. data/spec/babushka/renderable_spec.rb +61 -28
  109. data/spec/babushka/shell_helpers_spec.rb +110 -85
  110. data/spec/babushka/shell_spec.rb +15 -0
  111. data/spec/babushka/source_pool_spec.rb +204 -210
  112. data/spec/babushka/source_spec.rb +125 -42
  113. data/spec/babushka/source_support.rb +1 -1
  114. data/spec/babushka/system_profile_spec.rb +86 -49
  115. data/spec/babushka/task_spec.rb +80 -13
  116. data/spec/babushka/vars_spec.rb +2 -1
  117. data/spec/babushka/version_of_spec.rb +29 -2
  118. data/spec/babushka/version_str_spec.rb +91 -65
  119. data/spec/babushka/xml_string_spec.rb +1 -1
  120. data/spec/deps/bad/broken.rb +2 -2
  121. data/spec/deps/bad/working.rb +0 -1
  122. data/spec/deps/good/{meta.rb → template.rb} +0 -0
  123. data/spec/deps/good/test.rb +0 -3
  124. data/spec/deps/outer/deps.rb +0 -2
  125. data/spec/fancypath/fancypath_spec.rb +30 -0
  126. data/spec/inkan/inkan_spec.rb +34 -32
  127. data/spec/spec_helper.rb +7 -50
  128. data/spec/system_detector_spec.rb +70 -0
  129. metadata +163 -177
  130. data/deps/os_x.rb +0 -33
  131. data/deps/templates/ppa.rb +0 -24
  132. data/lib/babushka/core_patches/io.rb +0 -8
  133. data/lib/babushka/dep_runner.rb +0 -85
  134. data/lib/babushka/helpers/suggest_helpers.rb +0 -16
  135. data/lib/babushka/pkg_helpers/base_helper.rb +0 -19
  136. data/lib/babushka/pkg_helpers/macports_helper.rb +0 -22
  137. data/spec/babushka/dep_definer_support.rb +0 -36
  138. data/spec/babushka/meta_dep_definer_spec.rb +0 -127
  139. data/spec/babushka/meta_dep_wrapper_spec.rb +0 -32
  140. data/spec/babushka/resource_spec.rb +0 -141
  141. data/spec/babushka/run_helpers_spec.rb +0 -26
  142. data/spec/babushka/source_pool_support.rb +0 -31
@@ -0,0 +1,176 @@
1
+ require 'spec_helper'
2
+
3
+ describe "name checks" do
4
+ describe "invalid names" do
5
+ it "should not allow blank names" do
6
+ L{ meta(nil) }.should raise_error(ArgumentError, "You can't define a template with a blank name.")
7
+ L{ meta('') }.should raise_error(ArgumentError, "You can't define a template with a blank name.")
8
+ end
9
+ it "should not allow reserved names" do
10
+ L{ meta(:base) }.should raise_error(ArgumentError, "You can't use 'base' for a template name, because it's reserved.")
11
+ end
12
+ it "should allow valid names" do
13
+ L{ meta(:a) }.should_not raise_error
14
+ L{ meta('b') }.should_not raise_error
15
+ L{ meta('valid') }.should_not raise_error
16
+ end
17
+ it "should not allow spaces and numbers" do
18
+ L{ meta('meta dep 2') }.should raise_error(ArgumentError, "You can't use 'meta dep 2' for a template name - it can only contain [a-z0-9_].")
19
+ end
20
+ it "should not allow invalid characters" do
21
+ L{ meta("meta\ndep") }.should raise_error(ArgumentError, "You can't use 'meta\ndep' for a template name - it can only contain [a-z0-9_].")
22
+ end
23
+ it "should not allow names that don't start with a letter" do
24
+ L{ meta('3d_dep') }.should raise_error(ArgumentError, "You can't use '3d_dep' for a template name - it must start with a letter.")
25
+ end
26
+ end
27
+
28
+ describe "duplicates" do
29
+ before { meta 'duplicate' }
30
+ it "should be prevented" do
31
+ L{ meta(:duplicate) }.should raise_error(ArgumentError, "A template called 'duplicate' has already been defined.")
32
+ end
33
+ after { Base.sources.anonymous.templates.clear! }
34
+ end
35
+
36
+ describe "valid names" do
37
+ it "should work" do
38
+ L{ meta 'count_test' }.should change(Base.sources.anonymous.templates, :count).by(1)
39
+ end
40
+ it "should downcase the name" do
41
+ meta("Case_Test").name.should == 'case_test'
42
+ end
43
+ end
44
+ end
45
+
46
+ describe "declaration" do
47
+ let(:template) { meta 'test' }
48
+ it "should set the name" do
49
+ template.name.should == 'test'
50
+ end
51
+ it "should set the source" do
52
+ template.source.should == Base.sources.anonymous
53
+ end
54
+ it "should define a dep context" do
55
+ template.context_class.should be_an_instance_of(Class)
56
+ template.context_class.ancestors.should include(Babushka::DepContext)
57
+ end
58
+ it "should define template on the context" do
59
+ template.context_class.source_template.should == template
60
+ end
61
+ it "should not define a dep helper" do
62
+ Object.new.should_not respond_to('test')
63
+ end
64
+ it "should not be marked as suffixed" do
65
+ template.opts[:suffix].should be_false
66
+ end
67
+ after { Base.sources.anonymous.templates.clear! }
68
+ end
69
+
70
+ describe "using" do
71
+ describe "invalid templates" do
72
+ it "should not define deps as options" do
73
+ L{
74
+ dep('something undefined', :template => 'undefined').should be_nil
75
+ }.should raise_error(TemplateNotFound, "There is no template named 'undefined' to define 'something undefined' against.")
76
+ end
77
+ it "should define deps as options" do
78
+ dep('something.undefined').should be_an_instance_of(Dep)
79
+ end
80
+ end
81
+
82
+ describe "without template" do
83
+ let!(:template) { meta('templateless_test') {} }
84
+ it "should define deps based on the template" do
85
+ dep('templateless dep.templateless_test').template.should == template
86
+ end
87
+ after { Base.sources.anonymous.templates.clear! }
88
+ end
89
+
90
+ describe "with template" do
91
+ let!(:template) {
92
+ meta 'template_test' do
93
+ def a_helper_method
94
+ 'hello from the helper!'
95
+ end
96
+ template {
97
+ def a_helper
98
+ 'hello from the helper in the template!'
99
+ end
100
+ met? {
101
+ 'this dep is met.'
102
+ }
103
+ }
104
+ end
105
+ }
106
+ it "should define the helper on the context class" do
107
+ template.context_class.respond_to?(:a_helper).should be_false
108
+ template.context_class.new(nil).respond_to?(:a_helper).should be_false
109
+ dep('dep1.template_test').context.define!.respond_to?(:a_helper).should be_true
110
+ end
111
+ it "should correctly define the helper method" do
112
+ dep('dep2.template_test').context.a_helper_method.should == 'hello from the helper!'
113
+ end
114
+ it "should correctly define the helper" do
115
+ dep('dep2.template_test').context.define!.a_helper.should == 'hello from the helper in the template!'
116
+ end
117
+ it "should correctly define the met? block" do
118
+ dep('dep3.template_test').send(:process_task, :met?).should == 'this dep is met.'
119
+ end
120
+ it "should override the template correctly" do
121
+ dep('dep4.template_test') {
122
+ met? { 'overridden met? block.' }
123
+ }.send(:process_task, :met?).should == 'overridden met? block.'
124
+ end
125
+ after { Base.sources.anonymous.templates.clear! }
126
+ end
127
+
128
+ describe "acceptors" do
129
+ let!(:template) {
130
+ meta 'acceptor_test' do
131
+ accepts_list_for :list_test
132
+ accepts_block_for :block_test
133
+ template {
134
+ met? {
135
+ list_test == ['valid']
136
+ }
137
+ meet {
138
+ block_test.call
139
+ }
140
+ }
141
+ end
142
+ }
143
+ it "should handle accepts_list_for" do
144
+ dep('unmet accepts_list_for.acceptor_test') { list_test 'invalid' }.met?.should be_false
145
+ dep('met accepts_list_for.acceptor_test') { list_test 'valid' }.met?.should be_true
146
+ end
147
+ it "should handle accepts_block_for" do
148
+ block_called = false
149
+ dep('accepts_block_for.acceptor_test') {
150
+ list_test 'invalid'
151
+ block_test {
152
+ block_called = true
153
+ }
154
+ }.meet
155
+ block_called.should be_true
156
+ end
157
+ after { Base.sources.anonymous.templates.clear! }
158
+ end
159
+
160
+ describe "calling accepted blocks" do
161
+ let(:a_meta) {
162
+ meta :acceptor_calling_test do
163
+ accepts_block_for(:testing) {
164
+ self
165
+ }
166
+ end
167
+ }
168
+ let(:a_dep) {
169
+ dep 'acceptor calling test', :template => a_meta.name
170
+ }
171
+
172
+ it "should run the default block in the dep's context" do
173
+ a_dep.context.invoke(:testing).should == a_dep.context
174
+ end
175
+ end
176
+ end
@@ -1,10 +1,10 @@
1
1
  require 'spec_helper'
2
2
  require 'dep_support'
3
3
 
4
- shared_examples_for "met?" do
4
+ shared_examples_for "met? when met" do
5
5
  describe "met?" do
6
6
  before { Dep('a').met? }
7
- it "should met?-check each dep exactly once" do
7
+ it "should met?-check deps that don't have failed subdeps" do
8
8
  %w[a b c d e f].each {|i| @yield_counts[i].should == @yield_counts_already_met }
9
9
  end
10
10
  it "shouldn't run the meet-only dep" do
@@ -13,6 +13,35 @@ shared_examples_for "met?" do
13
13
  end
14
14
  end
15
15
 
16
+ shared_examples_for "met? when unmet" do
17
+ describe "met?" do
18
+ before { Dep('a').met? }
19
+ it "should met?-check deps that don't have failed subdeps" do
20
+ %w[f].each {|i| @yield_counts[i].should == @yield_counts_already_met }
21
+ end
22
+ it "should not met?-check deps that have failed subdeps" do
23
+ %w[a b c d e].each {|i| @yield_counts[i].should == @yield_counts_dep_failed }
24
+ end
25
+ it "shouldn't run the meet-only dep" do
26
+ @yield_counts['g'].should == @yield_counts_none
27
+ end
28
+ end
29
+ end
30
+
31
+ describe "met? return value" do
32
+ before {
33
+ dep 'return value a' do
34
+ requires 'return value b'
35
+ end
36
+ dep 'return value b' do
37
+ met? { false }
38
+ end
39
+ }
40
+ it "should return false when subdeps are unmet" do
41
+ Dep('return value a').met?.should be_false
42
+ end
43
+ end
44
+
16
45
  describe "an already met dep tree" do
17
46
  before {
18
47
  setup_yield_counts
@@ -24,7 +53,7 @@ describe "an already met dep tree" do
24
53
  make_counter_dep :name => 'f'
25
54
  make_counter_dep :name => 'g'
26
55
  }
27
- it_should_behave_like "met?"
56
+ it_should_behave_like "met? when met"
28
57
  describe "meet" do
29
58
  before { Dep('a').meet }
30
59
  it "should meet no deps" do
@@ -48,7 +77,7 @@ describe "an unmeetable dep tree" do
48
77
  make_counter_dep :name => 'f', :met? => L{ false }
49
78
  make_counter_dep :name => 'g', :met? => L{ false }
50
79
  }
51
- it_should_behave_like "met?"
80
+ it_should_behave_like "met? when unmet"
52
81
  describe "meet" do
53
82
  before { Dep('a').meet }
54
83
  it "should fail on the bootom-most dep" do
@@ -67,15 +96,15 @@ end
67
96
  describe "a meetable dep tree" do
68
97
  before {
69
98
  setup_yield_counts
70
- make_counter_dep :name => 'a', :requires => %w[b c] , :met? => L{ @yield_counts['a'][:met?] > 1 }
71
- make_counter_dep :name => 'b', :requires => %w[c d e], :met? => L{ @yield_counts['b'][:met?] > 1 }
72
- make_counter_dep :name => 'c', :requires => %w[f] , :met? => L{ @yield_counts['c'][:met?] > 1 }, :requires_when_unmet => %w[g]
73
- make_counter_dep :name => 'd', :requires => %w[e f] , :met? => L{ @yield_counts['d'][:met?] > 1 }
74
- make_counter_dep :name => 'e', :requires => %w[f] , :met? => L{ @yield_counts['e'][:met?] > 1 }
75
- make_counter_dep :name => 'f', :met? => L{ @yield_counts['f'][:met?] > 1 }
76
- make_counter_dep :name => 'g', :met? => L{ @yield_counts['g'][:met?] > 1 }
99
+ make_counter_dep :name => 'a', :requires => %w[b c] , :met? => L{ @yield_counts['a'][:meet] > 0 }
100
+ make_counter_dep :name => 'b', :requires => %w[c d e], :met? => L{ @yield_counts['b'][:meet] > 0 }
101
+ make_counter_dep :name => 'c', :requires => %w[f] , :met? => L{ @yield_counts['c'][:meet] > 0 }, :requires_when_unmet => %w[g]
102
+ make_counter_dep :name => 'd', :requires => %w[e f] , :met? => L{ @yield_counts['d'][:meet] > 0 }
103
+ make_counter_dep :name => 'e', :requires => %w[f] , :met? => L{ @yield_counts['e'][:meet] > 0 }
104
+ make_counter_dep :name => 'f', :met? => L{ @yield_counts['f'][:meet] > 0 }
105
+ make_counter_dep :name => 'g', :met? => L{ @yield_counts['g'][:meet] > 0 }
77
106
  }
78
- it_should_behave_like "met?"
107
+ it_should_behave_like "met? when unmet"
79
108
  describe "meet" do
80
109
  before { Dep('a').meet }
81
110
  it "should meet each dep exactly once" do
@@ -88,15 +117,15 @@ end
88
117
  describe "a partially meetable dep tree" do
89
118
  before {
90
119
  setup_yield_counts
91
- make_counter_dep :name => 'a', :requires => %w[b c] , :met? => L{ @yield_counts['a'][:met?] > 1 }
92
- make_counter_dep :name => 'b', :requires => %w[c d e], :met? => L{ @yield_counts['b'][:met?] > 1 }
93
- make_counter_dep :name => 'c', :requires => %w[f] , :met? => L{ @yield_counts['c'][:met?] > 1 }, :requires_when_unmet => %w[g]
94
- make_counter_dep :name => 'd', :requires => %w[e f] , :met? => L{ @yield_counts['d'][:met?] > 1 }
120
+ make_counter_dep :name => 'a', :requires => %w[b c] , :met? => L{ @yield_counts['a'][:meet] > 0 }
121
+ make_counter_dep :name => 'b', :requires => %w[c d e], :met? => L{ @yield_counts['b'][:meet] > 0 }
122
+ make_counter_dep :name => 'c', :requires => %w[f] , :met? => L{ @yield_counts['c'][:meet] > 0 }, :requires_when_unmet => %w[g]
123
+ make_counter_dep :name => 'd', :requires => %w[e f] , :met? => L{ @yield_counts['d'][:meet] > 0 }
95
124
  make_counter_dep :name => 'e', :requires => %w[f] , :met? => L{ false }
96
- make_counter_dep :name => 'f', :met? => L{ @yield_counts['f'][:met?] > 1 }
97
- make_counter_dep :name => 'g', :met? => L{ @yield_counts['g'][:met?] > 1 }
125
+ make_counter_dep :name => 'f', :met? => L{ @yield_counts['f'][:meet] > 0 }
126
+ make_counter_dep :name => 'g', :met? => L{ @yield_counts['g'][:meet] > 0 }
98
127
  }
99
- it_should_behave_like "met?"
128
+ it_should_behave_like "met? when unmet"
100
129
  describe "meet" do
101
130
  before { Dep('a').meet }
102
131
  it "should meet deps until one fails" do
@@ -1,67 +1,54 @@
1
1
  require 'spec_helper'
2
2
 
3
- def stub_env_info
4
- GemHelper.stub!(:env_info).and_return(%q{
5
- RubyGems Environment:
6
- - INSTALLATION DIRECTORY: /Library/Ruby/Gems/1.8
7
- })
8
- end
9
-
10
- def stub_versions_of
11
- GemHelper.stub!(:versions_of).and_return([
12
- VersionStr.new('0.2.11'),
13
- VersionStr.new('0.2.11.3'),
14
- VersionStr.new('0.3.7'),
15
- VersionStr.new('0.3.9')
16
- ])
17
- end
18
-
19
- describe "has?" do
3
+ describe Babushka::GemHelper do
4
+ let(:gem_helper) { Babushka::GemHelper }
20
5
  before {
21
- stub_versions_of
6
+ gem_helper.stub!(:versions_of).and_return([
7
+ VersionStr.new('0.2.11'),
8
+ VersionStr.new('0.2.11.3'),
9
+ VersionStr.new('0.3.7'),
10
+ VersionStr.new('0.3.9')
11
+ ])
22
12
  }
23
- it "should report installed gems correctly" do
24
- GemHelper.has?('hammock 0.3.9').should == VersionStr.new('0.3.9')
25
- end
26
- it "should report missing gems correctly" do
27
- GemHelper.has?('hammock 0.3.8').should be_nil
28
- end
29
- it "should report matching gems correctly" do
30
- GemHelper.has?('hammock >= 0.3.10').should be_nil
31
- GemHelper.has?('hammock >= 0.3.9').should == VersionStr.new('0.3.9')
32
- GemHelper.has?('hammock >= 0.3.8').should == VersionStr.new('0.3.9')
33
- GemHelper.has?('hammock >= 0.3.7').should == VersionStr.new('0.3.9')
34
- GemHelper.has?('hammock ~> 0.2.7').should == VersionStr.new('0.2.11.3')
35
- GemHelper.has?('hammock ~> 0.3.7').should == VersionStr.new('0.3.9')
13
+ describe "has?" do
14
+ it "should report installed gems correctly" do
15
+ gem_helper.has?('hammock 0.3.9').should == VersionStr.new('0.3.9')
16
+ end
17
+ it "should report missing gems correctly" do
18
+ gem_helper.has?('hammock 0.3.8').should be_nil
19
+ end
20
+ it "should report matching gems correctly" do
21
+ gem_helper.has?('hammock >= 0.3.10').should be_nil
22
+ gem_helper.has?('hammock >= 0.3.9').should == VersionStr.new('0.3.9')
23
+ gem_helper.has?('hammock >= 0.3.8').should == VersionStr.new('0.3.9')
24
+ gem_helper.has?('hammock >= 0.3.7').should == VersionStr.new('0.3.9')
25
+ gem_helper.has?('hammock ~> 0.2.7').should == VersionStr.new('0.2.11.3')
26
+ gem_helper.has?('hammock ~> 0.3.7').should == VersionStr.new('0.3.9')
27
+ end
36
28
  end
37
- end
38
29
 
39
- describe "gem_path_for" do
40
- before {
41
- stub_env_info
42
- stub_versions_of
43
- @prefix = '/Library/Ruby/Gems/1.8/gems'
44
- }
45
- it "should return the correct path" do
46
- GemHelper.gem_path_for('hammock').should == @prefix / 'hammock-0.3.9'
47
- GemHelper.gem_path_for('hammock', '0.3.9').should == @prefix / 'hammock-0.3.9'
48
- GemHelper.gem_path_for('hammock', '~> 0.3.7').should == @prefix / 'hammock-0.3.9'
49
- GemHelper.gem_path_for('hammock', '0.3.8').should be_nil
30
+ describe "gem_path_for" do
31
+ let(:prefix) { '/Library/Ruby/Gems/1.8/gems' }
32
+ before { Babushka.ruby.stub!(:gem_dir).and_return(prefix) }
33
+ it "should return the correct path" do
34
+ gem_helper.gem_path_for('hammock').should == prefix / 'hammock-0.3.9'
35
+ gem_helper.gem_path_for('hammock', '0.3.9').should == prefix / 'hammock-0.3.9'
36
+ gem_helper.gem_path_for('hammock', '~> 0.3.7').should == prefix / 'hammock-0.3.9'
37
+ gem_helper.gem_path_for('hammock', '0.3.8').should be_nil
38
+ end
50
39
  end
51
- end
52
40
 
53
- describe Babushka::GemHelper do
54
41
  describe '.should_sudo?' do
55
- before :each do
56
- Babushka::GemHelper.stub!(
57
- :gem_root => '/path/to/gems'.p,
58
- :bin_path => '/path/to/bins'.p
42
+ before {
43
+ Babushka.ruby.stub!(
44
+ :gem_dir => '/path/to/gems'.p,
45
+ :bin_dir => '/path/to/bins'.p
59
46
  )
60
- end
61
-
47
+ }
48
+
62
49
  it "should return true if the bin dir is not writeable" do
63
50
  File.should_receive(:writable?).with('/path/to/bins').and_return(false)
64
- Babushka::GemHelper.should_sudo?.should be_true
51
+ gem_helper.should_sudo?.should be_true
65
52
  end
66
53
 
67
54
  context "when the bin dir is writable" do
@@ -69,20 +56,20 @@ describe Babushka::GemHelper do
69
56
  File.should_receive(:writable?).with('/path/to/bins').and_return(true)
70
57
  }
71
58
  it "should return false if the gem dir does not exist" do
72
- Babushka::GemHelper.gem_root.should_receive(:exists?).and_return(false)
73
- Babushka::GemHelper.should_sudo?.should be_false
59
+ Babushka.ruby.gem_dir.should_receive(:exists?).and_return(false)
60
+ gem_helper.should_sudo?.should be_false
74
61
  end
75
62
  context "when the gem dir exists" do
76
63
  before {
77
- Babushka::GemHelper.gem_root.should_receive(:exists?).and_return(true)
64
+ Babushka.ruby.gem_dir.should_receive(:exists?).and_return(true)
78
65
  }
79
66
  it "should return true if the gem dir is not writeable" do
80
- Babushka::GemHelper.gem_root.should_receive(:writable?).and_return(false)
81
- Babushka::GemHelper.should_sudo?.should be_true
67
+ Babushka.ruby.gem_dir.should_receive(:writable?).and_return(false)
68
+ gem_helper.should_sudo?.should be_true
82
69
  end
83
70
  it "should return false if the gem dir is writeable" do
84
- Babushka::GemHelper.gem_root.should_receive(:writable?).and_return(true)
85
- Babushka::GemHelper.should_sudo?.should be_false
71
+ Babushka.ruby.gem_dir.should_receive(:writable?).and_return(true)
72
+ gem_helper.should_sudo?.should be_false
86
73
  end
87
74
  end
88
75
  end
@@ -2,31 +2,31 @@ require 'spec_helper'
2
2
 
3
3
  def stub_commitless_repo name
4
4
  (tmp_prefix / 'repos' / name).rm
5
- cd tmp_prefix / 'repos' / name, :create => true do
6
- shell "git init"
5
+ PathHelpers.cd tmp_prefix / 'repos' / name, :create => true do
6
+ ShellHelpers.shell "git init"
7
7
  end
8
8
  end
9
9
 
10
10
  def stub_repo name
11
11
  (tmp_prefix / 'repos' / "#{name}_remote").rm
12
- cd tmp_prefix / 'repos' / "#{name}_remote", :create => true do
13
- shell "tar -zxvf #{File.dirname(__FILE__) / '../repos/remote.git.tgz'}"
12
+ PathHelpers.cd tmp_prefix / 'repos' / "#{name}_remote", :create => true do
13
+ ShellHelpers.shell "tar -zxvf #{File.dirname(__FILE__) / '../repos/remote.git.tgz'}"
14
14
  end
15
15
 
16
16
  (tmp_prefix / 'repos' / name).rm
17
- cd tmp_prefix / 'repos' do
18
- shell "git clone #{name}_remote/remote.git #{name}"
17
+ PathHelpers.cd tmp_prefix / 'repos' do
18
+ ShellHelpers.shell "git clone #{name}_remote/remote.git #{name}"
19
19
  end
20
20
  end
21
21
 
22
22
  def repo_context name, &block
23
- cd(tmp_prefix / 'repos'/ name, &block)
23
+ PathHelpers.cd(tmp_prefix / 'repos'/ name, &block)
24
24
  end
25
25
 
26
26
  describe GitRepo, 'creation' do
27
27
  before(:all) { stub_repo 'a' }
28
28
  it "should return nil on nonexistent paths" do
29
- Babushka::GitRepo.new(tmp_prefix / 'repos/nonexistent').root.should == nil
29
+ Babushka::GitRepo.new(tmp_prefix / 'repos/missing').root.should == nil
30
30
  end
31
31
  it "should return nil on non-repo paths" do
32
32
  Babushka::GitRepo.new(tmp_prefix / 'repos').root.should == nil
@@ -54,22 +54,46 @@ describe GitRepo, 'creation' do
54
54
  end
55
55
  end
56
56
 
57
+ describe GitRepo, 'without a dir' do
58
+ subject { Babushka::GitRepo.new(tmp_prefix / 'repos/missing') }
59
+ it "should not exist" do
60
+ subject.exists?.should be_false
61
+ end
62
+ [:clean?, :dirty?, :current_branch, :current_head, :remote_branch_exists?, :ahead?].each {|method|
63
+ it "should raise on #{method}" do
64
+ L{ subject.send(method) }.should raise_error(Babushka::GitRepoError, "There is no repo at #{tmp_prefix / 'repos/missing'}.")
65
+ end
66
+ }
67
+ context "with lazy eval" do
68
+ subject { Babushka::GitRepo.new(tmp_prefix / 'repos/lazy_dir') }
69
+ it "should fail before the repo is created, but work afterwards" do
70
+ subject.exists?.should be_false
71
+ L{ subject.clean? }.should raise_error(Babushka::GitRepoError, "There is no repo at #{tmp_prefix / 'repos/lazy_dir'}.")
72
+ stub_repo 'lazy_dir'
73
+ subject.exists?.should be_true
74
+ subject.should be_clean
75
+ end
76
+ end
77
+ end
78
+
57
79
  describe GitRepo, 'without a repo' do
58
- subject { Babushka::GitRepo.new(tmp_prefix / 'repos/nonexistent') }
80
+ subject { Babushka::GitRepo.new(tmp_prefix / 'repos/empty') }
81
+ before { (tmp_prefix / 'repos/empty').mkdir }
82
+
59
83
  it "should not exist" do
60
84
  subject.exists?.should be_false
61
85
  end
62
86
  [:clean?, :dirty?, :current_branch, :current_head, :remote_branch_exists?, :ahead?].each {|method|
63
87
  it "should raise on #{method}" do
64
- L{ subject.send(method) }.should raise_error(Babushka::GitRepoError, "There is no repo at #{tmp_prefix / 'repos/nonexistent'}.")
88
+ L{ subject.send(method) }.should raise_error(Babushka::GitRepoError, "There is no repo at #{tmp_prefix / 'repos/empty'}.")
65
89
  end
66
90
  }
67
91
  context "with lazy eval" do
68
- subject { Babushka::GitRepo.new(tmp_prefix / 'repos/lazy') }
92
+ subject { Babushka::GitRepo.new(tmp_prefix / 'repos/lazy_repo') }
69
93
  it "should fail before the repo is created, but work afterwards" do
70
94
  subject.exists?.should be_false
71
- L{ subject.clean? }.should raise_error(Babushka::GitRepoError, "There is no repo at #{tmp_prefix / 'repos/lazy'}.")
72
- stub_repo 'lazy'
95
+ L{ subject.clean? }.should raise_error(Babushka::GitRepoError, "There is no repo at #{tmp_prefix / 'repos/lazy_repo'}.")
96
+ stub_repo 'lazy_repo'
73
97
  subject.exists?.should be_true
74
98
  subject.should be_clean
75
99
  end
@@ -104,7 +128,7 @@ describe GitRepo, '#clean? / #dirty?' do
104
128
  end
105
129
  context "when there are changes" do
106
130
  before {
107
- cd(tmp_prefix / 'repos/a') { shell "echo dirt >> content.txt" }
131
+ PathHelpers.cd(tmp_prefix / 'repos/a') { ShellHelpers.shell "echo dirt >> content.txt" }
108
132
  }
109
133
  it "should be dirty" do
110
134
  subject.should_not be_clean
@@ -112,7 +136,7 @@ describe GitRepo, '#clean? / #dirty?' do
112
136
  end
113
137
  context "when the changes are staged" do
114
138
  before {
115
- cd(tmp_prefix / 'repos/a') { shell "git add --update ." }
139
+ PathHelpers.cd(tmp_prefix / 'repos/a') { ShellHelpers.shell "git add --update ." }
116
140
  }
117
141
  it "should be dirty" do
118
142
  subject.should_not be_clean
@@ -144,21 +168,29 @@ describe GitRepo, '#branches' do
144
168
  subject.branches.should == ['master']
145
169
  end
146
170
  context "after creating another branch" do
147
- before {
148
- repo_context('a') { shell "git checkout -b next" }
171
+ before(:all) {
172
+ repo_context('a') { ShellHelpers.shell "git checkout -b next" }
149
173
  }
150
174
  it "should return both branches" do
151
175
  subject.branches.should == ['master', 'next']
152
176
  end
153
177
  context "after changing back to master" do
154
178
  before {
155
- repo_context('a') { shell "git checkout master" }
179
+ repo_context('a') { ShellHelpers.shell "git checkout master" }
156
180
  }
157
181
  it "should return both branches" do
158
182
  subject.branches.should == ['master', 'next']
159
183
  end
160
184
  end
161
185
  end
186
+ context "with a detached HEAD" do
187
+ before {
188
+ repo_context('a') { ShellHelpers.shell "git checkout origin/next~" }
189
+ }
190
+ it "should not include the '(no branch)' entry" do
191
+ subject.branches.should == ['master', 'next']
192
+ end
193
+ end
162
194
  end
163
195
  context "on a repo with no commits" do
164
196
  before { stub_commitless_repo 'a' }
@@ -168,6 +200,46 @@ describe GitRepo, '#branches' do
168
200
  end
169
201
  end
170
202
 
203
+ describe GitRepo, '#all_branches' do
204
+ subject { Babushka::GitRepo.new(tmp_prefix / 'repos/a') }
205
+ context "on a repo with commits" do
206
+ before(:all) { stub_repo 'a' }
207
+ it "should return the only branch in a list" do
208
+ subject.all_branches.should == ["master", "origin/master", "origin/next"]
209
+ end
210
+ context "after creating another branch" do
211
+ before(:all) {
212
+ repo_context('a') { ShellHelpers.shell "git checkout -b next" }
213
+ }
214
+ it "should return both branches" do
215
+ subject.all_branches.should == ["master", "next", "origin/master", "origin/next"]
216
+ end
217
+ context "after changing back to master" do
218
+ before {
219
+ repo_context('a') { ShellHelpers.shell "git checkout master" }
220
+ }
221
+ it "should return both branches" do
222
+ subject.all_branches.should == ["master", "next", "origin/master", "origin/next"]
223
+ end
224
+ end
225
+ end
226
+ context "with a detached HEAD" do
227
+ before {
228
+ repo_context('a') { ShellHelpers.shell "git checkout origin/next~" }
229
+ }
230
+ it "should not include the '(no branch)' entry" do
231
+ subject.all_branches.should == ["master", "next", "origin/master", "origin/next"]
232
+ end
233
+ end
234
+ end
235
+ context "on a repo with no commits" do
236
+ before { stub_commitless_repo 'a' }
237
+ it "should return no branches" do
238
+ subject.all_branches.should == []
239
+ end
240
+ end
241
+ end
242
+
171
243
  describe GitRepo, '#current_branch' do
172
244
  before(:all) { stub_repo 'a' }
173
245
  subject { Babushka::GitRepo.new(tmp_prefix / 'repos/a') }
@@ -175,15 +247,15 @@ describe GitRepo, '#current_branch' do
175
247
  subject.current_branch.should == 'master'
176
248
  end
177
249
  context "after creating another branch" do
178
- before {
179
- repo_context('a') { shell "git checkout -b next" }
250
+ before(:all) {
251
+ repo_context('a') { ShellHelpers.shell "git checkout -b next" }
180
252
  }
181
253
  it "should return 'next'" do
182
254
  subject.current_branch.should == 'next'
183
255
  end
184
256
  context "after changing back to master" do
185
257
  before {
186
- repo_context('a') { shell "git checkout master" }
258
+ repo_context('a') { ShellHelpers.shell "git checkout master" }
187
259
  }
188
260
  it "should return 'next'" do
189
261
  subject.current_branch.should == 'master'
@@ -192,6 +264,23 @@ describe GitRepo, '#current_branch' do
192
264
  end
193
265
  end
194
266
 
267
+ describe GitRepo, '#current_remote_branch' do
268
+ before(:all) { stub_repo 'a' }
269
+ subject { Babushka::GitRepo.new(tmp_prefix / 'repos/a') }
270
+ it "should return the namespaced remote branch" do
271
+ subject.current_remote_branch.should == 'origin/master'
272
+ end
273
+ context "after switching to a custom branch" do
274
+ before {
275
+ subject.repo_shell('git checkout -b next')
276
+ subject.repo_shell('git config branch.next.remote upstream')
277
+ }
278
+ it "should return 'origin' when no remote is set" do
279
+ subject.current_remote_branch.should == 'upstream/next'
280
+ end
281
+ end
282
+ end
283
+
195
284
  describe GitRepo, '#current_head' do
196
285
  before { stub_repo 'a' }
197
286
  subject { Babushka::GitRepo.new(tmp_prefix / 'repos/a') }
@@ -208,11 +297,33 @@ describe GitRepo, '#current_full_head' do
208
297
  end
209
298
  end
210
299
 
300
+ describe GitRepo, '#resolve' do
301
+ before { stub_repo 'a' }
302
+ subject { Babushka::GitRepo.new(tmp_prefix / 'repos/a') }
303
+ it "should return a full commit id" do
304
+ subject.resolve('master').should =~ /^[0-9a-f]{7,40}$/
305
+ end
306
+ end
307
+
308
+ describe GitRepo, '#remote_for' do
309
+ before(:all) {
310
+ stub_repo 'a'
311
+ subject.repo_shell('git config branch.next.remote upstream')
312
+ }
313
+ subject { Babushka::GitRepo.new(tmp_prefix / 'repos/a') }
314
+ it "should return the remote when it's set in the config" do
315
+ subject.remote_for('next').should == 'upstream'
316
+ end
317
+ it "should return 'origin' when no remote is set" do
318
+ subject.remote_for('lolbranch').should == 'origin'
319
+ end
320
+ end
321
+
211
322
  describe GitRepo, '#ahead?' do
212
323
  before(:all) {
213
324
  stub_repo 'a'
214
- cd(tmp_prefix / 'repos/a') {
215
- shell "git checkout -b topic"
325
+ PathHelpers.cd(tmp_prefix / 'repos/a') {
326
+ ShellHelpers.shell "git checkout -b topic"
216
327
  }
217
328
  }
218
329
  subject { Babushka::GitRepo.new(tmp_prefix / 'repos/a') }
@@ -225,10 +336,10 @@ describe GitRepo, '#ahead?' do
225
336
  end
226
337
  context "when remote branch exists" do
227
338
  before(:all) {
228
- cd(tmp_prefix / 'repos/a') {
229
- shell "git push origin topic"
230
- shell 'echo "Ch-ch-ch-changes" >> content.txt'
231
- shell 'git commit -a -m "Changes!"'
339
+ PathHelpers.cd(tmp_prefix / 'repos/a') {
340
+ ShellHelpers.shell "git push origin topic"
341
+ ShellHelpers.shell 'echo "Ch-ch-ch-changes" >> content.txt'
342
+ ShellHelpers.shell 'git commit -a -m "Changes!"'
232
343
  }
233
344
  }
234
345
  it "should have a local topic branch" do
@@ -240,14 +351,23 @@ describe GitRepo, '#ahead?' do
240
351
  end
241
352
  context "when the branch is fully pushed" do
242
353
  before {
243
- cd(tmp_prefix / 'repos/a') {
244
- shell "git push origin topic"
354
+ PathHelpers.cd(tmp_prefix / 'repos/a') {
355
+ ShellHelpers.shell "git push origin topic"
245
356
  }
246
357
  }
247
358
  it "should not be ahead" do
248
359
  subject.remote_branch_exists?.should be_true
249
360
  subject.should_not be_ahead
250
361
  end
362
+ context "when the remote doesn't exist" do
363
+ before {
364
+ subject.repo_shell('git config branch.topic.remote upstream')
365
+ }
366
+ it "should be ahead" do
367
+ subject.remote_branch_exists?.should be_false
368
+ subject.should be_ahead
369
+ end
370
+ end
251
371
  end
252
372
  end
253
373
  end
@@ -255,9 +375,9 @@ end
255
375
  describe GitRepo, '#behind?' do
256
376
  before(:all) {
257
377
  stub_repo 'a'
258
- cd(tmp_prefix / 'repos/a') {
259
- shell "git checkout -b next"
260
- shell "git reset --hard origin/next^"
378
+ PathHelpers.cd(tmp_prefix / 'repos/a') {
379
+ ShellHelpers.shell "git checkout -b next"
380
+ ShellHelpers.shell "git reset --hard origin/next^"
261
381
  }
262
382
  }
263
383
  subject { Babushka::GitRepo.new(tmp_prefix / 'repos/a') }
@@ -267,14 +387,23 @@ describe GitRepo, '#behind?' do
267
387
  end
268
388
  context "when the remote is merged" do
269
389
  before {
270
- cd(tmp_prefix / 'repos/a') {
271
- shell "git merge origin/next"
390
+ PathHelpers.cd(tmp_prefix / 'repos/a') {
391
+ ShellHelpers.shell "git merge origin/next"
272
392
  }
273
393
  }
274
394
  it "should not be behind" do
275
395
  subject.remote_branch_exists?.should be_true
276
396
  subject.should_not be_behind
277
397
  end
398
+ context "when the remote doesn't exist" do
399
+ before {
400
+ subject.repo_shell('git config branch.next.remote upstream')
401
+ }
402
+ it "should be ahead" do
403
+ subject.remote_branch_exists?.should be_false
404
+ subject.should be_ahead
405
+ end
406
+ end
278
407
  end
279
408
  end
280
409
 
@@ -296,7 +425,7 @@ describe GitRepo, '#clone!' do
296
425
  context "when the clone fails" do
297
426
  it "should raise" do
298
427
  L{
299
- subject.clone!(tmp_prefix / 'repos/a_remote/nonexistent.git')
428
+ subject.clone!(tmp_prefix / 'repos/a_remote/missing.git')
300
429
  }.should raise_error(GitRepoError)
301
430
  end
302
431
  end
@@ -321,7 +450,7 @@ origin\t#{tmp_prefix / 'repos/a_remote/remote.git'} (push)
321
450
  end
322
451
  end
323
452
  after {
324
- shell "rm -rf #{tmp_prefix / 'repos/b'}"
453
+ ShellHelpers.shell "rm -rf #{tmp_prefix / 'repos/b'}"
325
454
  }
326
455
  end
327
456
  end
@@ -332,14 +461,41 @@ describe GitRepo, '#branch!' do
332
461
  it "should not already have a next branch" do
333
462
  subject.branches.should_not include('next')
334
463
  end
335
- context "after tracking" do
336
- before { subject.branch! "next" }
337
- it "should have created a next branch" do
464
+ context "after branching" do
465
+ before(:all) { subject.branch! "next" }
466
+ it "should have created the branch" do
338
467
  subject.branches.should include('next')
339
468
  end
469
+ it "should have pointed the branch at HEAD" do
470
+ subject.resolve('next').should == subject.resolve("master")
471
+ end
340
472
  it "should not be tracking anything" do
341
473
  subject.repo_shell('git config branch.next.remote').should be_nil
342
474
  end
475
+ it "should not have checked out the branch" do
476
+ subject.current_branch.should == "master"
477
+ end
478
+ end
479
+ context "after branching to a ref" do
480
+ before(:all) {
481
+ PathHelpers.cd(tmp_prefix / 'repos/a') {
482
+ ShellHelpers.shell 'echo "Ch-ch-ch-changes" >> content.txt'
483
+ ShellHelpers.shell 'git commit -a -m "Changes!"'
484
+ }
485
+ subject.branch! "another", "master~"
486
+ }
487
+ it "should have created the branch" do
488
+ subject.branches.should include('another')
489
+ end
490
+ it "should have pointed the branch at the right ref" do
491
+ subject.resolve('another').should == subject.resolve("master~")
492
+ end
493
+ it "should not be tracking anything" do
494
+ subject.repo_shell('git config branch.another.remote').should be_nil
495
+ end
496
+ it "should not have checked out the branch" do
497
+ subject.current_branch.should == "master"
498
+ end
343
499
  end
344
500
  end
345
501
 
@@ -350,7 +506,7 @@ describe GitRepo, '#track!' do
350
506
  subject.branches.should_not include('next')
351
507
  end
352
508
  context "after tracking" do
353
- before { subject.track! "origin/next" }
509
+ before(:all) { subject.track! "origin/next" }
354
510
  it "should have created a next branch" do
355
511
  subject.branches.should include('next')
356
512
  end
@@ -363,28 +519,63 @@ end
363
519
  describe GitRepo, '#checkout!' do
364
520
  before(:all) {
365
521
  stub_repo 'a'
366
- cd(tmp_prefix / 'repos/a') {
367
- shell "git checkout -b next"
522
+ PathHelpers.cd(tmp_prefix / 'repos/a') {
523
+ ShellHelpers.shell "git checkout -b next"
368
524
  }
369
525
  }
370
526
  subject { Babushka::GitRepo.new(tmp_prefix / 'repos/a') }
371
- it "should already have a next branch" do
372
- subject.branches.should =~ %w[master next]
373
- subject.current_branch.should == 'next'
527
+ describe "checking out a branch" do
528
+ it "should already have a next branch" do
529
+ subject.branches.should =~ %w[master next]
530
+ subject.current_branch.should == 'next'
531
+ end
532
+ context "after checking out" do
533
+ before {
534
+ subject.checkout! "master"
535
+ }
536
+ it "should be on the master branch now" do
537
+ subject.current_branch.should == 'master'
538
+ end
539
+ end
374
540
  end
375
- context "after checking out" do
376
- before { subject.checkout! "master" }
377
- it "should be on the master branch now" do
378
- subject.current_branch.should == 'master'
541
+ describe "checking out a ref" do
542
+ before {
543
+ subject.checkout! 'origin/next~'
544
+ }
545
+ it "should detach the HEAD" do
546
+ subject.branches.should =~ %w[master next]
547
+ subject.current_branch.should =~ /^[0-9a-f]{40}$/
379
548
  end
380
549
  end
381
550
  end
382
551
 
552
+ describe GitRepo, '#detach!' do
553
+ before(:all) {
554
+ stub_repo 'a'
555
+ }
556
+ subject { Babushka::GitRepo.new(tmp_prefix / 'repos/a') }
557
+ it "should detach to HEAD when no ref is supplied" do
558
+ subject.detach!
559
+ subject.current_branch.should =~ /^[0-9a-f]{40}$/
560
+ subject.current_branch.starts_with?(subject.resolve('master')).should be_true
561
+ end
562
+ it "should detach the HEAD when a ref is supplied" do
563
+ subject.detach! 'origin/next'
564
+ subject.current_branch.should =~ /^[0-9a-f]{40}$/
565
+ subject.current_branch.starts_with?(subject.resolve('origin/next')).should be_true
566
+ end
567
+ it "should detach the HEAD when a branch is supplied" do
568
+ subject.detach! "master"
569
+ subject.current_branch.should =~ /^[0-9a-f]{40}$/
570
+ subject.current_branch.starts_with?(subject.resolve('master')).should be_true
571
+ end
572
+ end
573
+
383
574
  describe GitRepo, '#reset_hard!' do
384
575
  before {
385
576
  stub_repo 'a'
386
- cd(tmp_prefix / 'repos/a') {
387
- shell "echo 'more rubies' >> lib/rubies.rb"
577
+ PathHelpers.cd(tmp_prefix / 'repos/a') {
578
+ ShellHelpers.shell "echo 'more rubies' >> lib/rubies.rb"
388
579
  }
389
580
  }
390
581
  subject { Babushka::GitRepo.new(tmp_prefix / 'repos/a') }