shoulda 2.0.0

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 (104) hide show
  1. data/CONTRIBUTION_GUIDELINES.rdoc +12 -0
  2. data/MIT-LICENSE +22 -0
  3. data/README.rdoc +132 -0
  4. data/Rakefile +72 -0
  5. data/bin/convert_to_should_syntax +42 -0
  6. data/lib/shoulda.rb +16 -0
  7. data/lib/shoulda/action_mailer.rb +10 -0
  8. data/lib/shoulda/action_mailer/assertions.rb +39 -0
  9. data/lib/shoulda/active_record.rb +12 -0
  10. data/lib/shoulda/active_record/assertions.rb +85 -0
  11. data/lib/shoulda/active_record/macros.rb +703 -0
  12. data/lib/shoulda/assertions.rb +45 -0
  13. data/lib/shoulda/context.rb +309 -0
  14. data/lib/shoulda/controller.rb +30 -0
  15. data/lib/shoulda/controller/formats/html.rb +201 -0
  16. data/lib/shoulda/controller/formats/xml.rb +170 -0
  17. data/lib/shoulda/controller/helpers.rb +64 -0
  18. data/lib/shoulda/controller/macros.rb +287 -0
  19. data/lib/shoulda/controller/resource_options.rb +236 -0
  20. data/lib/shoulda/controller/routing.rb +0 -0
  21. data/lib/shoulda/controller/routing/macros.rb +0 -0
  22. data/lib/shoulda/helpers.rb +10 -0
  23. data/lib/shoulda/macros.rb +80 -0
  24. data/lib/shoulda/private_helpers.rb +22 -0
  25. data/lib/shoulda/proc_extensions.rb +14 -0
  26. data/lib/shoulda/rails.rb +19 -0
  27. data/lib/shoulda/tasks.rb +3 -0
  28. data/lib/shoulda/tasks/list_tests.rake +24 -0
  29. data/lib/shoulda/tasks/yaml_to_shoulda.rake +28 -0
  30. data/test/README +36 -0
  31. data/test/fixtures/addresses.yml +3 -0
  32. data/test/fixtures/friendships.yml +0 -0
  33. data/test/fixtures/posts.yml +5 -0
  34. data/test/fixtures/products.yml +0 -0
  35. data/test/fixtures/taggings.yml +0 -0
  36. data/test/fixtures/tags.yml +9 -0
  37. data/test/fixtures/users.yml +6 -0
  38. data/test/functional/posts_controller_test.rb +104 -0
  39. data/test/functional/users_controller_test.rb +36 -0
  40. data/test/other/context_test.rb +145 -0
  41. data/test/other/convert_to_should_syntax_test.rb +63 -0
  42. data/test/other/helpers_test.rb +183 -0
  43. data/test/other/private_helpers_test.rb +34 -0
  44. data/test/other/should_test.rb +266 -0
  45. data/test/rails_root/app/controllers/application.rb +25 -0
  46. data/test/rails_root/app/controllers/posts_controller.rb +85 -0
  47. data/test/rails_root/app/controllers/users_controller.rb +81 -0
  48. data/test/rails_root/app/helpers/application_helper.rb +3 -0
  49. data/test/rails_root/app/helpers/posts_helper.rb +2 -0
  50. data/test/rails_root/app/helpers/users_helper.rb +2 -0
  51. data/test/rails_root/app/models/address.rb +7 -0
  52. data/test/rails_root/app/models/dog.rb +5 -0
  53. data/test/rails_root/app/models/flea.rb +3 -0
  54. data/test/rails_root/app/models/friendship.rb +4 -0
  55. data/test/rails_root/app/models/post.rb +12 -0
  56. data/test/rails_root/app/models/product.rb +12 -0
  57. data/test/rails_root/app/models/tag.rb +8 -0
  58. data/test/rails_root/app/models/tagging.rb +4 -0
  59. data/test/rails_root/app/models/user.rb +28 -0
  60. data/test/rails_root/app/views/layouts/posts.rhtml +17 -0
  61. data/test/rails_root/app/views/layouts/users.rhtml +17 -0
  62. data/test/rails_root/app/views/posts/edit.rhtml +27 -0
  63. data/test/rails_root/app/views/posts/index.rhtml +25 -0
  64. data/test/rails_root/app/views/posts/new.rhtml +26 -0
  65. data/test/rails_root/app/views/posts/show.rhtml +18 -0
  66. data/test/rails_root/app/views/users/edit.rhtml +22 -0
  67. data/test/rails_root/app/views/users/index.rhtml +22 -0
  68. data/test/rails_root/app/views/users/new.rhtml +21 -0
  69. data/test/rails_root/app/views/users/show.rhtml +13 -0
  70. data/test/rails_root/config/boot.rb +109 -0
  71. data/test/rails_root/config/database.yml +4 -0
  72. data/test/rails_root/config/environment.rb +14 -0
  73. data/test/rails_root/config/environments/sqlite3.rb +0 -0
  74. data/test/rails_root/config/initializers/new_rails_defaults.rb +15 -0
  75. data/test/rails_root/config/initializers/shoulda.rb +8 -0
  76. data/test/rails_root/config/routes.rb +6 -0
  77. data/test/rails_root/db/migrate/001_create_users.rb +18 -0
  78. data/test/rails_root/db/migrate/002_create_posts.rb +13 -0
  79. data/test/rails_root/db/migrate/003_create_taggings.rb +12 -0
  80. data/test/rails_root/db/migrate/004_create_tags.rb +11 -0
  81. data/test/rails_root/db/migrate/005_create_dogs.rb +12 -0
  82. data/test/rails_root/db/migrate/006_create_addresses.rb +14 -0
  83. data/test/rails_root/db/migrate/007_create_fleas.rb +11 -0
  84. data/test/rails_root/db/migrate/008_create_dogs_fleas.rb +12 -0
  85. data/test/rails_root/db/migrate/009_create_products.rb +17 -0
  86. data/test/rails_root/db/migrate/010_create_friendships.rb +14 -0
  87. data/test/rails_root/db/schema.rb +0 -0
  88. data/test/rails_root/log/sqlite3.log +0 -0
  89. data/test/rails_root/public/404.html +30 -0
  90. data/test/rails_root/public/422.html +30 -0
  91. data/test/rails_root/public/500.html +30 -0
  92. data/test/rails_root/script/console +3 -0
  93. data/test/rails_root/script/generate +3 -0
  94. data/test/test_helper.rb +33 -0
  95. data/test/unit/address_test.rb +10 -0
  96. data/test/unit/dog_test.rb +7 -0
  97. data/test/unit/flea_test.rb +6 -0
  98. data/test/unit/friendship_test.rb +6 -0
  99. data/test/unit/post_test.rb +15 -0
  100. data/test/unit/product_test.rb +27 -0
  101. data/test/unit/tag_test.rb +14 -0
  102. data/test/unit/tagging_test.rb +6 -0
  103. data/test/unit/user_test.rb +52 -0
  104. metadata +170 -0
