warbler 1.2.1 → 1.3.0.beta1

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 (65) hide show
  1. data/Gemfile +8 -5
  2. data/History.txt +5 -0
  3. data/Manifest.txt +43 -23
  4. data/README.txt +67 -26
  5. data/Rakefile +17 -6
  6. data/ext/JarMain.java +147 -0
  7. data/ext/{Main.java → WarMain.java} +4 -4
  8. data/ext/{WarblerWar.java → WarblerJar.java} +79 -13
  9. data/ext/{WarblerWarService.java → WarblerJarService.java} +2 -2
  10. data/lib/warbler/application.rb +9 -9
  11. data/lib/warbler/config.rb +58 -204
  12. data/lib/warbler/gems.rb +2 -2
  13. data/lib/warbler/jar.rb +247 -0
  14. data/lib/warbler/task.rb +28 -60
  15. data/lib/warbler/templates/config.erb +1 -1
  16. data/lib/warbler/templates/rack.erb +1 -1
  17. data/lib/warbler/templates/rails.erb +1 -1
  18. data/lib/warbler/traits/bundler.rb +58 -0
  19. data/lib/warbler/traits/gemspec.rb +64 -0
  20. data/lib/warbler/traits/jar.rb +53 -0
  21. data/lib/warbler/traits/merb.rb +34 -0
  22. data/lib/warbler/traits/nogemspec.rb +41 -0
  23. data/lib/warbler/traits/rack.rb +31 -0
  24. data/lib/warbler/traits/rails.rb +57 -0
  25. data/lib/warbler/traits/war.rb +191 -0
  26. data/lib/warbler/traits.rb +105 -0
  27. data/lib/warbler/version.rb +1 -1
  28. data/lib/warbler/war.rb +1 -247
  29. data/lib/warbler.rb +2 -5
  30. data/lib/warbler_jar.jar +0 -0
  31. data/spec/sample_jar/History.txt +6 -0
  32. data/spec/sample_jar/Manifest.txt +8 -0
  33. data/spec/sample_jar/README.txt +30 -0
  34. data/spec/sample_jar/lib/sample_jar.rb +6 -0
  35. data/spec/sample_jar/sample_jar.gemspec +41 -0
  36. data/spec/sample_jar/test/test_sample_jar.rb +8 -0
  37. data/spec/{sample → sample_war}/app/controllers/application.rb +0 -0
  38. data/spec/{sample → sample_war}/app/helpers/application_helper.rb +0 -0
  39. data/spec/{sample → sample_war}/config/boot.rb +0 -0
  40. data/spec/{sample → sample_war}/config/database.yml +0 -0
  41. data/spec/{sample → sample_war}/config/environment.rb +0 -0
  42. data/spec/{sample → sample_war}/config/environments/development.rb +0 -0
  43. data/spec/{sample → sample_war}/config/environments/production.rb +0 -0
  44. data/spec/{sample → sample_war}/config/environments/test.rb +0 -0
  45. data/spec/{sample → sample_war}/config/initializers/inflections.rb +0 -0
  46. data/spec/{sample → sample_war}/config/initializers/mime_types.rb +0 -0
  47. data/spec/{sample → sample_war}/config/initializers/new_rails_defaults.rb +0 -0
  48. data/spec/{sample → sample_war}/config/routes.rb +0 -0
  49. data/spec/{sample → sample_war}/lib/tasks/utils.rake +0 -0
  50. data/spec/{sample → sample_war}/public/404.html +0 -0
  51. data/spec/{sample → sample_war}/public/422.html +0 -0
  52. data/spec/{sample → sample_war}/public/500.html +0 -0
  53. data/spec/{sample → sample_war}/public/favicon.ico +0 -0
  54. data/spec/{sample → sample_war}/public/index.html +0 -0
  55. data/spec/{sample → sample_war}/public/robots.txt +0 -0
  56. data/spec/spec_helper.rb +40 -0
  57. data/spec/warbler/application_spec.rb +2 -9
  58. data/spec/warbler/config_spec.rb +101 -83
  59. data/spec/warbler/jar_spec.rb +763 -0
  60. data/spec/warbler/task_spec.rb +56 -41
  61. data/spec/warbler/traits_spec.rb +16 -0
  62. data/spec/warbler/war_spec.rb +2 -492
  63. data/warble.rb +36 -32
  64. metadata +57 -35
  65. data/lib/warbler_war.jar +0 -0
