rubycut-babushka 0.10.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (171) hide show
  1. data/Gemfile +8 -0
  2. data/Gemfile.lock +31 -0
  3. data/README.markdown +246 -0
  4. data/Rakefile +26 -0
  5. data/bin/babushka +11 -0
  6. data/deps/babushka.rb +101 -0
  7. data/deps/dev.rb +12 -0
  8. data/deps/fhs.rb +31 -0
  9. data/deps/git.rb +29 -0
  10. data/deps/homebrew.rb +30 -0
  11. data/deps/os_x.rb +33 -0
  12. data/deps/packages.rb +22 -0
  13. data/deps/pkg_managers.rb +110 -0
  14. data/deps/ruby.rb +23 -0
  15. data/deps/rubygems.rb +24 -0
  16. data/deps/system.rb +10 -0
  17. data/deps/templates/app.rb +68 -0
  18. data/deps/templates/external.rb +12 -0
  19. data/deps/templates/installer.rb +31 -0
  20. data/deps/templates/managed.rb +105 -0
  21. data/deps/templates/ppa.rb +24 -0
  22. data/deps/templates/src.rb +42 -0
  23. data/deps/templates/tmbundle.rb +15 -0
  24. data/lib/babushka.rb +28 -0
  25. data/lib/babushka/accepts_block_for.rb +72 -0
  26. data/lib/babushka/accepts_list_for.rb +49 -0
  27. data/lib/babushka/accepts_value_for.rb +24 -0
  28. data/lib/babushka/base.rb +78 -0
  29. data/lib/babushka/bug_reporter.rb +55 -0
  30. data/lib/babushka/cmdline.rb +133 -0
  31. data/lib/babushka/cmdline/handler.rb +41 -0
  32. data/lib/babushka/cmdline/helpers.rb +127 -0
  33. data/lib/babushka/cmdline/parser.rb +69 -0
  34. data/lib/babushka/colorizer.rb +59 -0
  35. data/lib/babushka/core_patches/array.rb +171 -0
  36. data/lib/babushka/core_patches/blank.rb +22 -0
  37. data/lib/babushka/core_patches/bytes.rb +52 -0
  38. data/lib/babushka/core_patches/hash.rb +107 -0
  39. data/lib/babushka/core_patches/hashish.rb +14 -0
  40. data/lib/babushka/core_patches/integer.rb +25 -0
  41. data/lib/babushka/core_patches/io.rb +8 -0
  42. data/lib/babushka/core_patches/numeric.rb +16 -0
  43. data/lib/babushka/core_patches/object.rb +27 -0
  44. data/lib/babushka/core_patches/string.rb +116 -0
  45. data/lib/babushka/core_patches/symbol.rb +12 -0
  46. data/lib/babushka/core_patches/try.rb +15 -0
  47. data/lib/babushka/core_patches/uri.rb +24 -0
  48. data/lib/babushka/dep.rb +470 -0
  49. data/lib/babushka/dep_context.rb +18 -0
  50. data/lib/babushka/dep_definer.rb +115 -0
  51. data/lib/babushka/dep_pool.rb +49 -0
  52. data/lib/babushka/dep_runner.rb +85 -0
  53. data/lib/babushka/dsl.rb +26 -0
  54. data/lib/babushka/git_repo.rb +185 -0
  55. data/lib/babushka/helpers/git_helpers.rb +32 -0
  56. data/lib/babushka/helpers/log_helpers.rb +176 -0
  57. data/lib/babushka/helpers/path_helpers.rb +34 -0
  58. data/lib/babushka/helpers/run_helpers.rb +145 -0
  59. data/lib/babushka/helpers/shell_helpers.rb +229 -0
  60. data/lib/babushka/helpers/suggest_helpers.rb +16 -0
  61. data/lib/babushka/helpers/uri_helpers.rb +36 -0
  62. data/lib/babushka/ip.rb +160 -0
  63. data/lib/babushka/lambda_chooser.rb +40 -0
  64. data/lib/babushka/levenshtein.rb +125 -0
  65. data/lib/babushka/meta_dep.rb +65 -0
  66. data/lib/babushka/meta_dep_context.rb +15 -0
  67. data/lib/babushka/parameter.rb +143 -0
  68. data/lib/babushka/pkg_helper.rb +81 -0
  69. data/lib/babushka/pkg_helpers/apt_helper.rb +61 -0
  70. data/lib/babushka/pkg_helpers/base_helper.rb +19 -0
  71. data/lib/babushka/pkg_helpers/binpkgsrc_helper.rb +48 -0
  72. data/lib/babushka/pkg_helpers/binports_helper.rb +34 -0
  73. data/lib/babushka/pkg_helpers/brew_helper.rb +110 -0
  74. data/lib/babushka/pkg_helpers/gem_helper.rb +120 -0
  75. data/lib/babushka/pkg_helpers/macports_helper.rb +22 -0
  76. data/lib/babushka/pkg_helpers/npm_helper.rb +45 -0
  77. data/lib/babushka/pkg_helpers/pacman_helper.rb +27 -0
  78. data/lib/babushka/pkg_helpers/pip_helper.rb +45 -0
  79. data/lib/babushka/pkg_helpers/src_helper.rb +16 -0
  80. data/lib/babushka/pkg_helpers/yum_helper.rb +25 -0
  81. data/lib/babushka/popen.rb +40 -0
  82. data/lib/babushka/prompt.rb +176 -0
  83. data/lib/babushka/renderable.rb +67 -0
  84. data/lib/babushka/resource.rb +215 -0
  85. data/lib/babushka/run_reporter.rb +60 -0
  86. data/lib/babushka/shell.rb +108 -0
  87. data/lib/babushka/source.rb +216 -0
  88. data/lib/babushka/source_pool.rb +146 -0
  89. data/lib/babushka/system_definitions.rb +97 -0
  90. data/lib/babushka/system_profile.rb +210 -0
  91. data/lib/babushka/task.rb +142 -0
  92. data/lib/babushka/vars.rb +108 -0
  93. data/lib/babushka/version_of.rb +65 -0
  94. data/lib/babushka/version_str.rb +57 -0
  95. data/lib/babushka/xml_string.rb +28 -0
  96. data/lib/components.rb +82 -0
  97. data/lib/fancypath/fancypath.rb +200 -0
  98. data/lib/inkan/inkan.rb +76 -0
  99. data/spec/acceptance/acceptance.rb +43 -0
  100. data/spec/acceptance_helper.rb +113 -0
  101. data/spec/archives/Blah.app.zip +0 -0
  102. data/spec/archives/archive.tar +0 -0
  103. data/spec/archives/archive.tar.bz2 +0 -0
  104. data/spec/archives/archive.tar.gz +0 -0
  105. data/spec/archives/archive.tbz2 +0 -0
  106. data/spec/archives/archive.tgz +0 -0
  107. data/spec/archives/archive.zip +0 -0
  108. data/spec/archives/content.txt +5 -0
  109. data/spec/archives/invalid_archive +5 -0
  110. data/spec/archives/nested archive/content.txt +5 -0
  111. data/spec/archives/nested_archive.tar +0 -0
  112. data/spec/archives/really_a_gzip.zip +0 -0
  113. data/spec/archives/test-0.3.1.tgz +0 -0
  114. data/spec/archives/tgz_archive +0 -0
  115. data/spec/archives/zip_without_extension +0 -0
  116. data/spec/babushka/accepts_for_spec.rb +174 -0
  117. data/spec/babushka/accepts_for_support.rb +72 -0
  118. data/spec/babushka/cmdline/console_spec.rb +11 -0
  119. data/spec/babushka/cmdline/help_spec.rb +61 -0
  120. data/spec/babushka/cmdline/version_spec.rb +10 -0
  121. data/spec/babushka/core_patches_spec.rb +171 -0
  122. data/spec/babushka/dep_context_spec.rb +58 -0
  123. data/spec/babushka/dep_definer_spec.rb +152 -0
  124. data/spec/babushka/dep_definer_support.rb +36 -0
  125. data/spec/babushka/dep_spec.rb +567 -0
  126. data/spec/babushka/dep_support.rb +29 -0
  127. data/spec/babushka/deps_spec.rb +113 -0
  128. data/spec/babushka/gem_helper_spec.rb +90 -0
  129. data/spec/babushka/git_repo_spec.rb +396 -0
  130. data/spec/babushka/ip_spec.rb +131 -0
  131. data/spec/babushka/lambda_chooser_spec.rb +115 -0
  132. data/spec/babushka/meta_dep_definer_spec.rb +127 -0
  133. data/spec/babushka/meta_dep_wrapper_spec.rb +32 -0
  134. data/spec/babushka/parameter_spec.rb +135 -0
  135. data/spec/babushka/path_helpers_spec.rb +102 -0
  136. data/spec/babushka/prompt_spec.rb +188 -0
  137. data/spec/babushka/renderable_spec.rb +100 -0
  138. data/spec/babushka/resource_spec.rb +141 -0
  139. data/spec/babushka/run_helpers_spec.rb +26 -0
  140. data/spec/babushka/shell_helpers_spec.rb +244 -0
  141. data/spec/babushka/shell_spec.rb +19 -0
  142. data/spec/babushka/source_pool_spec.rb +320 -0
  143. data/spec/babushka/source_pool_support.rb +31 -0
  144. data/spec/babushka/source_spec.rb +382 -0
  145. data/spec/babushka/source_support.rb +17 -0
  146. data/spec/babushka/system_profile_spec.rb +61 -0
  147. data/spec/babushka/task_spec.rb +141 -0
  148. data/spec/babushka/uri_spec.rb +13 -0
  149. data/spec/babushka/vars_spec.rb +59 -0
  150. data/spec/babushka/version_of_spec.rb +110 -0
  151. data/spec/babushka/version_str_spec.rb +130 -0
  152. data/spec/babushka/version_str_support.rb +37 -0
  153. data/spec/babushka/xml_string_spec.rb +98 -0
  154. data/spec/deps/bad/broken.rb +7 -0
  155. data/spec/deps/bad/working.rb +3 -0
  156. data/spec/deps/good/meta.rb +14 -0
  157. data/spec/deps/good/test.rb +11 -0
  158. data/spec/deps/outer/deps.rb +19 -0
  159. data/spec/deps/outer/more deps.rb +11 -0
  160. data/spec/deps/params/params.rb +10 -0
  161. data/spec/fancypath/fancypath_spec.rb +272 -0
  162. data/spec/fancypath_support.rb +10 -0
  163. data/spec/inkan/inkan_spec.rb +217 -0
  164. data/spec/renderable/different_example.conf.erb +4 -0
  165. data/spec/renderable/example.conf.erb +3 -0
  166. data/spec/renderable/example.sh +6 -0
  167. data/spec/renderable/with_binding.conf.erb +4 -0
  168. data/spec/renderable/xml_example.conf.erb +8 -0
  169. data/spec/repos/remote.git.tgz +0 -0
  170. data/spec/spec_helper.rb +87 -0
  171. metadata +238 -0
