rdmopensource-warbler 1.1.0

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