halorgium-actionpack 3.0.pre

Sign up to get free protection for your applications and to get access to all the features.
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