@@ -0,0 +1,45 @@
1
+ module ThoughtBot # :nodoc:
2
+ module Shoulda # :nodoc:
3
+ module Assertions
4
+ # Asserts that two arrays contain the same elements, the same number of times. Essentially ==, but unordered.
5
+ #
6
+ # assert_same_elements([:a, :b, :c], [:c, :a, :b]) => passes
7
+ def assert_same_elements(a1, a2, msg = nil)
8
+ [:select, :inject, :size].each do |m|
9
+ [a1, a2].each {|a| assert_respond_to(a, m, "Are you sure that #{a.inspect} is an array? It doesn't respond to #{m}.") }
10
+ end
11
+
12
+ assert a1h = a1.inject({}) { |h,e| h[e] = a1.select { |i| i == e }.size; h }
13
+ assert a2h = a2.inject({}) { |h,e| h[e] = a2.select { |i| i == e }.size; h }
14
+
15
+ assert_equal(a1h, a2h, msg)
16
+ end
17
+
18
+ # Asserts that the given collection contains item x. If x is a regular expression, ensure that
19
+ # at least one element from the collection matches x. +extra_msg+ is appended to the error message if the assertion fails.
20
+ #
21
+ # assert_contains(['a', '1'], /\d/) => passes
22
+ # assert_contains(['a', '1'], 'a') => passes
23
+ # assert_contains(['a', '1'], /not there/) => fails
24
+ def assert_contains(collection, x, extra_msg = "")
25
+ collection = [collection] unless collection.is_a?(Array)
26
+ msg = "#{x.inspect} not found in #{collection.to_a.inspect} #{extra_msg}"
27
+ case x
28
+ when Regexp: assert(collection.detect { |e| e =~ x }, msg)
29
+ else assert(collection.include?(x), msg)
30
+ end
31
+ end
32
+
33
+ # Asserts that the given collection does not contain item x. If x is a regular expression, ensure that
34
+ # none of the elements from the collection match x.
35
+ def assert_does_not_contain(collection, x, extra_msg = "")
36
+ collection = [collection] unless collection.is_a?(Array)
37
+ msg = "#{x.inspect} found in #{collection.to_a.inspect} " + extra_msg
38
+ case x
39
+ when Regexp: assert(!collection.detect { |e| e =~ x }, msg)
40
+ else assert(!collection.include?(x), msg)
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,309 @@
1
+ module Thoughtbot # :nodoc:
2
+ module Shoulda
3
+ VERSION = '2.0.0'
4
+
5
+ class << self
6
+ attr_accessor :contexts
7
+ def contexts # :nodoc:
8
+ @contexts ||= []
9
+ end
10
+
11
+ def current_context # :nodoc:
12
+ self.contexts.last
13
+ end
14
+
15
+ def add_context(context) # :nodoc:
16
+ self.contexts.push(context)
17
+ end
18
+
19
+ def remove_context # :nodoc:
20
+ self.contexts.pop
21
+ end
22
+ end
23
+
24
+ # == Should statements
25
+ #
26
+ # Should statements are just syntactic sugar over normal Test::Unit test methods. A should block
27
+ # contains all the normal code and assertions you're used to seeing, with the added benefit that
28
+ # they can be wrapped inside context blocks (see below).
29
+ #
30
+ # === Example:
31
+ #
32
+ # class UserTest << Test::Unit::TestCase
33
+ #
34
+ # def setup
35
+ # @user = User.new("John", "Doe")
36
+ # end
37
+ #
38
+ # should "return its full name"
39
+ # assert_equal 'John Doe', @user.full_name
40
+ # end
41
+ #
42
+ # end
43
+ #
44
+ # ...will produce the following test:
45
+ # * <tt>"test: User should return its full name. "</tt>
46
+ #
47
+ # Note: The part before <tt>should</tt> in the test name is gleamed from the name of the Test::Unit class.
48
+ #
49
+ # Should statements can also take a Proc as a <tt>:before </tt>option. This proc runs after any
50
+ # parent context's setups but before the current context's setup.
51
+ #
52
+ # === Example:
53
+ #
54
+ # context "Some context" do
55
+ # setup { puts("I run after the :before proc") }
56
+ #
57
+ # should "run a :before proc", :before => lambda { puts("I run before the setup") } do
58
+ # assert true
59
+ # end
60
+ # end
61
+
62
+ def should(name, options = {}, &blk)
63
+ if Shoulda.current_context
64
+ block_given? ? Shoulda.current_context.should(name, options, &blk) : Should.current_context.should_eventually(name)
65
+ else
66
+ context_name = self.name.gsub(/Test/, "")
67
+ context = Thoughtbot::Shoulda::Context.new(context_name, self) do
68
+ block_given? ? should(name, options, &blk) : should_eventually(name)
69
+ end
70
+ context.build
71
+ end
72
+ end
73
+
74
+ # == Before statements
75
+ #
76
+ # Before statements are simply should statements that run before the current
77
+ # context's setup. These are especially useful when setting expectations.
78
+ #
79
+ # === Example:
80
+ #
81
+ # class UserControllerTest << Test::Unit::TestCase
82
+ # context "the index action" do
83
+ # setup do
84
+ # @users = [Factory(:user)]
85
+ # User.stubs(:find).returns(@users)
86
+ # end
87
+ #
88
+ # context "on GET" do
89
+ # setup do
90
+ # get :index
91
+ # end
92
+ #
93
+ # # normal should statement
94
+ # should_respond_with :success
95
+ #
96
+ # # runs before "get :index"
97
+ # before_should "find all users" do
98
+ # User.expects(:find).with(:all).returns(@users)
99
+ # end
100
+ # end
101
+ # end
102
+ # end
103
+ def before_should(name, &blk)
104
+ should(name, :before => blk) { assert true }
105
+ end
106
+
107
+ # Just like should, but never runs, and instead prints an 'X' in the Test::Unit output.
108
+ def should_eventually(name, options = {}, &blk)
109
+ context_name = self.name.gsub(/Test/, "")
110
+ context = Thoughtbot::Shoulda::Context.new(context_name, self) do
111
+ should_eventually(name, &blk)
112
+ end
113
+ context.build
114
+ end
115
+
116
+ # == Contexts
117
+ #
118
+ # A context block groups should statements under a common set of setup/teardown methods.
119
+ # Context blocks can be arbitrarily nested, and can do wonders for improving the maintainability
120
+ # and readability of your test code.
121
+ #
122
+ # A context block can contain setup, should, should_eventually, and teardown blocks.
123
+ #
124
+ # class UserTest << Test::Unit::TestCase
125
+ # context "A User instance" do
126
+ # setup do
127
+ # @user = User.find(:first)
128
+ # end
129
+ #
130
+ # should "return its full name"
131
+ # assert_equal 'John Doe', @user.full_name
132
+ # end
133
+ # end
134
+ # end
135
+ #
136
+ # This code will produce the method <tt>"test: A User instance should return its full name. "</tt>.
137
+ #
138
+ # Contexts may be nested. Nested contexts run their setup blocks from out to in before each
139
+ # should statement. They then run their teardown blocks from in to out after each should statement.
140
+ #
141
+ # class UserTest << Test::Unit::TestCase
142
+ # context "A User instance" do
143
+ # setup do
144
+ # @user = User.find(:first)
145
+ # end
146
+ #
147
+ # should "return its full name"
148
+ # assert_equal 'John Doe', @user.full_name
149
+ # end
150
+ #
151
+ # context "with a profile" do
152
+ # setup do
153
+ # @user.profile = Profile.find(:first)
154
+ # end
155
+ #
156
+ # should "return true when sent :has_profile?"
157
+ # assert @user.has_profile?
158
+ # end
159
+ # end
160
+ # end
161
+ # end
162
+ #
163
+ # This code will produce the following methods
164
+ # * <tt>"test: A User instance should return its full name. "</tt>
165
+ # * <tt>"test: A User instance with a profile should return true when sent :has_profile?. "</tt>
166
+ #
167
+ # <b>Just like should statements, a context block can exist next to normal <tt>def test_the_old_way; end</tt>
168
+ # tests</b>. This means you do not have to fully commit to the context/should syntax in a test file.
169
+
170
+ def context(name, &blk)
171
+ if Shoulda.current_context
172
+ Shoulda.current_context.context(name, &blk)
173
+ else
174
+ context = Thoughtbot::Shoulda::Context.new(name, self, &blk)
175
+ context.build
176
+ end
177
+ end
178
+
179
+ class Context # :nodoc:
180
+
181
+ attr_accessor :name # my name
182
+ attr_accessor :parent # may be another context, or the original test::unit class.
183
+ attr_accessor :subcontexts # array of contexts nested under myself
184
+ attr_accessor :setup_blocks # blocks given via setup methods
185
+ attr_accessor :teardown_blocks # blocks given via teardown methods
186
+ attr_accessor :shoulds # array of hashes representing the should statements
187
+ attr_accessor :should_eventuallys # array of hashes representing the should eventually statements
188
+
189
+ def initialize(name, parent, &blk)
190
+ Shoulda.add_context(self)
191
+ self.name = name
192
+ self.parent = parent
193
+ self.setup_blocks = []
194
+ self.teardown_blocks = []
195
+ self.shoulds = []
196
+ self.should_eventuallys = []
197
+ self.subcontexts = []
198
+
199
+ merge_block(&blk)
200
+ Shoulda.remove_context
201
+ end
202
+
203
+ def merge_block(&blk)
204
+ blk.bind(self).call
205
+ end
206
+
207
+ def context(name, &blk)
208
+ self.subcontexts << Context.new(name, self, &blk)
209
+ end
210
+
211
+ def setup(&blk)
212
+ self.setup_blocks << blk
213
+ end
214
+
215
+ def teardown(&blk)
216
+ self.teardown_blocks << blk
217
+ end
218
+
219
+ def should(name, options = {}, &blk)
220
+ if block_given?
221
+ self.shoulds << { :name => name, :before => options[:before], :block => blk }
222
+ else
223
+ self.should_eventuallys << { :name => name }
224
+ end
225
+ end
226
+
227
+ def should_eventually(name, &blk)
228
+ self.should_eventuallys << { :name => name, :block => blk }
229
+ end
230
+
231
+ def full_name
232
+ parent_name = parent.full_name if am_subcontext?
233
+ return [parent_name, name].join(" ").strip
234
+ end
235
+
236
+ def am_subcontext?
237
+ parent.is_a?(self.class) # my parent is the same class as myself.
238
+ end
239
+
240
+ def test_unit_class
241
+ am_subcontext? ? parent.test_unit_class : parent
242
+ end
243
+
244
+ def create_test_from_should_hash(should)
245
+ test_name = ["test:", full_name, "should", "#{should[:name]}. "].flatten.join(' ').to_sym
246
+
247
+ if test_unit_class.instance_methods.include?(test_name.to_s)
248
+ warn " * WARNING: '#{test_name}' is already defined"
249
+ end
250
+
251
+ context = self
252
+ test_unit_class.send(:define_method, test_name) do
253
+ begin
254
+ context.run_parent_setup_blocks(self)
255
+ should[:before].bind(self).call if should[:before]
256
+ context.run_current_setup_blocks(self)
257
+ should[:block].bind(self).call
258
+ ensure
259
+ context.run_all_teardown_blocks(self)
260
+ end
261
+ end
262
+ end
263
+
264
+ def run_all_setup_blocks(binding)
265
+ run_parent_setup_blocks(binding)
266
+ run_current_setup_blocks(binding)
267
+ end
268
+
269
+ def run_parent_setup_blocks(binding)
270
+ self.parent.run_all_setup_blocks(binding) if am_subcontext?
271
+ end
272
+
273
+ def run_current_setup_blocks(binding)
274
+ setup_blocks.each do |setup_block|
275
+ setup_block.bind(binding).call
276
+ end
277
+ end
278
+
279
+ def run_all_teardown_blocks(binding)
280
+ teardown_blocks.reverse.each do |teardown_block|
281
+ teardown_block.bind(binding).call
282
+ end
283
+ self.parent.run_all_teardown_blocks(binding) if am_subcontext?
284
+ end
285
+
286
+ def print_should_eventuallys
287
+ should_eventuallys.each do |should|
288
+ test_name = [full_name, "should", "#{should[:name]}. "].flatten.join(' ')
289
+ puts " * DEFERRED: " + test_name
290
+ end
291
+ end
292
+
293
+ def build
294
+ shoulds.each do |should|
295
+ create_test_from_should_hash(should)
296
+ end
297
+
298
+ subcontexts.each { |context| context.build }
299
+
300
+ print_should_eventuallys
301
+ end
302
+
303
+ def method_missing(method, *args, &blk)
304
+ test_unit_class.send(method, *args, &blk)
305
+ end
306
+
307
+ end
308
+ end
309
+ end
@@ -0,0 +1,30 @@
1
+ require 'shoulda'
2
+ require 'shoulda/controller/helpers'
3
+ require 'shoulda/controller/resource_options'
4
+ require 'shoulda/controller/macros'
5
+
6
+ module Test # :nodoc: all
7
+ module Unit
8
+ class TestCase
9
+ extend ThoughtBot::Shoulda::Controller::Macros
10
+ include ThoughtBot::Shoulda::Controller::Helpers
11
+ ThoughtBot::Shoulda::Controller::VALID_FORMATS.each do |format|
12
+ include "ThoughtBot::Shoulda::Controller::#{format.to_s.upcase}".constantize
13
+ end
14
+ end
15
+ end
16
+ end
17
+
18
+ require 'shoulda/active_record/assertions'
19
+ require 'shoulda/action_mailer/assertions'
20
+
21
+ module ActionController #:nodoc: all
22
+ module Integration
23
+ class Session
24
+ include ThoughtBot::Shoulda::Assertions
25
+ include ThoughtBot::Shoulda::Helpers
26
+ include ThoughtBot::Shoulda::ActiveRecord::Assertions
27
+ include ThoughtBot::Shoulda::ActionMailer::Assertions
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,201 @@
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 controller_name_from_class
13
+ self.name.gsub(/Test/, '')
14
+ end
15
+
16
+ def make_show_html_tests(res)
17
+ context "on GET to #{controller_name_from_class}#show" do
18
+ setup do
19
+ record = get_existing_record(res)
20
+ parent_params = make_parent_params(res, record)
21
+ get :show, parent_params.merge({ res.identifier => record.to_param })
22
+ end
23
+
24
+ if res.denied.actions.include?(:show)
25
+ should_not_assign_to res.object
26
+ should_redirect_to res.denied.redirect
27
+ should_set_the_flash_to res.denied.flash
28
+ else
29
+ should_assign_to res.object
30
+ should_respond_with :success
31
+ should_render_template :show
32
+ should_not_set_the_flash
33
+ end
34
+ end
35
+ end
36
+
37
+ def make_edit_html_tests(res)
38
+ context "on GET to #{controller_name_from_class}#edit" do
39
+ setup do
40
+ @record = get_existing_record(res)
41
+ parent_params = make_parent_params(res, @record)
42
+ get :edit, parent_params.merge({ res.identifier => @record.to_param })
43
+ end
44
+
45
+ if res.denied.actions.include?(:edit)
46
+ should_not_assign_to res.object
47
+ should_redirect_to res.denied.redirect
48
+ should_set_the_flash_to res.denied.flash
49
+ else
50
+ should_assign_to res.object
51
+ should_respond_with :success
52
+ should_render_template :edit
53
+ should_not_set_the_flash
54
+ should_render_a_form
55
+ should "set @#{res.object} to requested instance" do
56
+ assert_equal @record, assigns(res.object)
57
+ end
58
+ end
59
+ end
60
+ end
61
+
62
+ def make_index_html_tests(res)
63
+ context "on GET to #{controller_name_from_class}#index" do
64
+ setup do
65
+ record = get_existing_record(res) rescue nil
66
+ parent_params = make_parent_params(res, record)
67
+ get(:index, parent_params)
68
+ end
69
+
70
+ if res.denied.actions.include?(:index)
71
+ should_not_assign_to res.object.to_s.pluralize
72
+ should_redirect_to res.denied.redirect
73
+ should_set_the_flash_to res.denied.flash
74
+ else
75
+ should_respond_with :success
76
+ should_assign_to res.object.to_s.pluralize
77
+ should_render_template :index
78
+ should_not_set_the_flash
79
+ end
80
+ end
81
+ end
82
+
83
+ def make_new_html_tests(res)
84
+ context "on GET to #{controller_name_from_class}#new" do
85
+ setup do
86
+ record = get_existing_record(res) rescue nil
87
+ parent_params = make_parent_params(res, record)
88
+ get(:new, parent_params)
89
+ end
90
+
91
+ if res.denied.actions.include?(:new)
92
+ should_not_assign_to res.object
93
+ should_redirect_to res.denied.redirect
94
+ should_set_the_flash_to res.denied.flash
95
+ else
96
+ should_respond_with :success
97
+ should_assign_to res.object
98
+ should_not_set_the_flash
99
+ should_render_template :new
100
+ should_render_a_form
101
+ end
102
+ end
103
+ end
104
+
105
+ def make_destroy_html_tests(res)
106
+ context "on DELETE to #{controller_name_from_class}#destroy" do
107
+ setup do
108
+ @record = get_existing_record(res)
109
+ parent_params = make_parent_params(res, @record)
110
+ delete :destroy, parent_params.merge({ res.identifier => @record.to_param })
111
+ end
112
+
113
+ if res.denied.actions.include?(:destroy)
114
+ should_redirect_to res.denied.redirect
115
+ should_set_the_flash_to res.denied.flash
116
+
117
+ should "not destroy record" do
118
+ assert_nothing_raised { assert @record.reload }
119
+ end
120
+ else
121
+ should_set_the_flash_to res.destroy.flash
122
+ if res.destroy.redirect.is_a? Symbol
123
+ should_respond_with res.destroy.redirect
124
+ else
125
+ should_redirect_to res.destroy.redirect
126
+ end
127
+
128
+ should "destroy record" do
129
+ assert_raises(::ActiveRecord::RecordNotFound, "@#{res.object} was not destroyed.") do
130
+ @record.reload
131
+ end
132
+ end
133
+ end
134
+ end
135
+ end
136
+
137
+ def make_create_html_tests(res)
138
+ context "on POST to #{controller_name_from_class}#create with #{res.create.params.inspect}" do
139
+ setup do
140
+ record = get_existing_record(res) rescue nil
141
+ parent_params = make_parent_params(res, record)
142
+ @count = res.klass.count
143
+ post :create, parent_params.merge(res.object => res.create.params)
144
+ end
145
+
146
+ if res.denied.actions.include?(:create)
147
+ should_redirect_to res.denied.redirect
148
+ should_set_the_flash_to res.denied.flash
149
+ should_not_assign_to res.object
150
+
151
+ should "not create new record" do
152
+ assert_equal @count, res.klass.count
153
+ end
154
+ else
155
+ should_assign_to res.object
156
+ should_set_the_flash_to res.create.flash
157
+ if res.create.redirect.is_a? Symbol
158
+ should_respond_with res.create.redirect
159
+ else
160
+ should_redirect_to res.create.redirect
161
+ end
162
+
163
+ should "not have errors on @#{res.object}" do
164
+ assert_equal [], pretty_error_messages(assigns(res.object)), "@#{res.object} has errors:"
165
+ end
166
+ end
167
+ end
168
+ end
169
+
170
+ def make_update_html_tests(res)
171
+ context "on PUT to #{controller_name_from_class}#update with #{res.create.params.inspect}" do
172
+ setup do
173
+ @record = get_existing_record(res)
174
+ parent_params = make_parent_params(res, @record)
175
+ put :update, parent_params.merge(res.identifier => @record.to_param, res.object => res.update.params)
176
+ end
177
+
178
+ if res.denied.actions.include?(:update)
179
+ should_not_assign_to res.object
180
+ should_redirect_to res.denied.redirect
181
+ should_set_the_flash_to res.denied.flash
182
+ else
183
+ should_assign_to res.object
184
+ should_set_the_flash_to(res.update.flash)
185
+ if res.update.redirect.is_a? Symbol
186
+ should_respond_with res.update.redirect
187
+ else
188
+ should_redirect_to res.update.redirect
189
+ end
190
+
191
+ should "not have errors on @#{res.object}" do
192
+ assert_equal [], pretty_error_messages(assigns(res.object)), "@#{res.object} has errors:"
193
+ end
194
+ end
195
+ end
196
+ end
197
+ end
198
+ end
199
+ end
200
+ end
201
+ end