rdmopensource-warbler 1.1.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 (47) hide show
  1. data/Gemfile +11 -0
  2. data/History.txt +167 -0
  3. data/LICENSE.txt +26 -0
  4. data/Manifest.txt +48 -0
  5. data/README.txt +194 -0
  6. data/Rakefile +92 -0
  7. data/bin/warble +11 -0
  8. data/ext/Main.java +110 -0
  9. data/ext/WarblerWar.java +115 -0
  10. data/ext/WarblerWarService.java +17 -0
  11. data/lib/warbler.rb +37 -0
  12. data/lib/warbler/application.rb +67 -0
  13. data/lib/warbler/config.rb +349 -0
  14. data/lib/warbler/gems.rb +37 -0
  15. data/lib/warbler/runtime.rb +44 -0
  16. data/lib/warbler/task.rb +224 -0
  17. data/lib/warbler/version.rb +10 -0
  18. data/lib/warbler/war.rb +226 -0
  19. data/lib/warbler_war.jar +0 -0
  20. data/spec/sample/app/controllers/application.rb +15 -0
  21. data/spec/sample/app/helpers/application_helper.rb +3 -0
  22. data/spec/sample/config/boot.rb +109 -0
  23. data/spec/sample/config/database.yml +19 -0
  24. data/spec/sample/config/environment.rb +67 -0
  25. data/spec/sample/config/environments/development.rb +17 -0
  26. data/spec/sample/config/environments/production.rb +22 -0
  27. data/spec/sample/config/environments/test.rb +22 -0
  28. data/spec/sample/config/initializers/inflections.rb +10 -0
  29. data/spec/sample/config/initializers/mime_types.rb +5 -0
  30. data/spec/sample/config/initializers/new_rails_defaults.rb +15 -0
  31. data/spec/sample/config/routes.rb +41 -0
  32. data/spec/sample/lib/tasks/utils.rake +0 -0
  33. data/spec/sample/public/404.html +30 -0
  34. data/spec/sample/public/422.html +30 -0
  35. data/spec/sample/public/500.html +30 -0
  36. data/spec/sample/public/favicon.ico +0 -0
  37. data/spec/sample/public/index.html +274 -0
  38. data/spec/sample/public/robots.txt +5 -0
  39. data/spec/spec_helper.rb +44 -0
  40. data/spec/warbler/application_spec.rb +93 -0
  41. data/spec/warbler/config_spec.rb +112 -0
  42. data/spec/warbler/gems_spec.rb +40 -0
  43. data/spec/warbler/task_spec.rb +146 -0
  44. data/spec/warbler/war_spec.rb +441 -0
  45. data/warble.rb +121 -0
  46. data/web.xml.erb +32 -0
  47. metadata +202 -0
