actionpack 2.1.2 → 2.2.2
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of actionpack might be problematic. Click here for more details.
- data/CHANGELOG +223 -7
- data/README +6 -12
- data/Rakefile +11 -11
- data/lib/action_controller.rb +9 -9
- data/lib/action_controller/assertions/response_assertions.rb +29 -78
- data/lib/action_controller/assertions/routing_assertions.rb +33 -33
- data/lib/action_controller/assertions/selector_assertions.rb +9 -5
- data/lib/action_controller/base.rb +227 -161
- data/lib/action_controller/benchmarking.rb +37 -24
- data/lib/action_controller/caching/actions.rb +53 -21
- data/lib/action_controller/caching/fragments.rb +10 -36
- data/lib/action_controller/caching/sweeping.rb +3 -3
- data/lib/action_controller/cgi_ext/session.rb +2 -22
- data/lib/action_controller/cgi_process.rb +8 -46
- data/lib/action_controller/components.rb +4 -1
- data/lib/action_controller/cookies.rb +10 -0
- data/lib/action_controller/dispatcher.rb +49 -15
- data/lib/action_controller/filters.rb +48 -10
- data/lib/action_controller/headers.rb +16 -14
- data/lib/action_controller/helpers.rb +2 -2
- data/lib/action_controller/http_authentication.rb +1 -1
- data/lib/action_controller/integration.rb +57 -60
- data/lib/action_controller/layout.rb +27 -53
- data/lib/action_controller/mime_responds.rb +5 -1
- data/lib/action_controller/mime_type.rb +64 -42
- data/lib/action_controller/mime_types.rb +2 -1
- data/lib/action_controller/performance_test.rb +16 -0
- data/lib/action_controller/polymorphic_routes.rb +16 -9
- data/lib/action_controller/rack_process.rb +303 -0
- data/lib/action_controller/request.rb +205 -97
- data/lib/action_controller/request_forgery_protection.rb +2 -2
- data/lib/action_controller/request_profiler.rb +0 -0
- data/lib/action_controller/rescue.rb +20 -115
- data/lib/action_controller/resources.rb +186 -83
- data/lib/action_controller/response.rb +140 -26
- data/lib/action_controller/routing.rb +28 -30
- data/lib/action_controller/routing/builder.rb +45 -54
- data/lib/action_controller/routing/optimisations.rb +31 -21
- data/lib/action_controller/routing/recognition_optimisation.rb +33 -27
- data/lib/action_controller/routing/route.rb +162 -147
- data/lib/action_controller/routing/route_set.rb +8 -7
- data/lib/action_controller/routing/routing_ext.rb +4 -1
- data/lib/action_controller/routing/segments.rb +50 -21
- data/lib/action_controller/session/cookie_store.rb +3 -2
- data/lib/action_controller/session/drb_server.rb +7 -7
- data/lib/action_controller/session_management.rb +6 -2
- data/lib/action_controller/streaming.rb +15 -8
- data/lib/action_controller/templates/rescues/diagnostics.erb +2 -2
- data/lib/action_controller/templates/rescues/template_error.erb +2 -2
- data/lib/action_controller/test_case.rb +66 -2
- data/lib/action_controller/test_process.rb +71 -66
- data/lib/action_controller/translation.rb +13 -0
- data/lib/action_controller/url_rewriter.rb +90 -13
- data/lib/action_controller/vendor/html-scanner/html/node.rb +9 -2
- data/lib/action_controller/vendor/html-scanner/html/sanitizer.rb +1 -1
- data/lib/action_controller/vendor/html-scanner/html/selector.rb +2 -2
- data/lib/action_controller/verification.rb +2 -2
- data/lib/action_pack/version.rb +1 -1
- data/lib/action_view.rb +19 -11
- data/lib/action_view/base.rb +184 -150
- data/lib/action_view/helpers.rb +38 -0
- data/lib/action_view/helpers/active_record_helper.rb +56 -27
- data/lib/action_view/helpers/asset_tag_helper.rb +356 -153
- data/lib/action_view/helpers/atom_feed_helper.rb +74 -19
- data/lib/action_view/helpers/benchmark_helper.rb +3 -3
- data/lib/action_view/helpers/cache_helper.rb +1 -2
- data/lib/action_view/helpers/capture_helper.rb +19 -44
- data/lib/action_view/helpers/date_helper.rb +486 -296
- data/lib/action_view/helpers/debug_helper.rb +20 -13
- data/lib/action_view/helpers/form_helper.rb +71 -30
- data/lib/action_view/helpers/form_options_helper.rb +15 -85
- data/lib/action_view/helpers/form_tag_helper.rb +61 -38
- data/lib/action_view/helpers/javascript_helper.rb +80 -89
- data/lib/action_view/helpers/number_helper.rb +179 -74
- data/lib/action_view/helpers/prototype_helper.rb +216 -201
- data/lib/action_view/helpers/record_tag_helper.rb +4 -5
- data/lib/action_view/helpers/sanitize_helper.rb +65 -33
- data/lib/action_view/helpers/scriptaculous_helper.rb +2 -2
- data/lib/action_view/helpers/tag_helper.rb +39 -22
- data/lib/action_view/helpers/text_helper.rb +212 -118
- data/lib/action_view/helpers/translation_helper.rb +21 -0
- data/lib/action_view/helpers/url_helper.rb +100 -58
- data/lib/action_view/inline_template.rb +13 -14
- data/lib/action_view/locale/en.yml +91 -0
- data/lib/action_view/partials.rb +100 -55
- data/lib/action_view/paths.rb +125 -0
- data/lib/action_view/renderable.rb +102 -0
- data/lib/action_view/renderable_partial.rb +48 -0
- data/lib/action_view/template.rb +90 -101
- data/lib/action_view/template_error.rb +11 -21
- data/lib/action_view/template_handler.rb +8 -28
- data/lib/action_view/template_handlers.rb +45 -0
- data/lib/action_view/template_handlers/builder.rb +5 -15
- data/lib/action_view/template_handlers/erb.rb +9 -6
- data/lib/action_view/template_handlers/rjs.rb +2 -17
- data/lib/action_view/test_case.rb +7 -4
- data/test/abstract_unit.rb +4 -1
- data/test/active_record_unit.rb +28 -30
- data/test/activerecord/render_partial_with_record_identification_test.rb +25 -12
- data/test/controller/action_pack_assertions_test.rb +8 -37
- data/test/controller/addresses_render_test.rb +0 -3
- data/test/controller/assert_select_test.rb +51 -24
- data/test/controller/base_test.rb +4 -4
- data/test/controller/caching_test.rb +136 -66
- data/test/controller/capture_test.rb +1 -21
- data/test/controller/cgi_test.rb +157 -10
- data/test/controller/components_test.rb +41 -25
- data/test/controller/content_type_test.rb +49 -17
- data/test/controller/cookie_test.rb +1 -1
- data/test/controller/deprecation/deprecated_base_methods_test.rb +0 -3
- data/test/controller/dispatcher_test.rb +9 -1
- data/test/controller/filter_params_test.rb +2 -2
- data/test/controller/filters_test.rb +13 -13
- data/test/controller/html-scanner/cdata_node_test.rb +15 -0
- data/test/controller/html-scanner/node_test.rb +21 -0
- data/test/controller/html-scanner/sanitizer_test.rb +14 -0
- data/test/controller/integration_test.rb +167 -6
- data/test/controller/layout_test.rb +11 -68
- data/test/controller/logging_test.rb +46 -0
- data/test/controller/mime_responds_test.rb +61 -59
- data/test/controller/mime_type_test.rb +6 -6
- data/test/controller/polymorphic_routes_test.rb +37 -2
- data/test/controller/rack_test.rb +323 -0
- data/test/controller/redirect_test.rb +72 -71
- data/test/controller/render_test.rb +1120 -108
- data/test/controller/request_forgery_protection_test.rb +66 -52
- data/test/controller/request_test.rb +103 -146
- data/test/controller/rescue_test.rb +20 -24
- data/test/controller/resources_test.rb +408 -25
- data/test/controller/routing_test.rb +1774 -1774
- data/test/controller/send_file_test.rb +0 -4
- data/test/controller/session/cookie_store_test.rb +53 -1
- data/test/controller/test_test.rb +15 -37
- data/test/controller/translation_test.rb +26 -0
- data/test/controller/url_rewriter_test.rb +27 -28
- data/test/controller/view_paths_test.rb +48 -47
- data/test/fixtures/_top_level_partial.html.erb +1 -0
- data/test/fixtures/_top_level_partial_only.erb +1 -0
- data/test/fixtures/developers/_developer.erb +1 -0
- data/test/fixtures/fun/games/_game.erb +1 -0
- data/test/fixtures/fun/serious/games/_game.erb +1 -0
- data/test/fixtures/functional_caching/formatted_fragment_cached.html.erb +3 -0
- data/test/fixtures/functional_caching/formatted_fragment_cached.js.rjs +6 -0
- data/test/fixtures/functional_caching/formatted_fragment_cached.xml.builder +5 -0
- data/test/fixtures/functional_caching/inline_fragment_cached.html.erb +2 -0
- data/test/fixtures/layouts/_column.html.erb +2 -0
- data/test/fixtures/projects/_project.erb +1 -0
- data/test/fixtures/public/javascripts/subdir/subdir.js +1 -0
- data/test/fixtures/public/stylesheets/subdir/subdir.css +1 -0
- data/test/fixtures/replies/_reply.erb +1 -0
- data/test/fixtures/test/_counter.html.erb +1 -0
- data/test/fixtures/test/_customer.erb +1 -1
- data/test/fixtures/test/_customer_with_var.erb +1 -0
- data/test/fixtures/test/_layout_for_block_with_args.html.erb +3 -0
- data/test/fixtures/test/_local_inspector.html.erb +1 -0
- data/test/fixtures/test/_partial_with_only_html_version.html.erb +1 -0
- data/test/fixtures/test/hello.builder +1 -1
- data/test/fixtures/test/hyphen-ated.erb +1 -0
- data/test/fixtures/test/implicit_content_type.atom.builder +2 -0
- data/test/fixtures/test/nested_layout.erb +3 -0
- data/test/fixtures/test/non_erb_block_content_for.builder +1 -1
- data/test/fixtures/test/sub_template_raise.html.erb +1 -0
- data/test/fixtures/test/template.erb +1 -0
- data/test/fixtures/test/using_layout_around_block_with_args.html.erb +1 -0
- data/test/template/active_record_helper_i18n_test.rb +46 -0
- data/test/template/active_record_helper_test.rb +24 -24
- data/test/template/asset_tag_helper_test.rb +161 -29
- data/test/template/atom_feed_helper_test.rb +114 -5
- data/test/template/compiled_templates_test.rb +59 -0
- data/test/template/date_helper_i18n_test.rb +113 -0
- data/test/template/date_helper_test.rb +403 -109
- data/test/template/form_helper_test.rb +213 -154
- data/test/template/form_options_helper_test.rb +249 -897
- data/test/template/form_tag_helper_test.rb +80 -32
- data/test/template/javascript_helper_test.rb +17 -18
- data/test/template/number_helper_i18n_test.rb +54 -0
- data/test/template/number_helper_test.rb +43 -13
- data/test/template/prototype_helper_test.rb +101 -84
- data/test/template/record_tag_helper_test.rb +24 -20
- data/test/template/render_test.rb +193 -0
- data/test/template/sanitize_helper_test.rb +3 -3
- data/test/template/tag_helper_test.rb +34 -14
- data/test/template/text_helper_test.rb +83 -9
- data/test/template/translation_helper_test.rb +28 -0
- data/test/template/url_helper_test.rb +55 -18
- metadata +57 -18
- data/lib/action_view/helpers/javascripts/controls.js +0 -963
- data/lib/action_view/helpers/javascripts/dragdrop.js +0 -972
- data/lib/action_view/helpers/javascripts/effects.js +0 -1120
- data/lib/action_view/helpers/javascripts/prototype.js +0 -4225
- data/lib/action_view/partial_template.rb +0 -70
- data/lib/action_view/template_finder.rb +0 -177
- data/lib/action_view/template_handlers/compilable.rb +0 -128
- data/test/controller/custom_handler_test.rb +0 -45
- data/test/controller/new_render_test.rb +0 -945
- data/test/fixtures/test/block_content_for.erb +0 -2
- data/test/fixtures/test/erb_content_for.erb +0 -2
- data/test/template/deprecated_erb_variable_test.rb +0 -9
- data/test/template/template_finder_test.rb +0 -73
- data/test/template/template_object_test.rb +0 -95
@@ -1,70 +0,0 @@
|
|
1
|
-
module ActionView #:nodoc:
|
2
|
-
class PartialTemplate < Template #:nodoc:
|
3
|
-
|
4
|
-
attr_reader :variable_name, :object
|
5
|
-
|
6
|
-
def initialize(view, partial_path, object = nil, locals = {})
|
7
|
-
@path, @variable_name = extract_partial_name_and_path(view, partial_path)
|
8
|
-
super(view, @path, true, locals)
|
9
|
-
add_object_to_local_assigns!(object)
|
10
|
-
|
11
|
-
# This is needed here in order to compile template with knowledge of 'counter'
|
12
|
-
initialize_counter
|
13
|
-
|
14
|
-
# Prepare early. This is a performance optimization for partial collections
|
15
|
-
prepare!
|
16
|
-
end
|
17
|
-
|
18
|
-
def render
|
19
|
-
ActionController::Base.benchmark("Rendered #{@path}", Logger::DEBUG, false) do
|
20
|
-
@handler.render(self)
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
def render_member(object)
|
25
|
-
@locals[:object] = @locals[@variable_name] = object
|
26
|
-
|
27
|
-
template = render_template
|
28
|
-
@locals[@counter_name] += 1
|
29
|
-
@locals.delete(@variable_name)
|
30
|
-
@locals.delete(:object)
|
31
|
-
|
32
|
-
template
|
33
|
-
end
|
34
|
-
|
35
|
-
def counter=(num)
|
36
|
-
@locals[@counter_name] = num
|
37
|
-
end
|
38
|
-
|
39
|
-
private
|
40
|
-
|
41
|
-
def add_object_to_local_assigns!(object)
|
42
|
-
@locals[:object] ||=
|
43
|
-
@locals[@variable_name] ||=
|
44
|
-
if object.is_a?(ActionView::Base::ObjectWrapper)
|
45
|
-
object.value
|
46
|
-
else
|
47
|
-
object
|
48
|
-
end || @view.controller.instance_variable_get("@#{variable_name}")
|
49
|
-
end
|
50
|
-
|
51
|
-
def extract_partial_name_and_path(view, partial_path)
|
52
|
-
path, partial_name = partial_pieces(view, partial_path)
|
53
|
-
[File.join(path, "_#{partial_name}"), partial_name.split('/').last.split('.').first.to_sym]
|
54
|
-
end
|
55
|
-
|
56
|
-
def partial_pieces(view, partial_path)
|
57
|
-
if partial_path.include?('/')
|
58
|
-
return File.dirname(partial_path), File.basename(partial_path)
|
59
|
-
else
|
60
|
-
return view.controller.class.controller_path, partial_path
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
|
-
def initialize_counter
|
65
|
-
@counter_name ||= "#{@variable_name}_counter".to_sym
|
66
|
-
@locals[@counter_name] = 0
|
67
|
-
end
|
68
|
-
|
69
|
-
end
|
70
|
-
end
|
@@ -1,177 +0,0 @@
|
|
1
|
-
module ActionView #:nodoc:
|
2
|
-
class TemplateFinder #:nodoc:
|
3
|
-
|
4
|
-
class InvalidViewPath < StandardError #:nodoc:
|
5
|
-
attr_reader :unprocessed_path
|
6
|
-
def initialize(path)
|
7
|
-
@unprocessed_path = path
|
8
|
-
super("Unprocessed view path found: #{@unprocessed_path.inspect}. Set your view paths with #append_view_path, #prepend_view_path, or #view_paths=.")
|
9
|
-
end
|
10
|
-
end
|
11
|
-
|
12
|
-
cattr_reader :processed_view_paths
|
13
|
-
@@processed_view_paths = Hash.new {|hash, key| hash[key] = []}
|
14
|
-
|
15
|
-
cattr_reader :file_extension_cache
|
16
|
-
@@file_extension_cache = Hash.new {|hash, key|
|
17
|
-
hash[key] = Hash.new {|hash, key| hash[key] = []}
|
18
|
-
}
|
19
|
-
|
20
|
-
class << self #:nodoc:
|
21
|
-
|
22
|
-
# This method is not thread safe. Mutex should be used whenever this is accessed from an instance method
|
23
|
-
def process_view_paths(*view_paths)
|
24
|
-
view_paths.flatten.compact.each do |dir|
|
25
|
-
next if @@processed_view_paths.has_key?(dir)
|
26
|
-
@@processed_view_paths[dir] = []
|
27
|
-
|
28
|
-
#
|
29
|
-
# Dir.glob("#{dir}/**/*/**") reads all the directories in view path and templates inside those directories
|
30
|
-
# Dir.glob("#{dir}/**") reads templates residing at top level of view path
|
31
|
-
#
|
32
|
-
(Dir.glob("#{dir}/**/*/**") | Dir.glob("#{dir}/**")).each do |file|
|
33
|
-
unless File.directory?(file)
|
34
|
-
@@processed_view_paths[dir] << file.split(dir).last.sub(/^\//, '')
|
35
|
-
|
36
|
-
# Build extension cache
|
37
|
-
extension = file.split(".").last
|
38
|
-
if template_handler_extensions.include?(extension)
|
39
|
-
key = file.split(dir).last.sub(/^\//, '').sub(/\.(\w+)$/, '')
|
40
|
-
@@file_extension_cache[dir][key] << extension
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
def update_extension_cache_for(extension)
|
48
|
-
@@processed_view_paths.keys.each do |dir|
|
49
|
-
Dir.glob("#{dir}/**/*.#{extension}").each do |file|
|
50
|
-
key = file.split(dir).last.sub(/^\//, '').sub(/\.(\w+)$/, '')
|
51
|
-
@@file_extension_cache[dir][key] << extension
|
52
|
-
end
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
def template_handler_extensions
|
57
|
-
ActionView::Template.template_handler_extensions
|
58
|
-
end
|
59
|
-
|
60
|
-
def reload!
|
61
|
-
view_paths = @@processed_view_paths.keys
|
62
|
-
|
63
|
-
@@processed_view_paths = Hash.new {|hash, key| hash[key] = []}
|
64
|
-
@@file_extension_cache = Hash.new {|hash, key|
|
65
|
-
hash[key] = Hash.new {|hash, key| hash[key] = []}
|
66
|
-
}
|
67
|
-
|
68
|
-
process_view_paths(view_paths)
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
|
-
attr_accessor :view_paths
|
73
|
-
|
74
|
-
def initialize(*args)
|
75
|
-
@template = args.shift
|
76
|
-
|
77
|
-
@view_paths = args.flatten
|
78
|
-
@view_paths = @view_paths.respond_to?(:find) ? @view_paths.dup : [*@view_paths].compact
|
79
|
-
check_view_paths(@view_paths)
|
80
|
-
end
|
81
|
-
|
82
|
-
def prepend_view_path(path)
|
83
|
-
@view_paths.unshift(*path)
|
84
|
-
|
85
|
-
self.class.process_view_paths(path)
|
86
|
-
end
|
87
|
-
|
88
|
-
def append_view_path(path)
|
89
|
-
@view_paths.push(*path)
|
90
|
-
|
91
|
-
self.class.process_view_paths(path)
|
92
|
-
end
|
93
|
-
|
94
|
-
def view_paths=(path)
|
95
|
-
@view_paths = path
|
96
|
-
self.class.process_view_paths(path)
|
97
|
-
end
|
98
|
-
|
99
|
-
def pick_template(template_path, extension)
|
100
|
-
file_name = "#{template_path}.#{extension}"
|
101
|
-
base_path = find_base_path_for(file_name)
|
102
|
-
base_path.blank? ? false : "#{base_path}/#{file_name}"
|
103
|
-
end
|
104
|
-
alias_method :template_exists?, :pick_template
|
105
|
-
|
106
|
-
def file_exists?(template_path)
|
107
|
-
# Clear the forward slash in the beginning if exists
|
108
|
-
template_path = template_path.sub(/^\//, '')
|
109
|
-
|
110
|
-
template_file_name, template_file_extension = path_and_extension(template_path)
|
111
|
-
|
112
|
-
if template_file_extension
|
113
|
-
template_exists?(template_file_name, template_file_extension)
|
114
|
-
else
|
115
|
-
template_exists?(template_file_name, pick_template_extension(template_path))
|
116
|
-
end
|
117
|
-
end
|
118
|
-
|
119
|
-
def find_base_path_for(template_file_name)
|
120
|
-
@view_paths.find { |path| @@processed_view_paths[path].include?(template_file_name) }
|
121
|
-
end
|
122
|
-
|
123
|
-
# Returns the view path that the full path resides in.
|
124
|
-
def extract_base_path_from(full_path)
|
125
|
-
@view_paths.find { |p| full_path[0..p.size - 1] == p }
|
126
|
-
end
|
127
|
-
|
128
|
-
# Gets the extension for an existing template with the given template_path.
|
129
|
-
# Returns the format with the extension if that template exists.
|
130
|
-
#
|
131
|
-
# pick_template_extension('users/show')
|
132
|
-
# # => 'html.erb'
|
133
|
-
#
|
134
|
-
# pick_template_extension('users/legacy')
|
135
|
-
# # => "rhtml"
|
136
|
-
#
|
137
|
-
def pick_template_extension(template_path)
|
138
|
-
if extension = find_template_extension_from_handler(template_path, @template.template_format) || find_template_extension_from_first_render
|
139
|
-
extension
|
140
|
-
elsif @template.template_format == :js && extension = find_template_extension_from_handler(template_path, :html)
|
141
|
-
@template.template_format = :html
|
142
|
-
extension
|
143
|
-
end
|
144
|
-
end
|
145
|
-
|
146
|
-
def find_template_extension_from_handler(template_path, template_format = @template.template_format)
|
147
|
-
formatted_template_path = "#{template_path}.#{template_format}"
|
148
|
-
|
149
|
-
view_paths.each do |path|
|
150
|
-
if (extensions = @@file_extension_cache[path][formatted_template_path]).any?
|
151
|
-
return "#{template_format}.#{extensions.first}"
|
152
|
-
elsif (extensions = @@file_extension_cache[path][template_path]).any?
|
153
|
-
return extensions.first.to_s
|
154
|
-
end
|
155
|
-
end
|
156
|
-
nil
|
157
|
-
end
|
158
|
-
|
159
|
-
# Splits the path and extension from the given template_path and returns as an array.
|
160
|
-
def path_and_extension(template_path)
|
161
|
-
template_path_without_extension = template_path.sub(/\.(\w+)$/, '')
|
162
|
-
[ template_path_without_extension, $1 ]
|
163
|
-
end
|
164
|
-
|
165
|
-
# Determine the template extension from the <tt>@first_render</tt> filename
|
166
|
-
def find_template_extension_from_first_render
|
167
|
-
File.basename(@template.first_render.to_s)[/^[^.]+\.(.+)$/, 1]
|
168
|
-
end
|
169
|
-
|
170
|
-
private
|
171
|
-
def check_view_paths(view_paths)
|
172
|
-
view_paths.each do |path|
|
173
|
-
raise InvalidViewPath.new(path) unless @@processed_view_paths.has_key?(path)
|
174
|
-
end
|
175
|
-
end
|
176
|
-
end
|
177
|
-
end
|
@@ -1,128 +0,0 @@
|
|
1
|
-
module ActionView
|
2
|
-
module TemplateHandlers
|
3
|
-
module Compilable
|
4
|
-
|
5
|
-
def self.included(base)
|
6
|
-
base.extend ClassMethod
|
7
|
-
|
8
|
-
# Map method names to their compile time
|
9
|
-
base.cattr_accessor :compile_time
|
10
|
-
base.compile_time = {}
|
11
|
-
|
12
|
-
# Map method names to the names passed in local assigns so far
|
13
|
-
base.cattr_accessor :template_args
|
14
|
-
base.template_args = {}
|
15
|
-
|
16
|
-
# Count the number of inline templates
|
17
|
-
base.cattr_accessor :inline_template_count
|
18
|
-
base.inline_template_count = 0
|
19
|
-
end
|
20
|
-
|
21
|
-
module ClassMethod
|
22
|
-
# If a handler is mixin this module, set compilable to true
|
23
|
-
def compilable?
|
24
|
-
true
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
def render(template)
|
29
|
-
@view.send :execute, template
|
30
|
-
end
|
31
|
-
|
32
|
-
# Compile and evaluate the template's code
|
33
|
-
def compile_template(template)
|
34
|
-
return unless compile_template?(template)
|
35
|
-
|
36
|
-
render_symbol = assign_method_name(template)
|
37
|
-
render_source = create_template_source(template, render_symbol)
|
38
|
-
line_offset = self.template_args[render_symbol].size + self.line_offset
|
39
|
-
|
40
|
-
begin
|
41
|
-
file_name = template.filename || 'compiled-template'
|
42
|
-
ActionView::Base::CompiledTemplates.module_eval(render_source, file_name, -line_offset)
|
43
|
-
rescue Exception => e # errors from template code
|
44
|
-
if @view.logger
|
45
|
-
@view.logger.debug "ERROR: compiling #{render_symbol} RAISED #{e}"
|
46
|
-
@view.logger.debug "Function body: #{render_source}"
|
47
|
-
@view.logger.debug "Backtrace: #{e.backtrace.join("\n")}"
|
48
|
-
end
|
49
|
-
|
50
|
-
raise ActionView::TemplateError.new(template, @view.assigns, e)
|
51
|
-
end
|
52
|
-
|
53
|
-
self.compile_time[render_symbol] = Time.now
|
54
|
-
# logger.debug "Compiled template #{file_name || template}\n ==> #{render_symbol}" if logger
|
55
|
-
end
|
56
|
-
|
57
|
-
private
|
58
|
-
|
59
|
-
# Method to check whether template compilation is necessary.
|
60
|
-
# The template will be compiled if the inline template or file has not been compiled yet,
|
61
|
-
# if local_assigns has a new key, which isn't supported by the compiled code yet,
|
62
|
-
# or if the file has changed on disk and checking file mods hasn't been disabled.
|
63
|
-
def compile_template?(template)
|
64
|
-
method_key = template.method_key
|
65
|
-
render_symbol = @view.method_names[method_key]
|
66
|
-
|
67
|
-
compile_time = self.compile_time[render_symbol]
|
68
|
-
if compile_time && supports_local_assigns?(render_symbol, template.locals)
|
69
|
-
if template.filename && !@view.cache_template_loading
|
70
|
-
template_changed_since?(template.filename, compile_time)
|
71
|
-
end
|
72
|
-
else
|
73
|
-
true
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|
77
|
-
def assign_method_name(template)
|
78
|
-
@view.method_names[template.method_key] ||= compiled_method_name(template)
|
79
|
-
end
|
80
|
-
|
81
|
-
def compiled_method_name(template)
|
82
|
-
['_run', self.class.to_s.demodulize.underscore, compiled_method_name_file_path_segment(template.filename)].compact.join('_').to_sym
|
83
|
-
end
|
84
|
-
|
85
|
-
def compiled_method_name_file_path_segment(file_name)
|
86
|
-
if file_name
|
87
|
-
s = File.expand_path(file_name)
|
88
|
-
s.sub!(/^#{Regexp.escape(File.expand_path(RAILS_ROOT))}/, '') if defined?(RAILS_ROOT)
|
89
|
-
s.gsub!(/([^a-zA-Z0-9_])/) { $1.ord }
|
90
|
-
s
|
91
|
-
else
|
92
|
-
(self.inline_template_count += 1).to_s
|
93
|
-
end
|
94
|
-
end
|
95
|
-
|
96
|
-
# Method to create the source code for a given template.
|
97
|
-
def create_template_source(template, render_symbol)
|
98
|
-
body = compile(template)
|
99
|
-
|
100
|
-
self.template_args[render_symbol] ||= {}
|
101
|
-
locals_keys = self.template_args[render_symbol].keys | template.locals.keys
|
102
|
-
self.template_args[render_symbol] = locals_keys.inject({}) { |h, k| h[k] = true; h }
|
103
|
-
|
104
|
-
locals_code = ""
|
105
|
-
locals_keys.each do |key|
|
106
|
-
locals_code << "#{key} = local_assigns[:#{key}]\n"
|
107
|
-
end
|
108
|
-
|
109
|
-
"def #{render_symbol}(local_assigns)\n#{locals_code}#{body}\nend"
|
110
|
-
end
|
111
|
-
|
112
|
-
# Return true if the given template was compiled for a superset of the keys in local_assigns
|
113
|
-
def supports_local_assigns?(render_symbol, local_assigns)
|
114
|
-
local_assigns.empty? ||
|
115
|
-
((args = self.template_args[render_symbol]) && local_assigns.all? { |k,_| args.has_key?(k) })
|
116
|
-
end
|
117
|
-
|
118
|
-
# Method to handle checking a whether a template has changed since last compile; isolated so that templates
|
119
|
-
# not stored on the file system can hook and extend appropriately.
|
120
|
-
def template_changed_since?(file_name, compile_time)
|
121
|
-
lstat = File.lstat(file_name)
|
122
|
-
compile_time < lstat.mtime ||
|
123
|
-
(lstat.symlink? && compile_time < File.stat(file_name).mtime)
|
124
|
-
end
|
125
|
-
|
126
|
-
end
|
127
|
-
end
|
128
|
-
end
|
@@ -1,45 +0,0 @@
|
|
1
|
-
require 'abstract_unit'
|
2
|
-
|
3
|
-
class CustomHandler < ActionView::TemplateHandler
|
4
|
-
def initialize( view )
|
5
|
-
@view = view
|
6
|
-
end
|
7
|
-
|
8
|
-
def render( template )
|
9
|
-
[ template.source,
|
10
|
-
template.locals,
|
11
|
-
@view ]
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
class CustomHandlerTest < Test::Unit::TestCase
|
16
|
-
def setup
|
17
|
-
ActionView::Template.register_template_handler "foo", CustomHandler
|
18
|
-
ActionView::Template.register_template_handler :foo2, CustomHandler
|
19
|
-
@view = ActionView::Base.new
|
20
|
-
end
|
21
|
-
|
22
|
-
def test_custom_render
|
23
|
-
template = ActionView::InlineTemplate.new(@view, "hello <%= one %>", { :one => "two" }, "foo")
|
24
|
-
|
25
|
-
result = @view.render_template(template)
|
26
|
-
assert_equal(
|
27
|
-
[ "hello <%= one %>", { :one => "two" }, @view ],
|
28
|
-
result )
|
29
|
-
end
|
30
|
-
|
31
|
-
def test_custom_render2
|
32
|
-
template = ActionView::InlineTemplate.new(@view, "hello <%= one %>", { :one => "two" }, "foo2")
|
33
|
-
result = @view.render_template(template)
|
34
|
-
assert_equal(
|
35
|
-
[ "hello <%= one %>", { :one => "two" }, @view ],
|
36
|
-
result )
|
37
|
-
end
|
38
|
-
|
39
|
-
def test_unhandled_extension
|
40
|
-
# uses the ERb handler by default if the extension isn't recognized
|
41
|
-
template = ActionView::InlineTemplate.new(@view, "hello <%= one %>", { :one => "two" }, "bar")
|
42
|
-
result = @view.render_template(template)
|
43
|
-
assert_equal "hello two", result
|
44
|
-
end
|
45
|
-
end
|
@@ -1,945 +0,0 @@
|
|
1
|
-
require 'abstract_unit'
|
2
|
-
require 'controller/fake_models'
|
3
|
-
|
4
|
-
class CustomersController < ActionController::Base
|
5
|
-
end
|
6
|
-
|
7
|
-
module Fun
|
8
|
-
class GamesController < ActionController::Base
|
9
|
-
def hello_world
|
10
|
-
end
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
|
-
module NewRenderTestHelper
|
15
|
-
def rjs_helper_method_from_module
|
16
|
-
page.visual_effect :highlight
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
class LabellingFormBuilder < ActionView::Helpers::FormBuilder
|
21
|
-
end
|
22
|
-
|
23
|
-
class NewRenderTestController < ActionController::Base
|
24
|
-
layout :determine_layout
|
25
|
-
|
26
|
-
def self.controller_name; "test"; end
|
27
|
-
def self.controller_path; "test"; end
|
28
|
-
|
29
|
-
def hello_world
|
30
|
-
end
|
31
|
-
|
32
|
-
def render_hello_world
|
33
|
-
render :template => "test/hello_world"
|
34
|
-
end
|
35
|
-
|
36
|
-
def render_hello_world_from_variable
|
37
|
-
@person = "david"
|
38
|
-
render :text => "hello #{@person}"
|
39
|
-
end
|
40
|
-
|
41
|
-
def render_action_hello_world
|
42
|
-
render :action => "hello_world"
|
43
|
-
end
|
44
|
-
|
45
|
-
def render_action_hello_world_as_symbol
|
46
|
-
render :action => :hello_world
|
47
|
-
end
|
48
|
-
|
49
|
-
def render_text_hello_world
|
50
|
-
render :text => "hello world"
|
51
|
-
end
|
52
|
-
|
53
|
-
def render_text_hello_world_with_layout
|
54
|
-
@variable_for_layout = ", I'm here!"
|
55
|
-
render :text => "hello world", :layout => true
|
56
|
-
end
|
57
|
-
|
58
|
-
def hello_world_with_layout_false
|
59
|
-
render :layout => false
|
60
|
-
end
|
61
|
-
|
62
|
-
def render_custom_code
|
63
|
-
render :text => "hello world", :status => "404 Moved"
|
64
|
-
end
|
65
|
-
|
66
|
-
def render_file_with_instance_variables
|
67
|
-
@secret = 'in the sauce'
|
68
|
-
path = File.join(File.dirname(__FILE__), '../fixtures/test/render_file_with_ivar.erb')
|
69
|
-
render :file => path
|
70
|
-
end
|
71
|
-
|
72
|
-
def render_file_from_template
|
73
|
-
@secret = 'in the sauce'
|
74
|
-
@path = File.expand_path(File.join(File.dirname(__FILE__), '../fixtures/test/render_file_with_ivar.erb'))
|
75
|
-
end
|
76
|
-
|
77
|
-
def render_file_with_locals
|
78
|
-
path = File.join(File.dirname(__FILE__), '../fixtures/test/render_file_with_locals.erb')
|
79
|
-
render :file => path, :locals => {:secret => 'in the sauce'}
|
80
|
-
end
|
81
|
-
|
82
|
-
def render_file_not_using_full_path
|
83
|
-
@secret = 'in the sauce'
|
84
|
-
render :file => 'test/render_file_with_ivar', :use_full_path => true
|
85
|
-
end
|
86
|
-
|
87
|
-
def render_file_not_using_full_path_with_dot_in_path
|
88
|
-
@secret = 'in the sauce'
|
89
|
-
render :file => 'test/dot.directory/render_file_with_ivar', :use_full_path => true
|
90
|
-
end
|
91
|
-
|
92
|
-
def render_xml_hello
|
93
|
-
@name = "David"
|
94
|
-
render :template => "test/hello"
|
95
|
-
end
|
96
|
-
|
97
|
-
def greeting
|
98
|
-
# let's just rely on the template
|
99
|
-
end
|
100
|
-
|
101
|
-
def layout_test
|
102
|
-
render :action => "hello_world"
|
103
|
-
end
|
104
|
-
|
105
|
-
def layout_test_with_different_layout
|
106
|
-
render :action => "hello_world", :layout => "standard"
|
107
|
-
end
|
108
|
-
|
109
|
-
def rendering_without_layout
|
110
|
-
render :action => "hello_world", :layout => false
|
111
|
-
end
|
112
|
-
|
113
|
-
def layout_overriding_layout
|
114
|
-
render :action => "hello_world", :layout => "standard"
|
115
|
-
end
|
116
|
-
|
117
|
-
def rendering_nothing_on_layout
|
118
|
-
render :nothing => true
|
119
|
-
end
|
120
|
-
|
121
|
-
def builder_layout_test
|
122
|
-
render :action => "hello"
|
123
|
-
end
|
124
|
-
|
125
|
-
def partials_list
|
126
|
-
@test_unchanged = 'hello'
|
127
|
-
@customers = [ Customer.new("david"), Customer.new("mary") ]
|
128
|
-
render :action => "list"
|
129
|
-
end
|
130
|
-
|
131
|
-
def partial_only
|
132
|
-
render :partial => true
|
133
|
-
end
|
134
|
-
|
135
|
-
def partial_only_with_layout
|
136
|
-
render :partial => "partial_only", :layout => true
|
137
|
-
end
|
138
|
-
|
139
|
-
def partial_with_locals
|
140
|
-
render :partial => "customer", :locals => { :customer => Customer.new("david") }
|
141
|
-
end
|
142
|
-
|
143
|
-
def partial_with_form_builder
|
144
|
-
render :partial => ActionView::Helpers::FormBuilder.new(:post, nil, @template, {}, Proc.new {})
|
145
|
-
end
|
146
|
-
|
147
|
-
def partial_with_form_builder_subclass
|
148
|
-
render :partial => LabellingFormBuilder.new(:post, nil, @template, {}, Proc.new {})
|
149
|
-
end
|
150
|
-
|
151
|
-
def partial_collection
|
152
|
-
render :partial => "customer", :collection => [ Customer.new("david"), Customer.new("mary") ]
|
153
|
-
end
|
154
|
-
|
155
|
-
def partial_collection_with_spacer
|
156
|
-
render :partial => "customer", :spacer_template => "partial_only", :collection => [ Customer.new("david"), Customer.new("mary") ]
|
157
|
-
end
|
158
|
-
|
159
|
-
def partial_collection_with_counter
|
160
|
-
render :partial => "customer_counter", :collection => [ Customer.new("david"), Customer.new("mary") ]
|
161
|
-
end
|
162
|
-
|
163
|
-
def partial_collection_with_locals
|
164
|
-
render :partial => "customer_greeting", :collection => [ Customer.new("david"), Customer.new("mary") ], :locals => { :greeting => "Bonjour" }
|
165
|
-
end
|
166
|
-
|
167
|
-
def partial_collection_shorthand_with_locals
|
168
|
-
render :partial => [ Customer.new("david"), Customer.new("mary") ], :locals => { :greeting => "Bonjour" }
|
169
|
-
end
|
170
|
-
|
171
|
-
def partial_collection_shorthand_with_different_types_of_records
|
172
|
-
render :partial => [
|
173
|
-
BadCustomer.new("mark"),
|
174
|
-
GoodCustomer.new("craig"),
|
175
|
-
BadCustomer.new("john"),
|
176
|
-
GoodCustomer.new("zach"),
|
177
|
-
GoodCustomer.new("brandon"),
|
178
|
-
BadCustomer.new("dan") ],
|
179
|
-
:locals => { :greeting => "Bonjour" }
|
180
|
-
end
|
181
|
-
|
182
|
-
def partial_collection_shorthand_with_different_types_of_records_with_counter
|
183
|
-
partial_collection_shorthand_with_different_types_of_records
|
184
|
-
end
|
185
|
-
|
186
|
-
def empty_partial_collection
|
187
|
-
render :partial => "customer", :collection => []
|
188
|
-
end
|
189
|
-
|
190
|
-
def partial_with_hash_object
|
191
|
-
render :partial => "hash_object", :object => {:first_name => "Sam"}
|
192
|
-
end
|
193
|
-
|
194
|
-
def partial_hash_collection
|
195
|
-
render :partial => "hash_object", :collection => [ {:first_name => "Pratik"}, {:first_name => "Amy"} ]
|
196
|
-
end
|
197
|
-
|
198
|
-
def partial_hash_collection_with_locals
|
199
|
-
render :partial => "hash_greeting", :collection => [ {:first_name => "Pratik"}, {:first_name => "Amy"} ], :locals => { :greeting => "Hola" }
|
200
|
-
end
|
201
|
-
|
202
|
-
def partial_with_implicit_local_assignment
|
203
|
-
@customer = Customer.new("Marcel")
|
204
|
-
render :partial => "customer"
|
205
|
-
end
|
206
|
-
|
207
|
-
def missing_partial
|
208
|
-
render :partial => 'thisFileIsntHere'
|
209
|
-
end
|
210
|
-
|
211
|
-
def hello_in_a_string
|
212
|
-
@customers = [ Customer.new("david"), Customer.new("mary") ]
|
213
|
-
render :text => "How's there? " << render_to_string(:template => "test/list")
|
214
|
-
end
|
215
|
-
|
216
|
-
def render_to_string_with_assigns
|
217
|
-
@before = "i'm before the render"
|
218
|
-
render_to_string :text => "foo"
|
219
|
-
@after = "i'm after the render"
|
220
|
-
render :action => "test/hello_world"
|
221
|
-
end
|
222
|
-
|
223
|
-
def render_to_string_with_partial
|
224
|
-
@partial_only = render_to_string :partial => "partial_only"
|
225
|
-
@partial_with_locals = render_to_string :partial => "customer", :locals => { :customer => Customer.new("david") }
|
226
|
-
render :action => "test/hello_world"
|
227
|
-
end
|
228
|
-
|
229
|
-
def render_to_string_with_exception
|
230
|
-
render_to_string :file => "exception that will not be caught - this will certainly not work", :use_full_path => true
|
231
|
-
end
|
232
|
-
|
233
|
-
def render_to_string_with_caught_exception
|
234
|
-
@before = "i'm before the render"
|
235
|
-
begin
|
236
|
-
render_to_string :file => "exception that will be caught- hope my future instance vars still work!", :use_full_path => true
|
237
|
-
rescue
|
238
|
-
end
|
239
|
-
@after = "i'm after the render"
|
240
|
-
render :action => "test/hello_world"
|
241
|
-
end
|
242
|
-
|
243
|
-
def accessing_params_in_template
|
244
|
-
render :inline => "Hello: <%= params[:name] %>"
|
245
|
-
end
|
246
|
-
|
247
|
-
def accessing_request_in_template
|
248
|
-
render :inline => "Hello: <%= request.host %>"
|
249
|
-
end
|
250
|
-
|
251
|
-
def accessing_logger_in_template
|
252
|
-
render :inline => "<%= logger.class %>"
|
253
|
-
end
|
254
|
-
|
255
|
-
def accessing_action_name_in_template
|
256
|
-
render :inline => "<%= action_name %>"
|
257
|
-
end
|
258
|
-
|
259
|
-
def accessing_params_in_template_with_layout
|
260
|
-
render :layout => nil, :inline => "Hello: <%= params[:name] %>"
|
261
|
-
end
|
262
|
-
|
263
|
-
def render_with_explicit_template
|
264
|
-
render :template => "test/hello_world"
|
265
|
-
end
|
266
|
-
|
267
|
-
def render_with_explicit_template_with_locals
|
268
|
-
render :template => "test/render_file_with_locals", :locals => { :secret => 'area51' }
|
269
|
-
end
|
270
|
-
|
271
|
-
def double_render
|
272
|
-
render :text => "hello"
|
273
|
-
render :text => "world"
|
274
|
-
end
|
275
|
-
|
276
|
-
def double_redirect
|
277
|
-
redirect_to :action => "double_render"
|
278
|
-
redirect_to :action => "double_render"
|
279
|
-
end
|
280
|
-
|
281
|
-
def render_and_redirect
|
282
|
-
render :text => "hello"
|
283
|
-
redirect_to :action => "double_render"
|
284
|
-
end
|
285
|
-
|
286
|
-
def render_to_string_and_render
|
287
|
-
@stuff = render_to_string :text => "here is some cached stuff"
|
288
|
-
render :text => "Hi web users! #{@stuff}"
|
289
|
-
end
|
290
|
-
|
291
|
-
def rendering_with_conflicting_local_vars
|
292
|
-
@name = "David"
|
293
|
-
def @template.name() nil end
|
294
|
-
render :action => "potential_conflicts"
|
295
|
-
end
|
296
|
-
|
297
|
-
def hello_world_from_rxml_using_action
|
298
|
-
render :action => "hello_world_from_rxml.builder"
|
299
|
-
end
|
300
|
-
|
301
|
-
def hello_world_from_rxml_using_template
|
302
|
-
render :template => "test/hello_world_from_rxml.builder"
|
303
|
-
end
|
304
|
-
|
305
|
-
def head_with_location_header
|
306
|
-
head :location => "/foo"
|
307
|
-
end
|
308
|
-
|
309
|
-
def head_with_symbolic_status
|
310
|
-
head :status => params[:status].intern
|
311
|
-
end
|
312
|
-
|
313
|
-
def head_with_integer_status
|
314
|
-
head :status => params[:status].to_i
|
315
|
-
end
|
316
|
-
|
317
|
-
def head_with_string_status
|
318
|
-
head :status => params[:status]
|
319
|
-
end
|
320
|
-
|
321
|
-
def head_with_custom_header
|
322
|
-
head :x_custom_header => "something"
|
323
|
-
end
|
324
|
-
|
325
|
-
def head_with_status_code_first
|
326
|
-
head :forbidden, :x_custom_header => "something"
|
327
|
-
end
|
328
|
-
|
329
|
-
def render_with_location
|
330
|
-
render :xml => "<hello/>", :location => "http://example.com", :status => 201
|
331
|
-
end
|
332
|
-
|
333
|
-
def render_with_object_location
|
334
|
-
customer = Customer.new("Some guy", 1)
|
335
|
-
render :xml => "<customer/>", :location => customer_url(customer), :status => :created
|
336
|
-
end
|
337
|
-
|
338
|
-
def render_with_to_xml
|
339
|
-
to_xmlable = Class.new do
|
340
|
-
def to_xml
|
341
|
-
"<i-am-xml/>"
|
342
|
-
end
|
343
|
-
end.new
|
344
|
-
|
345
|
-
render :xml => to_xmlable
|
346
|
-
end
|
347
|
-
|
348
|
-
helper NewRenderTestHelper
|
349
|
-
helper do
|
350
|
-
def rjs_helper_method(value)
|
351
|
-
page.visual_effect :highlight, value
|
352
|
-
end
|
353
|
-
end
|
354
|
-
|
355
|
-
def enum_rjs_test
|
356
|
-
render :update do |page|
|
357
|
-
page.select('.product').each do |value|
|
358
|
-
page.rjs_helper_method_from_module
|
359
|
-
page.rjs_helper_method(value)
|
360
|
-
page.sortable(value, :url => { :action => "order" })
|
361
|
-
page.draggable(value)
|
362
|
-
end
|
363
|
-
end
|
364
|
-
end
|
365
|
-
|
366
|
-
def delete_with_js
|
367
|
-
@project_id = 4
|
368
|
-
end
|
369
|
-
|
370
|
-
def render_js_with_explicit_template
|
371
|
-
@project_id = 4
|
372
|
-
render :template => 'test/delete_with_js'
|
373
|
-
end
|
374
|
-
|
375
|
-
def render_js_with_explicit_action_template
|
376
|
-
@project_id = 4
|
377
|
-
render :action => 'delete_with_js'
|
378
|
-
end
|
379
|
-
|
380
|
-
def update_page
|
381
|
-
render :update do |page|
|
382
|
-
page.replace_html 'balance', '$37,000,000.00'
|
383
|
-
page.visual_effect :highlight, 'balance'
|
384
|
-
end
|
385
|
-
end
|
386
|
-
|
387
|
-
def update_page_with_instance_variables
|
388
|
-
@money = '$37,000,000.00'
|
389
|
-
@div_id = 'balance'
|
390
|
-
render :update do |page|
|
391
|
-
page.replace_html @div_id, @money
|
392
|
-
page.visual_effect :highlight, @div_id
|
393
|
-
end
|
394
|
-
end
|
395
|
-
|
396
|
-
def action_talk_to_layout
|
397
|
-
# Action template sets variable that's picked up by layout
|
398
|
-
end
|
399
|
-
|
400
|
-
def render_text_with_assigns
|
401
|
-
@hello = "world"
|
402
|
-
render :text => "foo"
|
403
|
-
end
|
404
|
-
|
405
|
-
def yield_content_for
|
406
|
-
render :action => "content_for", :layout => "yield"
|
407
|
-
end
|
408
|
-
|
409
|
-
def render_content_type_from_body
|
410
|
-
response.content_type = Mime::RSS
|
411
|
-
render :text => "hello world!"
|
412
|
-
end
|
413
|
-
|
414
|
-
def render_call_to_partial_with_layout
|
415
|
-
render :action => "calling_partial_with_layout"
|
416
|
-
end
|
417
|
-
|
418
|
-
def render_call_to_partial_with_layout_in_main_layout_and_within_content_for_layout
|
419
|
-
render :action => "calling_partial_with_layout"
|
420
|
-
end
|
421
|
-
|
422
|
-
def render_using_layout_around_block
|
423
|
-
render :action => "using_layout_around_block"
|
424
|
-
end
|
425
|
-
|
426
|
-
def render_using_layout_around_block_in_main_layout_and_within_content_for_layout
|
427
|
-
render :action => "using_layout_around_block"
|
428
|
-
end
|
429
|
-
|
430
|
-
def rescue_action(e) raise end
|
431
|
-
|
432
|
-
private
|
433
|
-
def determine_layout
|
434
|
-
case action_name
|
435
|
-
when "hello_world", "layout_test", "rendering_without_layout",
|
436
|
-
"rendering_nothing_on_layout", "render_text_hello_world",
|
437
|
-
"render_text_hello_world_with_layout",
|
438
|
-
"hello_world_with_layout_false",
|
439
|
-
"partial_only", "partial_only_with_layout",
|
440
|
-
"accessing_params_in_template",
|
441
|
-
"accessing_params_in_template_with_layout",
|
442
|
-
"render_with_explicit_template",
|
443
|
-
"render_js_with_explicit_template",
|
444
|
-
"render_js_with_explicit_action_template",
|
445
|
-
"delete_with_js", "update_page", "update_page_with_instance_variables"
|
446
|
-
|
447
|
-
"layouts/standard"
|
448
|
-
when "builder_layout_test"
|
449
|
-
"layouts/builder"
|
450
|
-
when "action_talk_to_layout", "layout_overriding_layout"
|
451
|
-
"layouts/talk_from_action"
|
452
|
-
when "render_call_to_partial_with_layout_in_main_layout_and_within_content_for_layout"
|
453
|
-
"layouts/partial_with_layout"
|
454
|
-
when "render_using_layout_around_block_in_main_layout_and_within_content_for_layout"
|
455
|
-
"layouts/block_with_layout"
|
456
|
-
end
|
457
|
-
end
|
458
|
-
end
|
459
|
-
|
460
|
-
NewRenderTestController.view_paths = [ File.dirname(__FILE__) + "/../fixtures/" ]
|
461
|
-
Fun::GamesController.view_paths = [ File.dirname(__FILE__) + "/../fixtures/" ]
|
462
|
-
|
463
|
-
class NewRenderTest < Test::Unit::TestCase
|
464
|
-
def setup
|
465
|
-
@controller = NewRenderTestController.new
|
466
|
-
|
467
|
-
# enable a logger so that (e.g.) the benchmarking stuff runs, so we can get
|
468
|
-
# a more accurate simulation of what happens in "real life".
|
469
|
-
@controller.logger = Logger.new(nil)
|
470
|
-
|
471
|
-
@request = ActionController::TestRequest.new
|
472
|
-
@response = ActionController::TestResponse.new
|
473
|
-
|
474
|
-
@request.host = "www.nextangle.com"
|
475
|
-
end
|
476
|
-
|
477
|
-
def test_simple_show
|
478
|
-
get :hello_world
|
479
|
-
assert_response :success
|
480
|
-
assert_template "test/hello_world"
|
481
|
-
assert_equal "<html>Hello world!</html>", @response.body
|
482
|
-
end
|
483
|
-
|
484
|
-
def test_do_with_render
|
485
|
-
get :render_hello_world
|
486
|
-
assert_template "test/hello_world"
|
487
|
-
end
|
488
|
-
|
489
|
-
def test_do_with_render_from_variable
|
490
|
-
get :render_hello_world_from_variable
|
491
|
-
assert_equal "hello david", @response.body
|
492
|
-
end
|
493
|
-
|
494
|
-
def test_do_with_render_action
|
495
|
-
get :render_action_hello_world
|
496
|
-
assert_template "test/hello_world"
|
497
|
-
end
|
498
|
-
|
499
|
-
def test_do_with_render_action_as_symbol
|
500
|
-
get :render_action_hello_world_as_symbol
|
501
|
-
assert_template "test/hello_world"
|
502
|
-
end
|
503
|
-
|
504
|
-
def test_do_with_render_text
|
505
|
-
get :render_text_hello_world
|
506
|
-
assert_equal "hello world", @response.body
|
507
|
-
end
|
508
|
-
|
509
|
-
def test_do_with_render_text_and_layout
|
510
|
-
get :render_text_hello_world_with_layout
|
511
|
-
assert_equal "<html>hello world, I'm here!</html>", @response.body
|
512
|
-
end
|
513
|
-
|
514
|
-
def test_do_with_render_action_and_layout_false
|
515
|
-
get :hello_world_with_layout_false
|
516
|
-
assert_equal 'Hello world!', @response.body
|
517
|
-
end
|
518
|
-
|
519
|
-
def test_do_with_render_custom_code
|
520
|
-
get :render_custom_code
|
521
|
-
assert_response :missing
|
522
|
-
end
|
523
|
-
|
524
|
-
def test_render_file_with_instance_variables
|
525
|
-
get :render_file_with_instance_variables
|
526
|
-
assert_equal "The secret is in the sauce\n", @response.body
|
527
|
-
end
|
528
|
-
|
529
|
-
def test_render_file_not_using_full_path
|
530
|
-
get :render_file_not_using_full_path
|
531
|
-
assert_equal "The secret is in the sauce\n", @response.body
|
532
|
-
end
|
533
|
-
|
534
|
-
def test_render_file_not_using_full_path_with_dot_in_path
|
535
|
-
get :render_file_not_using_full_path_with_dot_in_path
|
536
|
-
assert_equal "The secret is in the sauce\n", @response.body
|
537
|
-
end
|
538
|
-
|
539
|
-
def test_render_file_with_locals
|
540
|
-
get :render_file_with_locals
|
541
|
-
assert_equal "The secret is in the sauce\n", @response.body
|
542
|
-
end
|
543
|
-
|
544
|
-
def test_render_file_from_template
|
545
|
-
get :render_file_from_template
|
546
|
-
assert_equal "The secret is in the sauce\n", @response.body
|
547
|
-
end
|
548
|
-
|
549
|
-
def test_attempt_to_access_object_method
|
550
|
-
assert_raises(ActionController::UnknownAction, "No action responded to [clone]") { get :clone }
|
551
|
-
end
|
552
|
-
|
553
|
-
def test_private_methods
|
554
|
-
assert_raises(ActionController::UnknownAction, "No action responded to [determine_layout]") { get :determine_layout }
|
555
|
-
end
|
556
|
-
|
557
|
-
def test_access_to_request_in_view
|
558
|
-
get :accessing_request_in_template
|
559
|
-
assert_equal "Hello: www.nextangle.com", @response.body
|
560
|
-
end
|
561
|
-
|
562
|
-
def test_access_to_logger_in_view
|
563
|
-
get :accessing_logger_in_template
|
564
|
-
assert_equal "Logger", @response.body
|
565
|
-
end
|
566
|
-
|
567
|
-
def test_access_to_action_name_in_view
|
568
|
-
get :accessing_action_name_in_template
|
569
|
-
assert_equal "accessing_action_name_in_template", @response.body
|
570
|
-
end
|
571
|
-
|
572
|
-
def test_render_xml
|
573
|
-
get :render_xml_hello
|
574
|
-
assert_equal "<html>\n <p>Hello David</p>\n<p>This is grand!</p>\n</html>\n", @response.body
|
575
|
-
end
|
576
|
-
|
577
|
-
def test_enum_rjs_test
|
578
|
-
get :enum_rjs_test
|
579
|
-
assert_equal <<-EOS.strip, @response.body
|
580
|
-
$$(".product").each(function(value, index) {
|
581
|
-
new Effect.Highlight(element,{});
|
582
|
-
new Effect.Highlight(value,{});
|
583
|
-
Sortable.create(value, {onUpdate:function(){new Ajax.Request('/test/order', {asynchronous:true, evalScripts:true, parameters:Sortable.serialize(value)})}});
|
584
|
-
new Draggable(value, {});
|
585
|
-
});
|
586
|
-
EOS
|
587
|
-
end
|
588
|
-
|
589
|
-
def test_render_xml_with_default
|
590
|
-
get :greeting
|
591
|
-
assert_equal "<p>This is grand!</p>\n", @response.body
|
592
|
-
end
|
593
|
-
|
594
|
-
def test_render_with_default_from_accept_header
|
595
|
-
@request.env["HTTP_ACCEPT"] = "text/javascript"
|
596
|
-
get :greeting
|
597
|
-
assert_equal "$(\"body\").visualEffect(\"highlight\");", @response.body
|
598
|
-
end
|
599
|
-
|
600
|
-
def test_render_rjs_with_default
|
601
|
-
get :delete_with_js
|
602
|
-
assert_equal %!Element.remove("person");\nnew Effect.Highlight(\"project-4\",{});!, @response.body
|
603
|
-
end
|
604
|
-
|
605
|
-
def test_render_rjs_template_explicitly
|
606
|
-
get :render_js_with_explicit_template
|
607
|
-
assert_equal %!Element.remove("person");\nnew Effect.Highlight(\"project-4\",{});!, @response.body
|
608
|
-
end
|
609
|
-
|
610
|
-
def test_rendering_rjs_action_explicitly
|
611
|
-
get :render_js_with_explicit_action_template
|
612
|
-
assert_equal %!Element.remove("person");\nnew Effect.Highlight(\"project-4\",{});!, @response.body
|
613
|
-
end
|
614
|
-
|
615
|
-
def test_layout_rendering
|
616
|
-
get :layout_test
|
617
|
-
assert_equal "<html>Hello world!</html>", @response.body
|
618
|
-
end
|
619
|
-
|
620
|
-
def test_layout_test_with_different_layout
|
621
|
-
get :layout_test_with_different_layout
|
622
|
-
assert_equal "<html>Hello world!</html>", @response.body
|
623
|
-
end
|
624
|
-
|
625
|
-
def test_rendering_without_layout
|
626
|
-
get :rendering_without_layout
|
627
|
-
assert_equal "Hello world!", @response.body
|
628
|
-
end
|
629
|
-
|
630
|
-
def test_layout_overriding_layout
|
631
|
-
get :layout_overriding_layout
|
632
|
-
assert_no_match %r{<title>}, @response.body
|
633
|
-
end
|
634
|
-
|
635
|
-
def test_rendering_nothing_on_layout
|
636
|
-
get :rendering_nothing_on_layout
|
637
|
-
assert_equal " ", @response.body
|
638
|
-
end
|
639
|
-
|
640
|
-
def test_render_xml_with_layouts
|
641
|
-
get :builder_layout_test
|
642
|
-
assert_equal "<wrapper>\n<html>\n <p>Hello </p>\n<p>This is grand!</p>\n</html>\n</wrapper>\n", @response.body
|
643
|
-
end
|
644
|
-
|
645
|
-
def test_partial_only
|
646
|
-
get :partial_only
|
647
|
-
assert_equal "only partial", @response.body
|
648
|
-
end
|
649
|
-
|
650
|
-
def test_partial_only_with_layout
|
651
|
-
get :partial_only_with_layout
|
652
|
-
assert_equal "<html>only partial</html>", @response.body
|
653
|
-
end
|
654
|
-
|
655
|
-
def test_render_to_string
|
656
|
-
assert_not_deprecated { get :hello_in_a_string }
|
657
|
-
assert_equal "How's there? goodbyeHello: davidHello: marygoodbye\n", @response.body
|
658
|
-
end
|
659
|
-
|
660
|
-
def test_render_to_string_doesnt_break_assigns
|
661
|
-
get :render_to_string_with_assigns
|
662
|
-
assert_equal "i'm before the render", assigns(:before)
|
663
|
-
assert_equal "i'm after the render", assigns(:after)
|
664
|
-
end
|
665
|
-
|
666
|
-
def test_render_to_string_partial
|
667
|
-
get :render_to_string_with_partial
|
668
|
-
assert_equal "only partial", assigns(:partial_only)
|
669
|
-
assert_equal "Hello: david", assigns(:partial_with_locals)
|
670
|
-
end
|
671
|
-
|
672
|
-
def test_bad_render_to_string_still_throws_exception
|
673
|
-
assert_raises(ActionView::MissingTemplate) { get :render_to_string_with_exception }
|
674
|
-
end
|
675
|
-
|
676
|
-
def test_render_to_string_that_throws_caught_exception_doesnt_break_assigns
|
677
|
-
assert_nothing_raised { get :render_to_string_with_caught_exception }
|
678
|
-
assert_equal "i'm before the render", assigns(:before)
|
679
|
-
assert_equal "i'm after the render", assigns(:after)
|
680
|
-
end
|
681
|
-
|
682
|
-
def test_nested_rendering
|
683
|
-
get :hello_world
|
684
|
-
assert_equal "Living in a nested world", Fun::GamesController.process(@request, @response).body
|
685
|
-
end
|
686
|
-
|
687
|
-
def test_accessing_params_in_template
|
688
|
-
get :accessing_params_in_template, :name => "David"
|
689
|
-
assert_equal "Hello: David", @response.body
|
690
|
-
end
|
691
|
-
|
692
|
-
def test_accessing_params_in_template_with_layout
|
693
|
-
get :accessing_params_in_template_with_layout, :name => "David"
|
694
|
-
assert_equal "<html>Hello: David</html>", @response.body
|
695
|
-
end
|
696
|
-
|
697
|
-
def test_render_with_explicit_template
|
698
|
-
get :render_with_explicit_template
|
699
|
-
assert_response :success
|
700
|
-
end
|
701
|
-
|
702
|
-
def test_double_render
|
703
|
-
assert_raises(ActionController::DoubleRenderError) { get :double_render }
|
704
|
-
end
|
705
|
-
|
706
|
-
def test_double_redirect
|
707
|
-
assert_raises(ActionController::DoubleRenderError) { get :double_redirect }
|
708
|
-
end
|
709
|
-
|
710
|
-
def test_render_and_redirect
|
711
|
-
assert_raises(ActionController::DoubleRenderError) { get :render_and_redirect }
|
712
|
-
end
|
713
|
-
|
714
|
-
# specify the one exception to double render rule - render_to_string followed by render
|
715
|
-
def test_render_to_string_and_render
|
716
|
-
get :render_to_string_and_render
|
717
|
-
assert_equal("Hi web users! here is some cached stuff", @response.body)
|
718
|
-
end
|
719
|
-
|
720
|
-
def test_rendering_with_conflicting_local_vars
|
721
|
-
get :rendering_with_conflicting_local_vars
|
722
|
-
assert_equal("First: David\nSecond: Stephan\nThird: David\nFourth: David\nFifth: ", @response.body)
|
723
|
-
end
|
724
|
-
|
725
|
-
def test_action_talk_to_layout
|
726
|
-
get :action_talk_to_layout
|
727
|
-
assert_equal "<title>Talking to the layout</title>\nAction was here!", @response.body
|
728
|
-
end
|
729
|
-
|
730
|
-
def test_partials_list
|
731
|
-
get :partials_list
|
732
|
-
assert_equal "goodbyeHello: davidHello: marygoodbye\n", @response.body
|
733
|
-
end
|
734
|
-
|
735
|
-
def test_partial_with_locals
|
736
|
-
get :partial_with_locals
|
737
|
-
assert_equal "Hello: david", @response.body
|
738
|
-
end
|
739
|
-
|
740
|
-
def test_partial_with_form_builder
|
741
|
-
get :partial_with_form_builder
|
742
|
-
assert_match(/<label/, @response.body)
|
743
|
-
assert_template('test/_form')
|
744
|
-
end
|
745
|
-
|
746
|
-
def test_partial_with_form_builder_subclass
|
747
|
-
get :partial_with_form_builder_subclass
|
748
|
-
assert_match(/<label/, @response.body)
|
749
|
-
assert_template('test/_labelling_form')
|
750
|
-
end
|
751
|
-
|
752
|
-
def test_partial_collection
|
753
|
-
get :partial_collection
|
754
|
-
assert_equal "Hello: davidHello: mary", @response.body
|
755
|
-
end
|
756
|
-
|
757
|
-
def test_partial_collection_with_counter
|
758
|
-
get :partial_collection_with_counter
|
759
|
-
assert_equal "david0mary1", @response.body
|
760
|
-
end
|
761
|
-
|
762
|
-
def test_partial_collection_with_locals
|
763
|
-
get :partial_collection_with_locals
|
764
|
-
assert_equal "Bonjour: davidBonjour: mary", @response.body
|
765
|
-
end
|
766
|
-
|
767
|
-
def test_partial_collection_with_spacer
|
768
|
-
get :partial_collection_with_spacer
|
769
|
-
assert_equal "Hello: davidonly partialHello: mary", @response.body
|
770
|
-
end
|
771
|
-
|
772
|
-
def test_partial_collection_shorthand_with_locals
|
773
|
-
get :partial_collection_shorthand_with_locals
|
774
|
-
assert_equal "Bonjour: davidBonjour: mary", @response.body
|
775
|
-
end
|
776
|
-
|
777
|
-
def test_partial_collection_shorthand_with_different_types_of_records
|
778
|
-
get :partial_collection_shorthand_with_different_types_of_records
|
779
|
-
assert_equal "Bonjour bad customer: mark0Bonjour good customer: craig1Bonjour bad customer: john2Bonjour good customer: zach3Bonjour good customer: brandon4Bonjour bad customer: dan5", @response.body
|
780
|
-
end
|
781
|
-
|
782
|
-
def test_empty_partial_collection
|
783
|
-
get :empty_partial_collection
|
784
|
-
assert_equal " ", @response.body
|
785
|
-
end
|
786
|
-
|
787
|
-
def test_partial_with_hash_object
|
788
|
-
get :partial_with_hash_object
|
789
|
-
assert_equal "Sam\nmaS\n", @response.body
|
790
|
-
end
|
791
|
-
|
792
|
-
def test_hash_partial_collection
|
793
|
-
get :partial_hash_collection
|
794
|
-
assert_equal "Pratik\nkitarP\nAmy\nymA\n", @response.body
|
795
|
-
end
|
796
|
-
|
797
|
-
def test_partial_hash_collection_with_locals
|
798
|
-
get :partial_hash_collection_with_locals
|
799
|
-
assert_equal "Hola: PratikHola: Amy", @response.body
|
800
|
-
end
|
801
|
-
|
802
|
-
def test_partial_with_implicit_local_assignment
|
803
|
-
get :partial_with_implicit_local_assignment
|
804
|
-
assert_equal "Hello: Marcel", @response.body
|
805
|
-
end
|
806
|
-
|
807
|
-
def test_render_missing_partial_template
|
808
|
-
assert_raises(ActionView::MissingTemplate) do
|
809
|
-
get :missing_partial
|
810
|
-
end
|
811
|
-
end
|
812
|
-
|
813
|
-
def test_render_text_with_assigns
|
814
|
-
get :render_text_with_assigns
|
815
|
-
assert_equal "world", assigns["hello"]
|
816
|
-
end
|
817
|
-
|
818
|
-
def test_template_with_locals
|
819
|
-
get :render_with_explicit_template_with_locals
|
820
|
-
assert_equal "The secret is area51\n", @response.body
|
821
|
-
end
|
822
|
-
|
823
|
-
def test_update_page
|
824
|
-
get :update_page
|
825
|
-
assert_template nil
|
826
|
-
assert_equal 'text/javascript; charset=utf-8', @response.headers['type']
|
827
|
-
assert_equal 2, @response.body.split($/).length
|
828
|
-
end
|
829
|
-
|
830
|
-
def test_update_page_with_instance_variables
|
831
|
-
get :update_page_with_instance_variables
|
832
|
-
assert_template nil
|
833
|
-
assert_equal 'text/javascript; charset=utf-8', @response.headers['type']
|
834
|
-
assert_match /balance/, @response.body
|
835
|
-
assert_match /\$37/, @response.body
|
836
|
-
end
|
837
|
-
|
838
|
-
def test_yield_content_for
|
839
|
-
assert_not_deprecated { get :yield_content_for }
|
840
|
-
assert_equal "<title>Putting stuff in the title!</title>\n\nGreat stuff!\n", @response.body
|
841
|
-
end
|
842
|
-
|
843
|
-
|
844
|
-
def test_overwritting_rendering_relative_file_with_extension
|
845
|
-
get :hello_world_from_rxml_using_template
|
846
|
-
assert_equal "<html>\n <p>Hello</p>\n</html>\n", @response.body
|
847
|
-
|
848
|
-
get :hello_world_from_rxml_using_action
|
849
|
-
assert_equal "<html>\n <p>Hello</p>\n</html>\n", @response.body
|
850
|
-
end
|
851
|
-
|
852
|
-
|
853
|
-
def test_head_with_location_header
|
854
|
-
get :head_with_location_header
|
855
|
-
assert @response.body.blank?
|
856
|
-
assert_equal "/foo", @response.headers["Location"]
|
857
|
-
assert_response :ok
|
858
|
-
end
|
859
|
-
|
860
|
-
def test_head_with_custom_header
|
861
|
-
get :head_with_custom_header
|
862
|
-
assert @response.body.blank?
|
863
|
-
assert_equal "something", @response.headers["X-Custom-Header"]
|
864
|
-
assert_response :ok
|
865
|
-
end
|
866
|
-
|
867
|
-
def test_head_with_symbolic_status
|
868
|
-
get :head_with_symbolic_status, :status => "ok"
|
869
|
-
assert_equal "200 OK", @response.headers["Status"]
|
870
|
-
assert_response :ok
|
871
|
-
|
872
|
-
get :head_with_symbolic_status, :status => "not_found"
|
873
|
-
assert_equal "404 Not Found", @response.headers["Status"]
|
874
|
-
assert_response :not_found
|
875
|
-
|
876
|
-
ActionController::StatusCodes::SYMBOL_TO_STATUS_CODE.each do |status, code|
|
877
|
-
get :head_with_symbolic_status, :status => status.to_s
|
878
|
-
assert_equal code, @response.response_code
|
879
|
-
assert_response status
|
880
|
-
end
|
881
|
-
end
|
882
|
-
|
883
|
-
def test_head_with_integer_status
|
884
|
-
ActionController::StatusCodes::STATUS_CODES.each do |code, message|
|
885
|
-
get :head_with_integer_status, :status => code.to_s
|
886
|
-
assert_equal message, @response.message
|
887
|
-
end
|
888
|
-
end
|
889
|
-
|
890
|
-
def test_head_with_string_status
|
891
|
-
get :head_with_string_status, :status => "404 Eat Dirt"
|
892
|
-
assert_equal 404, @response.response_code
|
893
|
-
assert_equal "Eat Dirt", @response.message
|
894
|
-
assert_response :not_found
|
895
|
-
end
|
896
|
-
|
897
|
-
def test_head_with_status_code_first
|
898
|
-
get :head_with_status_code_first
|
899
|
-
assert_equal 403, @response.response_code
|
900
|
-
assert_equal "Forbidden", @response.message
|
901
|
-
assert_equal "something", @response.headers["X-Custom-Header"]
|
902
|
-
assert_response :forbidden
|
903
|
-
end
|
904
|
-
|
905
|
-
def test_rendering_with_location_should_set_header
|
906
|
-
get :render_with_location
|
907
|
-
assert_equal "http://example.com", @response.headers["Location"]
|
908
|
-
end
|
909
|
-
|
910
|
-
def test_rendering_xml_should_call_to_xml_if_possible
|
911
|
-
get :render_with_to_xml
|
912
|
-
assert_equal "<i-am-xml/>", @response.body
|
913
|
-
end
|
914
|
-
|
915
|
-
def test_rendering_with_object_location_should_set_header_with_url_for
|
916
|
-
ActionController::Routing::Routes.draw do |map|
|
917
|
-
map.resources :customers
|
918
|
-
map.connect ':controller/:action/:id'
|
919
|
-
end
|
920
|
-
|
921
|
-
get :render_with_object_location
|
922
|
-
assert_equal "http://www.nextangle.com/customers/1", @response.headers["Location"]
|
923
|
-
end
|
924
|
-
|
925
|
-
def test_render_call_to_partial_with_layout
|
926
|
-
get :render_call_to_partial_with_layout
|
927
|
-
assert_equal "Before (David)\nInside from partial (David)\nAfter", @response.body
|
928
|
-
end
|
929
|
-
|
930
|
-
def test_render_call_to_partial_with_layout_in_main_layout_and_within_content_for_layout
|
931
|
-
get :render_call_to_partial_with_layout_in_main_layout_and_within_content_for_layout
|
932
|
-
assert_equal "Before (Anthony)\nInside from partial (Anthony)\nAfter\nBefore (David)\nInside from partial (David)\nAfter\nBefore (Ramm)\nInside from partial (Ramm)\nAfter", @response.body
|
933
|
-
end
|
934
|
-
|
935
|
-
def test_using_layout_around_block
|
936
|
-
get :render_using_layout_around_block
|
937
|
-
assert_equal "Before (David)\nInside from block\nAfter", @response.body
|
938
|
-
end
|
939
|
-
|
940
|
-
def test_using_layout_around_block_in_main_layout_and_within_content_for_layout
|
941
|
-
get :render_using_layout_around_block_in_main_layout_and_within_content_for_layout
|
942
|
-
assert_equal "Before (Anthony)\nInside from first block in layout\nAfter\nBefore (David)\nInside from block\nAfter\nBefore (Ramm)\nInside from second block in layout\nAfter\n", @response.body
|
943
|
-
end
|
944
|
-
|
945
|
-
end
|