halorgium-actionpack 3.0.pre
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.
- data/CHANGELOG +5179 -0
- data/MIT-LICENSE +21 -0
- data/README +409 -0
- data/lib/abstract_controller.rb +16 -0
- data/lib/abstract_controller/base.rb +158 -0
- data/lib/abstract_controller/callbacks.rb +113 -0
- data/lib/abstract_controller/exceptions.rb +12 -0
- data/lib/abstract_controller/helpers.rb +151 -0
- data/lib/abstract_controller/layouts.rb +250 -0
- data/lib/abstract_controller/localized_cache.rb +49 -0
- data/lib/abstract_controller/logger.rb +61 -0
- data/lib/abstract_controller/rendering_controller.rb +188 -0
- data/lib/action_controller.rb +72 -0
- data/lib/action_controller/base.rb +168 -0
- data/lib/action_controller/caching.rb +80 -0
- data/lib/action_controller/caching/actions.rb +163 -0
- data/lib/action_controller/caching/fragments.rb +116 -0
- data/lib/action_controller/caching/pages.rb +154 -0
- data/lib/action_controller/caching/sweeping.rb +97 -0
- data/lib/action_controller/deprecated.rb +4 -0
- data/lib/action_controller/deprecated/integration_test.rb +2 -0
- data/lib/action_controller/deprecated/performance_test.rb +1 -0
- data/lib/action_controller/dispatch/dispatcher.rb +57 -0
- data/lib/action_controller/metal.rb +129 -0
- data/lib/action_controller/metal/benchmarking.rb +73 -0
- data/lib/action_controller/metal/compatibility.rb +145 -0
- data/lib/action_controller/metal/conditional_get.rb +86 -0
- data/lib/action_controller/metal/configuration.rb +28 -0
- data/lib/action_controller/metal/cookies.rb +105 -0
- data/lib/action_controller/metal/exceptions.rb +55 -0
- data/lib/action_controller/metal/filter_parameter_logging.rb +77 -0
- data/lib/action_controller/metal/flash.rb +162 -0
- data/lib/action_controller/metal/head.rb +27 -0
- data/lib/action_controller/metal/helpers.rb +115 -0
- data/lib/action_controller/metal/hide_actions.rb +47 -0
- data/lib/action_controller/metal/http_authentication.rb +312 -0
- data/lib/action_controller/metal/layouts.rb +171 -0
- data/lib/action_controller/metal/mime_responds.rb +317 -0
- data/lib/action_controller/metal/rack_convenience.rb +27 -0
- data/lib/action_controller/metal/redirector.rb +22 -0
- data/lib/action_controller/metal/render_options.rb +103 -0
- data/lib/action_controller/metal/rendering_controller.rb +57 -0
- data/lib/action_controller/metal/request_forgery_protection.rb +108 -0
- data/lib/action_controller/metal/rescuable.rb +13 -0
- data/lib/action_controller/metal/responder.rb +200 -0
- data/lib/action_controller/metal/session.rb +15 -0
- data/lib/action_controller/metal/session_management.rb +45 -0
- data/lib/action_controller/metal/streaming.rb +188 -0
- data/lib/action_controller/metal/testing.rb +39 -0
- data/lib/action_controller/metal/url_for.rb +41 -0
- data/lib/action_controller/metal/verification.rb +130 -0
- data/lib/action_controller/middleware.rb +38 -0
- data/lib/action_controller/notifications.rb +10 -0
- data/lib/action_controller/polymorphic_routes.rb +183 -0
- data/lib/action_controller/record_identifier.rb +91 -0
- data/lib/action_controller/testing/process.rb +111 -0
- data/lib/action_controller/testing/test_case.rb +345 -0
- data/lib/action_controller/translation.rb +13 -0
- data/lib/action_controller/url_rewriter.rb +204 -0
- data/lib/action_controller/vendor/html-scanner.rb +16 -0
- data/lib/action_controller/vendor/html-scanner/html/document.rb +68 -0
- data/lib/action_controller/vendor/html-scanner/html/node.rb +537 -0
- data/lib/action_controller/vendor/html-scanner/html/sanitizer.rb +176 -0
- data/lib/action_controller/vendor/html-scanner/html/selector.rb +828 -0
- data/lib/action_controller/vendor/html-scanner/html/tokenizer.rb +105 -0
- data/lib/action_controller/vendor/html-scanner/html/version.rb +11 -0
- data/lib/action_dispatch.rb +70 -0
- data/lib/action_dispatch/http/headers.rb +33 -0
- data/lib/action_dispatch/http/mime_type.rb +231 -0
- data/lib/action_dispatch/http/mime_types.rb +23 -0
- data/lib/action_dispatch/http/request.rb +539 -0
- data/lib/action_dispatch/http/response.rb +290 -0
- data/lib/action_dispatch/http/status_codes.rb +42 -0
- data/lib/action_dispatch/http/utils.rb +20 -0
- data/lib/action_dispatch/middleware/callbacks.rb +50 -0
- data/lib/action_dispatch/middleware/params_parser.rb +79 -0
- data/lib/action_dispatch/middleware/rescue.rb +26 -0
- data/lib/action_dispatch/middleware/session/abstract_store.rb +208 -0
- data/lib/action_dispatch/middleware/session/cookie_store.rb +235 -0
- data/lib/action_dispatch/middleware/session/mem_cache_store.rb +47 -0
- data/lib/action_dispatch/middleware/show_exceptions.rb +143 -0
- data/lib/action_dispatch/middleware/stack.rb +116 -0
- data/lib/action_dispatch/middleware/static.rb +44 -0
- data/lib/action_dispatch/middleware/string_coercion.rb +29 -0
- data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.erb +24 -0
- data/lib/action_dispatch/middleware/templates/rescues/_trace.erb +26 -0
- data/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb +10 -0
- data/lib/action_dispatch/middleware/templates/rescues/layout.erb +29 -0
- data/lib/action_dispatch/middleware/templates/rescues/missing_template.erb +2 -0
- data/lib/action_dispatch/middleware/templates/rescues/routing_error.erb +10 -0
- data/lib/action_dispatch/middleware/templates/rescues/template_error.erb +21 -0
- data/lib/action_dispatch/middleware/templates/rescues/unknown_action.erb +2 -0
- data/lib/action_dispatch/routing.rb +381 -0
- data/lib/action_dispatch/routing/deprecated_mapper.rb +878 -0
- data/lib/action_dispatch/routing/mapper.rb +327 -0
- data/lib/action_dispatch/routing/route.rb +49 -0
- data/lib/action_dispatch/routing/route_set.rb +497 -0
- data/lib/action_dispatch/testing/assertions.rb +8 -0
- data/lib/action_dispatch/testing/assertions/dom.rb +35 -0
- data/lib/action_dispatch/testing/assertions/model.rb +19 -0
- data/lib/action_dispatch/testing/assertions/response.rb +145 -0
- data/lib/action_dispatch/testing/assertions/routing.rb +144 -0
- data/lib/action_dispatch/testing/assertions/selector.rb +639 -0
- data/lib/action_dispatch/testing/assertions/tag.rb +123 -0
- data/lib/action_dispatch/testing/integration.rb +504 -0
- data/lib/action_dispatch/testing/performance_test.rb +15 -0
- data/lib/action_dispatch/testing/test_request.rb +83 -0
- data/lib/action_dispatch/testing/test_response.rb +131 -0
- data/lib/action_pack.rb +24 -0
- data/lib/action_pack/version.rb +9 -0
- data/lib/action_view.rb +58 -0
- data/lib/action_view/base.rb +308 -0
- data/lib/action_view/context.rb +44 -0
- data/lib/action_view/erb/util.rb +48 -0
- data/lib/action_view/helpers.rb +62 -0
- data/lib/action_view/helpers/active_model_helper.rb +306 -0
- data/lib/action_view/helpers/ajax_helper.rb +68 -0
- data/lib/action_view/helpers/asset_tag_helper.rb +830 -0
- data/lib/action_view/helpers/atom_feed_helper.rb +198 -0
- data/lib/action_view/helpers/cache_helper.rb +39 -0
- data/lib/action_view/helpers/capture_helper.rb +168 -0
- data/lib/action_view/helpers/date_helper.rb +988 -0
- data/lib/action_view/helpers/debug_helper.rb +38 -0
- data/lib/action_view/helpers/form_helper.rb +1102 -0
- data/lib/action_view/helpers/form_options_helper.rb +600 -0
- data/lib/action_view/helpers/form_tag_helper.rb +495 -0
- data/lib/action_view/helpers/javascript_helper.rb +208 -0
- data/lib/action_view/helpers/number_helper.rb +311 -0
- data/lib/action_view/helpers/prototype_helper.rb +1309 -0
- data/lib/action_view/helpers/raw_output_helper.rb +9 -0
- data/lib/action_view/helpers/record_identification_helper.rb +20 -0
- data/lib/action_view/helpers/record_tag_helper.rb +58 -0
- data/lib/action_view/helpers/sanitize_helper.rb +259 -0
- data/lib/action_view/helpers/scriptaculous_helper.rb +226 -0
- data/lib/action_view/helpers/tag_helper.rb +151 -0
- data/lib/action_view/helpers/text_helper.rb +594 -0
- data/lib/action_view/helpers/translation_helper.rb +39 -0
- data/lib/action_view/helpers/url_helper.rb +639 -0
- data/lib/action_view/locale/en.yml +117 -0
- data/lib/action_view/paths.rb +80 -0
- data/lib/action_view/render/partials.rb +342 -0
- data/lib/action_view/render/rendering.rb +134 -0
- data/lib/action_view/safe_buffer.rb +28 -0
- data/lib/action_view/template/error.rb +101 -0
- data/lib/action_view/template/handler.rb +36 -0
- data/lib/action_view/template/handlers.rb +52 -0
- data/lib/action_view/template/handlers/builder.rb +17 -0
- data/lib/action_view/template/handlers/erb.rb +53 -0
- data/lib/action_view/template/handlers/rjs.rb +18 -0
- data/lib/action_view/template/resolver.rb +165 -0
- data/lib/action_view/template/template.rb +131 -0
- data/lib/action_view/template/text.rb +38 -0
- data/lib/action_view/test_case.rb +163 -0
- metadata +236 -0
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
require "pathname"
|
|
2
|
+
require "active_support/core_ext/class"
|
|
3
|
+
require "action_view/template/template"
|
|
4
|
+
|
|
5
|
+
module ActionView
|
|
6
|
+
# Abstract superclass
|
|
7
|
+
class Resolver
|
|
8
|
+
|
|
9
|
+
class_inheritable_accessor(:registered_details)
|
|
10
|
+
self.registered_details = {}
|
|
11
|
+
|
|
12
|
+
def self.register_detail(name, options = {})
|
|
13
|
+
registered_details[name] = lambda do |val|
|
|
14
|
+
val ||= yield
|
|
15
|
+
val |= [nil] unless options[:allow_nil] == false
|
|
16
|
+
val
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
register_detail(:locale) { [I18n.locale] }
|
|
21
|
+
register_detail(:formats) { Mime::SET.symbols }
|
|
22
|
+
register_detail(:handlers, :allow_nil => false) do
|
|
23
|
+
TemplateHandlers.extensions
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def initialize(options = {})
|
|
27
|
+
@cache = options[:cache]
|
|
28
|
+
@cached = {}
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# Normalizes the arguments and passes it on to find_template
|
|
32
|
+
def find(*args)
|
|
33
|
+
find_all(*args).first
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def find_all(name, details = {}, prefix = nil, partial = nil)
|
|
37
|
+
details = normalize_details(details)
|
|
38
|
+
name, prefix = normalize_name(name, prefix)
|
|
39
|
+
|
|
40
|
+
cached([name, details, prefix, partial]) do
|
|
41
|
+
find_templates(name, details, prefix, partial)
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
private
|
|
46
|
+
|
|
47
|
+
# This is what child classes implement. No defaults are needed
|
|
48
|
+
# because Resolver guarantees that the arguments are present and
|
|
49
|
+
# normalized.
|
|
50
|
+
def find_templates(name, details, prefix, partial)
|
|
51
|
+
raise NotImplementedError
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def normalize_details(details)
|
|
55
|
+
details = details.dup
|
|
56
|
+
# TODO: Refactor this concern out of the resolver
|
|
57
|
+
details.delete(:formats) if details[:formats] == [:"*/*"]
|
|
58
|
+
registered_details.each do |k, v|
|
|
59
|
+
details[k] = v.call(details[k])
|
|
60
|
+
end
|
|
61
|
+
details
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
# Support legacy foo.erb names even though we now ignore .erb
|
|
65
|
+
# as well as incorrectly putting part of the path in the template
|
|
66
|
+
# name instead of the prefix.
|
|
67
|
+
def normalize_name(name, prefix)
|
|
68
|
+
handlers = TemplateHandlers.extensions.join('|')
|
|
69
|
+
name = name.to_s.gsub(/\.(?:#{handlers})$/, '')
|
|
70
|
+
|
|
71
|
+
parts = name.split('/')
|
|
72
|
+
return parts.pop, [prefix, *parts].compact.join("/")
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def cached(key)
|
|
76
|
+
return yield unless @cache
|
|
77
|
+
return @cached[key] if @cached.key?(key)
|
|
78
|
+
@cached[key] = yield
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
class PathResolver < Resolver
|
|
83
|
+
|
|
84
|
+
EXTENSION_ORDER = [:locale, :formats, :handlers]
|
|
85
|
+
|
|
86
|
+
def to_s
|
|
87
|
+
@path.to_s
|
|
88
|
+
end
|
|
89
|
+
alias to_path to_s
|
|
90
|
+
|
|
91
|
+
def find_templates(name, details, prefix, partial)
|
|
92
|
+
path = build_path(name, details, prefix, partial)
|
|
93
|
+
query(path, EXTENSION_ORDER.map { |ext| details[ext] })
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
private
|
|
97
|
+
|
|
98
|
+
def build_path(name, details, prefix, partial)
|
|
99
|
+
path = ""
|
|
100
|
+
path << "#{prefix}/" unless prefix.empty?
|
|
101
|
+
path << (partial ? "_#{name}" : name)
|
|
102
|
+
path
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def query(path, exts)
|
|
106
|
+
query = "#{@path}/#{path}"
|
|
107
|
+
exts.each do |ext|
|
|
108
|
+
query << '{' << ext.map {|e| e && ".#{e}" }.join(',') << '}'
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
Dir[query].map do |path|
|
|
112
|
+
next if File.directory?(path)
|
|
113
|
+
source = File.read(path)
|
|
114
|
+
identifier = Pathname.new(path).expand_path.to_s
|
|
115
|
+
|
|
116
|
+
Template.new(source, identifier, *path_to_details(path))
|
|
117
|
+
end.compact
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
# # TODO: fix me
|
|
121
|
+
# # :api: plugin
|
|
122
|
+
def path_to_details(path)
|
|
123
|
+
# [:erb, :format => :html, :locale => :en, :partial => true/false]
|
|
124
|
+
if m = path.match(%r'(?:^|/)(_)?[\w-]+((?:\.[\w-]+)*)\.(\w+)$')
|
|
125
|
+
partial = m[1] == '_'
|
|
126
|
+
details = (m[2]||"").split('.').reject { |e| e.empty? }
|
|
127
|
+
handler = Template.handler_class_for_extension(m[3])
|
|
128
|
+
|
|
129
|
+
format = Mime[details.last] && details.pop.to_sym
|
|
130
|
+
locale = details.last && details.pop.to_sym
|
|
131
|
+
|
|
132
|
+
return handler, :format => format, :locale => locale, :partial => partial
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
class FileSystemResolver < PathResolver
|
|
138
|
+
def initialize(path, options = {})
|
|
139
|
+
raise ArgumentError, "path already is a Resolver class" if path.is_a?(Resolver)
|
|
140
|
+
super(options)
|
|
141
|
+
@path = Pathname.new(path).expand_path
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
# OMG HAX
|
|
146
|
+
# TODO: remove hax
|
|
147
|
+
class FileSystemResolverWithFallback < Resolver
|
|
148
|
+
def initialize(path, options = {})
|
|
149
|
+
super(options)
|
|
150
|
+
@paths = [FileSystemResolver.new(path, options), FileSystemResolver.new("", options), FileSystemResolver.new("/", options)]
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
def find_templates(*args)
|
|
154
|
+
@paths.each do |p|
|
|
155
|
+
template = p.find_templates(*args)
|
|
156
|
+
return template unless template.empty?
|
|
157
|
+
end
|
|
158
|
+
[]
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
def to_s
|
|
162
|
+
@paths.first.to_s
|
|
163
|
+
end
|
|
164
|
+
end
|
|
165
|
+
end
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
# This is so that templates compiled in this file are UTF-8
|
|
3
|
+
|
|
4
|
+
require 'set'
|
|
5
|
+
require "action_view/template/resolver"
|
|
6
|
+
|
|
7
|
+
module ActionView
|
|
8
|
+
class Template
|
|
9
|
+
extend TemplateHandlers
|
|
10
|
+
attr_reader :source, :identifier, :handler, :mime_type, :formats, :details
|
|
11
|
+
|
|
12
|
+
def initialize(source, identifier, handler, details)
|
|
13
|
+
@source = source
|
|
14
|
+
@identifier = identifier
|
|
15
|
+
@handler = handler
|
|
16
|
+
@details = details
|
|
17
|
+
@method_names = {}
|
|
18
|
+
|
|
19
|
+
format = details.delete(:format) || begin
|
|
20
|
+
# TODO: Clean this up
|
|
21
|
+
handler.respond_to?(:default_format) ? handler.default_format.to_sym.to_s : "html"
|
|
22
|
+
end
|
|
23
|
+
@mime_type = Mime::Type.lookup_by_extension(format.to_s)
|
|
24
|
+
@formats = [format.to_sym]
|
|
25
|
+
@formats << :html if format == :js
|
|
26
|
+
@details[:formats] = Array.wrap(format.to_sym)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def render(view, locals, &block)
|
|
30
|
+
ActiveSupport::Notifications.instrument(:render_template, :identifier => identifier) do
|
|
31
|
+
method_name = compile(locals, view)
|
|
32
|
+
view.send(method_name, locals, &block)
|
|
33
|
+
end
|
|
34
|
+
rescue Exception => e
|
|
35
|
+
if e.is_a?(TemplateError)
|
|
36
|
+
e.sub_template_of(self)
|
|
37
|
+
raise e
|
|
38
|
+
else
|
|
39
|
+
raise TemplateError.new(self, view.assigns, e)
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# TODO: Figure out how to abstract this
|
|
44
|
+
def variable_name
|
|
45
|
+
@variable_name ||= identifier[%r'_?(\w+)(\.\w+)*$', 1].to_sym
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# TODO: Figure out how to abstract this
|
|
49
|
+
def counter_name
|
|
50
|
+
@counter_name ||= "#{variable_name}_counter".to_sym
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# TODO: kill hax
|
|
54
|
+
def partial?
|
|
55
|
+
@details[:partial]
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def inspect
|
|
59
|
+
if defined?(Rails.root)
|
|
60
|
+
identifier.sub("#{Rails.root}/", '')
|
|
61
|
+
else
|
|
62
|
+
identifier
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
private
|
|
67
|
+
def compile(locals, view)
|
|
68
|
+
method_name = build_method_name(locals)
|
|
69
|
+
|
|
70
|
+
return method_name if view.respond_to?(method_name)
|
|
71
|
+
|
|
72
|
+
locals_code = locals.keys.map! { |key| "#{key} = local_assigns[:#{key}];" }.join
|
|
73
|
+
|
|
74
|
+
code = @handler.call(self)
|
|
75
|
+
if code.sub!(/\A(#.*coding.*)\n/, '')
|
|
76
|
+
encoding_comment = $1
|
|
77
|
+
elsif defined?(Encoding) && Encoding.respond_to?(:default_external)
|
|
78
|
+
encoding_comment = "#coding:#{Encoding.default_external}"
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
source = <<-end_src
|
|
82
|
+
def #{method_name}(local_assigns)
|
|
83
|
+
old_output_buffer = output_buffer;#{locals_code};#{code}
|
|
84
|
+
ensure
|
|
85
|
+
self.output_buffer = old_output_buffer
|
|
86
|
+
end
|
|
87
|
+
end_src
|
|
88
|
+
|
|
89
|
+
if encoding_comment
|
|
90
|
+
source = "#{encoding_comment}\n#{source}"
|
|
91
|
+
line = -1
|
|
92
|
+
else
|
|
93
|
+
line = 0
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
begin
|
|
97
|
+
ActionView::CompiledTemplates.module_eval(source, identifier, line)
|
|
98
|
+
method_name
|
|
99
|
+
rescue Exception => e # errors from template code
|
|
100
|
+
if logger = (view && view.logger)
|
|
101
|
+
logger.debug "ERROR: compiling #{method_name} RAISED #{e}"
|
|
102
|
+
logger.debug "Function body: #{source}"
|
|
103
|
+
logger.debug "Backtrace: #{e.backtrace.join("\n")}"
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
raise ActionView::TemplateError.new(self, {}, e)
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
class LocalsKey
|
|
111
|
+
@hash_keys = Hash.new {|h,k| h[k] = Hash.new {|h,k| h[k] = {} } }
|
|
112
|
+
|
|
113
|
+
def self.get(*locals)
|
|
114
|
+
@hash_keys[*locals] ||= new(klass, format, locale)
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
attr_accessor :hash
|
|
118
|
+
def initialize(klass, format, locale)
|
|
119
|
+
@hash = locals.hash
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
alias_method :eql?, :equal?
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
def build_method_name(locals)
|
|
126
|
+
# TODO: is locals.keys.hash reliably the same?
|
|
127
|
+
@method_names[locals.keys.hash] ||=
|
|
128
|
+
"_render_template_#{@identifier.hash}_#{__id__}_#{locals.keys.hash}".gsub('-', "_")
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
module ActionView #:nodoc:
|
|
2
|
+
class TextTemplate < String #:nodoc:
|
|
3
|
+
HTML = Mime[:html]
|
|
4
|
+
|
|
5
|
+
def initialize(string, content_type = HTML)
|
|
6
|
+
super(string.to_s)
|
|
7
|
+
@content_type = Mime[content_type] || content_type
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def details
|
|
11
|
+
{:formats => [@content_type.to_sym]}
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def identifier
|
|
15
|
+
self
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def inspect
|
|
19
|
+
'text template'
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def render(*args)
|
|
23
|
+
to_s
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def mime_type
|
|
27
|
+
@content_type
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def formats
|
|
31
|
+
[mime_type]
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def partial?
|
|
35
|
+
false
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
require 'active_support/test_case'
|
|
2
|
+
require 'action_controller/testing/test_case'
|
|
3
|
+
|
|
4
|
+
module ActionView
|
|
5
|
+
class Base
|
|
6
|
+
alias_method :initialize_without_template_tracking, :initialize
|
|
7
|
+
def initialize(*args)
|
|
8
|
+
@_rendered = { :template => nil, :partials => Hash.new(0) }
|
|
9
|
+
initialize_without_template_tracking(*args)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
attr_internal :rendered
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
class Template
|
|
16
|
+
alias_method :render_without_tracking, :render
|
|
17
|
+
def render(view, locals, &blk)
|
|
18
|
+
rendered = view.rendered
|
|
19
|
+
rendered[:partials][self] += 1 if partial?
|
|
20
|
+
rendered[:template] ||= []
|
|
21
|
+
rendered[:template] << self
|
|
22
|
+
render_without_tracking(view, locals, &blk)
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
class TestCase < ActiveSupport::TestCase
|
|
27
|
+
class TestController < ActionController::Base
|
|
28
|
+
attr_accessor :request, :response, :params
|
|
29
|
+
|
|
30
|
+
def self.controller_path
|
|
31
|
+
''
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def initialize
|
|
35
|
+
@request = ActionController::TestRequest.new
|
|
36
|
+
@response = ActionController::TestResponse.new
|
|
37
|
+
|
|
38
|
+
@params = {}
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
include ActionDispatch::Assertions
|
|
43
|
+
include ActionController::TestProcess
|
|
44
|
+
include ActionView::Context
|
|
45
|
+
|
|
46
|
+
include ActionController::PolymorphicRoutes
|
|
47
|
+
include ActionController::RecordIdentifier
|
|
48
|
+
|
|
49
|
+
include ActionView::Helpers
|
|
50
|
+
include ActionController::Helpers
|
|
51
|
+
|
|
52
|
+
class_inheritable_accessor :helper_class
|
|
53
|
+
attr_accessor :controller, :output_buffer, :rendered
|
|
54
|
+
|
|
55
|
+
setup :setup_with_controller
|
|
56
|
+
def setup_with_controller
|
|
57
|
+
@controller = TestController.new
|
|
58
|
+
@output_buffer = ActionView::SafeBuffer.new
|
|
59
|
+
@rendered = ''
|
|
60
|
+
|
|
61
|
+
self.class.send(:include_helper_modules!)
|
|
62
|
+
make_test_case_available_to_view!
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def render(options = {}, local_assigns = {}, &block)
|
|
66
|
+
@rendered << output = _view.render(options, local_assigns, &block)
|
|
67
|
+
output
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def protect_against_forgery?
|
|
71
|
+
false
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
class << self
|
|
75
|
+
def tests(helper_class)
|
|
76
|
+
self.helper_class = helper_class
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def helper_class
|
|
80
|
+
if current_helper_class = read_inheritable_attribute(:helper_class)
|
|
81
|
+
current_helper_class
|
|
82
|
+
else
|
|
83
|
+
self.helper_class = determine_default_helper_class(name)
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def determine_default_helper_class(name)
|
|
88
|
+
name.sub(/Test$/, '').constantize
|
|
89
|
+
rescue NameError
|
|
90
|
+
nil
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def helper_method(*methods)
|
|
94
|
+
# Almost a duplicate from ActionController::Helpers
|
|
95
|
+
methods.flatten.each do |method|
|
|
96
|
+
_helpers.module_eval <<-end_eval
|
|
97
|
+
def #{method}(*args, &block) # def current_user(*args, &block)
|
|
98
|
+
_test_case.send(%(#{method}), *args, &block) # test_case.send(%(current_user), *args, &block)
|
|
99
|
+
end # end
|
|
100
|
+
end_eval
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
private
|
|
105
|
+
def include_helper_modules!
|
|
106
|
+
helper(helper_class) if helper_class
|
|
107
|
+
include _helpers
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
private
|
|
112
|
+
def make_test_case_available_to_view!
|
|
113
|
+
test_case_instance = self
|
|
114
|
+
_helpers.module_eval do
|
|
115
|
+
define_method(:_test_case) { test_case_instance }
|
|
116
|
+
private :_test_case
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
def _view
|
|
121
|
+
view = ActionView::Base.new(ActionController::Base.view_paths, _assigns, @controller)
|
|
122
|
+
view.class.send :include, _helpers
|
|
123
|
+
view
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
# Support the selector assertions
|
|
127
|
+
#
|
|
128
|
+
# Need to experiment if this priority is the best one: rendered => output_buffer
|
|
129
|
+
def response_from_page_or_rjs
|
|
130
|
+
HTML::Document.new(rendered.blank? ? output_buffer : rendered).root
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
EXCLUDE_IVARS = %w{
|
|
134
|
+
@output_buffer
|
|
135
|
+
@fixture_cache
|
|
136
|
+
@method_name
|
|
137
|
+
@_result
|
|
138
|
+
@loaded_fixtures
|
|
139
|
+
@test_passed
|
|
140
|
+
@view
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
def _instance_variables
|
|
144
|
+
instance_variables - EXCLUDE_IVARS
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
def _assigns
|
|
148
|
+
_instance_variables.inject({}) do |hash, var|
|
|
149
|
+
name = var[1..-1].to_sym
|
|
150
|
+
hash[name] = instance_variable_get(var)
|
|
151
|
+
hash
|
|
152
|
+
end
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
def method_missing(selector, *args)
|
|
156
|
+
if ActionController::Routing::Routes.named_routes.helpers.include?(selector)
|
|
157
|
+
@controller.__send__(selector, *args)
|
|
158
|
+
else
|
|
159
|
+
super
|
|
160
|
+
end
|
|
161
|
+
end
|
|
162
|
+
end
|
|
163
|
+
end
|