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.
Files changed (154) hide show
  1. data/CHANGELOG +5179 -0
  2. data/MIT-LICENSE +21 -0
  3. data/README +409 -0
  4. data/lib/abstract_controller.rb +16 -0
  5. data/lib/abstract_controller/base.rb +158 -0
  6. data/lib/abstract_controller/callbacks.rb +113 -0
  7. data/lib/abstract_controller/exceptions.rb +12 -0
  8. data/lib/abstract_controller/helpers.rb +151 -0
  9. data/lib/abstract_controller/layouts.rb +250 -0
  10. data/lib/abstract_controller/localized_cache.rb +49 -0
  11. data/lib/abstract_controller/logger.rb +61 -0
  12. data/lib/abstract_controller/rendering_controller.rb +188 -0
  13. data/lib/action_controller.rb +72 -0
  14. data/lib/action_controller/base.rb +168 -0
  15. data/lib/action_controller/caching.rb +80 -0
  16. data/lib/action_controller/caching/actions.rb +163 -0
  17. data/lib/action_controller/caching/fragments.rb +116 -0
  18. data/lib/action_controller/caching/pages.rb +154 -0
  19. data/lib/action_controller/caching/sweeping.rb +97 -0
  20. data/lib/action_controller/deprecated.rb +4 -0
  21. data/lib/action_controller/deprecated/integration_test.rb +2 -0
  22. data/lib/action_controller/deprecated/performance_test.rb +1 -0
  23. data/lib/action_controller/dispatch/dispatcher.rb +57 -0
  24. data/lib/action_controller/metal.rb +129 -0
  25. data/lib/action_controller/metal/benchmarking.rb +73 -0
  26. data/lib/action_controller/metal/compatibility.rb +145 -0
  27. data/lib/action_controller/metal/conditional_get.rb +86 -0
  28. data/lib/action_controller/metal/configuration.rb +28 -0
  29. data/lib/action_controller/metal/cookies.rb +105 -0
  30. data/lib/action_controller/metal/exceptions.rb +55 -0
  31. data/lib/action_controller/metal/filter_parameter_logging.rb +77 -0
  32. data/lib/action_controller/metal/flash.rb +162 -0
  33. data/lib/action_controller/metal/head.rb +27 -0
  34. data/lib/action_controller/metal/helpers.rb +115 -0
  35. data/lib/action_controller/metal/hide_actions.rb +47 -0
  36. data/lib/action_controller/metal/http_authentication.rb +312 -0
  37. data/lib/action_controller/metal/layouts.rb +171 -0
  38. data/lib/action_controller/metal/mime_responds.rb +317 -0
  39. data/lib/action_controller/metal/rack_convenience.rb +27 -0
  40. data/lib/action_controller/metal/redirector.rb +22 -0
  41. data/lib/action_controller/metal/render_options.rb +103 -0
  42. data/lib/action_controller/metal/rendering_controller.rb +57 -0
  43. data/lib/action_controller/metal/request_forgery_protection.rb +108 -0
  44. data/lib/action_controller/metal/rescuable.rb +13 -0
  45. data/lib/action_controller/metal/responder.rb +200 -0
  46. data/lib/action_controller/metal/session.rb +15 -0
  47. data/lib/action_controller/metal/session_management.rb +45 -0
  48. data/lib/action_controller/metal/streaming.rb +188 -0
  49. data/lib/action_controller/metal/testing.rb +39 -0
  50. data/lib/action_controller/metal/url_for.rb +41 -0
  51. data/lib/action_controller/metal/verification.rb +130 -0
  52. data/lib/action_controller/middleware.rb +38 -0
  53. data/lib/action_controller/notifications.rb +10 -0
  54. data/lib/action_controller/polymorphic_routes.rb +183 -0
  55. data/lib/action_controller/record_identifier.rb +91 -0
  56. data/lib/action_controller/testing/process.rb +111 -0
  57. data/lib/action_controller/testing/test_case.rb +345 -0
  58. data/lib/action_controller/translation.rb +13 -0
  59. data/lib/action_controller/url_rewriter.rb +204 -0
  60. data/lib/action_controller/vendor/html-scanner.rb +16 -0
  61. data/lib/action_controller/vendor/html-scanner/html/document.rb +68 -0
  62. data/lib/action_controller/vendor/html-scanner/html/node.rb +537 -0
  63. data/lib/action_controller/vendor/html-scanner/html/sanitizer.rb +176 -0
  64. data/lib/action_controller/vendor/html-scanner/html/selector.rb +828 -0
  65. data/lib/action_controller/vendor/html-scanner/html/tokenizer.rb +105 -0
  66. data/lib/action_controller/vendor/html-scanner/html/version.rb +11 -0
  67. data/lib/action_dispatch.rb +70 -0
  68. data/lib/action_dispatch/http/headers.rb +33 -0
  69. data/lib/action_dispatch/http/mime_type.rb +231 -0
  70. data/lib/action_dispatch/http/mime_types.rb +23 -0
  71. data/lib/action_dispatch/http/request.rb +539 -0
  72. data/lib/action_dispatch/http/response.rb +290 -0
  73. data/lib/action_dispatch/http/status_codes.rb +42 -0
  74. data/lib/action_dispatch/http/utils.rb +20 -0
  75. data/lib/action_dispatch/middleware/callbacks.rb +50 -0
  76. data/lib/action_dispatch/middleware/params_parser.rb +79 -0
  77. data/lib/action_dispatch/middleware/rescue.rb +26 -0
  78. data/lib/action_dispatch/middleware/session/abstract_store.rb +208 -0
  79. data/lib/action_dispatch/middleware/session/cookie_store.rb +235 -0
  80. data/lib/action_dispatch/middleware/session/mem_cache_store.rb +47 -0
  81. data/lib/action_dispatch/middleware/show_exceptions.rb +143 -0
  82. data/lib/action_dispatch/middleware/stack.rb +116 -0
  83. data/lib/action_dispatch/middleware/static.rb +44 -0
  84. data/lib/action_dispatch/middleware/string_coercion.rb +29 -0
  85. data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.erb +24 -0
  86. data/lib/action_dispatch/middleware/templates/rescues/_trace.erb +26 -0
  87. data/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb +10 -0
  88. data/lib/action_dispatch/middleware/templates/rescues/layout.erb +29 -0
  89. data/lib/action_dispatch/middleware/templates/rescues/missing_template.erb +2 -0
  90. data/lib/action_dispatch/middleware/templates/rescues/routing_error.erb +10 -0
  91. data/lib/action_dispatch/middleware/templates/rescues/template_error.erb +21 -0
  92. data/lib/action_dispatch/middleware/templates/rescues/unknown_action.erb +2 -0
  93. data/lib/action_dispatch/routing.rb +381 -0
  94. data/lib/action_dispatch/routing/deprecated_mapper.rb +878 -0
  95. data/lib/action_dispatch/routing/mapper.rb +327 -0
  96. data/lib/action_dispatch/routing/route.rb +49 -0
  97. data/lib/action_dispatch/routing/route_set.rb +497 -0
  98. data/lib/action_dispatch/testing/assertions.rb +8 -0
  99. data/lib/action_dispatch/testing/assertions/dom.rb +35 -0
  100. data/lib/action_dispatch/testing/assertions/model.rb +19 -0
  101. data/lib/action_dispatch/testing/assertions/response.rb +145 -0
  102. data/lib/action_dispatch/testing/assertions/routing.rb +144 -0
  103. data/lib/action_dispatch/testing/assertions/selector.rb +639 -0
  104. data/lib/action_dispatch/testing/assertions/tag.rb +123 -0
  105. data/lib/action_dispatch/testing/integration.rb +504 -0
  106. data/lib/action_dispatch/testing/performance_test.rb +15 -0
  107. data/lib/action_dispatch/testing/test_request.rb +83 -0
  108. data/lib/action_dispatch/testing/test_response.rb +131 -0
  109. data/lib/action_pack.rb +24 -0
  110. data/lib/action_pack/version.rb +9 -0
  111. data/lib/action_view.rb +58 -0
  112. data/lib/action_view/base.rb +308 -0
  113. data/lib/action_view/context.rb +44 -0
  114. data/lib/action_view/erb/util.rb +48 -0
  115. data/lib/action_view/helpers.rb +62 -0
  116. data/lib/action_view/helpers/active_model_helper.rb +306 -0
  117. data/lib/action_view/helpers/ajax_helper.rb +68 -0
  118. data/lib/action_view/helpers/asset_tag_helper.rb +830 -0
  119. data/lib/action_view/helpers/atom_feed_helper.rb +198 -0
  120. data/lib/action_view/helpers/cache_helper.rb +39 -0
  121. data/lib/action_view/helpers/capture_helper.rb +168 -0
  122. data/lib/action_view/helpers/date_helper.rb +988 -0
  123. data/lib/action_view/helpers/debug_helper.rb +38 -0
  124. data/lib/action_view/helpers/form_helper.rb +1102 -0
  125. data/lib/action_view/helpers/form_options_helper.rb +600 -0
  126. data/lib/action_view/helpers/form_tag_helper.rb +495 -0
  127. data/lib/action_view/helpers/javascript_helper.rb +208 -0
  128. data/lib/action_view/helpers/number_helper.rb +311 -0
  129. data/lib/action_view/helpers/prototype_helper.rb +1309 -0
  130. data/lib/action_view/helpers/raw_output_helper.rb +9 -0
  131. data/lib/action_view/helpers/record_identification_helper.rb +20 -0
  132. data/lib/action_view/helpers/record_tag_helper.rb +58 -0
  133. data/lib/action_view/helpers/sanitize_helper.rb +259 -0
  134. data/lib/action_view/helpers/scriptaculous_helper.rb +226 -0
  135. data/lib/action_view/helpers/tag_helper.rb +151 -0
  136. data/lib/action_view/helpers/text_helper.rb +594 -0
  137. data/lib/action_view/helpers/translation_helper.rb +39 -0
  138. data/lib/action_view/helpers/url_helper.rb +639 -0
  139. data/lib/action_view/locale/en.yml +117 -0
  140. data/lib/action_view/paths.rb +80 -0
  141. data/lib/action_view/render/partials.rb +342 -0
  142. data/lib/action_view/render/rendering.rb +134 -0
  143. data/lib/action_view/safe_buffer.rb +28 -0
  144. data/lib/action_view/template/error.rb +101 -0
  145. data/lib/action_view/template/handler.rb +36 -0
  146. data/lib/action_view/template/handlers.rb +52 -0
  147. data/lib/action_view/template/handlers/builder.rb +17 -0
  148. data/lib/action_view/template/handlers/erb.rb +53 -0
  149. data/lib/action_view/template/handlers/rjs.rb +18 -0
  150. data/lib/action_view/template/resolver.rb +165 -0
  151. data/lib/action_view/template/template.rb +131 -0
  152. data/lib/action_view/template/text.rb +38 -0
  153. data/lib/action_view/test_case.rb +163 -0
  154. 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