rubycut-babushka 0.10.6

Sign up to get free protection for your applications and to get access to all the features.
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