actionpack 0.9.0

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.

Files changed (100) hide show
  1. data/CHANGELOG +604 -0
  2. data/MIT-LICENSE +21 -0
  3. data/README +418 -0
  4. data/RUNNING_UNIT_TESTS +14 -0
  5. data/examples/.htaccess +24 -0
  6. data/examples/address_book/index.rhtml +33 -0
  7. data/examples/address_book/layout.rhtml +8 -0
  8. data/examples/address_book_controller.cgi +9 -0
  9. data/examples/address_book_controller.fcgi +6 -0
  10. data/examples/address_book_controller.rb +52 -0
  11. data/examples/address_book_controller.rbx +4 -0
  12. data/examples/benchmark.rb +52 -0
  13. data/examples/benchmark_with_ar.fcgi +89 -0
  14. data/examples/blog_controller.cgi +53 -0
  15. data/examples/debate/index.rhtml +14 -0
  16. data/examples/debate/new_topic.rhtml +22 -0
  17. data/examples/debate/topic.rhtml +32 -0
  18. data/examples/debate_controller.cgi +57 -0
  19. data/install.rb +93 -0
  20. data/lib/action_controller.rb +47 -0
  21. data/lib/action_controller/assertions/action_pack_assertions.rb +166 -0
  22. data/lib/action_controller/assertions/active_record_assertions.rb +65 -0
  23. data/lib/action_controller/base.rb +626 -0
  24. data/lib/action_controller/benchmarking.rb +49 -0
  25. data/lib/action_controller/cgi_ext/cgi_ext.rb +43 -0
  26. data/lib/action_controller/cgi_ext/cgi_methods.rb +91 -0
  27. data/lib/action_controller/cgi_process.rb +123 -0
  28. data/lib/action_controller/filters.rb +279 -0
  29. data/lib/action_controller/flash.rb +65 -0
  30. data/lib/action_controller/layout.rb +143 -0
  31. data/lib/action_controller/request.rb +92 -0
  32. data/lib/action_controller/rescue.rb +94 -0
  33. data/lib/action_controller/response.rb +15 -0
  34. data/lib/action_controller/scaffolding.rb +183 -0
  35. data/lib/action_controller/session/active_record_store.rb +72 -0
  36. data/lib/action_controller/session/drb_server.rb +9 -0
  37. data/lib/action_controller/session/drb_store.rb +31 -0
  38. data/lib/action_controller/support/class_attribute_accessors.rb +57 -0
  39. data/lib/action_controller/support/class_inheritable_attributes.rb +37 -0
  40. data/lib/action_controller/support/clean_logger.rb +10 -0
  41. data/lib/action_controller/support/cookie_performance_fix.rb +121 -0
  42. data/lib/action_controller/support/inflector.rb +70 -0
  43. data/lib/action_controller/templates/rescues/_request_and_response.rhtml +28 -0
  44. data/lib/action_controller/templates/rescues/diagnostics.rhtml +22 -0
  45. data/lib/action_controller/templates/rescues/layout.rhtml +29 -0
  46. data/lib/action_controller/templates/rescues/missing_template.rhtml +2 -0
  47. data/lib/action_controller/templates/rescues/template_error.rhtml +26 -0
  48. data/lib/action_controller/templates/rescues/unknown_action.rhtml +2 -0
  49. data/lib/action_controller/templates/scaffolds/edit.rhtml +6 -0
  50. data/lib/action_controller/templates/scaffolds/layout.rhtml +29 -0
  51. data/lib/action_controller/templates/scaffolds/list.rhtml +24 -0
  52. data/lib/action_controller/templates/scaffolds/new.rhtml +5 -0
  53. data/lib/action_controller/templates/scaffolds/show.rhtml +9 -0
  54. data/lib/action_controller/test_process.rb +194 -0
  55. data/lib/action_controller/url_rewriter.rb +153 -0
  56. data/lib/action_view.rb +40 -0
  57. data/lib/action_view/base.rb +253 -0
  58. data/lib/action_view/helpers/active_record_helper.rb +171 -0
  59. data/lib/action_view/helpers/date_helper.rb +223 -0
  60. data/lib/action_view/helpers/debug_helper.rb +17 -0
  61. data/lib/action_view/helpers/form_helper.rb +176 -0
  62. data/lib/action_view/helpers/form_options_helper.rb +169 -0
  63. data/lib/action_view/helpers/tag_helper.rb +59 -0
  64. data/lib/action_view/helpers/text_helper.rb +129 -0
  65. data/lib/action_view/helpers/url_helper.rb +72 -0
  66. data/lib/action_view/partials.rb +61 -0
  67. data/lib/action_view/template_error.rb +84 -0
  68. data/lib/action_view/vendor/builder.rb +13 -0
  69. data/lib/action_view/vendor/builder/blankslate.rb +21 -0
  70. data/lib/action_view/vendor/builder/xmlbase.rb +143 -0
  71. data/lib/action_view/vendor/builder/xmlevents.rb +63 -0
  72. data/lib/action_view/vendor/builder/xmlmarkup.rb +288 -0
  73. data/rakefile +105 -0
  74. data/test/abstract_unit.rb +9 -0
  75. data/test/controller/action_pack_assertions_test.rb +295 -0
  76. data/test/controller/active_record_assertions_test.rb +118 -0
  77. data/test/controller/cgi_test.rb +142 -0
  78. data/test/controller/cookie_test.rb +38 -0
  79. data/test/controller/filters_test.rb +159 -0
  80. data/test/controller/flash_test.rb +69 -0
  81. data/test/controller/layout_test.rb +49 -0
  82. data/test/controller/redirect_test.rb +44 -0
  83. data/test/controller/render_test.rb +169 -0
  84. data/test/controller/url_test.rb +318 -0
  85. data/test/fixtures/layouts/builder.rxml +3 -0
  86. data/test/fixtures/layouts/standard.rhtml +1 -0
  87. data/test/fixtures/test/_customer.rhtml +1 -0
  88. data/test/fixtures/test/greeting.rhtml +1 -0
  89. data/test/fixtures/test/hello.rxml +4 -0
  90. data/test/fixtures/test/hello_world.rhtml +1 -0
  91. data/test/fixtures/test/hello_xml_world.rxml +11 -0
  92. data/test/fixtures/test/list.rhtml +1 -0
  93. data/test/template/active_record_helper_test.rb +76 -0
  94. data/test/template/date_helper_test.rb +103 -0
  95. data/test/template/form_helper_test.rb +115 -0
  96. data/test/template/form_options_helper_test.rb +174 -0
  97. data/test/template/tag_helper_test.rb +18 -0
  98. data/test/template/text_helper_test.rb +62 -0
  99. data/test/template/url_helper_test.rb +35 -0
  100. metadata +154 -0