@@ -0,0 +1,763 @@
1
+ #--
2
+ # Copyright (c) 2010 Engine Yard, Inc.
3
+ # This source code is available under the MIT license.
4
+ # See the file LICENSE.txt for details.
5
+ #++
6
+
7
+ require File.dirname(__FILE__) + '/../spec_helper'
8
+
9
+ describe Warbler::Jar do
10
+ use_fresh_rake_application
11
+ use_fresh_environment
12
+
13
+ def file_list(regex)
14
+ jar.files.keys.select {|f| f =~ regex }
15
+ end
16
+
17
+ def use_config(&block)
18
+ @extra_config = block
19
+ end
20
+
21
+ def apply_extra_config(config)
22
+ @extra_config.call(config) if @extra_config
23
+ end
24
+
25
+ let(:config) { Warbler::Config.new {|c| apply_extra_config(c) } }
26
+ let(:jar) { Warbler::Jar.new }
27
+
28
+ context "in a jar project" do
29
+ run_in_directory "spec/sample_jar"
30
+ cleanup_temp_files
31
+
32
+ it "detects a Jar trait" do
33
+ config.traits.should include(Warbler::Traits::Jar)
34
+ end
35
+
36
+ it "collects java libraries" do
37
+ jar.apply(config)
38
+ file_list(%r{^META-INF/lib/jruby-.*\.jar$}).should_not be_empty
39
+ end
40
+
41
+ it "adds a JarMain class" do
42
+ jar.apply(config)
43
+ file_list(%r{^JarMain\.class$}).should_not be_empty
44
+ end
45
+
46
+ it "adds an init.rb" do
47
+ jar.apply(config)
48
+ file_list(%r{^META-INF/init.rb$}).should_not be_empty
49
+ end
50
+
51
+ it "requires 'rubygems' in init.rb" do
52
+ jar.add_init_file(config)
53
+ contents = jar.files['META-INF/init.rb'].read
54
+ contents.split("\n").grep(/require 'rubygems'/).should_not be_empty
55
+ end
56
+
57
+ it "adds a main.rb" do
58
+ jar.apply(config)
59
+ file_list(%r{^META-INF/main.rb$}).should_not be_empty
60
+ end
61
+
62
+ it "accepts a custom manifest file" do
63
+ touch 'manifest'
64
+ use_config do |config|
65
+ config.manifest_file = 'manifest'
66
+ end
67
+ jar.apply(config)
68
+ jar.files['META-INF/MANIFEST.MF'].should == "manifest"
69
+ end
70
+
71
+ it "accepts a MANIFEST.MF file if it exists in the project root" do
72
+ touch 'MANIFEST.MF'
73
+ jar.apply(config)
74
+ jar.files['META-INF/MANIFEST.MF'].should == "MANIFEST.MF"
75
+ end
76
+
77
+ it "does not add a manifest if one already exists" do
78
+ jar.files['META-INF/MANIFEST.MF'] = 'manifest'
79
+ jar.add_manifest(config)
80
+ jar.files['META-INF/MANIFEST.MF'].should == "manifest"
81
+ end
82
+
83
+ context "with a .gemspec" do
84
+ it "detects a Gemspec trait" do
85
+ config.traits.should include(Warbler::Traits::Gemspec)
86
+ end
87
+
88
+ it "detects gem dependencies" do
89
+ jar.apply(config)
90
+ file_list(%r{^gems/rubyzip.*/lib/zip/zip.rb}).should_not be_empty
91
+ file_list(%r{^specifications/rubyzip.*\.gemspec}).should_not be_empty
92
+ end
93
+
94
+ it "sets files to be stored in the archive from the spec" do
95
+ touch "extra.foobar"
96
+ jar.apply(config)
97
+ file_list(%r{^sample_jar/History\.txt$}).should_not be_empty
98
+ file_list(%r{^sample_jar/lib/sample_jar\.rb$}).should_not be_empty
99
+ file_list(%r{^sample_jar/extra\.foobar$}).should be_empty
100
+ end
101
+
102
+ it "sets load paths in init.rb" do
103
+ jar.add_init_file(config)
104
+ contents = jar.files['META-INF/init.rb'].read
105
+ contents.split("\n").grep(/LOAD_PATH\.unshift.*sample_jar\/lib/).should_not be_empty
106
+ end
107
+
108
+ it "loads the default executable in main.rb" do
109
+ jar.apply(config)
110
+ contents = jar.files['META-INF/main.rb'].read
111
+ contents.split("\n").grep(/load.*sample_jar\/bin\/sample_jar/).should_not be_empty
112
+ end
113
+
114
+ it "includes compiled .rb and .class files" do
115
+ config.compiled_ruby_files = %w(lib/sample_jar.rb)
116
+ jar.compile(config)
117
+ jar.apply(config)
118
+ file_list(%r{^sample_jar/lib/sample_jar\.class$}).should_not be_empty
119
+ jar.files['sample_jar/lib/sample_jar.rb'].read.should =~ /require __FILE__\.sub/
120
+ end
121
+
122
+ context "and a missing file" do
123
+ before :each do
124
+ mv "Rakefile", "Rakefile.tmp"
125
+ end
126
+
127
+ after :each do
128
+ mv "Rakefile.tmp", "Rakefile"
129
+ end
130
+
131
+ it "should warn about the missing file but still continue" do
132
+ capture { jar.apply(config) }.should =~ /Rakefile/
133
+ end
134
+ end
135
+ end
136
+
137
+ context "with a gemspec without a default executable" do
138
+ before :each do
139
+ Dir['*.gemspec'].each do |f|
140
+ cp f, "#{f}.tmp"
141
+ lines = IO.readlines(f)
142
+ File.open(f, 'w') do |io|
143
+ lines.each do |line|
144
+ next if line =~ /executable/
145
+ io << line
146
+ end
147
+ end
148
+ end
149
+ end
150
+
151
+ after :each do
152
+ Dir['*.gemspec.tmp'].each {|f| mv f, "#{f.sub /\.tmp$/, ''}"}
153
+ end
154
+
155
+ it "loads the first bin/executable in main.rb" do
156
+ silence { jar.apply(config) }
157
+ contents = jar.files['META-INF/main.rb'].read
158
+ contents.split("\n").grep(/load.*sample_jar\/bin\/sample_jar/).should_not be_empty
159
+ end
160
+ end
161
+
162
+ context "without a .gemspec" do
163
+ before :each do
164
+ Dir['*.gemspec'].each {|f| mv f, "#{f}.tmp"}
165
+ end
166
+
167
+ after :each do
168
+ Dir['*.gemspec.tmp'].each {|f| mv f, "#{f.sub /\.tmp$/, ''}"}
169
+ end
170
+
171
+ it "detects a NoGemspec trait" do
172
+ config.traits.should include(Warbler::Traits::NoGemspec)
173
+ end
174
+
175
+ it "collects gem files from configuration" do
176
+ use_config do |config|
177
+ config.gems << "rake"
178
+ end
179
+ jar.apply(config)
180
+ file_list(%r{^gems/rake.*/lib/rake.rb}).should_not be_empty
181
+ file_list(%r{^specifications/rake.*\.gemspec}).should_not be_empty
182
+ end
183
+
184
+ it "collects all project files in the directory" do
185
+ touch "extra.foobar"
186
+ jar.apply(config)
187
+ file_list(%r{^sample_jar/bin$}).should_not be_empty
188
+ file_list(%r{^sample_jar/test$}).should_not be_empty
189
+ file_list(%r{^sample_jar/lib/sample_jar.rb$}).should_not be_empty
190
+ file_list(%r{^sample_jar/extra\.foobar$}).should_not be_empty
191
+ end
192
+
193
+ it "sets load paths in init.rb" do
194
+ jar.add_init_file(config)
195
+ contents = jar.files['META-INF/init.rb'].read
196
+ contents.split("\n").grep(/LOAD_PATH\.unshift.*sample_jar\/lib/).should_not be_empty
197
+ end
198
+
199
+ it "loads the first bin/executable in main.rb" do
200
+ jar.apply(config)
201
+ contents = jar.files['META-INF/main.rb'].read
202
+ contents.split("\n").grep(/load.*sample_jar\/bin\/sample_jar/).should_not be_empty
203
+ end
204
+ end
205
+ end
206
+
207
+ context "in a war project" do
208
+ run_in_directory "spec/sample_war"
209
+ cleanup_temp_files
210
+
211
+ before(:each) do
212
+ mkdir_p "log"
213
+ touch "log/test.log"
214
+ end
215
+
216
+ it "detects a War trait" do
217
+ config.traits.should include(Warbler::Traits::War)
218
+ end
219
+
220
+ it "collects files in public" do
221
+ jar.apply(config)
222
+ file_list(%r{^index\.html}).should_not be_empty
223
+ end
224
+
225
+ it "collects gem files" do
226
+ use_config do |config|
227
+ config.gems << "rake"
228
+ end
229
+ jar.apply(config)
230
+ file_list(%r{WEB-INF/gems/gems/rake.*/lib/rake.rb}).should_not be_empty
231
+ file_list(%r{WEB-INF/gems/specifications/rake.*\.gemspec}).should_not be_empty
232
+ end
233
+
234
+ it "does not include log files by default" do
235
+ jar.apply(config)
236
+ file_list(%r{WEB-INF/log}).should_not be_empty
237
+ file_list(%r{WEB-INF/log/.*\.log}).should be_empty
238
+ end
239
+
240
+ def expand_webxml
241
+ jar.apply(config)
242
+ jar.files.should include("WEB-INF/web.xml")
243
+ require 'rexml/document'
244
+ REXML::Document.new(jar.files["WEB-INF/web.xml"]).root.elements
245
+ end
246
+
247
+ it "creates a web.xml file" do
248
+ use_config do |config|
249
+ config.webxml.jruby.max.runtimes = 5
250
+ end
251
+ elements = expand_webxml
252
+ elements.to_a(
253
+ "context-param/param-name[text()='jruby.max.runtimes']"
254
+ ).should_not be_empty
255
+ elements.to_a(
256
+ "context-param/param-name[text()='jruby.max.runtimes']/../param-value"
257
+ ).first.text.should == "5"
258
+ end
259
+
260
+ it "includes custom context parameters in web.xml" do
261
+ use_config do |config|
262
+ config.webxml.some.custom.config = "myconfig"
263
+ end
264
+ elements = expand_webxml
265
+ elements.to_a(
266
+ "context-param/param-name[text()='some.custom.config']"
267
+ ).should_not be_empty
268
+ elements.to_a(
269
+ "context-param/param-name[text()='some.custom.config']/../param-value"
270
+ ).first.text.should == "myconfig"
271
+ end
272
+
273
+ it "allows one jndi resource to be included" do
274
+ use_config do |config|
275
+ config.webxml.jndi = 'jndi/rails'
276
+ end
277
+ elements = expand_webxml
278
+ elements.to_a(
279
+ "resource-ref/res-ref-name[text()='jndi/rails']"
280
+ ).should_not be_empty
281
+ end
282
+
283
+ it "allows multiple jndi resources to be included" do
284
+ use_config do |config|
285
+ config.webxml.jndi = ['jndi/rails1', 'jndi/rails2']
286
+ end
287
+ elements = expand_webxml
288
+ elements.to_a(
289
+ "resource-ref/res-ref-name[text()='jndi/rails1']"
290
+ ).should_not be_empty
291
+ elements.to_a(
292
+ "resource-ref/res-ref-name[text()='jndi/rails2']"
293
+ ).should_not be_empty
294
+ end
295
+
296
+ it "does not include any ignored context parameters" do
297
+ use_config do |config|
298
+ config.webxml.foo = "bar"
299
+ config.webxml.ignored << "foo"
300
+ end
301
+ elements = expand_webxml
302
+ elements.to_a(
303
+ "context-param/param-name[text()='foo']"
304
+ ).should be_empty
305
+ elements.to_a(
306
+ "context-param/param-name[text()='ignored']"
307
+ ).should be_empty
308
+ elements.to_a(
309
+ "context-param/param-name[text()='jndi']"
310
+ ).should be_empty
311
+ end
312
+
313
+ it "uses a config/web.xml if it exists" do
314
+ mkdir_p "config"
315
+ touch "config/web.xml"
316
+ jar.apply(config)
317
+ jar.files["WEB-INF/web.xml"].should == "config/web.xml"
318
+ end
319
+
320
+ it "uses a config/web.xml.erb if it exists" do
321
+ mkdir_p "config"
322
+ File.open("config/web.xml.erb", "w") {|f| f << "Hi <%= webxml.public.root %>" }
323
+ jar.apply(config)
324
+ jar.files["WEB-INF/web.xml"].should_not be_nil
325
+ jar.files["WEB-INF/web.xml"].read.should == "Hi /"
326
+ end
327
+
328
+ it "collects java libraries" do
329
+ jar.apply(config)
330
+ file_list(%r{WEB-INF/lib/jruby-.*\.jar$}).should_not be_empty
331
+ end
332
+
333
+ it "collects application files" do
334
+ jar.apply(config)
335
+ file_list(%r{WEB-INF/app$}).should_not be_empty
336
+ file_list(%r{WEB-INF/config$}).should_not be_empty
337
+ file_list(%r{WEB-INF/lib$}).should_not be_empty
338
+ end
339
+
340
+ it "accepts an autodeploy directory where the war should be created" do
341
+ require 'tmpdir'
342
+ use_config do |config|
343
+ config.jar_name = 'warbler'
344
+ config.autodeploy_dir = Dir::tmpdir
345
+ end
346
+ touch "file.txt"
347
+ jar.files["file.txt"] = "file.txt"
348
+ silence { jar.create(config) }
349
+ File.exist?(File.join("#{Dir::tmpdir}","warbler.war")).should == true
350
+ end
351
+
352
+ it "allows the jar extension to be customized" do
353
+ use_config do |config|
354
+ config.jar_name = 'warbler'
355
+ config.jar_extension = 'foobar'
356
+ end
357
+ touch "file.txt"
358
+ jar.files["file.txt"] = "file.txt"
359
+ silence { jar.create(config) }
360
+ File.exist?("warbler.foobar").should == true
361
+ end
362
+
363
+ it "can exclude files from the .war" do
364
+ use_config do |config|
365
+ config.excludes += FileList['lib/tasks/utils.rake']
366
+ end
367
+ jar.apply(config)
368
+ file_list(%r{lib/tasks/utils.rake}).should be_empty
369
+ end
370
+
371
+ it "reads configuration from #{Warbler::Config::FILE}" do
372
+ mkdir_p "config"
373
+ File.open(Warbler::Config::FILE, "w") do |dest|
374
+ contents =
375
+ File.open("#{Warbler::WARBLER_HOME}/warble.rb") do |src|
376
+ src.read
377
+ end
378
+ dest << contents.sub(/# config\.jar_name/, 'config.jar_name'
379
+ ).sub(/# config.gems << "tzinfo"/, 'config.gems = []')
380
+ end
381
+ t = Warbler::Task.new "warble"
382
+ t.config.jar_name.should == "mywar"
383
+ end
384
+
385
+ it "fails if a gem is requested that is not installed" do
386
+ use_config do |config|
387
+ config.gems = ["nonexistent-gem"]
388
+ end
389
+ lambda {
390
+ Warbler::Task.new "warble", config
391
+ jar.apply(config)
392
+ }.should raise_error
393
+ end
394
+
395
+ it "allows specification of dependency by Gem::Dependency" do
396
+ spec = mock "gem spec"
397
+ spec.stub!(:full_name).and_return "hpricot-0.6.157"
398
+ spec.stub!(:full_gem_path).and_return "hpricot-0.6.157"
399
+ spec.stub!(:loaded_from).and_return "hpricot.gemspec"
400
+ spec.stub!(:files).and_return ["Rakefile"]
401
+ spec.stub!(:dependencies).and_return []
402
+ Gem.source_index.should_receive(:search).and_return do |gem|
403
+ gem.name.should == "hpricot"
404
+ [spec]
405
+ end
406
+ use_config do |config|
407
+ config.gems = [Gem::Dependency.new("hpricot", "> 0.6")]
408
+ end
409
+ jar.apply(config)
410
+ end
411
+
412
+ it "copies loose java classes to WEB-INF/classes" do
413
+ use_config do |config|
414
+ config.java_classes = FileList["Rakefile"]
415
+ end
416
+ jar.apply(config)
417
+ file_list(%r{WEB-INF/classes/Rakefile$}).should_not be_empty
418
+ end
419
+
420
+ it "does not try to autodetect frameworks when Warbler.framework_detection is false" do
421
+ begin
422
+ Warbler.framework_detection = false
423
+ task :environment
424
+ config.webxml.booter.should_not == :rails
425
+ t = Rake::Task['environment']
426
+ class << t; public :instance_variable_get; end
427
+ t.instance_variable_get("@already_invoked").should == false
428
+ ensure
429
+ Warbler.framework_detection = true
430
+ end
431
+ end
432
+
433
+ context "with the executable feature" do
434
+ it "adds a WarMain class" do
435
+ use_config do |config|
436
+ config.features << "executable"
437
+ end
438
+ jar.apply(config)
439
+ file_list(%r{^WarMain\.class$}).should_not be_empty
440
+ end
441
+ end
442
+
443
+ context "in a Rails application" do
444
+ before :each do
445
+ @rails = nil
446
+ task :environment do
447
+ @rails = mock_rails_module
448
+ end
449
+ end
450
+
451
+ def mock_rails_module
452
+ rails = Module.new
453
+ Object.const_set("Rails", rails)
454
+ version = Module.new
455
+ rails.const_set("VERSION", version)
456
+ version.const_set("STRING", "2.1.0")
457
+ rails
458
+ end
459
+
460
+ it "detects a Rails trait" do
461
+ config.traits.should include(Warbler::Traits::Rails)
462
+ end
463
+
464
+ it "auto-detects a Rails application" do
465
+ config.webxml.booter.should == :rails
466
+ config.gems["rails"].should == "2.1.0"
467
+ end
468
+
469
+ it "provides Rails gems by default, unless vendor/rails is present" do
470
+ config.gems.should have_key("rails")
471
+
472
+ mkdir_p "vendor/rails"
473
+ config = Warbler::Config.new
474
+ config.gems.should be_empty
475
+
476
+ rm_rf "vendor/rails"
477
+ @rails.stub!(:vendor_rails?).and_return true
478
+ config = Warbler::Config.new
479
+ config.gems.should be_empty
480
+ end
481
+
482
+ it "automatically adds Rails.configuration.gems to the list of gems" do
483
+ task :environment do
484
+ config = mock "config"
485
+ @rails.stub!(:configuration).and_return(config)
486
+ gem = mock "gem"
487
+ gem.stub!(:name).and_return "hpricot"
488
+ gem.stub!(:requirement).and_return Gem::Requirement.new("=0.6")
489
+ config.stub!(:gems).and_return [gem]
490
+ end
491
+
492
+ config.webxml.booter.should == :rails
493
+ config.gems.keys.should include(Gem::Dependency.new("hpricot", Gem::Requirement.new("=0.6")))
494
+ end
495
+
496
+ it "sets the jruby max runtimes to 1 when MT Rails is detected" do
497
+ task :environment do
498
+ config = mock "config"
499
+ @rails.stub!(:configuration).and_return(config)
500
+ config.stub!(:threadsafe!)
501
+ config.should_receive(:allow_concurrency).and_return true
502
+ config.should_receive(:preload_frameworks).and_return true
503
+ end
504
+
505
+ config.webxml.booter.should == :rails
506
+ config.webxml.jruby.max.runtimes.should == 1
507
+ end
508
+
509
+ it "adds RAILS_ENV to init.rb" do
510
+ use_config do |config|
511
+ config.webxml.booter = :rails
512
+ end
513
+ jar.add_init_file(config)
514
+ contents = jar.files['META-INF/init.rb'].read
515
+ contents.should =~ /ENV\['RAILS_ENV'\]/
516
+ contents.should =~ /'production'/
517
+ end
518
+ end
519
+
520
+ context "in a Merb application" do
521
+ before :each do
522
+ touch "config/init.rb"
523
+ @merb = nil
524
+ task :merb_env do
525
+ @merb = mock_merb_module
526
+ end
527
+ end
528
+
529
+ after :each do
530
+ rm_f "config/init.rb"
531
+ end
532
+
533
+ def mock_merb_module
534
+ merb = Module.new
535
+ silence { Object.const_set("Merb", merb) }
536
+ boot_loader = Module.new
537
+ merb.const_set("BootLoader", boot_loader)
538
+ merb.const_set("VERSION", "1.0")
539
+ dependencies = Class.new do
540
+ @@dependencies = []
541
+ def self.dependencies
542
+ @@dependencies
543
+ end
544
+ def self.dependencies=(deps)
545
+ @@dependencies = deps
546
+ end
547
+ end
548
+ boot_loader.const_set("Dependencies", dependencies)
549
+ dependencies
550
+ end
551
+
552
+ it "detects a Merb trait" do
553
+ config.traits.should include(Warbler::Traits::Merb)
554
+ end
555
+
556
+ it "auto-detects a Merb application" do
557
+ config.webxml.booter.should == :merb
558
+ config.gems.keys.should_not include("rails")
559
+ end
560
+
561
+ it "automatically adds Merb::BootLoader::Dependencies.dependencies to the list of gems" do
562
+ task :merb_env do
563
+ @merb.dependencies = [Gem::Dependency.new("merb-core", ">= 1.0.6.1")]
564
+ end
565
+ config.gems.keys.should include(Gem::Dependency.new("merb-core", ">= 1.0.6.1"))
566
+ end
567
+
568
+ it "skips Merb development dependencies" do
569
+ task :merb_env do
570
+ @merb.dependencies = [Gem::Dependency.new("rake", "= #{RAKEVERSION}", :development)]
571
+ end
572
+ jar.apply(config)
573
+ file_list(/rake-#{RAKEVERSION}/).should be_empty
574
+ end
575
+
576
+ it "warns about using Merb < 1.0" do
577
+ task :merb_env do
578
+ silence { Object.const_set("Merb", Module.new) }
579
+ end
580
+ silence { config.webxml.booter.should == :merb }
581
+ end
582
+ end
583
+
584
+ context "in a Rack application" do
585
+ before :each do
586
+ Dir.chdir('tmp')
587
+ rackup = "run Proc.new {|env| [200, {}, ['Hello World']]}"
588
+ File.open("config.ru", "w") {|f| f << rackup }
589
+ end
590
+
591
+ it "detects a Rack trait" do
592
+ config.traits.should include(Warbler::Traits::Rack)
593
+ end
594
+
595
+ it "auto-detects a Rack application with a config.ru file" do
596
+ jar.apply(config)
597
+ jar.files['WEB-INF/config.ru'].should == 'config.ru'
598
+ end
599
+
600
+ it "adds RACK_ENV to init.rb" do
601
+ jar.add_init_file(config)
602
+ contents = jar.files['META-INF/init.rb'].read
603
+ contents.should =~ /ENV\['RACK_ENV'\]/
604
+ contents.should =~ /'production'/
605
+ end
606
+ end
607
+
608
+ context "with Bundler" do
609
+ before :each do
610
+ File.open("Gemfile", "w") {|f| f << "gem 'rspec'"}
611
+ end
612
+
613
+ it "detects a Bundler trait" do
614
+ config.traits.should include(Warbler::Traits::Bundler)
615
+ end
616
+
617
+ it "detects a Bundler Gemfile and process only its gems" do
618
+ use_config do |config|
619
+ config.gems << "rake"
620
+ end
621
+ jar.apply(config)
622
+ file_list(%r{WEB-INF/Gemfile}).should_not be_empty
623
+ file_list(%r{WEB-INF/gems/specifications/rspec}).should_not be_empty
624
+ file_list(%r{WEB-INF/gems/specifications/rake}).should be_empty
625
+ end
626
+
627
+ it "copies Bundler gemfiles into the war" do
628
+ File.open("Gemfile.lock", "w") {|f| f << "GEM"}
629
+ jar.apply(config)
630
+ file_list(%r{WEB-INF/Gemfile}).should_not be_empty
631
+ file_list(%r{WEB-INF/Gemfile.lock}).should_not be_empty
632
+ end
633
+
634
+ it "allows overriding of the gem path when using Bundler" do
635
+ use_config do |config|
636
+ config.gem_path = '/WEB-INF/jewels'
637
+ end
638
+ jar.apply(config)
639
+ file_list(%r{WEB-INF/jewels/specifications/rspec}).should_not be_empty
640
+ end
641
+
642
+ it "works with :git entries in Bundler Gemfiles" do
643
+ File.open("Gemfile", "w") {|f| f << "gem 'warbler', :git => '#{Warbler::WARBLER_HOME}'\n"}
644
+ silence { ruby "-S", "bundle", "install", "--local" }
645
+ jar.apply(config)
646
+ file_list(%r{WEB-INF/gems/gems/warbler[^/]*/lib/warbler/version\.rb}).should_not be_empty
647
+ file_list(%r{WEB-INF/gems/specifications/warbler}).should_not be_empty
648
+ end
649
+
650
+ it "does not bundle dependencies in the test group by default" do
651
+ File.open("Gemfile", "w") {|f| f << "gem 'rake'\ngroup :test do\ngem 'rspec'\nend\n"}
652
+ jar.apply(config)
653
+ file_list(%r{WEB-INF/gems/gems/rake[^/]*/}).should_not be_empty
654
+ file_list(%r{WEB-INF/gems/gems/rspec[^/]*/}).should be_empty
655
+ file_list(%r{WEB-INF/gems/specifications/rake}).should_not be_empty
656
+ file_list(%r{WEB-INF/gems/specifications/rspec}).should be_empty
657
+ end
658
+
659
+ it "adds BUNDLE_WITHOUT to init.rb" do
660
+ jar.add_init_file(config)
661
+ contents = jar.files['META-INF/init.rb'].read
662
+ contents.should =~ /ENV\['BUNDLE_WITHOUT'\]/
663
+ contents.should =~ /'development:test'/
664
+ end
665
+ end
666
+
667
+ it "skips directories that don't exist in config.dirs and print a warning" do
668
+ use_config do |config|
669
+ config.dirs = %w(lib notexist)
670
+ end
671
+ silence { jar.apply(config) }
672
+ file_list(%r{WEB-INF/lib}).should_not be_empty
673
+ file_list(%r{WEB-INF/notexist}).should be_empty
674
+ end
675
+
676
+ it "excludes Warbler's old tmp/war directory by default" do
677
+ mkdir_p "tmp/war"
678
+ touch "tmp/war/index.html"
679
+ use_config do |config|
680
+ config.dirs += ["tmp"]
681
+ end
682
+ jar.apply(config)
683
+ file_list(%r{WEB-INF/tmp/war/index\.html}).should be_empty
684
+ end
685
+
686
+ it "writes gems to location specified by gem_path" do
687
+ use_config do |config|
688
+ config.gem_path = "/WEB-INF/jewels"
689
+ config.gems << 'rake'
690
+ end
691
+ elements = expand_webxml
692
+ file_list(%r{WEB-INF/jewels}).should_not be_empty
693
+ elements.to_a(
694
+ "context-param/param-name[text()='gem.path']"
695
+ ).should_not be_empty
696
+ elements.to_a(
697
+ "context-param/param-name[text()='gem.path']/../param-value"
698
+ ).first.text.should == "/WEB-INF/jewels"
699
+ end
700
+
701
+ it "allows adding additional WEB-INF files via config.webinf_files" do
702
+ File.open("myserver-web.xml", "w") do |f|
703
+ f << "<web-app></web-app>"
704
+ end
705
+ use_config do |config|
706
+ config.webinf_files = FileList['myserver-web.xml']
707
+ end
708
+ jar.apply(config)
709
+ file_list(%r{WEB-INF/myserver-web.xml}).should_not be_empty
710
+ end
711
+
712
+ it "allows expanding of additional WEB-INF files via config.webinf_files" do
713
+ File.open("myserver-web.xml.erb", "w") do |f|
714
+ f << "<web-app><%= webxml.rails.env %></web-app>"
715
+ end
716
+ use_config do |config|
717
+ config.webinf_files = FileList['myserver-web.xml.erb']
718
+ end
719
+ jar.apply(config)
720
+ file_list(%r{WEB-INF/myserver-web.xml}).should_not be_empty
721
+ jar.files['WEB-INF/myserver-web.xml'].read.should =~ /web-app.*production/
722
+ end
723
+
724
+ it "excludes test files in gems according to config.gem_excludes" do
725
+ use_config do |config|
726
+ config.gem_excludes += [/^(test|spec)\//]
727
+ end
728
+ jar.apply(config)
729
+ file_list(%r{WEB-INF/gems/gems/rake([^/]+)/test/test_rake.rb}).should be_empty
730
+ end
731
+
732
+ it "creates a META-INF/init.rb file with startup config" do
733
+ jar.apply(config)
734
+ file_list(%r{META-INF/init.rb}).should_not be_empty
735
+ end
736
+
737
+ it "allows adjusting the init file location in the war" do
738
+ use_config do |config|
739
+ config.init_filename = 'WEB-INF/init.rb'
740
+ end
741
+ jar.add_init_file(config)
742
+ file_list(%r{WEB-INF/init.rb}).should_not be_empty
743
+ end
744
+
745
+ it "allows adding custom files' contents to init.rb" do
746
+ use_config do |config|
747
+ config.init_contents << "Rakefile"
748
+ end
749
+ jar.add_init_file(config)
750
+ contents = jar.files['META-INF/init.rb'].read
751
+ contents.should =~ /require 'rake'/
752
+ end
753
+
754
+ it "does not have escaped HTML in WARBLER_CONFIG" do
755
+ use_config do |config|
756
+ config.webxml.dummy = '<dummy/>'
757
+ end
758
+ jar.apply(config)
759
+ jar.files['META-INF/init.rb'].read.should =~ /<dummy\/>/
760
+ end
761
+ end
762
+ end
763
+