mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Refactor ActionView::Template
ActionView::Template is now completely independent from template storage, which allows different back ends such as the database. ActionView::Template's only responsibility is to take in the template source (passed in from ActionView::Path), compile it, and render it.
This commit is contained in:
parent
da3c21ead5
commit
cecafc52ee
23 changed files with 359 additions and 300 deletions
|
@ -494,8 +494,18 @@ module ActionController #:nodoc:
|
|||
end
|
||||
protected :filter_parameters
|
||||
end
|
||||
|
||||
@@exempt_from_layout = [ActionView::TemplateHandlers::RJS]
|
||||
|
||||
def exempt_from_layout(*types)
|
||||
types.each do |type|
|
||||
@@exempt_from_layout <<
|
||||
ActionView::Template.handler_class_for_extension(type)
|
||||
end
|
||||
|
||||
@@exempt_from_layout
|
||||
end
|
||||
|
||||
delegate :exempt_from_layout, :to => 'ActionView::Template'
|
||||
end
|
||||
|
||||
public
|
||||
|
@ -856,13 +866,13 @@ module ActionController #:nodoc:
|
|||
return (performed? ? ret : default_render) if called
|
||||
|
||||
begin
|
||||
default_render
|
||||
rescue ActionView::MissingTemplate => e
|
||||
raise e unless e.action_name == action_name
|
||||
# If the path is the same as the action_name, the action is completely missing
|
||||
view_paths.find_by_parts(action_name, {:formats => formats, :locales => [I18n.locale]}, controller_path)
|
||||
rescue => e
|
||||
raise UnknownAction, "No action responded to #{action_name}. Actions: " +
|
||||
"#{action_methods.sort.to_sentence}", caller
|
||||
end
|
||||
|
||||
default_render
|
||||
end
|
||||
|
||||
# Returns true if a render or redirect has already been performed.
|
||||
|
|
|
@ -378,13 +378,14 @@ module ActionController
|
|||
# ==== Arguments
|
||||
# parts<Array[String, Array[Symbol*], String, Boolean]>::
|
||||
# Example: ["show", [:html, :xml], "users", false]
|
||||
def render_for_parts(parts, layout, options = {})
|
||||
def render_for_parts(parts, layout_details, options = {})
|
||||
parts[1] = {:formats => parts[1], :locales => [I18n.locale]}
|
||||
|
||||
tmp = view_paths.find_by_parts(*parts)
|
||||
|
||||
layout = _pick_layout(*layout) unless tmp.exempt_from_layout?
|
||||
|
||||
layout = _pick_layout(*layout_details) unless
|
||||
self.class.exempt_from_layout.include?(tmp.handler)
|
||||
|
||||
render_for_text(
|
||||
@template._render_template_with_layout(tmp, layout, options, parts[3]))
|
||||
end
|
||||
|
|
|
@ -98,22 +98,22 @@ module ActionController
|
|||
clean_backtrace do
|
||||
case options
|
||||
when NilClass, String
|
||||
rendered = @controller.response.rendered[:template].to_s
|
||||
rendered = (@controller.response.rendered[:template] || []).map { |t| t.identifier }
|
||||
msg = build_message(message,
|
||||
"expecting <?> but rendering with <?>",
|
||||
options, rendered)
|
||||
options, rendered.join(', '))
|
||||
assert_block(msg) do
|
||||
if options.nil?
|
||||
@controller.response.rendered[:template].blank?
|
||||
else
|
||||
rendered.to_s.match(options)
|
||||
rendered.any? { |t| t.match(options) }
|
||||
end
|
||||
end
|
||||
when Hash
|
||||
if expected_partial = options[:partial]
|
||||
partials = @controller.response.rendered[:partials]
|
||||
if expected_count = options[:count]
|
||||
found = partials.detect { |p, _| p.to_s.match(expected_partial) }
|
||||
found = partials.detect { |p, _| p.identifier.match(expected_partial) }
|
||||
actual_count = found.nil? ? 0 : found.second
|
||||
msg = build_message(message,
|
||||
"expecting ? to be rendered ? time(s) but rendered ? time(s)",
|
||||
|
@ -123,7 +123,7 @@ module ActionController
|
|||
msg = build_message(message,
|
||||
"expecting partial <?> but action rendered <?>",
|
||||
options[:partial], partials.keys)
|
||||
assert(partials.keys.any? { |p| p.to_s.match(expected_partial) }, msg)
|
||||
assert(partials.keys.any? { |p| p.identifier.match(expected_partial) }, msg)
|
||||
end
|
||||
else
|
||||
assert @controller.response.rendered[:partials].empty?,
|
||||
|
|
|
@ -196,7 +196,9 @@ module ActionView #:nodoc:
|
|||
delegate :controller_path, :to => :controller, :allow_nil => true
|
||||
|
||||
delegate :request_forgery_protection_token, :template, :params, :session, :cookies, :response, :headers,
|
||||
:flash, :logger, :action_name, :controller_name, :to => :controller
|
||||
:flash, :action_name, :controller_name, :to => :controller
|
||||
|
||||
delegate :logger, :to => :controller, :allow_nil => true
|
||||
|
||||
delegate :find_by_parts, :to => :view_paths
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ module ActionView #:nodoc:
|
|||
def self.type_cast(obj)
|
||||
if obj.is_a?(String)
|
||||
cache = !Object.const_defined?(:Rails) || Rails.configuration.cache_classes
|
||||
Template::FileSystemPath.new(obj, :cache => cache)
|
||||
Template::FileSystemPathWithFallback.new(obj, :cache => cache)
|
||||
else
|
||||
obj
|
||||
end
|
||||
|
@ -34,18 +34,18 @@ module ActionView #:nodoc:
|
|||
end
|
||||
|
||||
def find_by_parts(path, details = {}, prefix = nil, partial = false)
|
||||
template_path = path.sub(/^\//, '')
|
||||
# template_path = path.sub(/^\//, '')
|
||||
template_path = path
|
||||
|
||||
each do |load_path|
|
||||
if template = load_path.find_by_parts(template_path, details, prefix, partial)
|
||||
return template
|
||||
end
|
||||
end
|
||||
|
||||
Template.new(path, self)
|
||||
rescue ActionView::MissingTemplate => e
|
||||
|
||||
# TODO: Have a fallback absolute path?
|
||||
extension = details[:formats] || []
|
||||
raise ActionView::MissingTemplate.new(self, "#{prefix}/#{path}.{#{extension.join(",")}}")
|
||||
raise ActionView::MissingTemplate.new(self, "#{prefix}/#{path} - #{details.inspect} - partial: #{!!partial}")
|
||||
end
|
||||
|
||||
def find_by_parts?(path, extension = nil, prefix = nil, partial = false)
|
||||
|
|
|
@ -46,8 +46,8 @@ module ActionView
|
|||
locals ||= {}
|
||||
|
||||
if controller && layout
|
||||
response.layout = layout.path_without_format_and_extension if controller.respond_to?(:response)
|
||||
logger.info("Rendering template within #{layout.path_without_format_and_extension}") if logger
|
||||
response.layout = layout.identifier if controller.respond_to?(:response)
|
||||
logger.info("Rendering template within #{layout.identifier}") if logger
|
||||
end
|
||||
|
||||
begin
|
||||
|
@ -76,7 +76,6 @@ module ActionView
|
|||
end
|
||||
end
|
||||
rescue Exception => e
|
||||
raise e if template.is_a?(InlineTemplate) || !template.filename
|
||||
if TemplateError === e
|
||||
e.sub_template_of(template)
|
||||
raise e
|
||||
|
@ -86,7 +85,9 @@ module ActionView
|
|||
end
|
||||
|
||||
def _render_inline(inline, layout, options)
|
||||
content = _render_template(InlineTemplate.new(options[:inline], options[:type]), options[:locals] || {})
|
||||
handler = Template.handler_class_for_extension(options[:type] || "erb")
|
||||
template = Template.new(options[:inline], "inline #{options[:inline].inspect}", handler, {})
|
||||
content = _render_template(template, options[:locals] || {})
|
||||
layout ? _render_content_with_layout(content, layout, options[:locals]) : content
|
||||
end
|
||||
|
||||
|
@ -96,7 +97,7 @@ module ActionView
|
|||
|
||||
def _render_template_with_layout(template, layout = nil, options = {}, partial = false)
|
||||
if controller && logger
|
||||
logger.info("Rendering #{template.path_without_extension}" +
|
||||
logger.info("Rendering #{template.identifier}" +
|
||||
(options[:status] ? " (#{options[:status]})" : ''))
|
||||
end
|
||||
|
||||
|
@ -107,7 +108,7 @@ module ActionView
|
|||
_render_template(template, options[:locals] || {})
|
||||
end
|
||||
|
||||
return content unless layout && !template.exempt_from_layout?
|
||||
return content unless layout
|
||||
_render_content_with_layout(content, layout, options[:locals] || {})
|
||||
end
|
||||
end
|
||||
|
|
|
@ -12,7 +12,7 @@ module ActionView
|
|||
end
|
||||
|
||||
def file_name
|
||||
@template.relative_path
|
||||
@template.identifier
|
||||
end
|
||||
|
||||
def message
|
||||
|
@ -30,7 +30,7 @@ module ActionView
|
|||
def sub_template_message
|
||||
if @sub_templates
|
||||
"Trace of template inclusion: " +
|
||||
@sub_templates.collect { |template| template.relative_path }.join(", ")
|
||||
@sub_templates.collect { |template| template.identifier }.join(", ")
|
||||
else
|
||||
""
|
||||
end
|
||||
|
|
|
@ -46,7 +46,7 @@ module ActionView #:nodoc:
|
|||
end
|
||||
|
||||
def handler_class_for_extension(extension)
|
||||
registered_template_handler(extension) || @@default_template_handlers
|
||||
(extension && registered_template_handler(extension.to_sym)) || @@default_template_handlers
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
require "pathname"
|
||||
|
||||
module ActionView
|
||||
class Template
|
||||
# Abstract super class
|
||||
|
@ -26,13 +28,6 @@ module ActionView
|
|||
def find_templates(name, details, prefix, partial)
|
||||
raise NotImplementedError
|
||||
end
|
||||
|
||||
# TODO: Refactor this to abstract out the file system
|
||||
def initialize_template(file)
|
||||
t = Template.new(file.split("#{self}/").last, self)
|
||||
t.load!
|
||||
t
|
||||
end
|
||||
|
||||
def valid_handlers
|
||||
@valid_handlers ||= TemplateHandlers.extensions
|
||||
|
@ -44,10 +39,10 @@ module ActionView
|
|||
/\.(?:#{e})$/
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
def handler_glob
|
||||
e = TemplateHandlers.extensions.join(',')
|
||||
".{#{e}}"
|
||||
e = TemplateHandlers.extensions.map{|h| ".#{h},"}.join
|
||||
"{#{e}}"
|
||||
end
|
||||
|
||||
def formats_glob
|
||||
|
@ -69,23 +64,19 @@ module ActionView
|
|||
def initialize(path, options = {})
|
||||
raise ArgumentError, "path already is a Path class" if path.is_a?(Path)
|
||||
super(options)
|
||||
@path = path
|
||||
@path = Pathname.new(path).expand_path
|
||||
end
|
||||
|
||||
|
||||
# TODO: This is the currently needed API. Make this suck less
|
||||
# ==== <suck>
|
||||
attr_reader :path
|
||||
|
||||
def to_s
|
||||
if defined?(RAILS_ROOT)
|
||||
path.to_s.sub(/^#{Regexp.escape(File.expand_path(RAILS_ROOT))}\//, '')
|
||||
else
|
||||
path.to_s
|
||||
end
|
||||
path.to_s
|
||||
end
|
||||
|
||||
def to_str
|
||||
path.to_str
|
||||
path.to_s
|
||||
end
|
||||
|
||||
def ==(path)
|
||||
|
@ -97,11 +88,15 @@ module ActionView
|
|||
end
|
||||
# ==== </suck>
|
||||
|
||||
def find_templates(name, details, prefix, partial)
|
||||
if glob = parts_to_glob(name, details, prefix, partial)
|
||||
def find_templates(name, details, prefix, partial, root = "#{@path}/")
|
||||
if glob = details_to_glob(name, details, prefix, partial, root)
|
||||
cached(glob) do
|
||||
Dir[glob].map do |path|
|
||||
initialize_template(path) unless File.directory?(path)
|
||||
next if File.directory?(path)
|
||||
source = File.read(path)
|
||||
identifier = Pathname.new(path).expand_path.to_s
|
||||
|
||||
Template.new(source, identifier, *path_to_details(path))
|
||||
end.compact
|
||||
end
|
||||
end
|
||||
|
@ -109,7 +104,8 @@ module ActionView
|
|||
|
||||
private
|
||||
|
||||
def parts_to_glob(name, details, prefix, partial)
|
||||
# :api: plugin
|
||||
def details_to_glob(name, details, prefix, partial, root)
|
||||
path = ""
|
||||
path << "#{prefix}/" unless prefix.empty?
|
||||
path << (partial ? "_#{name}" : name)
|
||||
|
@ -123,8 +119,34 @@ module ActionView
|
|||
end
|
||||
end
|
||||
|
||||
"#{@path}/#{path}#{extensions}#{handler_glob}"
|
||||
"#{root}#{path}#{extensions}#{handler_glob}"
|
||||
end
|
||||
|
||||
# TODO: fix me
|
||||
# :api: plugin
|
||||
def path_to_details(path)
|
||||
# [:erb, :format => :html, :locale => :en, :partial => true/false]
|
||||
if m = path.match(%r'/(_)?[\w-]+(\.[\w-]+)*\.(\w+)$')
|
||||
partial = m[1] == '_'
|
||||
details = (m[2]||"").split('.').reject { |e| e.empty? }
|
||||
handler = Template.handler_class_for_extension(m[3])
|
||||
|
||||
format = Mime[details.last] && details.pop.to_sym
|
||||
locale = details.last && details.pop.to_sym
|
||||
|
||||
return handler, :format => format, :locale => locale, :partial => partial
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class FileSystemPathWithFallback < FileSystemPath
|
||||
|
||||
def find_templates(name, details, prefix, partial)
|
||||
templates = super
|
||||
return super(name, details, prefix, partial, '') if templates.empty?
|
||||
templates
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,188 +1,230 @@
|
|||
# encoding: utf-8
|
||||
# This is so that templates compiled in this file are UTF-8
|
||||
|
||||
require 'set'
|
||||
require "action_view/template/path"
|
||||
|
||||
module ActionView #:nodoc:
|
||||
module ActionView
|
||||
class Template
|
||||
extend TemplateHandlers
|
||||
extend ActiveSupport::Memoizable
|
||||
attr_reader :source, :identifier, :handler
|
||||
|
||||
module Loading
|
||||
def load!
|
||||
@cached = true
|
||||
# freeze
|
||||
end
|
||||
def initialize(source, identifier, handler, details)
|
||||
@source = source
|
||||
@identifier = identifier
|
||||
@handler = handler
|
||||
@details = details
|
||||
end
|
||||
include Loading
|
||||
|
||||
include Renderable
|
||||
|
||||
# Templates that are exempt from layouts
|
||||
@@exempt_from_layout = Set.new([/\.rjs$/])
|
||||
|
||||
# Don't render layouts for templates with the given extensions.
|
||||
def self.exempt_from_layout(*extensions)
|
||||
regexps = extensions.collect do |extension|
|
||||
extension.is_a?(Regexp) ? extension : /\.#{Regexp.escape(extension.to_s)}$/
|
||||
end
|
||||
@@exempt_from_layout.merge(regexps)
|
||||
def render(view, locals, &blk)
|
||||
method_name = compile(locals, view)
|
||||
view.send(method_name, locals, &blk)
|
||||
end
|
||||
|
||||
# TODO: Figure out how to abstract this
|
||||
def variable_name
|
||||
identifier[%r'_?(\w+)(\.\w+)*$', 1].to_sym
|
||||
end
|
||||
|
||||
attr_accessor :template_path, :filename, :load_path, :base_path
|
||||
attr_accessor :locale, :name, :format, :extension
|
||||
delegate :to_s, :to => :path
|
||||
|
||||
def initialize(template_path, load_paths = [])
|
||||
template_path = template_path.dup
|
||||
@load_path, @filename = find_full_path(template_path, load_paths)
|
||||
@base_path, @name, @locale, @format, @extension = split(template_path)
|
||||
@base_path.to_s.gsub!(/\/$/, '') # Push to split method
|
||||
|
||||
# Extend with partial super powers
|
||||
extend RenderablePartial if @name =~ /^_/
|
||||
# TODO: Figure out how to abstract this
|
||||
def counter_name
|
||||
"#{variable_name}_counter".to_sym
|
||||
end
|
||||
|
||||
def accessible_paths
|
||||
paths = []
|
||||
|
||||
if valid_extension?(extension)
|
||||
paths << path
|
||||
paths << path_without_extension
|
||||
if multipart?
|
||||
formats = format.split(".")
|
||||
paths << "#{path_without_format_and_extension}.#{formats.first}"
|
||||
paths << "#{path_without_format_and_extension}.#{formats.second}"
|
||||
end
|
||||
else
|
||||
# template without explicit template handler should only be reachable through its exact path
|
||||
paths << template_path
|
||||
end
|
||||
|
||||
paths
|
||||
# TODO: kill hax
|
||||
def partial?
|
||||
@details[:partial]
|
||||
end
|
||||
|
||||
def relative_path
|
||||
path = File.expand_path(filename)
|
||||
path.sub!(/^#{Regexp.escape(File.expand_path(RAILS_ROOT))}\//, '') if defined?(RAILS_ROOT)
|
||||
path
|
||||
end
|
||||
memoize :relative_path
|
||||
|
||||
def source
|
||||
File.read(filename)
|
||||
end
|
||||
memoize :source
|
||||
|
||||
def exempt_from_layout?
|
||||
@@exempt_from_layout.any? { |exempted| path =~ exempted }
|
||||
end
|
||||
|
||||
def path_without_extension
|
||||
[base_path, [name, locale, format].compact.join('.')].compact.join('/')
|
||||
end
|
||||
memoize :path_without_extension
|
||||
|
||||
def path_without_format_and_extension
|
||||
[base_path, [name, locale].compact.join('.')].compact.join('/')
|
||||
end
|
||||
memoize :path_without_format_and_extension
|
||||
|
||||
def path
|
||||
[base_path, [name, locale, format, extension].compact.join('.')].compact.join('/')
|
||||
end
|
||||
memoize :path
|
||||
|
||||
# TODO: Move out of Template
|
||||
def mime_type
|
||||
Mime::Type.lookup_by_extension(format) if format && defined?(::Mime)
|
||||
Mime::Type.lookup_by_extension(@details[:format]) if @details[:format]
|
||||
end
|
||||
memoize :mime_type
|
||||
|
||||
def multipart?
|
||||
format && format.include?('.')
|
||||
end
|
||||
|
||||
def content_type
|
||||
format && format.gsub('.', '/')
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def format_and_extension
|
||||
(extensions = [format, extension].compact.join(".")).blank? ? nil : extensions
|
||||
end
|
||||
memoize :format_and_extension
|
||||
|
||||
def mtime
|
||||
File.mtime(filename)
|
||||
end
|
||||
memoize :mtime
|
||||
def compile(locals, view)
|
||||
method_name = build_method_name(locals)
|
||||
|
||||
return method_name if view.respond_to?(method_name)
|
||||
|
||||
locals_code = locals.keys.map! { |key| "#{key} = local_assigns[:#{key}];" }.join
|
||||
|
||||
def method_segment
|
||||
relative_path.to_s.gsub(/([^a-zA-Z0-9_])/) { $1.ord }
|
||||
end
|
||||
memoize :method_segment
|
||||
|
||||
def stale?
|
||||
File.mtime(filename) > mtime
|
||||
end
|
||||
|
||||
def recompile?
|
||||
!@cached
|
||||
end
|
||||
|
||||
def valid_extension?(extension)
|
||||
!Template.registered_template_handler(extension).nil?
|
||||
end
|
||||
|
||||
def valid_locale?(locale)
|
||||
I18n.available_locales.include?(locale.to_sym)
|
||||
end
|
||||
|
||||
def find_full_path(path, load_paths)
|
||||
load_paths = Array(load_paths) + [nil]
|
||||
load_paths.each do |load_path|
|
||||
file = load_path ? "#{load_path.to_str}/#{path}" : path
|
||||
return load_path, file if File.file?(file)
|
||||
end
|
||||
raise MissingTemplate.new(load_paths, path)
|
||||
end
|
||||
|
||||
# Returns file split into an array
|
||||
# [base_path, name, locale, format, extension]
|
||||
def split(file)
|
||||
if m = file.to_s.match(/^(.*\/)?([^\.]+)\.(.*)$/)
|
||||
base_path = m[1]
|
||||
name = m[2]
|
||||
extensions = m[3]
|
||||
else
|
||||
return
|
||||
end
|
||||
|
||||
locale = nil
|
||||
format = nil
|
||||
extension = nil
|
||||
|
||||
if m = extensions.split(".")
|
||||
if valid_locale?(m[0]) && m[1] && valid_extension?(m[2]) # All three
|
||||
locale = m[0]
|
||||
format = m[1]
|
||||
extension = m[2]
|
||||
elsif m[0] && m[1] && valid_extension?(m[2]) # Multipart formats
|
||||
format = "#{m[0]}.#{m[1]}"
|
||||
extension = m[2]
|
||||
elsif valid_locale?(m[0]) && valid_extension?(m[1]) # locale and extension
|
||||
locale = m[0]
|
||||
extension = m[1]
|
||||
elsif valid_extension?(m[1]) # format and extension
|
||||
format = m[0]
|
||||
extension = m[1]
|
||||
elsif valid_extension?(m[0]) # Just extension
|
||||
extension = m[0]
|
||||
else # No extension
|
||||
format = m[0]
|
||||
source = <<-end_src
|
||||
def #{method_name}(local_assigns)
|
||||
old_output_buffer = output_buffer;#{locals_code};#{@handler.call(self)}
|
||||
ensure
|
||||
self.output_buffer = old_output_buffer
|
||||
end
|
||||
end
|
||||
end_src
|
||||
|
||||
[base_path, name, locale, format, extension]
|
||||
begin
|
||||
ActionView::Base::CompiledTemplates.module_eval(source, identifier, 0)
|
||||
method_name
|
||||
rescue Exception => e # errors from template code
|
||||
if logger = (view && view.logger)
|
||||
logger.debug "ERROR: compiling #{method_name} RAISED #{e}"
|
||||
logger.debug "Function body: #{source}"
|
||||
logger.debug "Backtrace: #{e.backtrace.join("\n")}"
|
||||
end
|
||||
|
||||
raise ActionView::TemplateError.new(self, {}, e)
|
||||
end
|
||||
end
|
||||
|
||||
def build_method_name(locals)
|
||||
# TODO: is locals.keys.hash reliably the same?
|
||||
"_render_template_#{@identifier.hash}_#{__id__}_#{locals.keys.hash}".gsub('-', "_")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if false
|
||||
module ActionView #:nodoc:
|
||||
class Template
|
||||
extend TemplateHandlers
|
||||
extend ActiveSupport::Memoizable
|
||||
|
||||
module Loading
|
||||
def load!
|
||||
@cached = true
|
||||
# freeze
|
||||
end
|
||||
end
|
||||
include Loading
|
||||
|
||||
include Renderable
|
||||
|
||||
# Templates that are exempt from layouts
|
||||
@@exempt_from_layout = Set.new([/\.rjs$/])
|
||||
|
||||
# Don't render layouts for templates with the given extensions.
|
||||
def self.exempt_from_layout(*extensions)
|
||||
regexps = extensions.collect do |extension|
|
||||
extension.is_a?(Regexp) ? extension : /\.#{Regexp.escape(extension.to_s)}$/
|
||||
end
|
||||
@@exempt_from_layout.merge(regexps)
|
||||
end
|
||||
|
||||
attr_accessor :template_path, :filename, :load_path, :base_path
|
||||
attr_accessor :locale, :name, :format, :extension
|
||||
delegate :to_s, :to => :path
|
||||
|
||||
def initialize(template_path, load_paths = [])
|
||||
template_path = template_path.dup
|
||||
@load_path, @filename = find_full_path(template_path, load_paths)
|
||||
@name = template_path.to_s.split("/").last.split(".").first
|
||||
# @base_path, @name, @locale, @format, @extension = split(template_path)
|
||||
@base_path.to_s.gsub!(/\/$/, '') # Push to split method
|
||||
|
||||
# Extend with partial super powers
|
||||
extend RenderablePartial if @name =~ /^_/
|
||||
end
|
||||
|
||||
def accessible_paths
|
||||
paths = []
|
||||
|
||||
if valid_extension?(extension)
|
||||
paths << path
|
||||
paths << path_without_extension
|
||||
if multipart?
|
||||
formats = format.split(".")
|
||||
paths << "#{path_without_format_and_extension}.#{formats.first}"
|
||||
paths << "#{path_without_format_and_extension}.#{formats.second}"
|
||||
end
|
||||
else
|
||||
# template without explicit template handler should only be reachable through its exact path
|
||||
paths << template_path
|
||||
end
|
||||
|
||||
paths
|
||||
end
|
||||
|
||||
def relative_path
|
||||
path = File.expand_path(filename)
|
||||
path.sub!(/^#{Regexp.escape(File.expand_path(RAILS_ROOT))}\//, '') if defined?(RAILS_ROOT)
|
||||
path
|
||||
end
|
||||
memoize :relative_path
|
||||
|
||||
def source
|
||||
File.read(filename)
|
||||
end
|
||||
memoize :source
|
||||
|
||||
def exempt_from_layout?
|
||||
@@exempt_from_layout.any? { |exempted| path =~ exempted }
|
||||
end
|
||||
|
||||
def path_without_extension
|
||||
[base_path, [name, locale, format].compact.join('.')].compact.join('/')
|
||||
end
|
||||
memoize :path_without_extension
|
||||
|
||||
def path_without_format_and_extension
|
||||
[base_path, [name, locale].compact.join('.')].compact.join('/')
|
||||
end
|
||||
memoize :path_without_format_and_extension
|
||||
|
||||
def path
|
||||
[base_path, [name, locale, format, extension].compact.join('.')].compact.join('/')
|
||||
end
|
||||
memoize :path
|
||||
|
||||
def mime_type
|
||||
Mime::Type.lookup_by_extension(format) if format && defined?(::Mime)
|
||||
end
|
||||
memoize :mime_type
|
||||
|
||||
def multipart?
|
||||
format && format.include?('.')
|
||||
end
|
||||
|
||||
def content_type
|
||||
format && format.gsub('.', '/')
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def format_and_extension
|
||||
(extensions = [format, extension].compact.join(".")).blank? ? nil : extensions
|
||||
end
|
||||
memoize :format_and_extension
|
||||
|
||||
def mtime
|
||||
File.mtime(filename)
|
||||
end
|
||||
memoize :mtime
|
||||
|
||||
def method_segment
|
||||
relative_path.to_s.gsub(/([^a-zA-Z0-9_])/) { $1.ord }
|
||||
end
|
||||
memoize :method_segment
|
||||
|
||||
def stale?
|
||||
File.mtime(filename) > mtime
|
||||
end
|
||||
|
||||
def recompile?
|
||||
!@cached
|
||||
end
|
||||
|
||||
def valid_extension?(extension)
|
||||
!Template.registered_template_handler(extension).nil?
|
||||
end
|
||||
|
||||
def valid_locale?(locale)
|
||||
I18n.available_locales.include?(locale.to_sym)
|
||||
end
|
||||
|
||||
def find_full_path(path, load_paths)
|
||||
load_paths = Array(load_paths) + [nil]
|
||||
load_paths.each do |load_path|
|
||||
file = load_path ? "#{load_path.to_str}/#{path}" : path
|
||||
return load_path, file if File.file?(file)
|
||||
end
|
||||
raise MissingTemplate.new(load_paths, path)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -10,9 +10,10 @@ module ActionView
|
|||
|
||||
alias_method :_render_template_without_template_tracking, :_render_template
|
||||
def _render_template(template, local_assigns = {})
|
||||
if template.respond_to?(:path) && !template.is_a?(InlineTemplate)
|
||||
@_rendered[:partials][template] += 1 if template.is_a?(RenderablePartial)
|
||||
@_rendered[:template] ||= template
|
||||
if template.respond_to?(:identifier)
|
||||
@_rendered[:partials][template] += 1 if template.partial?
|
||||
@_rendered[:template] ||= []
|
||||
@_rendered[:template] << template
|
||||
end
|
||||
_render_template_without_template_tracking(template, local_assigns)
|
||||
end
|
||||
|
|
|
@ -139,7 +139,7 @@ module AbstractController
|
|||
private
|
||||
def self.layout(formats)
|
||||
begin
|
||||
view_paths.find_by_parts(name.underscore, {:formats => formats}t, "layouts")
|
||||
view_paths.find_by_parts(name.underscore, {:formats => formats}, "layouts")
|
||||
rescue ActionView::MissingTemplate
|
||||
begin
|
||||
view_paths.find_by_parts("application", {:formats => formats}, "layouts")
|
||||
|
|
|
@ -211,7 +211,7 @@ class IsolatedHelpersTest < Test::Unit::TestCase
|
|||
end
|
||||
|
||||
def test_helper_in_a
|
||||
assert_raise(NameError) { A.process(@request, @response) }
|
||||
assert_raise(ActionView::TemplateError) { A.process(@request, @response) }
|
||||
end
|
||||
|
||||
def test_helper_in_b
|
||||
|
|
|
@ -56,8 +56,8 @@ class LayoutAutoDiscoveryTest < ActionController::TestCase
|
|||
def test_third_party_template_library_auto_discovers_layout
|
||||
@controller = ThirdPartyTemplateLibraryController.new
|
||||
get :hello
|
||||
assert_equal 'layouts/third_party_template_library.mab', @controller.active_layout(true).to_s
|
||||
assert_equal 'layouts/third_party_template_library', @response.layout
|
||||
assert @controller.active_layout(true).identifier.include?('layouts/third_party_template_library.mab')
|
||||
assert @response.layout.include?('layouts/third_party_template_library')
|
||||
assert_response :success
|
||||
assert_equal 'Mab', @response.body
|
||||
end
|
||||
|
@ -72,7 +72,7 @@ class LayoutAutoDiscoveryTest < ActionController::TestCase
|
|||
def test_namespaced_controllers_auto_detect_layouts
|
||||
@controller = MultipleExtensions.new
|
||||
get :hello
|
||||
assert_equal 'layouts/multiple_extensions.html.erb', @controller.active_layout(true).to_s
|
||||
assert @controller.active_layout(true).identifier.include?('layouts/multiple_extensions.html.erb')
|
||||
assert_equal 'multiple_extensions.html.erb hello.rhtml', @response.body.strip
|
||||
end
|
||||
end
|
||||
|
@ -116,22 +116,24 @@ class RendersNoLayoutController < LayoutTest
|
|||
end
|
||||
|
||||
class LayoutSetInResponseTest < ActionController::TestCase
|
||||
include ActionView::TemplateHandlers
|
||||
|
||||
def test_layout_set_when_using_default_layout
|
||||
@controller = DefaultLayoutController.new
|
||||
get :hello
|
||||
assert_equal 'layouts/layout_test', @response.layout
|
||||
assert @response.layout.include?('layouts/layout_test')
|
||||
end
|
||||
|
||||
def test_layout_set_when_set_in_controller
|
||||
@controller = HasOwnLayoutController.new
|
||||
get :hello
|
||||
assert_equal 'layouts/item', @response.layout
|
||||
assert @response.layout.include?('layouts/item')
|
||||
end
|
||||
|
||||
def test_layout_only_exception_when_included
|
||||
@controller = OnlyLayoutController.new
|
||||
get :hello
|
||||
assert_equal 'layouts/item', @response.layout
|
||||
assert @response.layout.include?('layouts/item')
|
||||
end
|
||||
|
||||
def test_layout_only_exception_when_excepted
|
||||
|
@ -143,7 +145,7 @@ class LayoutSetInResponseTest < ActionController::TestCase
|
|||
def test_layout_except_exception_when_included
|
||||
@controller = ExceptLayoutController.new
|
||||
get :hello
|
||||
assert_equal 'layouts/item', @response.layout
|
||||
assert @response.layout.include?('layouts/item')
|
||||
end
|
||||
|
||||
def test_layout_except_exception_when_excepted
|
||||
|
@ -155,7 +157,7 @@ class LayoutSetInResponseTest < ActionController::TestCase
|
|||
def test_layout_set_when_using_render
|
||||
@controller = SetsLayoutInRenderController.new
|
||||
get :hello
|
||||
assert_equal 'layouts/third_party_template_library', @response.layout
|
||||
assert @response.layout.include?('layouts/third_party_template_library')
|
||||
end
|
||||
|
||||
def test_layout_is_not_set_when_none_rendered
|
||||
|
@ -165,14 +167,14 @@ class LayoutSetInResponseTest < ActionController::TestCase
|
|||
end
|
||||
|
||||
def test_exempt_from_layout_honored_by_render_template
|
||||
ActionController::Base.exempt_from_layout :rhtml
|
||||
ActionController::Base.exempt_from_layout :erb
|
||||
@controller = RenderWithTemplateOptionController.new
|
||||
|
||||
get :hello
|
||||
assert_equal "alt/hello.rhtml", @response.body.strip
|
||||
|
||||
ensure
|
||||
ActionController::Base.exempt_from_layout.delete(/\.rhtml$/)
|
||||
ActionController::Base.exempt_from_layout.delete(ERB)
|
||||
end
|
||||
|
||||
def test_layout_is_picked_from_the_controller_instances_view_path
|
||||
|
@ -232,7 +234,7 @@ unless RUBY_PLATFORM =~ /(:?mswin|mingw|bccwin)/
|
|||
@controller = LayoutSymlinkedTest.new
|
||||
get :hello
|
||||
assert_response 200
|
||||
assert_equal "layouts/symlinked/symlinked_layout", @response.layout
|
||||
assert @response.layout.include?("layouts/symlinked/symlinked_layout")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -773,7 +773,7 @@ class RenderTest < ActionController::TestCase
|
|||
begin
|
||||
get :render_line_offset
|
||||
flunk "the action should have raised an exception"
|
||||
rescue RuntimeError => exc
|
||||
rescue StandardError => exc
|
||||
line = exc.backtrace.first
|
||||
assert(line =~ %r{:(\d+):})
|
||||
assert_equal "1", $1,
|
||||
|
@ -1736,7 +1736,7 @@ class RenderingLoggingTest < ActionController::TestCase
|
|||
@controller.logger = MockLogger.new
|
||||
get :layout_test
|
||||
logged = @controller.logger.logged.find_all {|l| l =~ /render/i }
|
||||
assert_equal "Rendering test/hello_world", logged[0]
|
||||
assert_equal "Rendering template within layouts/standard", logged[1]
|
||||
assert logged[0] =~ %r{Rendering.*test/hello_world}
|
||||
assert logged[1] =~ %r{Rendering template within.*layouts/standard}
|
||||
end
|
||||
end
|
||||
|
|
|
@ -20,7 +20,7 @@ class ViewLoadPathsTest < ActionController::TestCase
|
|||
layout 'test/sub'
|
||||
def hello_world; render(:template => 'test/hello_world'); end
|
||||
end
|
||||
|
||||
|
||||
def setup
|
||||
TestController.view_paths = nil
|
||||
|
||||
|
@ -42,30 +42,39 @@ class ViewLoadPathsTest < ActionController::TestCase
|
|||
ActiveSupport::Deprecation.behavior = @old_behavior
|
||||
end
|
||||
|
||||
def expand(array)
|
||||
array.map {|x| File.expand_path(x)}
|
||||
end
|
||||
|
||||
def assert_paths(*paths)
|
||||
controller = paths.first.is_a?(Class) ? paths.shift : @controller
|
||||
assert_equal expand(paths), controller.view_paths.map(&:to_s)
|
||||
end
|
||||
|
||||
def test_template_load_path_was_set_correctly
|
||||
assert_equal [FIXTURE_LOAD_PATH], @controller.view_paths.map(&:to_s)
|
||||
assert_paths FIXTURE_LOAD_PATH
|
||||
end
|
||||
|
||||
def test_controller_appends_view_path_correctly
|
||||
@controller.append_view_path 'foo'
|
||||
assert_equal [FIXTURE_LOAD_PATH, 'foo'], @controller.view_paths.map(&:to_s)
|
||||
assert_paths(FIXTURE_LOAD_PATH, "foo")
|
||||
|
||||
@controller.append_view_path(%w(bar baz))
|
||||
assert_equal [FIXTURE_LOAD_PATH, 'foo', 'bar', 'baz'], @controller.view_paths.map(&:to_s)
|
||||
|
||||
assert_paths(FIXTURE_LOAD_PATH, "foo", "bar", "baz")
|
||||
|
||||
@controller.append_view_path(FIXTURE_LOAD_PATH)
|
||||
assert_equal [FIXTURE_LOAD_PATH, 'foo', 'bar', 'baz', FIXTURE_LOAD_PATH], @controller.view_paths.map(&:to_s)
|
||||
assert_paths(FIXTURE_LOAD_PATH, "foo", "bar", "baz", FIXTURE_LOAD_PATH)
|
||||
end
|
||||
|
||||
def test_controller_prepends_view_path_correctly
|
||||
@controller.prepend_view_path 'baz'
|
||||
assert_equal ['baz', FIXTURE_LOAD_PATH], @controller.view_paths.map(&:to_s)
|
||||
assert_paths("baz", FIXTURE_LOAD_PATH)
|
||||
|
||||
@controller.prepend_view_path(%w(foo bar))
|
||||
assert_equal ['foo', 'bar', 'baz', FIXTURE_LOAD_PATH], @controller.view_paths.map(&:to_s)
|
||||
assert_paths "foo", "bar", "baz", FIXTURE_LOAD_PATH
|
||||
|
||||
@controller.prepend_view_path(FIXTURE_LOAD_PATH)
|
||||
assert_equal [FIXTURE_LOAD_PATH, 'foo', 'bar', 'baz', FIXTURE_LOAD_PATH], @controller.view_paths.map(&:to_s)
|
||||
assert_paths FIXTURE_LOAD_PATH, "foo", "bar", "baz", FIXTURE_LOAD_PATH
|
||||
end
|
||||
|
||||
def test_template_appends_view_path_correctly
|
||||
|
@ -73,11 +82,11 @@ class ViewLoadPathsTest < ActionController::TestCase
|
|||
class_view_paths = TestController.view_paths
|
||||
|
||||
@controller.append_view_path 'foo'
|
||||
assert_equal [FIXTURE_LOAD_PATH, 'foo'], @controller.view_paths.map(&:to_s)
|
||||
assert_paths FIXTURE_LOAD_PATH, "foo"
|
||||
|
||||
@controller.append_view_path(%w(bar baz))
|
||||
assert_equal [FIXTURE_LOAD_PATH, 'foo', 'bar', 'baz'], @controller.view_paths.map(&:to_s)
|
||||
assert_equal class_view_paths, TestController.view_paths
|
||||
assert_paths FIXTURE_LOAD_PATH, "foo", "bar", "baz"
|
||||
assert_paths TestController, *class_view_paths
|
||||
end
|
||||
|
||||
def test_template_prepends_view_path_correctly
|
||||
|
@ -85,11 +94,11 @@ class ViewLoadPathsTest < ActionController::TestCase
|
|||
class_view_paths = TestController.view_paths
|
||||
|
||||
@controller.prepend_view_path 'baz'
|
||||
assert_equal ['baz', FIXTURE_LOAD_PATH], @controller.view_paths.map(&:to_s)
|
||||
assert_paths "baz", FIXTURE_LOAD_PATH
|
||||
|
||||
@controller.prepend_view_path(%w(foo bar))
|
||||
assert_equal ['foo', 'bar', 'baz', FIXTURE_LOAD_PATH], @controller.view_paths.map(&:to_s)
|
||||
assert_equal class_view_paths, TestController.view_paths
|
||||
assert_paths "foo", "bar", "baz", FIXTURE_LOAD_PATH
|
||||
assert_paths TestController, *class_view_paths
|
||||
end
|
||||
|
||||
def test_view_paths
|
||||
|
@ -130,12 +139,12 @@ class ViewLoadPathsTest < ActionController::TestCase
|
|||
|
||||
A.view_paths = ['a/path']
|
||||
|
||||
assert_equal ['a/path'], A.view_paths.map(&:to_s)
|
||||
assert_equal A.view_paths, B.view_paths
|
||||
assert_equal original_load_paths, C.view_paths
|
||||
|
||||
assert_paths A, "a/path"
|
||||
assert_paths A, *B.view_paths
|
||||
assert_paths C, *original_load_paths
|
||||
|
||||
C.view_paths = []
|
||||
assert_nothing_raised { C.view_paths << 'c/path' }
|
||||
assert_equal ['c/path'], C.view_paths.map(&:to_s)
|
||||
assert_paths C, "c/path"
|
||||
end
|
||||
end
|
||||
|
|
1
actionpack/test/fixtures/test/render_file_with_locals_and_default.erb
vendored
Normal file
1
actionpack/test/fixtures/test/render_file_with_locals_and_default.erb
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
<%= secret ||= 'one' %>
|
|
@ -5,37 +5,13 @@ class CompiledTemplatesTest < Test::Unit::TestCase
|
|||
def setup
|
||||
@compiled_templates = ActionView::Base::CompiledTemplates
|
||||
@compiled_templates.instance_methods.each do |m|
|
||||
@compiled_templates.send(:remove_method, m) if m =~ /^_run_/
|
||||
@compiled_templates.send(:remove_method, m) if m =~ /^_render_template_/
|
||||
end
|
||||
end
|
||||
|
||||
def test_template_gets_compiled
|
||||
assert_equal 0, @compiled_templates.instance_methods.size
|
||||
assert_equal "Hello world!", render(:file => "test/hello_world.erb")
|
||||
assert_equal 1, @compiled_templates.instance_methods.size
|
||||
end
|
||||
|
||||
|
||||
def test_template_gets_recompiled_when_using_different_keys_in_local_assigns
|
||||
assert_equal 0, @compiled_templates.instance_methods.size
|
||||
assert_equal "Hello world!", render(:file => "test/hello_world.erb")
|
||||
assert_equal "Hello world!", render(:file => "test/hello_world.erb", :locals => {:foo => "bar"})
|
||||
assert_equal 2, @compiled_templates.instance_methods.size
|
||||
end
|
||||
|
||||
def test_compiled_template_will_not_be_recompiled_when_rendered_with_identical_local_assigns
|
||||
assert_equal 0, @compiled_templates.instance_methods.size
|
||||
assert_equal "Hello world!", render(:file => "test/hello_world.erb")
|
||||
ActionView::Template.any_instance.expects(:compile!).never
|
||||
assert_equal "Hello world!", render(:file => "test/hello_world.erb")
|
||||
end
|
||||
|
||||
def test_compiled_template_will_always_be_recompiled_when_template_is_not_cached
|
||||
ActionView::Template.any_instance.expects(:recompile?).times(3).returns(true)
|
||||
assert_equal 0, @compiled_templates.instance_methods.size
|
||||
assert_equal "Hello world!", render(:file => "#{FIXTURE_LOAD_PATH}/test/hello_world.erb")
|
||||
ActionView::Template.any_instance.expects(:compile!).times(3)
|
||||
3.times { assert_equal "Hello world!", render(:file => "#{FIXTURE_LOAD_PATH}/test/hello_world.erb") }
|
||||
assert_equal 1, @compiled_templates.instance_methods.size
|
||||
assert_equal "one", render(:file => "test/render_file_with_locals_and_default.erb")
|
||||
assert_equal "two", render(:file => "test/render_file_with_locals_and_default.erb", :locals => { :secret => "two" })
|
||||
end
|
||||
|
||||
def test_template_changes_are_not_reflected_with_cached_templates
|
||||
|
@ -61,14 +37,12 @@ class CompiledTemplatesTest < Test::Unit::TestCase
|
|||
|
||||
def render_with_cache(*args)
|
||||
view_paths = ActionController::Base.view_paths
|
||||
assert_equal ActionView::Template::FileSystemPath, view_paths.first.class
|
||||
ActionView::Base.new(view_paths, {}).render(*args)
|
||||
end
|
||||
|
||||
def render_without_cache(*args)
|
||||
path = ActionView::Template::FileSystemPath.new(FIXTURE_LOAD_PATH)
|
||||
path = ActionView::Template::FileSystemPathWithFallback.new(FIXTURE_LOAD_PATH)
|
||||
view_paths = ActionView::Base.process_view_paths(path)
|
||||
assert_equal ActionView::Template::FileSystemPath, view_paths.first.class
|
||||
ActionView::Base.new(view_paths, {}).render(*args)
|
||||
end
|
||||
|
||||
|
|
|
@ -91,10 +91,6 @@ module RenderTestCases
|
|||
assert_equal "The secret is in the sauce\n", @view.render(:file => "test/dot.directory/render_file_with_ivar")
|
||||
end
|
||||
|
||||
def test_render_has_access_current_template
|
||||
assert_equal "test/template.erb", @view.render(:file => "test/template.erb")
|
||||
end
|
||||
|
||||
def test_render_update
|
||||
# TODO: You should not have to stub out template because template is self!
|
||||
@view.instance_variable_set(:@template, @view)
|
||||
|
@ -240,10 +236,6 @@ module RenderTestCases
|
|||
end
|
||||
end
|
||||
|
||||
def test_template_with_malformed_template_handler_is_reachable_through_its_exact_filename
|
||||
assert_equal "Don't render me!", @view.render(:file => 'test/malformed/malformed.html.erb~')
|
||||
end
|
||||
|
||||
def test_render_with_layout
|
||||
assert_equal %(<title></title>\nHello world!\n),
|
||||
@view.render(:file => "test/hello_world.erb", :layout => "layouts/yield")
|
||||
|
@ -269,7 +261,7 @@ class CachedViewRenderTest < ActiveSupport::TestCase
|
|||
# Ensure view path cache is primed
|
||||
def setup
|
||||
view_paths = ActionController::Base.view_paths
|
||||
assert_equal ActionView::Template::FileSystemPath, view_paths.first.class
|
||||
assert_equal ActionView::Template::FileSystemPathWithFallback, view_paths.first.class
|
||||
setup_view(view_paths)
|
||||
end
|
||||
end
|
||||
|
@ -280,9 +272,9 @@ class LazyViewRenderTest < ActiveSupport::TestCase
|
|||
# Test the same thing as above, but make sure the view path
|
||||
# is not eager loaded
|
||||
def setup
|
||||
path = ActionView::Template::FileSystemPath.new(FIXTURE_LOAD_PATH)
|
||||
path = ActionView::Template::FileSystemPathWithFallback.new(FIXTURE_LOAD_PATH)
|
||||
view_paths = ActionView::Base.process_view_paths(path)
|
||||
assert_equal ActionView::Template::FileSystemPath, view_paths.first.class
|
||||
assert_equal ActionView::Template::FileSystemPathWithFallback, view_paths.first.class
|
||||
setup_view(view_paths)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -110,8 +110,10 @@ class Module
|
|||
|
||||
allow_nil = options[:allow_nil] && "#{to} && "
|
||||
|
||||
file, line = caller[0].split(":")
|
||||
|
||||
methods.each do |method|
|
||||
module_eval(<<-EOS, "(__DELEGATION__)", 1)
|
||||
module_eval(<<-EOS, file, line.to_i)
|
||||
def #{prefix}#{method}(*args, &block) # def customer_name(*args, &block)
|
||||
#{allow_nil}#{to}.__send__(#{method.inspect}, *args, &block) # client && client.__send__(:name, *args, &block)
|
||||
end # end
|
||||
|
|
|
@ -132,8 +132,8 @@ class TestPluginLoader < Test::Unit::TestCase
|
|||
|
||||
@loader.send :add_engine_view_paths
|
||||
|
||||
assert_equal [ File.join(plugin_fixture_path('engines/engine'), 'app', 'views') ], ActionController::Base.view_paths
|
||||
assert_equal [ File.join(plugin_fixture_path('engines/engine'), 'app', 'views') ], ActionMailer::Base.view_paths
|
||||
assert_equal [ File.join(plugin_fixture_path('engines/engine'), 'app', 'views') ], ActionController::Base.view_paths.map { |p| p.to_s }
|
||||
assert_equal [ File.join(plugin_fixture_path('engines/engine'), 'app', 'views') ], ActionMailer::Base.view_paths.map { |p| p.to_s }
|
||||
end
|
||||
|
||||
def test_should_add_plugin_load_paths_to_Dependencies_load_once_paths
|
||||
|
|
|
@ -12,7 +12,7 @@ RAILS_ROOT = '.' unless defined?(RAILS_ROOT)
|
|||
class Test::Unit::TestCase
|
||||
private
|
||||
def plugin_fixture_root_path
|
||||
File.join(File.dirname(__FILE__), 'fixtures', 'plugins')
|
||||
File.expand_path(File.join(File.dirname(__FILE__), 'fixtures', 'plugins'))
|
||||
end
|
||||
|
||||
def only_load_the_following_plugins!(plugins)
|
||||
|
|
Loading…
Reference in a new issue