powcloud-sprinkle 0.3.0

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 (106) hide show
  1. data/.gitignore +5 -0
  2. data/CREDITS +33 -0
  3. data/MIT-LICENSE +20 -0
  4. data/README.markdown +241 -0
  5. data/Rakefile +50 -0
  6. data/VERSION +1 -0
  7. data/bin/sprinkle +90 -0
  8. data/examples/packages/build_essential.rb +9 -0
  9. data/examples/packages/databases/mysql.rb +13 -0
  10. data/examples/packages/databases/sqlite3.rb +16 -0
  11. data/examples/packages/phusion.rb +55 -0
  12. data/examples/packages/ruby/rails.rb +9 -0
  13. data/examples/packages/ruby/ruby.rb +17 -0
  14. data/examples/packages/ruby/rubygems.rb +17 -0
  15. data/examples/packages/scm/git.rb +11 -0
  16. data/examples/packages/scm/subversion.rb +4 -0
  17. data/examples/packages/servers/apache.rb +15 -0
  18. data/examples/rails/README +15 -0
  19. data/examples/rails/deploy.rb +2 -0
  20. data/examples/rails/packages/database.rb +9 -0
  21. data/examples/rails/packages/essential.rb +9 -0
  22. data/examples/rails/packages/rails.rb +29 -0
  23. data/examples/rails/packages/scm.rb +11 -0
  24. data/examples/rails/packages/search.rb +11 -0
  25. data/examples/rails/packages/server.rb +28 -0
  26. data/examples/rails/rails.rb +73 -0
  27. data/examples/sprinkle/sprinkle.rb +38 -0
  28. data/lib/sprinkle/actors/actors.rb +17 -0
  29. data/lib/sprinkle/actors/capistrano.rb +140 -0
  30. data/lib/sprinkle/actors/local.rb +37 -0
  31. data/lib/sprinkle/actors/ssh.rb +123 -0
  32. data/lib/sprinkle/actors/vlad.rb +78 -0
  33. data/lib/sprinkle/configurable.rb +31 -0
  34. data/lib/sprinkle/deployment.rb +73 -0
  35. data/lib/sprinkle/extensions/arbitrary_options.rb +10 -0
  36. data/lib/sprinkle/extensions/array.rb +5 -0
  37. data/lib/sprinkle/extensions/blank_slate.rb +5 -0
  38. data/lib/sprinkle/extensions/dsl_accessor.rb +15 -0
  39. data/lib/sprinkle/extensions/string.rb +10 -0
  40. data/lib/sprinkle/extensions/symbol.rb +7 -0
  41. data/lib/sprinkle/installers/apt.rb +52 -0
  42. data/lib/sprinkle/installers/binary.rb +46 -0
  43. data/lib/sprinkle/installers/bsd_port.rb +33 -0
  44. data/lib/sprinkle/installers/deb.rb +38 -0
  45. data/lib/sprinkle/installers/freebsd_pkg.rb +37 -0
  46. data/lib/sprinkle/installers/freebsd_portinstall.rb +36 -0
  47. data/lib/sprinkle/installers/gem.rb +64 -0
  48. data/lib/sprinkle/installers/install_package.rb +79 -0
  49. data/lib/sprinkle/installers/installer.rb +120 -0
  50. data/lib/sprinkle/installers/mac_port.rb +38 -0
  51. data/lib/sprinkle/installers/noop.rb +20 -0
  52. data/lib/sprinkle/installers/openbsd_pkg.rb +47 -0
  53. data/lib/sprinkle/installers/opensolaris_pkg.rb +43 -0
  54. data/lib/sprinkle/installers/push_text.rb +45 -0
  55. data/lib/sprinkle/installers/rake.rb +37 -0
  56. data/lib/sprinkle/installers/rpm.rb +37 -0
  57. data/lib/sprinkle/installers/smart.rb +29 -0
  58. data/lib/sprinkle/installers/source.rb +190 -0
  59. data/lib/sprinkle/installers/transfer.rb +164 -0
  60. data/lib/sprinkle/installers/yum.rb +37 -0
  61. data/lib/sprinkle/package.rb +309 -0
  62. data/lib/sprinkle/policy.rb +125 -0
  63. data/lib/sprinkle/script.rb +23 -0
  64. data/lib/sprinkle/verifiers/directory.rb +16 -0
  65. data/lib/sprinkle/verifiers/executable.rb +53 -0
  66. data/lib/sprinkle/verifiers/file.rb +26 -0
  67. data/lib/sprinkle/verifiers/package.rb +26 -0
  68. data/lib/sprinkle/verifiers/process.rb +21 -0
  69. data/lib/sprinkle/verifiers/rpm.rb +21 -0
  70. data/lib/sprinkle/verifiers/ruby.rb +25 -0
  71. data/lib/sprinkle/verifiers/symlink.rb +30 -0
  72. data/lib/sprinkle/verify.rb +114 -0
  73. data/lib/sprinkle.rb +32 -0
  74. data/script/console +8 -0
  75. data/script/destroy +14 -0
  76. data/script/generate +14 -0
  77. data/spec/spec.opts +1 -0
  78. data/spec/spec_helper.rb +17 -0
  79. data/spec/sprinkle/actors/capistrano_spec.rb +265 -0
  80. data/spec/sprinkle/actors/local_spec.rb +29 -0
  81. data/spec/sprinkle/configurable_spec.rb +46 -0
  82. data/spec/sprinkle/deployment_spec.rb +80 -0
  83. data/spec/sprinkle/extensions/array_spec.rb +19 -0
  84. data/spec/sprinkle/extensions/string_spec.rb +21 -0
  85. data/spec/sprinkle/installers/apt_spec.rb +70 -0
  86. data/spec/sprinkle/installers/bsd_port_spec.rb +42 -0
  87. data/spec/sprinkle/installers/freebsd_pkg_spec.rb +49 -0
  88. data/spec/sprinkle/installers/freebsd_portinstall_spec.rb +42 -0
  89. data/spec/sprinkle/installers/gem_spec.rb +107 -0
  90. data/spec/sprinkle/installers/installer_spec.rb +151 -0
  91. data/spec/sprinkle/installers/mac_port_spec.rb +42 -0
  92. data/spec/sprinkle/installers/noop_spec.rb +23 -0
  93. data/spec/sprinkle/installers/openbsd_pkg_spec.rb +49 -0
  94. data/spec/sprinkle/installers/opensolaris_pkg_spec.rb +49 -0
  95. data/spec/sprinkle/installers/push_text_spec.rb +66 -0
  96. data/spec/sprinkle/installers/rake_spec.rb +29 -0
  97. data/spec/sprinkle/installers/rpm_spec.rb +50 -0
  98. data/spec/sprinkle/installers/source_spec.rb +371 -0
  99. data/spec/sprinkle/installers/transfer_spec.rb +98 -0
  100. data/spec/sprinkle/installers/yum_spec.rb +49 -0
  101. data/spec/sprinkle/package_spec.rb +466 -0
  102. data/spec/sprinkle/policy_spec.rb +126 -0
  103. data/spec/sprinkle/script_spec.rb +51 -0
  104. data/spec/sprinkle/sprinkle_spec.rb +25 -0
  105. data/spec/sprinkle/verify_spec.rb +174 -0
  106. metadata +244 -0
