pager-resource_controller 1.0.20080513

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 (201) hide show
  1. data/LICENSE +22 -0
  2. data/README +276 -0
  3. data/Rakefile +55 -0
  4. data/TODO +1 -0
  5. data/generators/scaffold_resource/USAGE +29 -0
  6. data/generators/scaffold_resource/scaffold_resource_generator.rb +101 -0
  7. data/generators/scaffold_resource/templates/controller.rb +2 -0
  8. data/generators/scaffold_resource/templates/fixtures.yml +10 -0
  9. data/generators/scaffold_resource/templates/functional_test.rb +57 -0
  10. data/generators/scaffold_resource/templates/helper.rb +2 -0
  11. data/generators/scaffold_resource/templates/migration.rb +15 -0
  12. data/generators/scaffold_resource/templates/model.rb +2 -0
  13. data/generators/scaffold_resource/templates/old_migration.rb +13 -0
  14. data/generators/scaffold_resource/templates/shoulda_functional_test.rb +19 -0
  15. data/generators/scaffold_resource/templates/unit_test.rb +7 -0
  16. data/generators/scaffold_resource/templates/view__form.erb +6 -0
  17. data/generators/scaffold_resource/templates/view__form.haml +5 -0
  18. data/generators/scaffold_resource/templates/view_edit.erb +16 -0
  19. data/generators/scaffold_resource/templates/view_edit.haml +11 -0
  20. data/generators/scaffold_resource/templates/view_index.erb +22 -0
  21. data/generators/scaffold_resource/templates/view_index.haml +19 -0
  22. data/generators/scaffold_resource/templates/view_new.erb +12 -0
  23. data/generators/scaffold_resource/templates/view_new.haml +9 -0
  24. data/generators/scaffold_resource/templates/view_show.erb +9 -0
  25. data/generators/scaffold_resource/templates/view_show.haml +9 -0
  26. data/init.rb +6 -0
  27. data/install.rb +1 -0
  28. data/lib/resource_controller.rb +11 -0
  29. data/lib/resource_controller/accessors.rb +76 -0
  30. data/lib/resource_controller/action_options.rb +28 -0
  31. data/lib/resource_controller/actions.rb +75 -0
  32. data/lib/resource_controller/base.rb +15 -0
  33. data/lib/resource_controller/class_methods.rb +22 -0
  34. data/lib/resource_controller/controller.rb +63 -0
  35. data/lib/resource_controller/failable_action_options.rb +17 -0
  36. data/lib/resource_controller/helpers.rb +28 -0
  37. data/lib/resource_controller/helpers/current_objects.rb +69 -0
  38. data/lib/resource_controller/helpers/internal.rb +59 -0
  39. data/lib/resource_controller/helpers/nested.rb +45 -0
  40. data/lib/resource_controller/helpers/urls.rb +124 -0
  41. data/lib/resource_controller/response_collector.rb +21 -0
  42. data/lib/urligence.rb +50 -0
  43. data/rails/init.rb +1 -0
  44. data/test/Rakefile +10 -0
  45. data/test/app/controllers/application.rb +7 -0
  46. data/test/app/controllers/cms/options_controller.rb +3 -0
  47. data/test/app/controllers/cms/products_controller.rb +2 -0
  48. data/test/app/controllers/comments_controller.rb +3 -0
  49. data/test/app/controllers/people_controller.rb +9 -0
  50. data/test/app/controllers/photos_controller.rb +10 -0
  51. data/test/app/controllers/posts_controller.rb +10 -0
  52. data/test/app/controllers/projects_controller.rb +3 -0
  53. data/test/app/controllers/somethings_controller.rb +3 -0
  54. data/test/app/controllers/tags_controller.rb +13 -0
  55. data/test/app/controllers/users_controller.rb +12 -0
  56. data/test/app/helpers/application_helper.rb +3 -0
  57. data/test/app/helpers/cms/products_helper.rb +2 -0
  58. data/test/app/helpers/comments_helper.rb +2 -0
  59. data/test/app/helpers/options_helper.rb +2 -0
  60. data/test/app/helpers/people_helper.rb +2 -0
  61. data/test/app/helpers/photos_helper.rb +2 -0
  62. data/test/app/helpers/posts_helper.rb +2 -0
  63. data/test/app/helpers/projects_helper.rb +2 -0
  64. data/test/app/helpers/somethings_helper.rb +2 -0
  65. data/test/app/helpers/tags_helper.rb +2 -0
  66. data/test/app/helpers/users_helper.rb +2 -0
  67. data/test/app/models/account.rb +3 -0
  68. data/test/app/models/comment.rb +3 -0
  69. data/test/app/models/option.rb +3 -0
  70. data/test/app/models/photo.rb +4 -0
  71. data/test/app/models/post.rb +3 -0
  72. data/test/app/models/product.rb +3 -0
  73. data/test/app/models/project.rb +2 -0
  74. data/test/app/models/something.rb +2 -0
  75. data/test/app/models/tag.rb +3 -0
  76. data/test/app/views/cms/options/edit.rhtml +17 -0
  77. data/test/app/views/cms/options/index.rhtml +20 -0
  78. data/test/app/views/cms/options/new.rhtml +16 -0
  79. data/test/app/views/cms/options/show.rhtml +8 -0
  80. data/test/app/views/cms/products/edit.rhtml +17 -0
  81. data/test/app/views/cms/products/index.rhtml +20 -0
  82. data/test/app/views/cms/products/new.rhtml +16 -0
  83. data/test/app/views/cms/products/show.rhtml +8 -0
  84. data/test/app/views/comments/edit.rhtml +27 -0
  85. data/test/app/views/comments/index.rhtml +24 -0
  86. data/test/app/views/comments/new.rhtml +26 -0
  87. data/test/app/views/comments/show.rhtml +18 -0
  88. data/test/app/views/layouts/application.rhtml +17 -0
  89. data/test/app/views/layouts/comments.rhtml +17 -0
  90. data/test/app/views/layouts/options.rhtml +17 -0
  91. data/test/app/views/layouts/people.rhtml +17 -0
  92. data/test/app/views/layouts/photos.rhtml +17 -0
  93. data/test/app/views/layouts/projects.rhtml +17 -0
  94. data/test/app/views/layouts/somethings.rhtml +17 -0
  95. data/test/app/views/layouts/tags.rhtml +17 -0
  96. data/test/app/views/people/edit.rhtml +17 -0
  97. data/test/app/views/people/index.rhtml +20 -0
  98. data/test/app/views/people/new.rhtml +16 -0
  99. data/test/app/views/people/show.rhtml +8 -0
  100. data/test/app/views/photos/edit.rhtml +17 -0
  101. data/test/app/views/photos/index.rhtml +20 -0
  102. data/test/app/views/photos/new.rhtml +16 -0
  103. data/test/app/views/photos/show.rhtml +8 -0
  104. data/test/app/views/posts/edit.rhtml +22 -0
  105. data/test/app/views/posts/index.rhtml +22 -0
  106. data/test/app/views/posts/new.rhtml +21 -0
  107. data/test/app/views/posts/show.rhtml +13 -0
  108. data/test/app/views/projects/edit.rhtml +17 -0
  109. data/test/app/views/projects/index.rhtml +20 -0
  110. data/test/app/views/projects/new.rhtml +16 -0
  111. data/test/app/views/projects/show.rhtml +8 -0
  112. data/test/app/views/somethings/edit.rhtml +17 -0
  113. data/test/app/views/somethings/index.rhtml +20 -0
  114. data/test/app/views/somethings/new.rhtml +16 -0
  115. data/test/app/views/somethings/show.rhtml +8 -0
  116. data/test/app/views/tags/edit.rhtml +17 -0
  117. data/test/app/views/tags/index.rhtml +20 -0
  118. data/test/app/views/tags/index.rjs +0 -0
  119. data/test/app/views/tags/new.rhtml +16 -0
  120. data/test/app/views/tags/show.rhtml +8 -0
  121. data/test/app/views/users/edit.rhtml +17 -0
  122. data/test/app/views/users/index.rhtml +20 -0
  123. data/test/app/views/users/new.rhtml +16 -0
  124. data/test/app/views/users/show.rhtml +8 -0
  125. data/test/config/boot.rb +45 -0
  126. data/test/config/database.yml +16 -0
  127. data/test/config/environment.rb +64 -0
  128. data/test/config/environments/development.rb +21 -0
  129. data/test/config/environments/test.rb +19 -0
  130. data/test/config/routes.rb +51 -0
  131. data/test/db/migrate/001_create_posts.rb +12 -0
  132. data/test/db/migrate/002_create_products.rb +11 -0
  133. data/test/db/migrate/003_create_comments.rb +13 -0
  134. data/test/db/migrate/004_create_options.rb +12 -0
  135. data/test/db/migrate/005_create_photos.rb +11 -0
  136. data/test/db/migrate/006_create_tags.rb +17 -0
  137. data/test/db/migrate/007_create_somethings.rb +11 -0
  138. data/test/db/migrate/008_create_accounts.rb +11 -0
  139. data/test/db/migrate/009_add_account_id_to_photos.rb +9 -0
  140. data/test/db/migrate/010_create_projects.rb +11 -0
  141. data/test/db/schema.rb +65 -0
  142. data/test/script/console +3 -0
  143. data/test/script/destroy +3 -0
  144. data/test/script/generate +3 -0
  145. data/test/script/server +3 -0
  146. data/test/test/fixtures/accounts.yml +7 -0
  147. data/test/test/fixtures/comments.yml +11 -0
  148. data/test/test/fixtures/options.yml +9 -0
  149. data/test/test/fixtures/photos.yml +9 -0
  150. data/test/test/fixtures/photos_tags.yml +3 -0
  151. data/test/test/fixtures/posts.yml +9 -0
  152. data/test/test/fixtures/products.yml +7 -0
  153. data/test/test/fixtures/projects.yml +7 -0
  154. data/test/test/fixtures/somethings.yml +7 -0
  155. data/test/test/fixtures/tags.yml +7 -0
  156. data/test/test/functional/cms/options_controller_test.rb +20 -0
  157. data/test/test/functional/cms/products_controller_test.rb +18 -0
  158. data/test/test/functional/comments_controller_test.rb +26 -0
  159. data/test/test/functional/people_controller_test.rb +34 -0
  160. data/test/test/functional/photos_controller_test.rb +128 -0
  161. data/test/test/functional/posts_controller_test.rb +34 -0
  162. data/test/test/functional/projects_controller_test.rb +18 -0
  163. data/test/test/functional/somethings_controller_test.rb +28 -0
  164. data/test/test/functional/tags_controller_test.rb +64 -0
  165. data/test/test/functional/users_controller_test.rb +24 -0
  166. data/test/test/test_helper.rb +12 -0
  167. data/test/test/unit/accessors_test.rb +91 -0
  168. data/test/test/unit/account_test.rb +7 -0
  169. data/test/test/unit/action_options_test.rb +66 -0
  170. data/test/test/unit/base_test.rb +11 -0
  171. data/test/test/unit/comment_test.rb +10 -0
  172. data/test/test/unit/failable_action_options_test.rb +50 -0
  173. data/test/test/unit/helpers/current_objects_test.rb +127 -0
  174. data/test/test/unit/helpers/internal_test.rb +88 -0
  175. data/test/test/unit/helpers/nested_test.rb +82 -0
  176. data/test/test/unit/helpers/urls_test.rb +71 -0
  177. data/test/test/unit/helpers_test.rb +25 -0
  178. data/test/test/unit/option_test.rb +10 -0
  179. data/test/test/unit/photo_test.rb +10 -0
  180. data/test/test/unit/post_test.rb +10 -0
  181. data/test/test/unit/project_test.rb +10 -0
  182. data/test/test/unit/response_collector_test.rb +31 -0
  183. data/test/test/unit/something_test.rb +10 -0
  184. data/test/test/unit/tag_test.rb +10 -0
  185. data/test/test/unit/urligence_test.rb +203 -0
  186. data/test/vendor/plugins/shoulda/README +123 -0
  187. data/test/vendor/plugins/shoulda/Rakefile +29 -0
  188. data/test/vendor/plugins/shoulda/bin/convert_to_should_syntax +40 -0
  189. data/test/vendor/plugins/shoulda/init.rb +3 -0
  190. data/test/vendor/plugins/shoulda/lib/shoulda.rb +47 -0
  191. data/test/vendor/plugins/shoulda/lib/shoulda/active_record_helpers.rb +338 -0
  192. data/test/vendor/plugins/shoulda/lib/shoulda/color.rb +77 -0
  193. data/test/vendor/plugins/shoulda/lib/shoulda/context.rb +143 -0
  194. data/test/vendor/plugins/shoulda/lib/shoulda/controller_tests/controller_tests.rb +470 -0
  195. data/test/vendor/plugins/shoulda/lib/shoulda/controller_tests/formats/html.rb +192 -0
  196. data/test/vendor/plugins/shoulda/lib/shoulda/controller_tests/formats/xml.rb +162 -0
  197. data/test/vendor/plugins/shoulda/lib/shoulda/general.rb +119 -0
  198. data/test/vendor/plugins/shoulda/lib/shoulda/private_helpers.rb +17 -0
  199. data/test/vendor/plugins/shoulda/tasks/list_tests.rake +40 -0
  200. data/uninstall.rb +1 -0
  201. metadata +410 -0