@@ -0,0 +1,36 @@
1
+ class TestDepContext < DepContext
2
+ def chooser
3
+ :osx # hardcode this for testing
4
+ end
5
+ end
6
+ class TestTemplate
7
+ def self.contextual_name; name end
8
+ def self.context_class; TestDepContext end
9
+ end
10
+ class FakeOSXSystemProfile < OSXSystemProfile
11
+ def version; '10.6.7' end
12
+ def get_version_info; '' end
13
+ def total_memory; 16_000_000_000 end
14
+ end
15
+
16
+ def setup_test_lambdas
17
+ @lambda_hello = L{ "hello world!" }
18
+ end
19
+
20
+ def test_accepts_block_for_response accepter_name, lambda, value, opts = {}
21
+ TestDepContext.accepts_block_for accepter_name
22
+ dep 'accepts_block_for' do
23
+ send accepter_name, opts, &lambda
24
+ end
25
+ on = opts[:on].nil? ? :all : Base.host.system
26
+ Dep('accepts_block_for').context.payload[accepter_name][on].should == value
27
+ end
28
+
29
+ def make_test_deps
30
+ dep 'test build tools' do
31
+ requires {
32
+ on :osx, 'xcode tools'
33
+ on :linux, 'build-essential', 'autoconf'
34
+ }
35
+ end
36
+ end
@@ -0,0 +1,567 @@
1
+ require 'spec_helper'
2
+ require 'dep_support'
3
+
4
+ describe "Dep.new" do
5
+ it "should reject deps with empty names" do
6
+ L{
7
+ Dep.new "", Base.sources.anonymous, [], {}, nil
8
+ }.should raise_error(InvalidDepName, "Deps can't have empty names.")
9
+ Dep("carriage\rreturn").should be_nil
10
+ end
11
+ it "should reject deps with nonprintable characters in their names" do
12
+ L{
13
+ Dep.new "carriage\rreturn", Base.sources.anonymous, [], {}, nil
14
+ }.should raise_error(InvalidDepName, "The dep name 'carriage\rreturn' contains nonprintable characters.")
15
+ Dep("carriage\rreturn").should be_nil
16
+ end
17
+ it "should reject deps slashes in their names" do
18
+ L{
19
+ Dep.new "slashes/invalidate names", Base.sources.anonymous, [], {}, nil
20
+ }.should raise_error(InvalidDepName, "The dep name 'slashes/invalidate names' contains '/', which isn't allowed (logs are named after deps, and filenames can't contain '/').")
21
+ Dep("slashes/invalidate names").should be_nil
22
+ end
23
+ it "should reject deps colons in their names" do
24
+ L{
25
+ Dep.new "colons:invalidate names", Base.sources.anonymous, [], {}, nil
26
+ }.should raise_error(InvalidDepName, "The dep name 'colons:invalidate names' contains ':', which isn't allowed (colons separate dep and template names from source prefixes).")
27
+ Dep("colons:invalidate names").should be_nil
28
+ end
29
+ it "should create deps with valid names" do
30
+ L{
31
+ Dep.new("valid dep name", Base.sources.anonymous, [], {}, nil)
32
+ }.should change(Base.sources.anonymous.deps, :count).by(1)
33
+ Dep("valid dep name").should be_an_instance_of(Dep)
34
+ end
35
+ it "should store the params" do
36
+ L{
37
+ Dep.new("valid dep with params", Base.sources.anonymous, [:some, :params], {}, nil)
38
+ }.should change(Base.sources.anonymous.deps, :count).by(1)
39
+ Dep("valid dep with params").params.should == [:some, :params]
40
+ end
41
+ context "without template" do
42
+ before {
43
+ @dep = Dep.new("valid base dep", Base.sources.anonymous, [], {}, nil)
44
+ }
45
+ it "should work" do
46
+ @dep.should be_an_instance_of(Dep)
47
+ @dep.template.should == Dep::BaseTemplate
48
+ end
49
+ end
50
+ context "with a missing template" do
51
+ it "should fail to define optioned deps against a missing template" do
52
+ L{
53
+ Dep.new("valid but missing template", Base.sources.anonymous, [], {:template => 'template'}, nil).template
54
+ }.should raise_error(TemplateNotFound, "There is no template named 'template' to define 'valid but missing template' against.")
55
+ end
56
+ end
57
+ context "with template" do
58
+ before {
59
+ @meta = meta('template')
60
+ }
61
+ it "should work when passed as an option" do
62
+ Dep.new("valid option dep", Base.sources.anonymous, [], {:template => 'template'}, nil).tap {|dep|
63
+ dep.should be_an_instance_of(Dep)
64
+ dep.template.should == @meta
65
+ }
66
+ end
67
+ it "should work when passed as a suffix" do
68
+ Dep.new("valid dep name.template", Base.sources.anonymous, [], {}, nil).tap {|dep|
69
+ dep.should be_an_instance_of(Dep)
70
+ dep.template.should == @meta
71
+ }
72
+ end
73
+ after { Base.sources.anonymous.templates.clear! }
74
+ end
75
+ end
76
+
77
+ describe Dep, '.find_or_suggest' do
78
+ before {
79
+ @dep = dep 'Dep.find_or_suggest tests'
80
+ }
81
+ it "should find the given dep and yield the block" do
82
+ Dep.find_or_suggest('Dep.find_or_suggest tests') {|dep| dep }.should == @dep
83
+ end
84
+ context "namespaced" do
85
+ before {
86
+ Dep.stub!(:suggest_value_for).and_return(nil)
87
+ @source = Source.new(nil, :name => 'namespaced')
88
+ Source.stub!(:present).and_return([@source])
89
+ Base.sources.load_context :source => @source do
90
+ @namespaced_dep = dep 'namespaced Dep.find_or_suggest tests'
91
+ end
92
+ }
93
+ it "should not find the dep without a namespace" do
94
+ Dep.find_or_suggest('namespaced Dep.find_or_suggest tests').should be_nil
95
+ end
96
+ it "should not find the dep with an incorrect namespace" do
97
+ Dep.find_or_suggest('incorrect:namespaced Dep.find_or_suggest tests').should be_nil
98
+ end
99
+ it "should find the dep with the correct namespace" do
100
+ Dep.find_or_suggest('namespaced:namespaced Dep.find_or_suggest tests').should == @namespaced_dep
101
+ end
102
+ it "should find the dep with the correct namespace and yield it to the block" do
103
+ Dep.find_or_suggest('namespaced:namespaced Dep.find_or_suggest tests') {|dep| dep }.should == @namespaced_dep
104
+ end
105
+ end
106
+ context "from other deps" do
107
+ before {
108
+ @source = Source.new(nil, :name => 'namespaced')
109
+ Source.stub!(:present).and_return([@source])
110
+ Base.sources.load_context :source => @source do
111
+ @namespaced_dep = dep 'namespaced Dep.find_or_suggest tests' do
112
+ requires 'Dep.find_or_suggest sub-dep'
113
+ end
114
+ end
115
+ }
116
+ context "without namespacing" do
117
+ before {
118
+ @sub_dep = dep 'Dep.find_or_suggest sub-dep'
119
+ }
120
+ it "should find the sub dep" do
121
+ @sub_dep.should_receive :process
122
+ @namespaced_dep.process
123
+ end
124
+ end
125
+ context "in the same namespace" do
126
+ before {
127
+ Base.sources.load_context :source => @source do
128
+ @sub_dep = dep 'Dep.find_or_suggest sub-dep'
129
+ end
130
+ }
131
+ it "should find the sub dep" do
132
+ @sub_dep.should_receive :process
133
+ @namespaced_dep.process
134
+ end
135
+ end
136
+ context "in a different namespace" do
137
+ before {
138
+ @source = Source.new(nil, :name => 'namespaced')
139
+ @source2 = Source.new(nil, :name => 'another namespaced')
140
+ Source.stub!(:present).and_return([@source, @source2])
141
+ Base.sources.load_context :source => @source do
142
+ @namespaced_dep = dep 'namespaced Dep.find_or_suggest tests' do
143
+ requires 'Dep.find_or_suggest sub-dep'
144
+ end
145
+ end
146
+ Base.sources.load_context :source => @source2 do
147
+ @sub_dep = dep 'Dep.find_or_suggest sub-dep'
148
+ end
149
+ }
150
+ it "should not find the sub dep" do
151
+ @sub_dep.should_not_receive :process
152
+ @namespaced_dep.process
153
+ end
154
+ end
155
+ end
156
+ end
157
+
158
+ describe "dep creation" do
159
+ it "should work for blank deps" do
160
+ L{
161
+ dep "a blank dep"
162
+ }.should change(Base.sources.anonymous.deps, :count).by(1)
163
+ Dep('a blank dep').should be_an_instance_of(Dep)
164
+ end
165
+ it "should work for filled in deps" do
166
+ L{
167
+ dep "a standard dep" do
168
+ requires 'some other dep'
169
+ before { }
170
+ met? { }
171
+ meet { }
172
+ after { }
173
+ end
174
+ }.should change(Base.sources.anonymous.deps, :count).by(1)
175
+ Dep('a standard dep').should be_an_instance_of(Dep)
176
+ end
177
+ it "should accept deps as dep names" do
178
+ L{
179
+ dep 'parent dep' do
180
+ requires dep('nested dep')
181
+ end.met?
182
+ }.should change(Base.sources.anonymous.deps, :count).by(2)
183
+ Dep('parent dep').context.requires.should == [Dep('nested dep')]
184
+ end
185
+ after { Base.sources.anonymous.deps.clear! }
186
+
187
+ context "without template" do
188
+ it "should use the base template" do
189
+ dep('without template').template.should == Dep::BaseTemplate
190
+ end
191
+ end
192
+ context "with template" do
193
+ before {
194
+ @template = meta 'template'
195
+ }
196
+ it "should use the template when passed as an option" do
197
+ dep('with template', :template => 'template').tap {|dep|
198
+ dep.template.should == @template
199
+ dep.should_not be_suffixed
200
+ dep.suffix.should be_nil
201
+ }
202
+ end
203
+ it "should use the template and be suffixed when passed as a suffix" do
204
+ dep('with template.template').tap {|dep|
205
+ dep.template.should == @template
206
+ dep.should be_suffixed
207
+ dep.suffix.should == 'template'
208
+ }
209
+ end
210
+ context "when both are passed" do
211
+ before {
212
+ @another_template = meta 'another_template'
213
+ }
214
+ it "should use the option template" do
215
+ dep('with both templates.template', :template => 'another_template').tap {|dep|
216
+ dep.template.should == @another_template
217
+ dep.should_not be_suffixed
218
+ dep.suffix.should == 'template'
219
+ }
220
+ end
221
+ end
222
+ end
223
+ after { Base.sources.anonymous.templates.clear! }
224
+ end
225
+
226
+ describe Dep, "defining" do
227
+ before {
228
+ Base.sources.stub!(:current_real_load_source).and_return(Base.sources.anonymous)
229
+ }
230
+ it "should not define the dep when called without a block" do
231
+ dep('lazy defining test').dep_defined?.should == nil
232
+ end
233
+ it "should not define the dep when called with a block" do
234
+ dep('lazy defining test with block') do
235
+ requires 'another dep'
236
+ end.dep_defined?.should == nil
237
+ end
238
+ context "after running" do
239
+ it "should be defined" do
240
+ dep('lazy defining test with run').tap {|dep|
241
+ dep.met?
242
+ }.dep_defined?.should == true
243
+ end
244
+ context "with a template" do
245
+ let!(:template) { meta 'lazy_defining_template' }
246
+ it "should use the template" do
247
+ dep('lazy defining test with template.lazy_defining_template').tap {|dep|
248
+ dep.met?
249
+ }.template.should == template
250
+ end
251
+ end
252
+ end
253
+ context "with errors" do
254
+ before {
255
+ Base.sources.stub!(:current_real_load_source).and_return(Base.sources.anonymous)
256
+ }
257
+ it "should not be defined, and then have failed defining after a run" do
258
+ dep('lazy defining test with errors') do
259
+ nonexistent_method
260
+ end.tap {|dep|
261
+ dep.dep_defined?.should == nil
262
+ dep.met?
263
+ }.dep_defined?.should == false
264
+ end
265
+ end
266
+ context "repeatedly" do
267
+ it "should only ever define the dep once" do
268
+ dep('lazy defining test with repetition').tap {|dep|
269
+ dep.met?
270
+ dep.context.should_receive(:define!).never
271
+ dep.met?
272
+ }
273
+ end
274
+ it "should not overwrite custom blocks" do
275
+ dep('lazy defining test with block overwriting') do
276
+ setup { 'initial' }
277
+ end.tap {|dep|
278
+ dep.context.setup { 'custom' }
279
+ dep.send(:define!)
280
+ }.send(:process_task, :setup).should == 'custom'
281
+ end
282
+ end
283
+ end
284
+
285
+ describe Dep, '#basename' do
286
+ context "for base deps" do
287
+ it "should be the same as the dep's name" do
288
+ dep('basename test').basename.should == 'basename test'
289
+ end
290
+ context "with a suffix" do
291
+ it "should be the same as the dep's name" do
292
+ dep('basename test.basename_test').basename.should == 'basename test.basename_test'
293
+ end
294
+ end
295
+ end
296
+ context "for option-templated deps" do
297
+ before { meta 'basename_template' }
298
+ it "should be the same as the dep's name" do
299
+ dep('basename test', :template => 'basename_template').basename.should == 'basename test'
300
+ end
301
+ context "with a suffix" do
302
+ it "should be the same as the dep's name" do
303
+ dep('basename test.basename_template', :template => 'basename_template').basename.should == 'basename test.basename_template'
304
+ end
305
+ end
306
+ after {
307
+ Base.sources.anonymous.deps.clear!
308
+ Base.sources.anonymous.templates.clear!
309
+ }
310
+ end
311
+ context "for suffix-templated deps" do
312
+ before { meta 'basename_template' }
313
+ it "should remove the suffix name" do
314
+ dep('basename test.basename_template').basename.should == 'basename test'
315
+ end
316
+ after {
317
+ Base.sources.anonymous.deps.clear!
318
+ Base.sources.anonymous.templates.clear!
319
+ }
320
+ end
321
+ end
322
+
323
+ describe Dep, "params" do
324
+ describe "non-symbol params" do
325
+ it "should be rejected, singular" do
326
+ L{
327
+ dep('non-symbol param', 'a')
328
+ }.should raise_error(DepParameterError, %{The dep 'non-symbol param' has a non-symbol param "a", which isn't allowed.})
329
+ end
330
+ it "should be rejected, plural" do
331
+ L{
332
+ dep('non-symbol params', 'a', 'b')
333
+ }.should raise_error(DepParameterError, %{The dep 'non-symbol params' has non-symbol params "a" and "b", which aren't allowed.})
334
+ end
335
+ end
336
+ it "should define methods on the context" do
337
+ dep('params test', :a_param).context.should respond_to(:a_param)
338
+ end
339
+ it "should raise on conflicting methods" do
340
+ L{
341
+ dep('conflicting param names', :name).context
342
+ }.should raise_error(DepParameterError, "You can't use :name as a parameter (on 'conflicting param names'), because that's already a method on Babushka::DepDefiner.")
343
+ end
344
+ it "should not pollute other deps" do
345
+ dep('params test', :a_param)
346
+ Dep('params test').context.should respond_to(:a_param)
347
+ dep('paramless dep').context.should_not respond_to(:a_param)
348
+ end
349
+ it "should return a param containing the value when it's set" do
350
+ dep('set params test', :a_set_param)
351
+ Dep('set params test').with('a value').context.a_set_param.should be_an_instance_of(Parameter)
352
+ Dep('set params test').with('a value').context.a_set_param.to_s.should == 'a value'
353
+ end
354
+ it "should ask for the value when it's not set" do
355
+ dep('unset params test', :an_unset_param)
356
+ Dep('unset params test').context.an_unset_param.should be_an_instance_of(Parameter)
357
+ Prompt.should_receive(:get_value).with('an_unset_param', {}).and_return('a value from the prompt')
358
+ Dep('unset params test').context.an_unset_param.to_s.should == 'a value from the prompt'
359
+ end
360
+ end
361
+
362
+ describe Dep, 'lambda lists' do
363
+ before {
364
+ Babushka::Base.host.stub!(:name).and_return(:test_name)
365
+ Babushka::Base.host.stub!(:system).and_return(:test_system)
366
+ Babushka::Base.host.stub!(:pkg_helper_key).and_return(:test_helper)
367
+
368
+ Babushka::SystemDefinitions.stub!(:all_names).and_return([:test_name, :other_name])
369
+ Babushka::SystemDefinitions.stub!(:all_systems).and_return([:test_system, :other_system])
370
+ Babushka::PkgHelper.stub!(:all_manager_keys).and_return([:test_helper, :other_helper])
371
+ }
372
+ it "should match against the system name" do
373
+ dep('lambda list name match') { requires { on :test_name, 'awesome' } }.context.requires.should == ['awesome']
374
+ end
375
+ it "should match against the system type" do
376
+ dep('lambda list system match') { requires { on :test_system, 'awesome' } }.context.requires.should == ['awesome']
377
+ end
378
+ it "should match against the system name" do
379
+ dep('lambda list pkg_helper_key match') { requires { on :test_helper, 'awesome' } }.context.requires.should == ['awesome']
380
+ end
381
+ end
382
+
383
+ describe Dep, '#requirements_for' do
384
+ let(:dependency) {
385
+ dep 'requirements_for specs' do
386
+ requires 'a dep'
387
+ requires 'another dep'.with(:some, :args)
388
+ requires 'a third'.with()
389
+ end
390
+ }
391
+ let(:requirements) {
392
+ dependency.send(:requirements_for, :requires)
393
+ }
394
+ it "should have the right number of requirements" do
395
+ requirements.length.should == 3
396
+ end
397
+ it "should return a Requirement for all the required deps" do
398
+ requirements.each {|c| c.should be_an_instance_of(Babushka::Dep::Requirement) }
399
+ end
400
+ it "should contain the right dep names" do
401
+ requirements.map(&:name).should == ['a dep', 'another dep', 'a third']
402
+ end
403
+ it "should work with empty args" do
404
+ requirements[0].args.should == []
405
+ requirements[2].args.should == []
406
+ end
407
+ context "arguments" do
408
+ let(:args) { requirements[1].args }
409
+ it "should have the right number of args" do
410
+ args.length.should == 2
411
+ end
412
+ it "should contain the right args" do
413
+ args.should == [:some, :args]
414
+ end
415
+ end
416
+ end
417
+
418
+ describe "calling met? on a single dep" do
419
+ before {
420
+ setup_yield_counts
421
+ }
422
+ it "should run if setup returns nil or false" do
423
+ make_counter_dep(
424
+ :name => 'unmeetable for met', :setup => L{ false }, :met? => L{ false }
425
+ ).met?.should == false
426
+ @yield_counts['unmeetable for met'].should == @yield_counts_met_run
427
+ end
428
+ it "should return false for unmet deps" do
429
+ make_counter_dep(
430
+ :name => 'unmeetable for met', :met? => L{ false }
431
+ ).met?.should == false
432
+ @yield_counts['unmeetable for met'].should == @yield_counts_met_run
433
+ end
434
+ it "should return true for already met deps" do
435
+ make_counter_dep(
436
+ :name => 'met for met'
437
+ ).met?.should == true
438
+ @yield_counts['met for met'].should == @yield_counts_met_run
439
+ end
440
+ after { Base.sources.anonymous.deps.clear! }
441
+ end
442
+
443
+ describe "exceptions" do
444
+ it "should be unmet after an exception in met? {}" do
445
+ dep 'exception met? test' do
446
+ met? { raise }
447
+ end.met?.should be_false
448
+ end
449
+ it "should be unmet after an exception in meet {}" do
450
+ dep 'exception meet test' do
451
+ met? { false }
452
+ meet { raise }
453
+ end.met?.should be_false
454
+ end
455
+ end
456
+
457
+ describe "calling meet on a single dep" do
458
+ before {
459
+ setup_yield_counts
460
+ }
461
+ it "should fail twice and return false on unmeetable deps" do
462
+ make_counter_dep(
463
+ :name => 'unmeetable', :met? => L{ false }
464
+ ).meet.should == false
465
+ @yield_counts['unmeetable'].should == @yield_counts_meet_run
466
+ end
467
+ it "should fail fast and return nil on explicitly unmeetable deps" do
468
+ make_counter_dep(
469
+ :name => 'explicitly unmeetable', :met? => L{ unmeetable }
470
+ ).meet.should == nil
471
+ @yield_counts['explicitly unmeetable'].should == @yield_counts_met_run
472
+ end
473
+ it "should fail, run meet, and then succeed on unmet deps" do
474
+ make_counter_dep(
475
+ :name => 'unmet', :met? => L{ @yield_counts['unmet'][:met?] > 1 }
476
+ ).meet.should == true
477
+ @yield_counts['unmet'].should == @yield_counts_meet_run
478
+ end
479
+ it "should fail, not run meet, and fail again on unmet deps where before fails" do
480
+ make_counter_dep(
481
+ :name => 'unmet, #before fails', :met? => L{ false }, :before => L{ false }
482
+ ).meet.should == false
483
+ @yield_counts['unmet, #before fails'].should == @yield_counts_failed_at_before
484
+ end
485
+ it "should fail, not run meet, and fail again on unmet deps where meet raises UnmeetableDep" do
486
+ make_counter_dep(
487
+ :name => 'unmet, #before fails', :met? => L{ false }, :meet => L{ unmeetable }
488
+ ).meet.should == nil
489
+ @yield_counts['unmet, #before fails'].should == @yield_counts_early_exit_meet_run
490
+ end
491
+ it "should fail, run meet, and then succeed on unmet deps where after fails" do
492
+ make_counter_dep(
493
+ :name => 'unmet, #after fails', :met? => L{ @yield_counts['unmet, #after fails'][:met?] > 1 }, :after => L{ false }
494
+ ).meet.should == true
495
+ @yield_counts['unmet, #after fails'].should == @yield_counts_meet_run
496
+ end
497
+ it "should succeed on already met deps" do
498
+ make_counter_dep(
499
+ :name => 'met', :met? => L{ true }
500
+ ).meet.should == true
501
+ @yield_counts['met'].should == @yield_counts_already_met
502
+ end
503
+ after { Base.sources.anonymous.deps.clear! }
504
+ end
505
+
506
+ describe "run_in" do
507
+ it "should run in the current directory when run_in isn't set" do
508
+ cwd = Dir.pwd
509
+ ran_in = nil
510
+ dep 'dep without run_in set' do
511
+ met? { ran_in = Dir.pwd }
512
+ end.met?
513
+ Dir.pwd.should == cwd
514
+ ran_in.should == cwd
515
+ end
516
+ it "should not run when run_in is set to a nonexistent directory" do
517
+ ran_in = nil
518
+ dep 'dep with run_in set' do
519
+ run_in tmp_prefix / 'nonexistent'
520
+ met? { ran_in = Dir.pwd }
521
+ end.met?
522
+ ran_in.should be_nil
523
+ end
524
+ it "should run in the specified directory when run_in is set" do
525
+ cwd = Dir.pwd
526
+ ran_in = nil
527
+ dep 'dep with run_in set' do
528
+ run_in tmp_prefix
529
+ met? { ran_in = Dir.pwd }
530
+ end.met?
531
+ Dir.pwd.should == cwd
532
+ ran_in.should == tmp_prefix
533
+ end
534
+ it "should run this deps' requirements in the original directory" do
535
+ cwd = Dir.pwd
536
+ ran_in = child_ran_in = nil
537
+ dep 'another without run_in set' do
538
+ met? { child_ran_in = Dir.pwd }
539
+ end
540
+ dep 'dep with run_in set' do
541
+ requires 'another without run_in set'
542
+ run_in tmp_prefix
543
+ met? { ran_in = Dir.pwd }
544
+ end.met?
545
+ Dir.pwd.should == cwd
546
+ ran_in.should == tmp_prefix
547
+ child_ran_in.should == cwd
548
+ end
549
+ it "should run this deps' requirements in their own directories when specified" do
550
+ cwd = Dir.pwd
551
+ ran_in = child_ran_in = nil
552
+ (tmp_prefix / 'run_in').mkdir
553
+ dep 'another with run_in set' do
554
+ run_in tmp_prefix / 'run_in'
555
+ met? { child_ran_in = Dir.pwd }
556
+ end
557
+ dep 'dep with run_in set' do
558
+ requires 'another with run_in set'
559
+ run_in tmp_prefix
560
+ met? { ran_in = Dir.pwd }
561
+ end.met?
562
+ Dir.pwd.should == cwd
563
+ ran_in.should == tmp_prefix
564
+ child_ran_in.should == tmp_prefix / 'run_in'
565
+ end
566
+ after { Base.sources.anonymous.deps.clear! }
567
+ end