warbler 1.2.1 → 1.3.0.beta1

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