@@ -0,0 +1,192 @@
1
+ module ThoughtBot # :nodoc:
2
+ module Shoulda # :nodoc:
3
+ module Controller # :nodoc:
4
+ module HTML # :nodoc: all
5
+ def self.included(other)
6
+ other.class_eval do
7
+ extend ThoughtBot::Shoulda::Controller::HTML::ClassMethods
8
+ end
9
+ end
10
+
11
+ module ClassMethods
12
+ def make_show_html_tests(res)
13
+ context "on GET to :show" do
14
+ setup do
15
+ record = get_existing_record(res)
16
+ parent_params = make_parent_params(res, record)
17
+ get :show, parent_params.merge({ res.identifier => record.to_param })
18
+ end
19
+
20
+ if res.denied.actions.include?(:show)
21
+ should_not_assign_to res.object
22
+ should_redirect_to res.denied.redirect
23
+ should_set_the_flash_to res.denied.flash
24
+ else
25
+ should_assign_to res.object
26
+ should_respond_with :success
27
+ should_render_template :show
28
+ should_not_set_the_flash
29
+ end
30
+ end
31
+ end
32
+
33
+ def make_edit_html_tests(res)
34
+ context "on GET to :edit" do
35
+ setup do
36
+ @record = get_existing_record(res)
37
+ parent_params = make_parent_params(res, @record)
38
+ get :edit, parent_params.merge({ res.identifier => @record.to_param })
39
+ end
40
+
41
+ if res.denied.actions.include?(:edit)
42
+ should_not_assign_to res.object
43
+ should_redirect_to res.denied.redirect
44
+ should_set_the_flash_to res.denied.flash
45
+ else
46
+ should_assign_to res.object
47
+ should_respond_with :success
48
+ should_render_template :edit
49
+ should_not_set_the_flash
50
+ should_render_a_form
51
+ should "set @#{res.object} to requested instance" do
52
+ assert_equal @record, assigns(res.object)
53
+ end
54
+ end
55
+ end
56
+ end
57
+
58
+ def make_index_html_tests(res)
59
+ context "on GET to :index" do
60
+ setup do
61
+ parent_params = make_parent_params(res)
62
+ get(:index, parent_params)
63
+ end
64
+
65
+ if res.denied.actions.include?(:index)
66
+ should_not_assign_to res.object.to_s.pluralize
67
+ should_redirect_to res.denied.redirect
68
+ should_set_the_flash_to res.denied.flash
69
+ else
70
+ should_respond_with :success
71
+ should_assign_to res.object.to_s.pluralize
72
+ should_render_template :index
73
+ should_not_set_the_flash
74
+ end
75
+ end
76
+ end
77
+
78
+ def make_new_html_tests(res)
79
+ context "on GET to :new" do
80
+ setup do
81
+ parent_params = make_parent_params(res)
82
+ get(:new, parent_params)
83
+ end
84
+
85
+ if res.denied.actions.include?(:new)
86
+ should_not_assign_to res.object
87
+ should_redirect_to res.denied.redirect
88
+ should_set_the_flash_to res.denied.flash
89
+ else
90
+ should_respond_with :success
91
+ should_assign_to res.object
92
+ should_not_set_the_flash
93
+ should_render_template :new
94
+ should_render_a_form
95
+ end
96
+ end
97
+ end
98
+
99
+ def make_destroy_html_tests(res)
100
+ context "on DELETE to :destroy" do
101
+ setup do
102
+ @record = get_existing_record(res)
103
+ parent_params = make_parent_params(res, @record)
104
+ delete :destroy, parent_params.merge({ res.identifier => @record.to_param })
105
+ end
106
+
107
+ if res.denied.actions.include?(:destroy)
108
+ should_redirect_to res.denied.redirect
109
+ should_set_the_flash_to res.denied.flash
110
+
111
+ should "not destroy record" do
112
+ assert_nothing_raised { assert @record.reload }
113
+ end
114
+ else
115
+ should_set_the_flash_to res.destroy.flash
116
+ if res.destroy.redirect.is_a? Symbol
117
+ should_respond_with res.destroy.redirect
118
+ else
119
+ should_redirect_to res.destroy.redirect
120
+ end
121
+
122
+ should "destroy record" do
123
+ assert_raises(::ActiveRecord::RecordNotFound) { @record.reload }
124
+ end
125
+ end
126
+ end
127
+ end
128
+
129
+ def make_create_html_tests(res)
130
+ context "on POST to :create with #{res.create.params.inspect}" do
131
+ setup do
132
+ parent_params = make_parent_params(res)
133
+ @count = res.klass.count
134
+ post :create, parent_params.merge(res.object => res.create.params)
135
+ end
136
+
137
+ if res.denied.actions.include?(:create)
138
+ should_redirect_to res.denied.redirect
139
+ should_set_the_flash_to res.denied.flash
140
+ should_not_assign_to res.object
141
+
142
+ should "not create new record" do
143
+ assert_equal @count, res.klass.count
144
+ end
145
+ else
146
+ should_assign_to res.object
147
+ should_set_the_flash_to res.create.flash
148
+ if res.create.redirect.is_a? Symbol
149
+ should_respond_with res.create.redirect
150
+ else
151
+ should_redirect_to res.create.redirect
152
+ end
153
+
154
+ should "not have errors on @#{res.object}" do
155
+ assert_equal [], assigns(res.object).errors.full_messages, "@#{res.object} has errors:"
156
+ end
157
+ end
158
+ end
159
+ end
160
+
161
+ def make_update_html_tests(res)
162
+ context "on PUT to :update with #{res.create.params.inspect}" do
163
+ setup do
164
+ @record = get_existing_record(res)
165
+ parent_params = make_parent_params(res, @record)
166
+ put :update, parent_params.merge(res.identifier => @record.to_param, res.object => res.update.params)
167
+ end
168
+
169
+ if res.denied.actions.include?(:update)
170
+ should_not_assign_to res.object
171
+ should_redirect_to res.denied.redirect
172
+ should_set_the_flash_to res.denied.flash
173
+ else
174
+ should_assign_to res.object
175
+ should_set_the_flash_to(res.update.flash)
176
+ if res.update.redirect.is_a? Symbol
177
+ should_respond_with res.update.redirect
178
+ else
179
+ should_redirect_to res.update.redirect
180
+ end
181
+
182
+ should "not have errors on @#{res.object}" do
183
+ assert_equal [], assigns(res.object).errors.full_messages, "@#{res.object} has errors:"
184
+ end
185
+ end
186
+ end
187
+ end
188
+ end
189
+ end
190
+ end
191
+ end
192
+ end
@@ -0,0 +1,162 @@
1
+ module ThoughtBot # :nodoc:
2
+ module Shoulda # :nodoc:
3
+ module Controller # :nodoc:
4
+ module XML
5
+ def self.included(other) #:nodoc:
6
+ other.class_eval do
7
+ extend ThoughtBot::Shoulda::Controller::XML::ClassMethods
8
+ end
9
+ end
10
+
11
+ module ClassMethods
12
+ # Macro that creates a test asserting that the controller responded with an XML content-type
13
+ # and that the XML contains +<name/>+ as the root element.
14
+ def should_respond_with_xml_for(name = nil)
15
+ should "have ContentType set to 'application/xml'" do
16
+ assert_xml_response
17
+ end
18
+
19
+ if name
20
+ should "return <#{name}/> as the root element" do
21
+ body = @response.body.first(100).map {|l| " #{l}"}
22
+ assert_select name.to_s.dasherize, 1, "Body:\n#{body}...\nDoes not have <#{name}/> as the root element."
23
+ end
24
+ end
25
+ end
26
+ alias should_respond_with_xml should_respond_with_xml_for
27
+
28
+ protected
29
+
30
+ def make_show_xml_tests(res) # :nodoc:
31
+ context "on GET to :show as xml" do
32
+ setup do
33
+ request_xml
34
+ record = get_existing_record(res)
35
+ parent_params = make_parent_params(res, record)
36
+ get :show, parent_params.merge({ res.identifier => record.to_param })
37
+ end
38
+
39
+ if res.denied.actions.include?(:show)
40
+ should_not_assign_to res.object
41
+ should_respond_with 401
42
+ else
43
+ should_assign_to res.object
44
+ should_respond_with :success
45
+ should_respond_with_xml_for res.object
46
+ end
47
+ end
48
+ end
49
+
50
+ def make_edit_xml_tests(res) # :nodoc:
51
+ # XML doesn't need an :edit action
52
+ end
53
+
54
+ def make_new_xml_tests(res) # :nodoc:
55
+ # XML doesn't need a :new action
56
+ end
57
+
58
+ def make_index_xml_tests(res) # :nodoc:
59
+ context "on GET to :index as xml" do
60
+ setup do
61
+ request_xml
62
+ parent_params = make_parent_params(res)
63
+ get(:index, parent_params)
64
+ end
65
+
66
+ if res.denied.actions.include?(:index)
67
+ should_not_assign_to res.object.to_s.pluralize
68
+ should_respond_with 401
69
+ else
70
+ should_respond_with :success
71
+ should_respond_with_xml_for res.object.to_s.pluralize
72
+ should_assign_to res.object.to_s.pluralize
73
+ end
74
+ end
75
+ end
76
+
77
+ def make_destroy_xml_tests(res) # :nodoc:
78
+ context "on DELETE to :destroy as xml" do
79
+ setup do
80
+ request_xml
81
+ @record = get_existing_record(res)
82
+ parent_params = make_parent_params(res, @record)
83
+ delete :destroy, parent_params.merge({ res.identifier => @record.to_param })
84
+ end
85
+
86
+ if res.denied.actions.include?(:destroy)
87
+ should_respond_with 401
88
+
89
+ should "not destroy record" do
90
+ assert @record.reload
91
+ end
92
+ else
93
+ should "destroy record" do
94
+ assert_raises(::ActiveRecord::RecordNotFound) { @record.reload }
95
+ end
96
+ end
97
+ end
98
+ end
99
+
100
+ def make_create_xml_tests(res) # :nodoc:
101
+ context "on POST to :create as xml" do
102
+ setup do
103
+ request_xml
104
+ parent_params = make_parent_params(res)
105
+ @count = res.klass.count
106
+ post :create, parent_params.merge(res.object => res.create.params)
107
+ end
108
+
109
+ if res.denied.actions.include?(:create)
110
+ should_respond_with 401
111
+ should_not_assign_to res.object
112
+
113
+ should "not create new record" do
114
+ assert_equal @count, res.klass.count
115
+ end
116
+ else
117
+ should_assign_to res.object
118
+
119
+ should "not have errors on @#{res.object}" do
120
+ assert_equal [], assigns(res.object).errors.full_messages, "@#{res.object} has errors:"
121
+ end
122
+ end
123
+ end
124
+ end
125
+
126
+ def make_update_xml_tests(res) # :nodoc:
127
+ context "on PUT to :update as xml" do
128
+ setup do
129
+ request_xml
130
+ @record = get_existing_record(res)
131
+ parent_params = make_parent_params(res, @record)
132
+ put :update, parent_params.merge(res.identifier => @record.to_param, res.object => res.update.params)
133
+ end
134
+
135
+ if res.denied.actions.include?(:update)
136
+ should_not_assign_to res.object
137
+ should_respond_with 401
138
+ else
139
+ should_assign_to res.object
140
+
141
+ should "not have errors on @#{res.object}" do
142
+ assert_equal [], assigns(res.object).errors.full_messages, "@#{res.object} has errors:"
143
+ end
144
+ end
145
+ end
146
+ end
147
+ end
148
+
149
+ # Sets the next request's format to 'application/xml'
150
+ def request_xml
151
+ @request.accept = "application/xml"
152
+ end
153
+
154
+ # Asserts that the controller's response was 'application/xml'
155
+ def assert_xml_response
156
+ assert_equal "application/xml; charset=utf-8", @response.headers['Content-Type'], "Body: #{@response.body.first(100)} ..."
157
+ end
158
+
159
+ end
160
+ end
161
+ end
162
+ end
@@ -0,0 +1,119 @@
1
+ module ThoughtBot # :nodoc:
2
+ module Shoulda # :nodoc:
3
+ module General
4
+ def self.included(other) # :nodoc:
5
+ other.class_eval do
6
+ extend ThoughtBot::Shoulda::General::ClassMethods
7
+ # include ThoughtBot::Shoulda::General::InstanceMethods
8
+ end
9
+ end
10
+
11
+ module ClassMethods
12
+ # Loads all fixture files (<tt>test/fixtures/*.yml</tt>)
13
+ def load_all_fixtures
14
+ all_fixtures = Dir.glob(File.join(Test::Unit::TestCase.fixture_path, "*.yml")).collect do |f|
15
+ File.basename(f, '.yml').to_sym
16
+ end
17
+ fixtures *all_fixtures
18
+ end
19
+ end
20
+
21
+ # Prints a message to stdout, tagged with the name of the calling method.
22
+ def report!(msg = "")
23
+ puts("#{caller.first}: #{msg}")
24
+ end
25
+
26
+ # Ensures that the number of items in the collection changes
27
+ #
28
+ # assert_difference(User, :count, 1) { User.create }
29
+ # assert_difference(User.packages, :size, 3, true) { User.add_three_packages }
30
+ #
31
+ # Setting reload to true will call <tt>object.reload</tt> after the block (for ActiveRecord associations)
32
+ def assert_difference(object, method, difference, reload = false, msg = nil)
33
+ initial_value = object.send(method)
34
+ yield
35
+ object.send(:reload) if reload
36
+ assert_equal initial_value + difference, object.send(method), (msg || "#{object}##{method} after block")
37
+ end
38
+
39
+ # Ensures that object.method does not change. See assert_difference for usage.
40
+ def assert_no_difference(object, method, reload = false, msg = nil, &block)
41
+ assert_difference(object, method, 0, reload, msg, &block)
42
+ end
43
+
44
+ # Asserts that two arrays contain the same elements, the same number of times. Essentially ==, but unordered.
45
+ #
46
+ # assert_same_elements([:a, :b, :c], [:c, :a, :b]) => passes
47
+ def assert_same_elements(a1, a2, msg = nil)
48
+ [:select, :inject, :size].each do |m|
49
+ [a1, a2].each {|a| assert_respond_to(a, m, "Are you sure that #{a.inspect} is an array? It doesn't respond to #{m}.") }
50
+ end
51
+
52
+ assert a1h = a1.inject({}) { |h,e| h[e] = a1.select { |i| i == e }.size; h }
53
+ assert a2h = a2.inject({}) { |h,e| h[e] = a2.select { |i| i == e }.size; h }
54
+
55
+ assert_equal(a1h, a2h, msg)
56
+ end
57
+
58
+ # Asserts that the given collection contains item x. If x is a regular expression, ensure that
59
+ # at least one element from the collection matches x. +extra_msg+ is appended to the error message if the assertion fails.
60
+ #
61
+ # assert_contains(['a', '1'], /\d/) => passes
62
+ # assert_contains(['a', '1'], 'a') => passes
63
+ # assert_contains(['a', '1'], /not there/) => fails
64
+ def assert_contains(collection, x, extra_msg = "")
65
+ collection = [collection] unless collection.is_a?(Array)
66
+ msg = "#{x.inspect} not found in #{collection.to_a.inspect} " + extra_msg
67
+ case x
68
+ when Regexp: assert(collection.detect { |e| e =~ x }, msg)
69
+ else assert(collection.include?(x), msg)
70
+ end
71
+ end
72
+
73
+ # Asserts that the given collection does not contain item x. If x is a regular expression, ensure that
74
+ # none of the elements from the collection match x.
75
+ def assert_does_not_contain(collection, x, extra_msg = "")
76
+ collection = [collection] unless collection.is_a?(Array)
77
+ msg = "#{x.inspect} found in #{collection.to_a.inspect} " + extra_msg
78
+ case x
79
+ when Regexp: assert(!collection.detect { |e| e =~ x }, msg)
80
+ else assert(!collection.include?(x), msg)
81
+ end
82
+ end
83
+
84
+ # Asserts that the given object can be saved
85
+ #
86
+ # assert_save User.new(params)
87
+ def assert_save(obj)
88
+ assert obj.save, "Errors: #{obj.errors.full_messages.join('; ')}"
89
+ obj.reload
90
+ end
91
+
92
+ # Asserts that the given object is valid
93
+ #
94
+ # assert_save User.new(params)
95
+ def assert_valid(obj)
96
+ assert obj.valid?, "Errors: #{obj.errors.full_messages.join('; ')}"
97
+ end
98
+
99
+ # Asserts that the block uses ActionMailer to send emails
100
+ #
101
+ # assert_sends_email(2) { Mailer.deliver_messages }
102
+ def assert_sends_email(num = 1, &blk)
103
+ ActionMailer::Base.deliveries.clear
104
+ blk.call
105
+ msg = "Sent #{ActionMailer::Base.deliveries.size} emails, when #{num} expected:\n"
106
+ ActionMailer::Base.deliveries.each { |m| msg << " '#{m.subject}' sent to #{m.to.to_sentence}\n" }
107
+ assert(num == ActionMailer::Base.deliveries.size, msg)
108
+ end
109
+
110
+ # Asserts that the block does not send emails thorough ActionMailer
111
+ #
112
+ # assert_does_not_send_email { # do nothing }
113
+ def assert_does_not_send_email(&blk)
114
+ assert_sends_email 0, &blk
115
+ end
116
+
117
+ end
118
+ end
119
+ end