Enhanced Rails Metal - the load order of metals can now be configured [#2057 state:resolved]

Signed-off-by: Joshua Peek <josh@joshpeek.com>
This commit is contained in:
Simon Jefford 2009-03-03 12:39:19 -06:00 committed by Joshua Peek
parent 818556ec4f
commit 4d4d2c3896
8 changed files with 105 additions and 3 deletions

View File

@ -559,6 +559,7 @@ Run `rake gems:install` to install the missing gems.
end
def initialize_metal
Rails::Rack::Metal.requested_metals = configuration.metals
Rails::Rack::Metal.metal_paths += plugin_loader.engine_metal_paths
configuration.middleware.insert_before(
@ -715,6 +716,11 @@ Run `rake gems:install` to install the missing gems.
@plugins = plugins.nil? ? nil : plugins.map { |p| p.to_sym }
end
# The list of metals to load. If this is set to <tt>nil</tt>, all metals will
# be loaded in alphabetical order. If this is set to <tt>[]</tt>, no metals will
# be loaded. Otherwise metals will be loaded in the order specified
attr_accessor :metals
# The path to the root of the plugins directory. By default, it is in
# <tt>vendor/plugins</tt>.
attr_accessor :plugin_paths

View File

@ -8,16 +8,26 @@ module Rails
cattr_accessor :metal_paths
self.metal_paths = ["#{Rails.root}/app/metal"]
cattr_accessor :requested_metals
def self.metals
matcher = /#{Regexp.escape('/app/metal/')}(.*)\.rb\Z/
metal_glob = metal_paths.map{ |base| "#{base}/**/*.rb" }
all_metals = {}
Dir[*metal_glob].sort.map do |file|
path = file.match(matcher)[1]
require path
path.classify.constantize
file = file.match(matcher)[1]
all_metals[file.classify] = file
end
load_list = requested_metals || all_metals.keys
load_list.map do |requested_metal|
if metal = all_metals[requested_metal]
require metal
requested_metal.constantize
end
end.compact
end
def initialize(app)

View File

@ -0,0 +1,5 @@
class MetalA < Rails::Rack::Metal
def self.call(env)
[200, { "Content-Type" => "text/html"}, "Hi"]
end
end

View File

@ -0,0 +1,5 @@
class MetalB < Rails::Rack::Metal
def self.call(env)
[200, { "Content-Type" => "text/html"}, "Hi"]
end
end

View File

@ -0,0 +1,5 @@
class FooMetal < Rails::Rack::Metal
def self.call(env)
[200, { "Content-Type" => "text/html"}, "Hi"]
end
end

View File

@ -0,0 +1,7 @@
module Folder
class MetalA < Rails::Rack::Metal
def self.call(env)
[200, { "Content-Type" => "text/html"}, "Hi"]
end
end
end

View File

@ -0,0 +1,7 @@
module Folder
class MetalB < Rails::Rack::Metal
def self.call(env)
[200, { "Content-Type" => "text/html"}, "Hi"]
end
end
end

View File

@ -0,0 +1,57 @@
require 'abstract_unit'
require 'initializer'
class MetalTest < Test::Unit::TestCase
def test_metals_should_return_list_of_found_metal_apps
use_appdir("singlemetal") do
assert_equal(["FooMetal"], found_metals_as_string_array)
end
end
def test_metals_should_return_alphabetical_list_of_found_metal_apps
use_appdir("multiplemetals") do
assert_equal(["MetalA", "MetalB"], found_metals_as_string_array)
end
end
def test_metals_load_order_should_be_overriden_by_requested_metals
use_appdir("multiplemetals") do
Rails::Rack::Metal.requested_metals = ["MetalB", "MetalA"]
assert_equal(["MetalB", "MetalA"], found_metals_as_string_array)
end
end
def test_metals_not_listed_should_not_load
use_appdir("multiplemetals") do
Rails::Rack::Metal.requested_metals = ["MetalB"]
assert_equal(["MetalB"], found_metals_as_string_array)
end
end
p
def test_metal_finding_should_work_with_subfolders
use_appdir("subfolders") do
assert_equal(["Folder::MetalA", "Folder::MetalB"], found_metals_as_string_array)
end
end
def test_metal_finding_with_requested_metals_should_work_with_subfolders
use_appdir("subfolders") do
Rails::Rack::Metal.requested_metals = ["Folder::MetalB"]
assert_equal(["Folder::MetalB"], found_metals_as_string_array)
end
end
private
def use_appdir(root)
dir = "#{File.dirname(__FILE__)}/fixtures/metal/#{root}"
Rails::Rack::Metal.metal_paths = ["#{dir}/app/metal"]
Rails::Rack::Metal.requested_metals = nil
$LOAD_PATH << "#{dir}/app/metal"
yield
end
def found_metals_as_string_array
Rails::Rack::Metal.metals.map { |m| m.to_s }
end
end