@@ -0,0 +1,38 @@
1
+ require File.dirname(__FILE__) + '/../abstract_unit'
2
+
3
+ class CookieTest < Test::Unit::TestCase
4
+ class TestController < ActionController::Base
5
+ def authenticate
6
+ cookie "name" => "user_name", "value" => "david"
7
+ render_text "hello world"
8
+ end
9
+
10
+ def access_frozen_cookies
11
+ @cookies["wont"] = "work"
12
+ end
13
+
14
+ def rescue_action(e) raise end
15
+ end
16
+
17
+ def setup
18
+ @request = ActionController::TestRequest.new
19
+ @response = ActionController::TestResponse.new
20
+
21
+ @request.host = "www.nextangle.com"
22
+ end
23
+
24
+ def test_setting_cookie
25
+ @request.action = "authenticate"
26
+ assert_equal [ CGI::Cookie::new("name" => "user_name", "value" => "david") ], process_request.headers["cookie"]
27
+ end
28
+
29
+ def test_setting_cookie
30
+ @request.action = "access_frozen_cookies"
31
+ assert_raises(TypeError) { process_request }
32
+ end
33
+
34
+ private
35
+ def process_request
36
+ TestController.process(@request, @response)
37
+ end
38
+ end
@@ -0,0 +1,159 @@
1
+ require File.dirname(__FILE__) + '/../abstract_unit'
2
+
3
+ class FilterTest < Test::Unit::TestCase
4
+ class TestController < ActionController::Base
5
+ before_filter :ensure_login
6
+
7
+ def show
8
+ render_text "ran action"
9
+ end
10
+
11
+ private
12
+ def ensure_login
13
+ @ran_filter ||= []
14
+ @ran_filter << "ensure_login"
15
+ end
16
+ end
17
+
18
+ class PrependingController < TestController
19
+ prepend_before_filter :wonderful_life
20
+
21
+ private
22
+ def wonderful_life
23
+ @ran_filter ||= []
24
+ @ran_filter << "wonderful_life"
25
+ end
26
+ end
27
+
28
+ class ProcController < PrependingController
29
+ before_filter(proc { |c| c.assigns["ran_proc_filter"] = true })
30
+ end
31
+
32
+ class ImplicitProcController < PrependingController
33
+ before_filter { |c| c.assigns["ran_proc_filter"] = true }
34
+ end
35
+
36
+ class AuditFilter
37
+ def self.filter(controller)
38
+ controller.assigns["was_audited"] = true
39
+ end
40
+ end
41
+
42
+ class AroundFilter
43
+ def before(controller)
44
+ @execution_log = "before"
45
+ controller.class.execution_log << " before aroundfilter " if controller.respond_to? :execution_log
46
+ controller.assigns["before_ran"] = true
47
+ end
48
+
49
+ def after(controller)
50
+ controller.assigns["execution_log"] = @execution_log + " and after"
51
+ controller.assigns["after_ran"] = true
52
+ controller.class.execution_log << " after aroundfilter " if controller.respond_to? :execution_log
53
+ end
54
+ end
55
+
56
+ class AppendedAroundFilter
57
+ def before(controller)
58
+ controller.class.execution_log << " before appended aroundfilter "
59
+ end
60
+
61
+ def after(controller)
62
+ controller.class.execution_log << " after appended aroundfilter "
63
+ end
64
+ end
65
+
66
+ class AuditController < ActionController::Base
67
+ before_filter(AuditFilter)
68
+
69
+ def show
70
+ render_text "hello"
71
+ end
72
+ end
73
+
74
+ class BadFilterController < ActionController::Base
75
+ before_filter 2
76
+
77
+ def show() "show" end
78
+
79
+ protected
80
+ def rescue_action(e) raise(e) end
81
+ end
82
+
83
+ class AroundFilterController < PrependingController
84
+ around_filter AroundFilter.new
85
+ end
86
+
87
+ class MixedFilterController < PrependingController
88
+ cattr_accessor :execution_log
89
+ def initialize
90
+ @@execution_log = ""
91
+ end
92
+
93
+ before_filter { |c| c.class.execution_log << " before procfilter " }
94
+ prepend_around_filter AroundFilter.new
95
+
96
+ after_filter { |c| c.class.execution_log << " after procfilter " }
97
+ append_around_filter AppendedAroundFilter.new
98
+ end
99
+
100
+
101
+ def test_added_filter_to_inheritance_graph
102
+ assert_equal [ :fire_flash, :ensure_login ], TestController.before_filters
103
+ end
104
+
105
+ def test_base_class_in_isolation
106
+ assert_equal [ :fire_flash ], ActionController::Base.before_filters
107
+ end
108
+
109
+ def test_prepending_filter
110
+ assert_equal [ :wonderful_life, :fire_flash, :ensure_login ], PrependingController.before_filters
111
+ end
112
+
113
+ def test_running_filters
114
+ assert_equal %w( wonderful_life ensure_login ), test_process(PrependingController).template.assigns["ran_filter"]
115
+ end
116
+
117
+ def test_running_filters_with_proc
118
+ assert test_process(ProcController).template.assigns["ran_proc_filter"]
119
+ end
120
+
121
+ def test_running_filters_with_implicit_proc
122
+ assert test_process(ImplicitProcController).template.assigns["ran_proc_filter"]
123
+ end
124
+
125
+ def test_running_filters_with_class
126
+ assert test_process(AuditController).template.assigns["was_audited"]
127
+ end
128
+
129
+ def test_bad_filter
130
+ assert_raises(ActionController::ActionControllerError) {
131
+ test_process(BadFilterController)
132
+ }
133
+ end
134
+
135
+ def test_around_filter
136
+ controller = test_process(AroundFilterController)
137
+ assert controller.template.assigns["before_ran"]
138
+ assert controller.template.assigns["after_ran"]
139
+ end
140
+
141
+ def test_having_properties_in_around_filter
142
+ controller = test_process(AroundFilterController)
143
+ assert_equal "before and after", controller.template.assigns["execution_log"]
144
+ end
145
+
146
+ def test_prepending_and_appending_around_filter
147
+ controller = test_process(MixedFilterController)
148
+ assert_equal " before aroundfilter before procfilter before appended aroundfilter " +
149
+ " after appended aroundfilter after aroundfilter after procfilter ",
150
+ MixedFilterController.execution_log
151
+ end
152
+
153
+ private
154
+ def test_process(controller)
155
+ request = ActionController::TestRequest.new
156
+ request.action = "show"
157
+ controller.process(request, ActionController::TestResponse.new)
158
+ end
159
+ end
@@ -0,0 +1,69 @@
1
+ require File.dirname(__FILE__) + '/../abstract_unit'
2
+
3
+ class FlashTest < Test::Unit::TestCase
4
+ class TestController < ActionController::Base
5
+ def set_flash
6
+ flash["that"] = "hello"
7
+ render_text "hello"
8
+ end
9
+
10
+ def use_flash
11
+ @flashy = flash["that"]
12
+ render_text "hello"
13
+ end
14
+
15
+ def use_flash_and_keep_it
16
+ @flashy = flash["that"]
17
+ keep_flash
18
+ render_text "hello"
19
+ end
20
+
21
+ def rescue_action(e)
22
+ raise unless ActionController::MissingTemplate === e
23
+ end
24
+ end
25
+
26
+ def setup
27
+ initialize_request_and_response
28
+ end
29
+
30
+ def test_flash
31
+ @request.action = "set_flash"
32
+ response = process_request
33
+
34
+ @request.action = "use_flash"
35
+ first_response = process_request
36
+ assert_equal "hello", first_response.template.assigns["flash"]["that"]
37
+ assert_equal "hello", first_response.template.assigns["flashy"]
38
+
39
+ second_response = process_request
40
+ assert_nil second_response.template.assigns["flash"]["that"], "On second flash"
41
+ end
42
+
43
+ def test_keep_flash
44
+ @request.action = "set_flash"
45
+ response = process_request
46
+
47
+ @request.action = "use_flash_and_keep_it"
48
+ first_response = process_request
49
+ assert_equal "hello", first_response.template.assigns["flash"]["that"]
50
+ assert_equal "hello", first_response.template.assigns["flashy"]
51
+
52
+ @request.action = "use_flash"
53
+ second_response = process_request
54
+ assert_equal "hello", second_response.template.assigns["flash"]["that"], "On second flash"
55
+
56
+ third_response = process_request
57
+ assert_nil third_response.template.assigns["flash"]["that"], "On third flash"
58
+ end
59
+
60
+ private
61
+ def initialize_request_and_response
62
+ @request = ActionController::TestRequest.new
63
+ @response = ActionController::TestResponse.new
64
+ end
65
+
66
+ def process_request
67
+ TestController.process(@request, @response)
68
+ end
69
+ end
@@ -0,0 +1,49 @@
1
+ require File.dirname(__FILE__) + '/../abstract_unit'
2
+
3
+ class TestLayoutController < ActionController::Base
4
+ layout "layouts/standard"
5
+
6
+ def hello_world
7
+ end
8
+
9
+ def hello_world_outside_layout
10
+ end
11
+
12
+ def rescue_action(e) raise end
13
+ end
14
+
15
+ class ChildWithoutTestLayoutController < TestLayoutController
16
+ layout nil
17
+
18
+ def hello_world
19
+ end
20
+ end
21
+
22
+ class ChildWithOtherTestLayoutController < TestLayoutController
23
+ layout nil
24
+
25
+ def hello_world
26
+ end
27
+ end
28
+
29
+ class RenderTest < Test::Unit::TestCase
30
+ def setup
31
+ @request = ActionController::TestRequest.new
32
+ @response = ActionController::TestResponse.new
33
+
34
+ @request.host = "www.nextangle.com"
35
+ end
36
+
37
+ def test_layout_rendering
38
+ @request.action = "hello_world"
39
+ response = process_request
40
+ assert_equal "200 OK", response.headers["Status"]
41
+ assert_equal "layouts/standard", response.template.template_name
42
+ end
43
+
44
+
45
+ private
46
+ def process_request
47
+ TestLayoutController.process(@request, @response)
48
+ end
49
+ end
@@ -0,0 +1,44 @@
1
+ require File.dirname(__FILE__) + '/../abstract_unit'
2
+
3
+ class RedirectTest < Test::Unit::TestCase
4
+ class RedirectController < ActionController::Base
5
+ def simple_redirect
6
+ redirect_to :action => "hello_world"
7
+ end
8
+
9
+ def method_redirect
10
+ redirect_to :dashbord_url, 1, "hello"
11
+ end
12
+
13
+ def rescue_errors(e) raise e end
14
+
15
+ protected
16
+ def dashbord_url(id, message)
17
+ url_for :action => "dashboard", :params => { "id" => id, "message" => message }
18
+ end
19
+ end
20
+
21
+ def setup
22
+ @request = ActionController::TestRequest.new
23
+ @response = ActionController::TestResponse.new
24
+ end
25
+
26
+ def test_simple_redirect
27
+ @request.path = "/redirect/simple_redirect"
28
+ @request.action = "simple_redirect"
29
+ response = process_request
30
+ assert_equal "http://test.host/redirect/hello_world", response.headers["location"]
31
+ end
32
+
33
+ def test_redirect_with_method_reference_and_parameters
34
+ @request.path = "/redirect/method_redirect"
35
+ @request.action = "method_redirect"
36
+ response = process_request
37
+ assert_equal "http://test.host/redirect/dashboard?message=hello&id=1", response.headers["location"]
38
+ end
39
+
40
+ private
41
+ def process_request
42
+ RedirectController.process(@request, @response)
43
+ end
44
+ end
@@ -0,0 +1,169 @@
1
+ require File.dirname(__FILE__) + '/../abstract_unit'
2
+
3
+ Customer = Struct.new("Customer", :name)
4
+
5
+ class RenderTest < Test::Unit::TestCase
6
+ class TestController < ActionController::Base
7
+ layout :determine_layout
8
+
9
+ def hello_world
10
+ end
11
+
12
+ def render_hello_world
13
+ render "test/hello_world"
14
+ end
15
+
16
+ def render_hello_world_from_variable
17
+ @person = "david"
18
+ render_text "hello #{@person}"
19
+ end
20
+
21
+ def render_action_hello_world
22
+ render_action "hello_world"
23
+ end
24
+
25
+ def render_text_hello_world
26
+ render_text "hello world"
27
+ end
28
+
29
+ def render_custom_code
30
+ render_text "hello world", "404 Moved"
31
+ end
32
+
33
+ def render_xml_hello
34
+ @name = "David"
35
+ render "test/hello"
36
+ end
37
+
38
+ def greeting
39
+ # let's just rely on the template
40
+ end
41
+
42
+ def layout_test
43
+ render_action "hello_world"
44
+ end
45
+
46
+ def builder_layout_test
47
+ render_action "hello"
48
+ end
49
+
50
+ def partials_list
51
+ @customers = [ Customer.new("david"), Customer.new("mary") ]
52
+ render_action "list"
53
+ end
54
+
55
+ def rescue_action(e) raise end
56
+
57
+ private
58
+ def determine_layout
59
+ case action_name
60
+ when "layout_test": "layouts/standard"
61
+ when "builder_layout_test": "layouts/builder"
62
+ end
63
+ end
64
+ end
65
+
66
+ TestController.template_root = File.dirname(__FILE__) + "/../fixtures/"
67
+
68
+ class TestLayoutController < ActionController::Base
69
+ layout "layouts/standard"
70
+
71
+ def hello_world
72
+ end
73
+
74
+ def hello_world_outside_layout
75
+ end
76
+
77
+ def rescue_action(e)
78
+ raise unless ActionController::MissingTemplate === e
79
+ end
80
+ end
81
+
82
+ def setup
83
+ @request = ActionController::TestRequest.new
84
+ @response = ActionController::TestResponse.new
85
+
86
+ @request.host = "www.nextangle.com"
87
+ end
88
+
89
+ def test_simple_show
90
+ @request.action = "hello_world"
91
+ response = process_request
92
+ assert_equal "200 OK", response.headers["Status"]
93
+ assert_equal "test/hello_world", response.template.first_render
94
+ end
95
+
96
+ def test_do_with_render
97
+ @request.action = "render_hello_world"
98
+ assert_equal "test/hello_world", process_request.template.first_render
99
+ end
100
+
101
+ def test_do_with_render_from_variable
102
+ @request.action = "render_hello_world_from_variable"
103
+ assert_equal "hello david", process_request.body
104
+ end
105
+
106
+ def test_do_with_render_action
107
+ @request.action = "render_action_hello_world"
108
+ assert_equal "test/hello_world", process_request.template.first_render
109
+ end
110
+
111
+ def test_do_with_render_text
112
+ @request.action = "render_text_hello_world"
113
+ assert_equal "hello world", process_request.body
114
+ end
115
+
116
+ def test_do_with_render_custom_code
117
+ @request.action = "render_custom_code"
118
+ assert_equal "404 Moved", process_request.headers["Status"]
119
+ end
120
+
121
+ def test_attempt_to_access_object_method
122
+ @request.action = "clone"
123
+ assert_raises(ActionController::UnknownAction, "No action responded to [clone]") { process_request }
124
+ end
125
+
126
+ def test_access_to_request_in_view
127
+ ActionController::Base.view_controller_internals = false
128
+
129
+ @request.action = "hello_world"
130
+ response = process_request
131
+ assert_nil response.template.assigns["request"]
132
+
133
+ ActionController::Base.view_controller_internals = true
134
+
135
+ @request.action = "hello_world"
136
+ response = process_request
137
+ assert_kind_of ActionController::AbstractRequest, response.template.assigns["request"]
138
+ end
139
+
140
+ def test_render_xml
141
+ @request.action = "render_xml_hello"
142
+ assert_equal "<html>\n <p>Hello David</p>\n<p>This is grand!</p>\n</html>\n", process_request.body
143
+ end
144
+
145
+ def test_render_xml_with_default
146
+ @request.action = "greeting"
147
+ assert_equal "<p>This is grand!</p>\n", process_request.body
148
+ end
149
+
150
+ def test_layout_rendering
151
+ @request.action = "layout_test"
152
+ assert_equal "<html>Hello world!</html>", process_request.body
153
+ end
154
+
155
+ def test_render_xml_with_layouts
156
+ @request.action = "builder_layout_test"
157
+ assert_equal "<wrapper>\n<html>\n <p>Hello </p>\n<p>This is grand!</p>\n</html>\n</wrapper>\n", process_request.body
158
+ end
159
+
160
+ def test_partials_list
161
+ @request.action = "partials_list"
162
+ assert_equal "Hello: davidHello: mary", process_request.body
163
+ end
164
+
165
+ private
166
+ def process_request
167
+ TestController.process(@request, @response)
168
+ end
169
+ end