@@ -0,0 +1,98 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
+ require 'tempfile'
3
+
4
+ describe Sprinkle::Installers::Transfer do
5
+ include Sprinkle::Deployment
6
+
7
+ before do
8
+ @package = mock(Sprinkle::Package, :name => 'package')
9
+ @empty = Proc.new { }
10
+ @delivery = mock(Sprinkle::Deployment, :process => true)
11
+ @source = 'source'
12
+ @destination = 'destination'
13
+ @installer = create_transfer(@source, @destination)
14
+ @roles = []
15
+ @deployment = deployment do
16
+ delivery :capistrano
17
+ installer do; prefix '/usr/bin'; end
18
+ end
19
+ end
20
+
21
+ def create_transfer(source, dest, options={}, &block)
22
+ i = Sprinkle::Installers::Transfer.new(@package, source, dest, options, &block)
23
+ i.delivery = @delivery
24
+ i
25
+ end
26
+
27
+ describe 'when created' do
28
+ it 'should accept a source and destination to install' do
29
+ @installer.source.should == @source
30
+ @installer.destination.should == @destination
31
+ end
32
+ end
33
+
34
+ describe 'during installation' do
35
+ before do
36
+ @installer = create_transfer @source, @destination do
37
+ pre :install, 'op1'
38
+ post :install, 'op2'
39
+ end
40
+
41
+ @delivery = @installer.delivery
42
+ end
43
+
44
+ it "should call the pre and post install commands around the file transfer" do
45
+ @delivery.should_receive(:process).with(@package.name, 'op1', @roles).once.ordered.and_return
46
+ @delivery.should_receive(:transfer).ordered.and_return
47
+ @delivery.should_receive(:process).with(@package.name, 'op2', @roles).once.ordered.and_return
48
+ end
49
+
50
+ it "should call transfer with recursive defaulted to nil" do
51
+ @delivery.should_receive(:process).and_return
52
+ @delivery.should_receive(:transfer).with(@package.name, @source, @destination, @roles, nil)
53
+ end
54
+
55
+ after do
56
+ @installer.process @roles
57
+ end
58
+ end
59
+
60
+ describe "if the :render flag is true" do
61
+ before do
62
+ @installer = create_transfer @source, @destination, :render => true
63
+ @delivery = @installer.delivery
64
+ @delivery.stub!(:render_template_file)
65
+ end
66
+
67
+ it "should render the source file as a template to a tempfile" do
68
+ @tempfile = Tempfile.new("foo")
69
+ @installer.should_receive(:render_template_file).with(@source, anything, @package.name).and_return(@tempfile)
70
+ @delivery.stub!(:transfer)
71
+ end
72
+
73
+ it "should call transfer with recursive set to false" do
74
+ @tempfile = Tempfile.new("foo")
75
+ @installer.should_receive(:render_template_file).with(@source, anything, @package.name).and_return(@tempfile)
76
+ @delivery.should_receive(:transfer).with(@package.name, @tempfile.path, @destination, @roles, false).ordered.and_return
77
+ end
78
+
79
+ after do
80
+ @installer.process @roles
81
+ end
82
+ end
83
+
84
+ describe "if the :recursive flag is explicitly set to false" do
85
+ before do
86
+ @installer = create_transfer @source, @destination, :recursive => false
87
+ end
88
+
89
+ it "should call transfer with recursive set to false" do
90
+ delivery = @installer.delivery
91
+ delivery.should_receive(:transfer).with(@package.name, @source, @destination, @roles, false).ordered.and_return
92
+ end
93
+
94
+ after do
95
+ @installer.process @roles
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,49 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
+
3
+ describe Sprinkle::Installers::Yum do
4
+
5
+ before do
6
+ @package = mock(Sprinkle::Package, :name => 'package')
7
+ end
8
+
9
+ def create_rpm(rpms, &block)
10
+ Sprinkle::Installers::Yum.new(@package, rpms, &block)
11
+ end
12
+
13
+ describe 'when created' do
14
+
15
+ it 'should accept a single package to install' do
16
+ @installer = create_rpm 'ruby'
17
+ @installer.packages.should == [ 'ruby' ]
18
+ end
19
+
20
+ it 'should accept an array of packages to install' do
21
+ @installer = create_rpm %w( gcc gdb g++ )
22
+ @installer.packages.should == ['gcc', 'gdb', 'g++']
23
+ end
24
+
25
+ end
26
+
27
+ describe 'during installation' do
28
+
29
+ before do
30
+ @installer = create_rpm 'ruby' do
31
+ pre :install, 'op1'
32
+ post :install, 'op2'
33
+ end
34
+ @install_commands = @installer.send :install_commands
35
+ end
36
+
37
+ it 'should invoke the rpm installer for all specified packages' do
38
+ @install_commands.should =~ /yum install ruby -y/
39
+ end
40
+
41
+ it 'should automatically insert pre/post commands for the specified package' do
42
+ @installer.send(:install_sequence).should == [ 'op1', 'yum install ruby -y', 'op2' ]
43
+ end
44
+
45
+ it 'should install a specific version if defined'
46
+
47
+ end
48
+
49
+ end
@@ -0,0 +1,466 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ describe Sprinkle::Package do
4
+ include Sprinkle::Package
5
+
6
+ before do
7
+ @name = :package_name
8
+ @empty = Proc.new { }
9
+ @opts = { }
10
+ end
11
+
12
+ # Kind of a messy way to do this but it works and DRYs out
13
+ # the specs. Checks to make sure an installer is receiving
14
+ # the block passed to it throught the package block.
15
+ def check_block_forwarding_on(installer)
16
+ eval(<<CODE)
17
+ pre_count = 0
18
+ lambda {
19
+ pkg = package @name do
20
+ #{installer} 'archive' do
21
+ pre :install, 'preOp'
22
+ end
23
+ end
24
+
25
+ pre_count = pkg.installers.first.instance_variable_get(:@pre)[:install].length
26
+ }.should change { pre_count }.by(1)
27
+ CODE
28
+ end
29
+
30
+ # More of Mitchell's meta-programming to dry up specs.
31
+ def create_package_with_blank_verify(n = 1)
32
+ eval(<<CODE)
33
+ @pkg = package @name do
34
+ gem 'gem'
35
+ #{"verify 'stuff happens' do; end\n" * n}
36
+ end
37
+ CODE
38
+ end
39
+
40
+ describe 'when created' do
41
+
42
+ it 'should be invalid without a block descriptor' do
43
+ lambda { package @name }.should raise_error
44
+ end
45
+
46
+ it 'should be invalid without a name' do
47
+ lambda { package nil, &@empty }.should raise_error
48
+ lambda { package @name, &@empty }.should_not raise_error
49
+ end
50
+
51
+ it 'should optionally accept a description' do
52
+ pkg = package @name do
53
+ description 'my package description'
54
+ end
55
+ pkg.description.should == 'my package description'
56
+ end
57
+
58
+ it 'should optionally accept a version' do
59
+ pkg = package @name do
60
+ version '2.0.2'
61
+ end
62
+ pkg.version.should == '2.0.2'
63
+ end
64
+
65
+ it 'should optionally accept an installer' do
66
+ pkg = package @name do
67
+ gem 'rails'
68
+ end
69
+ pkg.installers.should_not be_empty
70
+ end
71
+
72
+ it 'should optionally accept dependencies' do
73
+ pkg = package @name do
74
+ requires :webserver, :database
75
+ end
76
+ pkg.dependencies.should == [:webserver, :database]
77
+ end
78
+
79
+ it 'should optionally accept recommended dependencies' do
80
+ pkg = package @name do
81
+ recommends :webserver, :database
82
+ end
83
+ pkg.recommends.should == [:webserver, :database]
84
+ end
85
+
86
+ it 'should optionally accept optional dependencies' do
87
+ pkg = package @name do
88
+ optional :webserver_configuration, :database_configuration
89
+ end
90
+ pkg.optional.should == [:webserver_configuration, :database_configuration]
91
+ end
92
+
93
+ it 'should optionally define a virtual package implementation' do
94
+ pkg = package @name, :provides => :database do; end
95
+ pkg.provides.should == :database
96
+ end
97
+
98
+ it 'should be able to represent itself as a string' do
99
+ pkg = package @name do; end
100
+ pkg.to_s.should == @name
101
+ end
102
+
103
+ end
104
+
105
+ describe 'helper method' do
106
+
107
+ it 'should added new packages to the global package hash' do
108
+ pkg = package @name do; end
109
+ Sprinkle::Package::PACKAGES[@name].should == pkg
110
+ end
111
+
112
+ it 'should add the new package to the provides list if specified' do
113
+ pkg = package @name, :provides => :database do; end
114
+ Sprinkle::Package::PACKAGES[:database].last.should == pkg
115
+ end
116
+
117
+ end
118
+
119
+ describe 'installer configuration' do
120
+
121
+ it 'should optionally accept an apt installer' do
122
+ pkg = package @name do
123
+ apt %w( deb1 deb2 )
124
+ end
125
+ pkg.should respond_to(:apt)
126
+ pkg.installers.first.class.should == Sprinkle::Installers::Apt
127
+ end
128
+
129
+ it 'should optionally accept an rpm installer' do
130
+ pkg = package @name do
131
+ rpm %w( rpm1 rpm2 )
132
+ end
133
+ pkg.should respond_to(:rpm)
134
+ pkg.installers.first.class.should == Sprinkle::Installers::Rpm
135
+ end
136
+
137
+ it 'should optionally accept a gem installer' do
138
+ pkg = package @name do
139
+ gem 'gem'
140
+ end
141
+ pkg.should respond_to(:gem)
142
+ pkg.installers.first.class.should == Sprinkle::Installers::Gem
143
+ end
144
+
145
+ it 'should optionally accept a source installer' do
146
+ pkg = package @name do
147
+ source 'archive'
148
+ end
149
+ pkg.should respond_to(:source)
150
+ pkg.installers.first.class.should == Sprinkle::Installers::Source
151
+ end
152
+
153
+ it 'should allow multiple installer steps to be defined and respect order' do
154
+ pkg = package @name do
155
+ source 'archive'
156
+ gem 'momoney'
157
+ end
158
+
159
+ pkg.installers.length.should == 2
160
+ pkg.installers[0].class.should == Sprinkle::Installers::Source
161
+ pkg.installers[1].class.should == Sprinkle::Installers::Gem
162
+ end
163
+ end
164
+
165
+ describe 'with a source installer' do
166
+
167
+ it 'should optionally accept a block containing customisations' do
168
+ pkg = package @name do
169
+ source 'archive' do; end
170
+ end
171
+ pkg.should respond_to(:source)
172
+ pkg.installers.first.class.should == Sprinkle::Installers::Source
173
+ end
174
+
175
+ it 'should forward block to installer superclass' do
176
+ check_block_forwarding_on(:source)
177
+ end
178
+
179
+ it 'should automatically add a build essential recommendation' do
180
+ pkg = package @name do
181
+ source 'archive'
182
+ end
183
+ pkg.recommends.should include(:build_essential)
184
+ end
185
+
186
+ end
187
+
188
+ describe 'with an apt installer' do
189
+ it 'should forward block to installer superclass' do
190
+ check_block_forwarding_on(:apt)
191
+ end
192
+ end
193
+
194
+ describe 'with an rpm installer' do
195
+ it 'should forward block to installer superclass' do
196
+ check_block_forwarding_on(:rpm)
197
+ end
198
+ end
199
+
200
+ describe 'with an gem installer' do
201
+
202
+ it 'should automatically add a rubygems recommendation' do
203
+ pkg = package @name do
204
+ gem 'gem'
205
+ end
206
+ pkg.recommends.should include(:rubygems)
207
+ end
208
+
209
+ it 'should forward block to installer superclass' do
210
+ check_block_forwarding_on(:gem)
211
+ end
212
+
213
+ end
214
+
215
+ describe 'when processing' do
216
+
217
+ before do
218
+ @deployment = mock(Sprinkle::Deployment)
219
+ @roles = [ :app, :db ]
220
+ @installer = mock(Sprinkle::Installers::Installer, :defaults => true, :process => true)
221
+ @package = package @name do; end
222
+ end
223
+
224
+ describe 'with an installer' do
225
+
226
+ before do
227
+ @package.installers = [ @installer ]
228
+ end
229
+
230
+ it 'should configure itself against the deployment context' do
231
+ @installer.should_receive(:defaults).with(@deployment).and_return
232
+ end
233
+
234
+ it 'should request the installer to process itself' do
235
+ @installer.should_receive(:process).with(@roles).and_return
236
+ end
237
+
238
+ after do
239
+ @package.process(@deployment, @roles)
240
+ end
241
+ end
242
+
243
+ describe 'without an installer' do
244
+
245
+ it 'should not request the installer to process if the package is a metapackage' do
246
+ @installer.should_not_receive(:process)
247
+ @package.process(@deployment, @roles)
248
+ end
249
+
250
+ end
251
+
252
+ describe 'with verifications' do
253
+ before do
254
+ @pkg = create_package_with_blank_verify(3)
255
+ @pkg.installers = [ @installer ]
256
+ @installer.stub!(:defaults)
257
+ @installer.stub!(:process)
258
+ end
259
+
260
+ describe 'with forcing' do
261
+ before do
262
+ # Being explicit
263
+ Sprinkle::OPTIONS[:force] = true
264
+ end
265
+
266
+ it 'should process verifications only once' do
267
+ @pkg.should_receive(:process_verifications).once
268
+ @pkg.process(@deployment, @roles)
269
+ end
270
+
271
+ after do
272
+ # Being explicit
273
+ Sprinkle::OPTIONS[:force] = false
274
+ end
275
+ end
276
+
277
+ describe 'without forcing' do
278
+ before do
279
+ # Being explicit
280
+ Sprinkle::OPTIONS[:force] = false
281
+ end
282
+
283
+ it 'should process verifications twice' do
284
+ @pkg.should_receive(:process_verifications).once.with(@deployment, @roles, true).and_raise(Sprinkle::VerificationFailed.new(@pkg, ''))
285
+ @pkg.should_receive(:process_verifications).once.with(@deployment, @roles).and_raise(Sprinkle::VerificationFailed.new(@pkg, ''))
286
+ end
287
+
288
+ it 'should continue with installation if pre-verification fails' do
289
+ @pkg.should_receive(:process_verifications).twice.and_raise(Sprinkle::VerificationFailed.new(@pkg, ''))
290
+ @installer.should_receive(:defaults)
291
+ @installer.should_receive(:process)
292
+ end
293
+
294
+ it 'should only process verifications once and should not process installer if verifications succeed' do
295
+ @pkg.should_receive(:process_verifications).once.and_return(nil)
296
+ @installer.should_not_receive(:defaults)
297
+ @installer.should_not_receive(:process)
298
+ end
299
+
300
+ after do
301
+ begin
302
+ @pkg.process(@deployment, @roles)
303
+ rescue Sprinkle::VerificationFailed => e; end
304
+ end
305
+ end
306
+ end
307
+
308
+ end
309
+
310
+ describe 'when processing verifications' do
311
+ before do
312
+ @deployment = mock(Sprinkle::Deployment)
313
+ @roles = [ :app, :db ]
314
+ @installer = mock(Sprinkle::Installers::Installer, :defaults => true, :process => true)
315
+ @pkg = create_package_with_blank_verify(3)
316
+ @pkg.installers = [ @installer ]
317
+ @installer.stub!(:defaults)
318
+ @installer.stub!(:process)
319
+ @logger = mock(ActiveSupport::BufferedLogger, :debug => true, :debug? => true)
320
+ @logger.stub!(:info)
321
+ end
322
+
323
+ it 'should request _each_ verification to configure itself against the deployment context' do
324
+ @pkg.verifications.each do |v|
325
+ v.should_receive(:defaults).with(@deployment).once
326
+ v.stub!(:process)
327
+ end
328
+ end
329
+
330
+ it 'should request _each_ verification to process' do
331
+ @pkg.verifications.each do |v|
332
+ v.stub!(:defaults)
333
+ v.should_receive(:process).with(@roles).once
334
+ end
335
+ end
336
+
337
+ it 'should enter a log info event to notify user whats happening' do
338
+ @pkg.verifications.each do |v|
339
+ v.stub!(:defaults)
340
+ v.stub!(:process)
341
+ end
342
+
343
+ @pkg.should_receive(:logger).once.and_return(@logger)
344
+ end
345
+
346
+ after do
347
+ @pkg.process_verifications(@deployment, @roles)
348
+ end
349
+ end
350
+
351
+ describe 'hierarchies' do
352
+
353
+ before do
354
+ @a = package :a do; requires :b; end
355
+ @b = package :b do; requires :c; end
356
+ @c = package :c do; recommends :d; end
357
+ @d = package :d do; end
358
+ @e = package :e do; optional :d; end
359
+ end
360
+
361
+ it 'should be able to return a dependency hierarchy tree' do
362
+ @a.tree.flatten.should == [ @d, @c, @b, @a ]
363
+ @b.tree.flatten.should == [ @d, @c, @b ]
364
+ @c.tree.flatten.should == [ @d, @c ]
365
+ @d.tree.flatten.should == [ @d ]
366
+ @e.tree.flatten.should == [ @e, @d ]
367
+ end
368
+
369
+ describe 'with missing recommendations' do
370
+
371
+ before do
372
+ @d.recommends :z
373
+ end
374
+
375
+ it 'should ignore missing recommendations' do
376
+ @d.tree.flatten.should == [ @d ]
377
+ end
378
+
379
+ end
380
+
381
+ describe 'with missing optional packages' do
382
+
383
+ before do
384
+ @d.optional :z
385
+ end
386
+
387
+ it 'should ignore missing recommendations' do
388
+ @d.tree.flatten.should == [ @d ]
389
+ end
390
+
391
+ end
392
+
393
+ it 'should optionally accept a block to call upon item in the tree during hierarchy traversal' do
394
+ @count = 0
395
+ @a.tree do
396
+ @count += 1
397
+ end
398
+ @count.should == 3
399
+ end
400
+
401
+ it 'should maintain a depth count of how deep the hierarchy is' do
402
+ @b.should_receive(:tree).with(2).and_return([@b])
403
+ @a.tree do; end
404
+ end
405
+
406
+ end
407
+
408
+ describe 'virtual package dependencies' do
409
+ before do
410
+ @a = package :a do; requires :virtual ; end
411
+ @v1 = package :v1, :provides => :virtual do; end
412
+ @v2 = package :v2, :provides => :virtual do; end
413
+ end
414
+
415
+ it 'should select package for an array' do
416
+ @a.should_receive(:select_package).with(:virtual, [@v1,@v2]).and_return(@v1)
417
+ @a.tree do; end
418
+ end
419
+ end
420
+
421
+ describe 'with missing dependencies' do
422
+
423
+ before do
424
+ @pkg = package @name do
425
+ gem 'gem'
426
+ requires :missing
427
+ end
428
+ end
429
+
430
+ it 'should raise an error if a package is missing' do
431
+ lambda { @pkg.tree }.should raise_error
432
+ end
433
+
434
+ end
435
+
436
+ describe 'with verifications' do
437
+ it 'should create a Sprinkle::Verification object for the verify block' do
438
+ Sprinkle::Verify.should_receive(:new).once
439
+
440
+ create_package_with_blank_verify
441
+ end
442
+
443
+ it 'should create multiple Sprinkle::Verification objects for multiple verify blocks' do
444
+ Sprinkle::Verify.should_receive(:new).twice
445
+
446
+ create_package_with_blank_verify(2)
447
+ end
448
+
449
+ it 'should add each Sprinkle::Verificaton object to the @verifications array' do
450
+ @pkg = create_package_with_blank_verify(3)
451
+ @pkg.verifications.length.should eql(3)
452
+ end
453
+
454
+ it 'should initialize Sprinkle::Verification with the package name, description, and block' do
455
+ Sprinkle::Verify.should_receive(:new) do |pkg, desc|
456
+ pkg.name.should eql(@name)
457
+ desc.should eql('stuff happens')
458
+ end
459
+
460
+ # We do a should_not raise_error because if a block was NOT passed, an error
461
+ # is raised. This is specced in verification_spec.rb
462
+ lambda { create_package_with_blank_verify }.should_not raise_error
463
+ end
464
+ end
465
+
466
+ end