@@ -0,0 +1,5 @@
1
+ # See http://www.robotstxt.org/wc/norobots.html for documentation on how to use the robots.txt file
2
+ #
3
+ # To ban all spiders from the entire site uncomment the next two lines:
4
+ # User-Agent: *
5
+ # Disallow: /
@@ -0,0 +1,44 @@
1
+ #--
2
+ # Copyright (c) 2010 Engine Yard, Inc.
3
+ # Copyright (c) 2007-2009 Sun Microsystems, Inc.
4
+ # This source code is available under the MIT license.
5
+ # See the file LICENSE.txt for details.
6
+ #++
7
+
8
+ require 'rubygems'
9
+ require 'spec'
10
+
11
+ $LOAD_PATH.unshift File.dirname(__FILE__) + '/../lib'
12
+ require 'warbler'
13
+
14
+ raise %{Error: detected running Warbler specs in a Rails app;
15
+ Warbler specs are destructive to application directories.} if File.directory?("app")
16
+
17
+ def silence(io = nil)
18
+ require 'stringio'
19
+ old_stdout = $stdout
20
+ old_stderr = $stderr
21
+ $stdout = io || StringIO.new
22
+ $stderr = io || StringIO.new
23
+ yield
24
+ ensure
25
+ $stdout = old_stdout
26
+ $stderr = old_stderr
27
+ end
28
+
29
+ def capture(&block)
30
+ require 'stringio'
31
+ io = StringIO.new
32
+ silence(io, &block)
33
+ io.string
34
+ end
35
+
36
+ Spec::Runner.configure do |config|
37
+ config.after(:each) do
38
+ class << Object
39
+ public :remove_const
40
+ end
41
+ Object.remove_const("Rails") rescue nil
42
+ rm_rf "vendor"
43
+ end
44
+ end
@@ -0,0 +1,93 @@
1
+ #--
2
+ # Copyright (c) 2010 Engine Yard, Inc.
3
+ # Copyright (c) 2007-2009 Sun Microsystems, Inc.
4
+ # This source code is available under the MIT license.
5
+ # See the file LICENSE.txt for details.
6
+ #++
7
+
8
+ require File.dirname(__FILE__) + '/../spec_helper'
9
+
10
+ describe Warbler::Application do
11
+ before :each do
12
+ verbose(false)
13
+ @pwd = Dir.getwd
14
+ Dir.chdir("spec/sample")
15
+ @argv = ARGV.dup
16
+ ARGV.clear
17
+ @app = Rake.application
18
+ rm_f "config/warble.rb"
19
+ @detection = Warbler.framework_detection
20
+ Warbler.framework_detection = false
21
+ end
22
+
23
+ after :each do
24
+ Rake.application = @app
25
+ Warbler.project_application = nil
26
+ Warbler.application = nil
27
+ Warbler.framework_detection = @detection
28
+ @argv.reverse.each {|a| ARGV.unshift a}
29
+ rm_rf FileList['vendor/plugins/warbler']
30
+ Dir.chdir(@pwd)
31
+ end
32
+
33
+ it "should be able to list its tasks" do
34
+ ARGV.unshift "-T"
35
+ output = capture do
36
+ Warbler::Application.new.run
37
+ end
38
+ output.should =~ /warble war\s/
39
+ output.should =~ /warble war:clean/
40
+ output.should =~ /warble war:debug/
41
+ end
42
+
43
+ it "should display the version" do
44
+ ARGV.unshift "version"
45
+ capture { Warbler::Application.new.run }.should =~ /#{Warbler::VERSION}/
46
+ end
47
+
48
+ it "should copy a fresh config file into place" do
49
+ File.exists?("config/warble.rb").should_not be_true
50
+ ARGV.unshift "config"
51
+ silence { Warbler::Application.new.run }
52
+ File.exists?("config/warble.rb").should be_true
53
+ end
54
+
55
+ it "should refuse to copy over an existing config file" do
56
+ touch "config/warble.rb"
57
+ ARGV.unshift "config"
58
+ capture { Warbler::Application.new.run }.should =~ /already exists/
59
+ end
60
+
61
+ it "should complain if the config directory is missing" do
62
+ begin
63
+ mv "config", "config-tmp"
64
+ ARGV.unshift "config"
65
+ capture { Warbler::Application.new.run }.should =~ /missing/
66
+ ensure
67
+ mv "config-tmp", "config"
68
+ end
69
+ end
70
+
71
+ it "should refuse to pluginize if the vendor/plugins/warbler directory exists" do
72
+ mkdir_p "vendor/plugins/warbler"
73
+ ARGV.unshift "pluginize"
74
+ silence { Warbler::Application.new.run }
75
+ File.exist?("vendor/plugins/warbler/tasks/warbler.rake").should_not be_true
76
+ end
77
+
78
+ it "should define a pluginize task for adding the tasks to a Rails application" do
79
+ ARGV.unshift "pluginize"
80
+ Warbler::Application.new.run
81
+ File.exist?("vendor/plugins/warbler/tasks/warbler.rake").should be_true
82
+ end
83
+
84
+ it "should provide a means to load the project Rakefile" do
85
+ Warbler::Application.new.load_project_rakefile
86
+ end
87
+
88
+ it "should define a gemjar task for setting up gem packaging inside a jar" do
89
+ ARGV.unshift "gemjar"
90
+ Warbler::Application.new.run
91
+ Rake::Task['war:jar'].prerequisites.should include('war:make_gemjar')
92
+ end
93
+ end
@@ -0,0 +1,112 @@
1
+ #--
2
+ # Copyright (c) 2010 Engine Yard, Inc.
3
+ # Copyright (c) 2007-2009 Sun Microsystems, Inc.
4
+ # This source code is available under the MIT license.
5
+ # See the file LICENSE.txt for details.
6
+ #++
7
+
8
+ require File.dirname(__FILE__) + '/../spec_helper'
9
+
10
+ describe Warbler::Config do
11
+ before :each do
12
+ verbose(false)
13
+ end
14
+
15
+ it "should have suitable default values" do
16
+ config = Warbler::Config.new
17
+ config.dirs.should include(*Warbler::Config::TOP_DIRS.select{|d| File.directory?(d)})
18
+ config.includes.should be_empty
19
+ config.java_libs.should_not be_empty
20
+ config.war_name.size.should > 0
21
+ config.webxml.should be_kind_of(OpenStruct)
22
+ config.pathmaps.should be_kind_of(OpenStruct)
23
+ config.pathmaps.public_html.should == ["%{public/,}p"]
24
+ end
25
+
26
+ it "should allow configuration through an initializer block" do
27
+ config = Warbler::Config.new do |c|
28
+ c.war_name = "mywar"
29
+ end
30
+ config.war_name.should == "mywar"
31
+ end
32
+
33
+ it "should allow gems to be added/changed with =, +=, -=, <<" do
34
+ config = Warbler::Config.new do |c|
35
+ c.gems += ["activerecord-jdbc-adapter"]
36
+ c.gems -= ["rails"]
37
+ c.gems << "tzinfo"
38
+ c.gems = ["camping"]
39
+ end
40
+ end
41
+
42
+ it "should exclude log files by default" do
43
+ mkdir_p "vendor"
44
+ touch "vendor/test.log"
45
+ config = Warbler::Config.new
46
+ config.exclude_logs.should == true
47
+ config.excludes.include?("vendor/test.log").should == true
48
+ end
49
+
50
+ it "should include log files if exclude_logs is false" do
51
+ mkdir_p "vendor"
52
+ touch "vendor/test.log"
53
+ config = Warbler::Config.new {|c| c.exclude_logs = false }
54
+ config.exclude_logs.should == false
55
+ config.excludes.include?("vendor/test.log").should == false
56
+ end
57
+
58
+ it "should exclude Warbler itself when run as a plugin" do
59
+ config = Warbler::Config.new
60
+ config.excludes.include?("vendor/plugins/warbler").should == false
61
+ config = Warbler::Config.new File.join(Dir.getwd, "vendor", "plugins", "warbler")
62
+ config.excludes.include?("vendor/plugins/warbler").should == true
63
+ end
64
+
65
+ it "should generate context parameters from the webxml openstruct" do
66
+ config = Warbler::Config.new
67
+ config.webxml.a.b.c = "123"
68
+ config.webxml.com.example.config = "blah"
69
+ config.webxml.rails.env = 'staging'
70
+ config.webxml.jruby.min.runtimes = 2
71
+ config.webxml.jruby.max.runtimes = 4
72
+ config.webxml['org']['jruby']['rack'] = "rails"
73
+ params = config.webxml.context_params
74
+ params.should have_key('a.b.c')
75
+ params.should have_key('rails.env')
76
+ params.should have_key('jruby.min.runtimes')
77
+ params.should have_key('jruby.max.runtimes')
78
+ params['a.b.c'].should == "123"
79
+ params['com.example.config'].should == "blah"
80
+ params['rails.env'].should == "staging"
81
+ params['jruby.min.runtimes'].should == "2"
82
+ params['jruby.max.runtimes'].should == "4"
83
+ params['org.jruby.rack'].should == "rails"
84
+ end
85
+
86
+ it "should determine the context listener from the webxml.booter parameter" do
87
+ config = Warbler::Config.new
88
+ config.webxml.booter = :rack
89
+ config.webxml.servlet_context_listener.should == "org.jruby.rack.RackServletContextListener"
90
+ config = Warbler::Config.new
91
+ config.webxml.booter = :merb
92
+ config.webxml.servlet_context_listener.should == "org.jruby.rack.merb.MerbServletContextListener"
93
+ config = Warbler::Config.new
94
+ config.webxml.servlet_context_listener.should == "org.jruby.rack.rails.RailsServletContextListener"
95
+ end
96
+
97
+ it "should not include ignored webxml keys in the context params hash" do
98
+ Warbler::Config.new.webxml.context_params.should_not have_key('ignored')
99
+ Warbler::Config.new.webxml.context_params.should_not have_key('jndi')
100
+ Warbler::Config.new.webxml.context_params.should_not have_key('booter')
101
+ end
102
+
103
+ it "should have a helpful string representation for an empty key" do
104
+ Warbler::Config.new.webxml.missing_key.to_s.should =~ /No value for 'missing_key' found/
105
+ end
106
+
107
+ it "should HTML-escape all webxml keys and values" do
108
+ config = Warbler::Config.new
109
+ config.webxml.a["b&"].c = "123<hi>456"
110
+ config.webxml.context_params['a.b&amp;.c'].should == "123&lt;hi&gt;456"
111
+ end
112
+ end
@@ -0,0 +1,40 @@
1
+ #--
2
+ # Copyright (c) 2010 Engine Yard, Inc.
3
+ # Copyright (c) 2007-2009 Sun Microsystems, Inc.
4
+ # This source code is available under the MIT license.
5
+ # See the file LICENSE.txt for details.
6
+ #++
7
+
8
+ require File.dirname(__FILE__) + '/../spec_helper'
9
+
10
+ describe Warbler::Gems do
11
+ it "should accept a hash for initialization" do
12
+ gems = Warbler::Gems.new({"actionpack" => "1.2.3"})
13
+ gems.should have_key("actionpack")
14
+ gems["actionpack"].should == "1.2.3"
15
+ end
16
+
17
+ it "should accept an array for initialization" do
18
+ gems = Warbler::Gems.new ["activerecord"]
19
+ gems.should have_key("activerecord")
20
+ end
21
+
22
+ it "should allow gems with a version" do
23
+ gems = Warbler::Gems.new
24
+ gems["actionpack"] = "> 1.2.3"
25
+ gems["actionpack"].should == "> 1.2.3"
26
+ end
27
+
28
+ it "should allow gems without an explicit version" do
29
+ gems = Warbler::Gems.new
30
+ gems << "actionpack"
31
+ gems.should have_key("actionpack")
32
+ end
33
+
34
+ it "should allow to add gems" do
35
+ gems = Warbler::Gems.new
36
+ gems << "rails"
37
+ gems += ["activerecord-jdbcmysql-adapter", "jdbc-mysql", "jruby-openssl"]
38
+ ["rails", "activerecord-jdbcmysql-adapter", "jdbc-mysql", "jruby-openssl"].each {|g| gems.should have_key(g)}
39
+ end
40
+ end
@@ -0,0 +1,146 @@
1
+ #--
2
+ # Copyright (c) 2010 Engine Yard, Inc.
3
+ # Copyright (c) 2007-2009 Sun Microsystems, Inc.
4
+ # This source code is available under the MIT license.
5
+ # See the file LICENSE.txt for details.
6
+ #++
7
+
8
+ require File.dirname(__FILE__) + '/../spec_helper'
9
+
10
+ describe Warbler::Task do
11
+ before(:each) do
12
+ @rake = Rake::Application.new
13
+ Rake.application = @rake
14
+ verbose(false)
15
+ @pwd = Dir.getwd
16
+ Dir.chdir("spec/sample")
17
+ mkdir_p "log"
18
+ touch "log/test.log"
19
+ @config = Warbler::Config.new do |config|
20
+ config.war_name = "warbler"
21
+ config.gems = ["rake"]
22
+ config.webxml.jruby.max.runtimes = 5
23
+ end
24
+ @task = Warbler::Task.new "warble", @config
25
+ end
26
+
27
+ after(:each) do
28
+ Rake::Task["warble:clean"].invoke
29
+ rm_rf "log"
30
+ rm_f FileList["config.ru", "*web.xml", "config/web.xml*", "config/warble.rb",
31
+ "config/special.txt", "config/link.txt", "tmp/gems.jar",
32
+ "file.txt", 'Gemfile', 'lib/rakelib']
33
+ Dir.chdir(@pwd)
34
+ end
35
+
36
+ it "should define a clean task for removing the war file" do
37
+ war_file = "#{@config.war_name}.war"
38
+ touch war_file
39
+ Rake::Task["warble:clean"].invoke
40
+ File.exist?(war_file).should == false
41
+ end
42
+
43
+ it "should define a make_gemjar task for storing gems in a jar file" do
44
+ silence { Rake::Task["warble:make_gemjar"].invoke }
45
+ File.exist?("tmp/gems.jar").should == true
46
+ @task.war.files.keys.should_not include(%r{WEB-INF\/gems})
47
+ @task.war.files.keys.should include("WEB-INF/lib/gems.jar")
48
+ end
49
+
50
+ it "should define a war task for bundling up everything" do
51
+ files_ran = false; task "warble:files" do; files_ran = true; end
52
+ jar_ran = false; task "warble:jar" do; jar_ran = true; end
53
+ silence { Rake::Task["warble"].invoke }
54
+ files_ran.should == true
55
+ jar_ran.should == true
56
+ end
57
+
58
+ it "should define a jar task for creating the .war" do
59
+ touch "file.txt"
60
+ @task.war.files["file.txt"] = "file.txt"
61
+ silence { Rake::Task["warble:jar"].invoke }
62
+ File.exist?("#{@config.war_name}.war").should == true
63
+ end
64
+
65
+ it "should invoke feature tasks configured in config.features" do
66
+ @config.features << "gemjar"
67
+ silence { Rake::Task["warble"].invoke }
68
+ @task.war.files.keys.should include("WEB-INF/lib/gems.jar")
69
+ end
70
+
71
+ it "should warn and skip unknown features configured in config.features" do
72
+ @config.features << "bogus"
73
+ capture { Rake::Task["warble"].invoke }.should =~ /unknown feature `bogus'/
74
+ end
75
+
76
+ it "should define an executable task for embedding a server in the war file" do
77
+ silence { Rake::Task["warble:executable"].invoke }
78
+ @task.war.files.keys.should include('WEB-INF/winstone.jar')
79
+ end
80
+
81
+ it "should be able to define all tasks successfully" do
82
+ Warbler::Task.new "warble", @config
83
+ end
84
+
85
+ it "should compile any ruby files specified" do
86
+ @config.compiled_ruby_files = FileList["app/helpers/application_helper.rb"]
87
+ silence { Rake::Task["warble"].invoke }
88
+
89
+ java_class_magic_number = [0xCA,0xFE,0xBA,0xBE].map { |magic_char| magic_char.chr }.join
90
+
91
+ Zip::ZipFile.open("#{@config.war_name}.war") do |zf|
92
+ java_class_header = zf.get_input_stream('WEB-INF/app/helpers/application_helper.class') {|io| io.read }[0..3]
93
+ ruby_class_definition = zf.get_input_stream('WEB-INF/app/helpers/application_helper.rb') {|io| io.read }
94
+
95
+ java_class_header.should == java_class_magic_number
96
+ ruby_class_definition.should == %{require __FILE__.sub(/.rb$/, '.class')}
97
+ end
98
+ end
99
+
100
+ it "should process symlinks by storing a file in the archive that has the same contents as the source" do
101
+ File.open("config/special.txt", "wb") {|f| f << "special"}
102
+ Dir.chdir("config") { ln_s "special.txt", "link.txt" }
103
+ silence { Rake::Task["warble"].invoke }
104
+ Zip::ZipFile.open("#{@config.war_name}.war") do |zf|
105
+ special = zf.get_input_stream('WEB-INF/config/special.txt') {|io| io.read }
106
+ link = zf.get_input_stream('WEB-INF/config/link.txt') {|io| io.read }
107
+ link.should == special
108
+ end
109
+ end
110
+
111
+ it "should process directory symlinks by copying the whole subdirectory" do
112
+ Dir.chdir("lib") { ln_s "tasks", "rakelib" }
113
+ silence { Rake::Task["warble"].invoke }
114
+ Zip::ZipFile.open("#{@config.war_name}.war") do |zf|
115
+ zf.find_entry("WEB-INF/lib/tasks/utils.rake").should_not be_nil
116
+ zf.find_entry("WEB-INF/lib/rakelib/").should_not be_nil
117
+ zf.find_entry("WEB-INF/lib/rakelib/utils.rake").should_not be_nil if defined?(JRUBY_VERSION)
118
+ end
119
+ end
120
+
121
+ it "should use a Bundler Gemfile to include gems" do
122
+ File.open("Gemfile", "w") {|f| f << "gem 'rspec'"}
123
+ @config.bundler = true
124
+ @config.send(:detect_bundler_gems)
125
+ silence { Rake::Task["warble"].invoke }
126
+ Zip::ZipFile.open("#{@config.war_name}.war") do |zf|
127
+ rspec_version = @config.gems.keys.detect {|k| k.name == 'rspec'}.version
128
+ zf.find_entry("WEB-INF/gems/specifications/rspec-#{rspec_version}.gemspec").should_not be_nil
129
+ end
130
+ end
131
+ end
132
+
133
+ describe "Debug targets" do
134
+ before(:each) do
135
+ @rake = Rake::Application.new
136
+ Rake.application = @rake
137
+ verbose(false)
138
+ silence { Warbler::Task.new :war, Object.new }
139
+ end
140
+
141
+ it "should print out lists of files" do
142
+ capture { Rake::Task["war:debug:includes"].invoke }.should =~ /include/
143
+ capture { Rake::Task["war:debug:excludes"].invoke }.should =~ /exclude/
144
+ capture { Rake::Task["war:debug"].invoke }.should =~ /Config/
145
+ end
146
+ end
@@ -0,0 +1,441 @@
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::War do
10
+ before(:each) do
11
+ @rake = Rake::Application.new
12
+ Rake.application = @rake
13
+ verbose(false)
14
+ @pwd = Dir.getwd
15
+ Dir.chdir("spec/sample")
16
+ mkdir_p "log"
17
+ touch "log/test.log"
18
+ @config = Warbler::Config.new do |config|
19
+ config.war_name = "warbler"
20
+ config.gems = ["rake"]
21
+ config.webxml.jruby.max.runtimes = 5
22
+ end
23
+ @war = Warbler::War.new
24
+ end
25
+
26
+ after(:each) do
27
+ rm_rf "log"
28
+ rm_rf ".bundle"
29
+ rm_f FileList["*.war", "config.ru", "*web.xml*", "config/web.xml*",
30
+ "config/warble.rb", "file.txt", 'manifest', 'Gemfile*']
31
+ Dir.chdir(@pwd)
32
+ end
33
+
34
+ def file_list(regex)
35
+ @war.files.keys.select {|f| f =~ regex }
36
+ end
37
+
38
+ it "should collect files in public" do
39
+ @war.apply(@config)
40
+ file_list(%r{^index\.html}).should_not be_empty
41
+ end
42
+
43
+ it "should collect gem files" do
44
+ @config.gems << "rake"
45
+ @war.apply(@config)
46
+ file_list(%r{WEB-INF/gems/gems/rake.*/lib/rake.rb}).should_not be_empty
47
+ file_list(%r{WEB-INF/gems/specifications/rake.*\.gemspec}).should_not be_empty
48
+ end
49
+
50
+ it "should not include log files by default" do
51
+ @war.apply(@config)
52
+ file_list(%r{WEB-INF/log}).should_not be_empty
53
+ file_list(%r{WEB-INF/log/.*\.log}).should be_empty
54
+ end
55
+
56
+ def expand_webxml
57
+ @war.apply(@config)
58
+ @war.files.should include("WEB-INF/web.xml")
59
+ require 'rexml/document'
60
+ REXML::Document.new(@war.files["WEB-INF/web.xml"]).root.elements
61
+ end
62
+
63
+ it "should create a web.xml file" do
64
+ elements = expand_webxml
65
+ elements.to_a(
66
+ "context-param/param-name[text()='jruby.max.runtimes']"
67
+ ).should_not be_empty
68
+ elements.to_a(
69
+ "context-param/param-name[text()='jruby.max.runtimes']/../param-value"
70
+ ).first.text.should == "5"
71
+ end
72
+
73
+ it "should include custom context parameters in web.xml" do
74
+ @config.webxml.some.custom.config = "myconfig"
75
+ elements = expand_webxml
76
+ elements.to_a(
77
+ "context-param/param-name[text()='some.custom.config']"
78
+ ).should_not be_empty
79
+ elements.to_a(
80
+ "context-param/param-name[text()='some.custom.config']/../param-value"
81
+ ).first.text.should == "myconfig"
82
+ end
83
+
84
+ it "should allow one jndi resource to be included" do
85
+ @config.webxml.jndi = 'jndi/rails'
86
+ elements = expand_webxml
87
+ elements.to_a(
88
+ "resource-ref/res-ref-name[text()='jndi/rails']"
89
+ ).should_not be_empty
90
+ end
91
+
92
+ it "should allow multiple jndi resources to be included" do
93
+ @config.webxml.jndi = ['jndi/rails1', 'jndi/rails2']
94
+ elements = expand_webxml
95
+ elements.to_a(
96
+ "resource-ref/res-ref-name[text()='jndi/rails1']"
97
+ ).should_not be_empty
98
+ elements.to_a(
99
+ "resource-ref/res-ref-name[text()='jndi/rails2']"
100
+ ).should_not be_empty
101
+ end
102
+
103
+ it "should not include any ignored context parameters" do
104
+ @config.webxml.foo = "bar"
105
+ @config.webxml.ignored << "foo"
106
+ elements = expand_webxml
107
+ elements.to_a(
108
+ "context-param/param-name[text()='foo']"
109
+ ).should be_empty
110
+ elements.to_a(
111
+ "context-param/param-name[text()='ignored']"
112
+ ).should be_empty
113
+ elements.to_a(
114
+ "context-param/param-name[text()='jndi']"
115
+ ).should be_empty
116
+ end
117
+
118
+ it "should use a config/web.xml if it exists" do
119
+ mkdir_p "config"
120
+ touch "config/web.xml"
121
+ @war.apply(Warbler::Config.new)
122
+ @war.files["WEB-INF/web.xml"].should == "config/web.xml"
123
+ end
124
+
125
+ it "should use a config/web.xml.erb if it exists" do
126
+ mkdir_p "config"
127
+ File.open("config/web.xml.erb", "w") {|f| f << "Hi <%= webxml.public.root %>" }
128
+ @war.apply(Warbler::Config.new)
129
+ @war.files["WEB-INF/web.xml"].should_not be_nil
130
+ @war.files["WEB-INF/web.xml"].read.should == "Hi /"
131
+ end
132
+
133
+ it "should collect java libraries" do
134
+ @war.apply(@config)
135
+ file_list(%r{WEB-INF/lib/jruby-.*\.jar$}).should_not be_empty
136
+ end
137
+
138
+ it "should collect application files" do
139
+ @war.apply(@config)
140
+ file_list(%r{WEB-INF/app$}).should_not be_empty
141
+ file_list(%r{WEB-INF/config$}).should_not be_empty
142
+ file_list(%r{WEB-INF/lib$}).should_not be_empty
143
+ end
144
+
145
+ it "should accept an autodeploy directory where the war should be created" do
146
+ require 'tmpdir'
147
+ @config.autodeploy_dir = Dir::tmpdir
148
+ touch "file.txt"
149
+ @war.files["file.txt"] = "file.txt"
150
+ silence { @war.create(@config) }
151
+ File.exist?(File.join("#{Dir::tmpdir}","warbler.war")).should == true
152
+ end
153
+
154
+ it "should accept a custom manifest file" do
155
+ touch 'manifest'
156
+ @config.manifest_file = 'manifest'
157
+ @war.apply(@config)
158
+ @war.files['META-INF/MANIFEST.MF'].should == "manifest"
159
+ end
160
+
161
+ it "should not add a manifest if one already exists" do
162
+ @war.files['META-INF/MANIFEST.MF'] = 'manifest'
163
+ @war.add_manifest(@config)
164
+ @war.files['META-INF/MANIFEST.MF'].should == "manifest"
165
+ end
166
+
167
+ it "should be able to exclude files from the .war" do
168
+ @config.excludes += FileList['lib/tasks/utils.rake']
169
+ @war.apply(@config)
170
+ file_list(%r{lib/tasks/utils.rake}).should be_empty
171
+ end
172
+
173
+ it "should read configuration from #{Warbler::Config::FILE}" do
174
+ mkdir_p "config"
175
+ File.open(Warbler::Config::FILE, "w") do |dest|
176
+ contents =
177
+ File.open("#{Warbler::WARBLER_HOME}/warble.rb") do |src|
178
+ src.read
179
+ end
180
+ dest << contents.sub(/# config\.war_name/, 'config.war_name'
181
+ ).sub(/# config.gems << "tzinfo"/, 'config.gems = []')
182
+ end
183
+ t = Warbler::Task.new "warble"
184
+ t.config.war_name.should == "mywar"
185
+ end
186
+
187
+ it "should fail if a gem is requested that is not installed" do
188
+ @config.gems = ["nonexistent-gem"]
189
+ lambda {
190
+ Warbler::Task.new "warble", @config
191
+ @war.apply(@config)
192
+ }.should raise_error
193
+ end
194
+
195
+ it "should allow specification of dependency by Gem::Dependency" do
196
+ spec = mock "gem spec"
197
+ spec.stub!(:full_name).and_return "hpricot-0.6.157"
198
+ spec.stub!(:full_gem_path).and_return "hpricot-0.6.157"
199
+ spec.stub!(:loaded_from).and_return "hpricot.gemspec"
200
+ spec.stub!(:files).and_return ["Rakefile"]
201
+ spec.stub!(:dependencies).and_return []
202
+ Gem.source_index.should_receive(:search).and_return do |gem|
203
+ gem.name.should == "hpricot"
204
+ [spec]
205
+ end
206
+ @config.gems = [Gem::Dependency.new("hpricot", "> 0.6")]
207
+ @war.apply(@config)
208
+ end
209
+
210
+ it "should copy loose java classes to WEB-INF/classes" do
211
+ @config.java_classes = FileList["Rakefile"]
212
+ @war.apply(@config)
213
+ file_list(%r{WEB-INF/classes/Rakefile$}).should_not be_empty
214
+ end
215
+
216
+ def mock_rails_module
217
+ rails = Module.new
218
+ Object.const_set("Rails", rails)
219
+ version = Module.new
220
+ rails.const_set("VERSION", version)
221
+ version.const_set("STRING", "2.1.0")
222
+ rails
223
+ end
224
+
225
+ def mock_merb_module
226
+ merb = Module.new
227
+ silence { Object.const_set("Merb", merb) }
228
+ boot_loader = Module.new
229
+ merb.const_set("BootLoader", boot_loader)
230
+ merb.const_set("VERSION", "1.0")
231
+ dependencies = Class.new do
232
+ @@dependencies = []
233
+ def self.dependencies
234
+ @@dependencies
235
+ end
236
+ def self.dependencies=(deps)
237
+ @@dependencies = deps
238
+ end
239
+ end
240
+ boot_loader.const_set("Dependencies", dependencies)
241
+ dependencies
242
+ end
243
+
244
+ it "should auto-detect a Rails application" do
245
+ task :environment do
246
+ mock_rails_module
247
+ end
248
+ @config = Warbler::Config.new
249
+ @config.webxml.booter.should == :rails
250
+ @config.gems["rails"].should == "2.1.0"
251
+ end
252
+
253
+ it "should provide Rails gems by default, unless vendor/rails is present" do
254
+ rails = nil
255
+ task :environment do
256
+ rails = mock_rails_module
257
+ end
258
+
259
+ config = Warbler::Config.new
260
+ config.gems.should have_key("rails")
261
+
262
+ mkdir_p "vendor/rails"
263
+ config = Warbler::Config.new
264
+ config.gems.should be_empty
265
+
266
+ rm_rf "vendor/rails"
267
+ rails.stub!(:vendor_rails?).and_return true
268
+ config = Warbler::Config.new
269
+ config.gems.should be_empty
270
+ end
271
+
272
+ it "should not try to autodetect frameworks when Warbler.framework_detection is false" do
273
+ begin
274
+ Warbler.framework_detection = false
275
+ task :environment
276
+ config = Warbler::Config.new
277
+ config.webxml.booter.should_not == :rails
278
+ t = Rake::Task['environment']
279
+ class << t; public :instance_variable_get; end
280
+ t.instance_variable_get("@already_invoked").should == false
281
+ ensure
282
+ Warbler.framework_detection = true
283
+ end
284
+ end
285
+
286
+ it "should auto-detect a Merb application" do
287
+ task :merb_env do
288
+ mock_merb_module
289
+ end
290
+ @config = Warbler::Config.new
291
+ @config.webxml.booter.should == :merb
292
+ @config.gems.keys.should_not include("rails")
293
+ end
294
+
295
+ it "should auto-detect a Rack application with a config.ru file" do
296
+ rackup = "run Proc.new {|env| [200, {}, ['Hello World']]}"
297
+ File.open("config.ru", "w") {|f| f << rackup }
298
+ @config = Warbler::Config.new
299
+ @war.apply(@config)
300
+ @war.files['WEB-INF/config.ru'].should == 'config.ru'
301
+ end
302
+
303
+ it "should automatically add Rails.configuration.gems to the list of gems" do
304
+ task :environment do
305
+ rails = mock_rails_module
306
+ config = mock "config"
307
+ rails.stub!(:configuration).and_return(config)
308
+ gem = mock "gem"
309
+ gem.stub!(:name).and_return "hpricot"
310
+ gem.stub!(:requirement).and_return Gem::Requirement.new("=0.6")
311
+ config.stub!(:gems).and_return [gem]
312
+ end
313
+
314
+ @config = Warbler::Config.new
315
+ @config.webxml.booter.should == :rails
316
+ @config.gems.keys.should include(Gem::Dependency.new("hpricot", Gem::Requirement.new("=0.6")))
317
+ end
318
+
319
+ it "should automatically add Merb::BootLoader::Dependencies.dependencies to the list of gems" do
320
+ task :merb_env do
321
+ deps = mock_merb_module
322
+ deps.dependencies = [Gem::Dependency.new("merb-core", ">= 1.0.6.1")]
323
+ end
324
+ @config = Warbler::Config.new
325
+ @config.webxml.booter.should == :merb
326
+ @config.gems.keys.should include(Gem::Dependency.new("merb-core", ">= 1.0.6.1"))
327
+ end
328
+
329
+ it "should skip Merb development dependencies" do
330
+ task :merb_env do
331
+ deps = mock_merb_module
332
+ deps.dependencies = [Gem::Dependency.new("rake", "= #{RAKEVERSION}", :development)]
333
+ end
334
+ @war.apply(Warbler::Config.new)
335
+ file_list(/rake-#{RAKEVERSION}/).should be_empty
336
+ end
337
+
338
+ it "should warn about using Merb < 1.0" do
339
+ task :merb_env do
340
+ silence { Object.const_set("Merb", Module.new) }
341
+ end
342
+ @config = silence { Warbler::Config.new }
343
+ @config.webxml.booter.should == :merb
344
+ end
345
+
346
+ it "should set the jruby max runtimes to 1 when MT Rails is detected" do
347
+ task :environment do
348
+ rails = mock_rails_module
349
+ config = mock "config"
350
+ rails.stub!(:configuration).and_return(config)
351
+ config.stub!(:threadsafe!)
352
+ config.should_receive(:allow_concurrency).and_return true
353
+ config.should_receive(:preload_frameworks).and_return true
354
+ end
355
+ @config = Warbler::Config.new
356
+ @config.webxml.booter.should == :rails
357
+ @config.webxml.jruby.max.runtimes.should == 1
358
+ end
359
+
360
+ it "should skip directories that don't exist in config.dirs and print a warning" do
361
+ @config.dirs = %w(lib notexist)
362
+ silence { @war.apply(@config) }
363
+ file_list(%r{WEB-INF/lib}).should_not be_empty
364
+ file_list(%r{WEB-INF/notexist}).should be_empty
365
+ end
366
+
367
+ it "should write gems to location specified by gem_path" do
368
+ @config = Warbler::Config.new {|c| c.gem_path = "/WEB-INF/jewels"; c.gems << 'rake' }
369
+ elements = expand_webxml
370
+ file_list(%r{WEB-INF/jewels}).should_not be_empty
371
+ elements.to_a(
372
+ "context-param/param-name[text()='gem.path']"
373
+ ).should_not be_empty
374
+ elements.to_a(
375
+ "context-param/param-name[text()='gem.path']/../param-value"
376
+ ).first.text.should == "/WEB-INF/jewels"
377
+
378
+ end
379
+
380
+ it "should detect a Bundler Gemfile and process only its gems" do
381
+ File.open("Gemfile", "w") {|f| f << "gem 'rspec'"}
382
+ @war.apply(Warbler::Config.new {|c| c.gems << "rake"})
383
+ file_list(%r{WEB-INF/Gemfile}).should_not be_empty
384
+ file_list(%r{WEB-INF/gems/specifications/rspec}).should_not be_empty
385
+ file_list(%r{WEB-INF/gems/specifications/rake}).should be_empty
386
+ end
387
+
388
+ it "should write a Bundler environment file into the war" do
389
+ File.open("Gemfile", "w") {|f| f << "gem 'rspec'"}
390
+ @war.apply(Warbler::Config.new)
391
+ file_list(%r{WEB-INF/Gemfile}).should_not be_empty
392
+ file_list(%r{WEB-INF/Gemfile.lock}).should be_empty
393
+ file_list(%r{WEB-INF/\.bundle/environment\.rb}).should be_empty
394
+ end
395
+
396
+ it "should only include Bundler lockfiles if Gemfile.lock exists" do
397
+ File.open("Gemfile", "w") {|f| f << "gem 'rspec'"}
398
+ `ruby -S bundle lock`
399
+ @war.apply(Warbler::Config.new)
400
+ file_list(%r{WEB-INF/Gemfile.lock}).should_not be_empty
401
+ file_list(%r{WEB-INF/\.bundle/environment\.rb}).should_not be_empty
402
+ end
403
+
404
+ it "should allow overriding of the gem path when using Bundler" do
405
+ File.open("Gemfile", "w") {|f| f << "gem 'rspec'"}
406
+ @war.apply(Warbler::Config.new {|c| c.gem_path = '/WEB-INF/jewels' })
407
+ file_list(%r{WEB-INF/jewels/specifications/rspec}).should_not be_empty
408
+ IO.readlines(".bundle/war-environment.rb").grep(/rspec/).last.should =~ %r{jewels/specifications}m
409
+ end
410
+
411
+ it "should not let the framework load Bundler from the locked environment" do
412
+ task :environment do
413
+ File.exist?('.bundle/environment.rb').should_not be_true
414
+ mock_rails_module
415
+ end
416
+
417
+ File.open("Gemfile", "w") {|f| f << "gem 'rspec'"}
418
+ `ruby -S bundle lock`
419
+ File.exist?('.bundle/environment.rb').should be_true
420
+ @war.apply(Warbler::Config.new)
421
+ hash = eval("[" + IO.readlines(".bundle/environment.rb").grep(/rspec/).last + "]").first
422
+ hash[:load_paths].each {|p| File.exist?(p).should be_true }
423
+ end
424
+
425
+ it "should allow adding additional WEB-INF files via config.webinf_files" do
426
+ File.open("myserver-web.xml", "w") do |f|
427
+ f << "<web-app></web-app>"
428
+ end
429
+ @war.apply(Warbler::Config.new {|c| c.webinf_files = FileList['myserver-web.xml'] })
430
+ file_list(%r{WEB-INF/myserver-web.xml}).should_not be_empty
431
+ end
432
+
433
+ it "should allow expanding of additional WEB-INF files via config.webinf_files" do
434
+ File.open("myserver-web.xml.erb", "w") do |f|
435
+ f << "<web-app><%= webxml.rails.env %></web-app>"
436
+ end
437
+ @war.apply(Warbler::Config.new {|c| c.webinf_files = FileList['myserver-web.xml.erb'] })
438
+ file_list(%r{WEB-INF/myserver-web.xml}).should_not be_empty
439
+ @war.files['WEB-INF/myserver-web.xml'].read.should =~ /web-app.*production/
440
+ end
441
+ end