shoulda 2.0.6 → 2.9.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (84) hide show
  1. data/README.rdoc +35 -7
  2. data/Rakefile +5 -3
  3. data/lib/shoulda.rb +7 -15
  4. data/lib/shoulda/action_mailer.rb +1 -1
  5. data/lib/shoulda/action_mailer/assertions.rb +32 -33
  6. data/lib/shoulda/active_record.rb +6 -2
  7. data/lib/shoulda/active_record/assertions.rb +62 -81
  8. data/lib/shoulda/active_record/helpers.rb +40 -0
  9. data/lib/shoulda/active_record/macros.rb +518 -639
  10. data/lib/shoulda/active_record/matchers.rb +42 -0
  11. data/lib/shoulda/active_record/matchers/allow_mass_assignment_of_matcher.rb +83 -0
  12. data/lib/shoulda/active_record/matchers/allow_value_matcher.rb +102 -0
  13. data/lib/shoulda/active_record/matchers/association_matcher.rb +226 -0
  14. data/lib/shoulda/active_record/matchers/ensure_inclusion_of_matcher.rb +87 -0
  15. data/lib/shoulda/active_record/matchers/ensure_length_of_matcher.rb +141 -0
  16. data/lib/shoulda/active_record/matchers/have_db_column_matcher.rb +169 -0
  17. data/lib/shoulda/active_record/matchers/have_index_matcher.rb +105 -0
  18. data/lib/shoulda/active_record/matchers/have_named_scope_matcher.rb +125 -0
  19. data/lib/shoulda/active_record/matchers/have_readonly_attribute_matcher.rb +59 -0
  20. data/lib/shoulda/active_record/matchers/validate_acceptance_of_matcher.rb +41 -0
  21. data/lib/shoulda/active_record/matchers/validate_numericality_of_matcher.rb +39 -0
  22. data/lib/shoulda/active_record/matchers/validate_presence_of_matcher.rb +60 -0
  23. data/lib/shoulda/active_record/matchers/validate_uniqueness_of_matcher.rb +148 -0
  24. data/lib/shoulda/active_record/matchers/validation_matcher.rb +56 -0
  25. data/lib/shoulda/assertions.rb +50 -40
  26. data/lib/shoulda/autoload_macros.rb +46 -0
  27. data/lib/shoulda/context.rb +124 -126
  28. data/lib/shoulda/controller.rb +8 -8
  29. data/lib/shoulda/controller/formats/html.rb +158 -160
  30. data/lib/shoulda/controller/formats/xml.rb +132 -134
  31. data/lib/shoulda/controller/helpers.rb +51 -53
  32. data/lib/shoulda/controller/macros.rb +278 -258
  33. data/lib/shoulda/controller/resource_options.rb +211 -214
  34. data/lib/shoulda/helpers.rb +5 -7
  35. data/lib/shoulda/macros.rb +63 -64
  36. data/lib/shoulda/private_helpers.rb +16 -18
  37. data/lib/shoulda/rails.rb +1 -8
  38. data/lib/shoulda/rspec.rb +5 -0
  39. data/lib/shoulda/tasks/list_tests.rake +6 -1
  40. data/lib/shoulda/test_unit.rb +19 -0
  41. data/rails/init.rb +1 -1
  42. data/test/README +2 -2
  43. data/test/fail_macros.rb +16 -16
  44. data/test/functional/posts_controller_test.rb +5 -2
  45. data/test/matchers/allow_mass_assignment_of_matcher_test.rb +68 -0
  46. data/test/matchers/allow_value_matcher_test.rb +41 -0
  47. data/test/matchers/association_matcher_test.rb +258 -0
  48. data/test/matchers/ensure_inclusion_of_matcher_test.rb +80 -0
  49. data/test/matchers/ensure_length_of_matcher_test.rb +158 -0
  50. data/test/matchers/have_db_column_matcher_test.rb +169 -0
  51. data/test/matchers/have_index_matcher_test.rb +74 -0
  52. data/test/matchers/have_named_scope_matcher_test.rb +65 -0
  53. data/test/matchers/have_readonly_attributes_matcher_test.rb +29 -0
  54. data/test/matchers/validate_acceptance_of_matcher_test.rb +44 -0
  55. data/test/matchers/validate_numericality_of_matcher_test.rb +52 -0
  56. data/test/matchers/validate_presence_of_matcher_test.rb +86 -0
  57. data/test/matchers/validate_uniqueness_of_matcher_test.rb +141 -0
  58. data/test/model_builder.rb +61 -0
  59. data/test/other/autoload_macro_test.rb +18 -0
  60. data/test/other/helpers_test.rb +58 -0
  61. data/test/other/private_helpers_test.rb +1 -1
  62. data/test/other/should_test.rb +16 -16
  63. data/test/rails_root/app/controllers/posts_controller.rb +6 -5
  64. data/test/rails_root/app/models/pets/dog.rb +10 -0
  65. data/test/rails_root/app/models/treat.rb +3 -0
  66. data/test/rails_root/app/models/user.rb +2 -2
  67. data/test/rails_root/app/views/layouts/posts.rhtml +2 -0
  68. data/test/rails_root/config/database.yml +1 -1
  69. data/test/rails_root/config/environments/{sqlite3.rb → test.rb} +0 -0
  70. data/test/rails_root/db/migrate/001_create_users.rb +3 -2
  71. data/test/rails_root/db/migrate/011_create_treats.rb +12 -0
  72. data/test/rails_root/log/test.log +0 -0
  73. data/test/rails_root/test/shoulda_macros/custom_macro.rb +6 -0
  74. data/test/rails_root/vendor/gems/gem_with_macro-0.0.1/shoulda_macros/gem_macro.rb +6 -0
  75. data/test/rails_root/vendor/plugins/plugin_with_macro/shoulda_macros/plugin_macro.rb +6 -0
  76. data/test/test_helper.rb +3 -1
  77. data/test/unit/address_test.rb +1 -1
  78. data/test/unit/dog_test.rb +5 -2
  79. data/test/unit/post_test.rb +7 -3
  80. data/test/unit/product_test.rb +2 -2
  81. data/test/unit/tag_test.rb +2 -1
  82. data/test/unit/user_test.rb +17 -8
  83. metadata +44 -4
  84. data/test/rails_root/app/models/dog.rb +0 -5
@@ -1,63 +1,61 @@
1
- module ThoughtBot # :nodoc:
2
- module Shoulda # :nodoc:
3
- module Controller # :nodoc:
4
- module Helpers # :nodoc:
5
- private # :enddoc:
1
+ module Shoulda # :nodoc:
2
+ module Controller # :nodoc:
3
+ module Helpers # :nodoc:
4
+ private # :enddoc:
6
5
 
7
- SPECIAL_INSTANCE_VARIABLES = %w{
8
- _cookies
9
- _flash
10
- _headers
11
- _params
12
- _request
13
- _response
14
- _session
15
- action_name
16
- before_filter_chain_aborted
17
- cookies
18
- flash
19
- headers
20
- ignore_missing_templates
21
- logger
22
- params
23
- request
24
- request_origin
25
- response
26
- session
27
- template
28
- template_class
29
- template_root
30
- url
31
- variables_added
32
- }.map(&:to_s)
6
+ SPECIAL_INSTANCE_VARIABLES = %w{
7
+ _cookies
8
+ _flash
9
+ _headers
10
+ _params
11
+ _request
12
+ _response
13
+ _session
14
+ action_name
15
+ before_filter_chain_aborted
16
+ cookies
17
+ flash
18
+ headers
19
+ ignore_missing_templates
20
+ logger
21
+ params
22
+ request
23
+ request_origin
24
+ response
25
+ session
26
+ template
27
+ template_class
28
+ template_root
29
+ url
30
+ variables_added
31
+ }.map(&:to_s)
33
32
 
34
- def instantiate_variables_from_assigns(*names, &blk)
35
- old = {}
36
- names = (@response.template.assigns.keys - SPECIAL_INSTANCE_VARIABLES) if names.empty?
37
- names.each do |name|
38
- old[name] = instance_variable_get("@#{name}")
39
- instance_variable_set("@#{name}", assigns(name.to_sym))
40
- end
41
- blk.call
42
- names.each do |name|
43
- instance_variable_set("@#{name}", old[name])
44
- end
33
+ def instantiate_variables_from_assigns(*names, &blk)
34
+ old = {}
35
+ names = (@response.template.assigns.keys - SPECIAL_INSTANCE_VARIABLES) if names.empty?
36
+ names.each do |name|
37
+ old[name] = instance_variable_get("@#{name}")
38
+ instance_variable_set("@#{name}", assigns(name.to_sym))
45
39
  end
40
+ blk.call
41
+ names.each do |name|
42
+ instance_variable_set("@#{name}", old[name])
43
+ end
44
+ end
46
45
 
47
- def get_existing_record(res) # :nodoc:
48
- returning(instance_variable_get("@#{res.object}")) do |record|
49
- assert(record, "This test requires you to set @#{res.object} in your setup block")
50
- end
46
+ def get_existing_record(res) # :nodoc:
47
+ returning(instance_variable_get("@#{res.object}")) do |record|
48
+ assert(record, "This test requires you to set @#{res.object} in your setup block")
51
49
  end
50
+ end
52
51
 
53
- def make_parent_params(resource, record = nil, parent_names = nil) # :nodoc:
54
- parent_names ||= resource.parents.reverse
55
- return {} if parent_names == [] # Base case
56
- parent_name = parent_names.shift
57
- parent = record ? record.send(parent_name) : parent_name.to_s.classify.constantize.find(:first)
52
+ def make_parent_params(resource, record = nil, parent_names = nil) # :nodoc:
53
+ parent_names ||= resource.parents.reverse
54
+ return {} if parent_names == [] # Base case
55
+ parent_name = parent_names.shift
56
+ parent = record ? record.send(parent_name) : parent_name.to_s.classify.constantize.find(:first)
58
57
 
59
- { :"#{parent_name}_id" => parent.to_param }.merge(make_parent_params(resource, parent, parent_names))
60
- end
58
+ { :"#{parent_name}_id" => parent.to_param }.merge(make_parent_params(resource, parent, parent_names))
61
59
  end
62
60
  end
63
61
  end
@@ -1,314 +1,334 @@
1
- module ThoughtBot # :nodoc:
2
- module Shoulda # :nodoc:
3
- module Controller # :nodoc:
4
- # = Macro test helpers for your controllers
1
+ module Shoulda # :nodoc:
2
+ module Controller # :nodoc:
3
+ # = Macro test helpers for your controllers
4
+ #
5
+ # By using the macro helpers you can quickly and easily create concise and easy to read test suites.
6
+ #
7
+ # This code segment:
8
+ # context "on GET to :show for first record" do
9
+ # setup do
10
+ # get :show, :id => 1
11
+ # end
12
+ #
13
+ # should_assign_to :user
14
+ # should_respond_with :success
15
+ # should_render_template :show
16
+ # should_not_set_the_flash
17
+ #
18
+ # should "do something else really cool" do
19
+ # assert_equal 1, assigns(:user).id
20
+ # end
21
+ # end
22
+ #
23
+ # Would produce 5 tests for the +show+ action
24
+ #
25
+ # Furthermore, the should_be_restful helper will create an entire set of tests which will verify that your
26
+ # controller responds restfully to a variety of requested formats.
27
+ module Macros
28
+ # <b>DEPRECATED:</b> Please see
29
+ # http://thoughtbot.lighthouseapp.com/projects/5807/tickets/78 for more
30
+ # information.
5
31
  #
6
- # By using the macro helpers you can quickly and easily create concise and easy to read test suites.
32
+ # Generates a full suite of tests for a restful controller.
7
33
  #
8
- # This code segment:
9
- # context "on GET to :show for first record" do
10
- # setup do
11
- # get :show, :id => 1
12
- # end
34
+ # The following definition will generate tests for the +index+, +show+, +new+,
35
+ # +edit+, +create+, +update+ and +destroy+ actions, in both +html+ and +xml+ formats:
13
36
  #
14
- # should_assign_to :user
15
- # should_respond_with :success
16
- # should_render_template :show
17
- # should_not_set_the_flash
37
+ # should_be_restful do |resource|
38
+ # resource.parent = :user
18
39
  #
19
- # should "do something else really cool" do
20
- # assert_equal 1, assigns(:user).id
21
- # end
40
+ # resource.create.params = { :title => "first post", :body => 'blah blah blah'}
41
+ # resource.update.params = { :title => "changed" }
22
42
  # end
23
43
  #
24
- # Would produce 5 tests for the +show+ action
44
+ # This generates about 40 tests, all of the format:
45
+ # "on GET to :show should assign @user."
46
+ # "on GET to :show should not set the flash."
47
+ # "on GET to :show should render 'show' template."
48
+ # "on GET to :show should respond with success."
49
+ # "on GET to :show as xml should assign @user."
50
+ # "on GET to :show as xml should have ContentType set to 'application/xml'."
51
+ # "on GET to :show as xml should respond with success."
52
+ # "on GET to :show as xml should return <user/> as the root element."
53
+ # The +resource+ parameter passed into the block is a ResourceOptions object, and
54
+ # is used to configure the tests for the details of your resources.
25
55
  #
26
- # Furthermore, the should_be_restful helper will create an entire set of tests which will verify that your
27
- # controller responds restfully to a variety of requested formats.
28
- module Macros
29
- # <b>DEPRECATED:</b> Please see
30
- # http://thoughtbot.lighthouseapp.com/projects/5807/tickets/78 for more
31
- # information.
32
- #
33
- # Generates a full suite of tests for a restful controller.
34
- #
35
- # The following definition will generate tests for the +index+, +show+, +new+,
36
- # +edit+, +create+, +update+ and +destroy+ actions, in both +html+ and +xml+ formats:
37
- #
38
- # should_be_restful do |resource|
39
- # resource.parent = :user
40
- #
41
- # resource.create.params = { :title => "first post", :body => 'blah blah blah'}
42
- # resource.update.params = { :title => "changed" }
43
- # end
44
- #
45
- # This generates about 40 tests, all of the format:
46
- # "on GET to :show should assign @user."
47
- # "on GET to :show should not set the flash."
48
- # "on GET to :show should render 'show' template."
49
- # "on GET to :show should respond with success."
50
- # "on GET to :show as xml should assign @user."
51
- # "on GET to :show as xml should have ContentType set to 'application/xml'."
52
- # "on GET to :show as xml should respond with success."
53
- # "on GET to :show as xml should return <user/> as the root element."
54
- # The +resource+ parameter passed into the block is a ResourceOptions object, and
55
- # is used to configure the tests for the details of your resources.
56
- #
57
- def should_be_restful(&blk) # :yields: resource
58
- warn "[DEPRECATION] should_be_restful is deprecated. Please see http://thoughtbot.lighthouseapp.com/projects/5807/tickets/78 for more information."
56
+ def should_be_restful(&blk) # :yields: resource
57
+ warn "[DEPRECATION] should_be_restful is deprecated. Please see http://thoughtbot.lighthouseapp.com/projects/5807/tickets/78 for more information."
59
58
 
60
- resource = ResourceOptions.new
61
- blk.call(resource)
62
- resource.normalize!(self)
59
+ resource = ResourceOptions.new
60
+ blk.call(resource)
61
+ resource.normalize!(self)
63
62
 
64
- resource.formats.each do |format|
65
- resource.actions.each do |action|
66
- if self.respond_to? :"make_#{action}_#{format}_tests"
67
- self.send(:"make_#{action}_#{format}_tests", resource)
68
- else
69
- should "test #{action} #{format}" do
70
- flunk "Test for #{action} as #{format} not implemented"
71
- end
63
+ resource.formats.each do |format|
64
+ resource.actions.each do |action|
65
+ if self.respond_to? :"make_#{action}_#{format}_tests"
66
+ self.send(:"make_#{action}_#{format}_tests", resource)
67
+ else
68
+ should "test #{action} #{format}" do
69
+ flunk "Test for #{action} as #{format} not implemented"
72
70
  end
73
71
  end
74
72
  end
75
73
  end
74
+ end
76
75
 
77
- # :section: Test macros
78
- # Macro that creates a test asserting that the flash contains the given value.
79
- # val can be a String, a Regex, or nil (indicating that the flash should not be set)
80
- #
81
- # Example:
82
- #
83
- # should_set_the_flash_to "Thank you for placing this order."
84
- # should_set_the_flash_to /created/i
85
- # should_set_the_flash_to nil
86
- def should_set_the_flash_to(val)
87
- if val
88
- should "have #{val.inspect} in the flash" do
89
- assert_contains flash.values, val, ", Flash: #{flash.inspect}"
90
- end
91
- else
92
- should "not set the flash" do
93
- assert_equal({}, flash, "Flash was set to:\n#{flash.inspect}")
94
- end
76
+ # :section: Test macros
77
+ # Macro that creates a test asserting that the flash contains the given value.
78
+ # val can be a String, a Regex, or nil (indicating that the flash should not be set)
79
+ #
80
+ # Example:
81
+ #
82
+ # should_set_the_flash_to "Thank you for placing this order."
83
+ # should_set_the_flash_to /created/i
84
+ # should_set_the_flash_to nil
85
+ def should_set_the_flash_to(val)
86
+ if val
87
+ should "have #{val.inspect} in the flash" do
88
+ assert_contains flash.values, val, ", Flash: #{flash.inspect}"
89
+ end
90
+ else
91
+ should "not set the flash" do
92
+ assert_equal({}, flash, "Flash was set to:\n#{flash.inspect}")
95
93
  end
96
94
  end
95
+ end
97
96
 
98
- # Macro that creates a test asserting that the flash is empty. Same as
99
- # @should_set_the_flash_to nil@
100
- def should_not_set_the_flash
101
- should_set_the_flash_to nil
102
- end
97
+ # Macro that creates a test asserting that the flash is empty. Same as
98
+ # @should_set_the_flash_to nil@
99
+ def should_not_set_the_flash
100
+ should_set_the_flash_to nil
101
+ end
103
102
 
104
- # Macro that creates a test asserting that filter_parameter_logging
105
- # is set for the specified keys
106
- #
107
- # Example:
108
- #
109
- # should_filter_params :password, :ssn
110
- def should_filter_params(*keys)
111
- keys.each do |key|
112
- should "filter #{key}" do
113
- assert @controller.respond_to?(:filter_parameters),
114
- "The key #{key} is not filtered"
115
- filtered = @controller.send(:filter_parameters, {key.to_s => key.to_s})
116
- assert_equal '[FILTERED]', filtered[key.to_s],
117
- "The key #{key} is not filtered"
118
- end
103
+ # Macro that creates a test asserting that filter_parameter_logging
104
+ # is set for the specified keys
105
+ #
106
+ # Example:
107
+ #
108
+ # should_filter_params :password, :ssn
109
+ def should_filter_params(*keys)
110
+ keys.each do |key|
111
+ should "filter #{key}" do
112
+ assert @controller.respond_to?(:filter_parameters),
113
+ "The key #{key} is not filtered"
114
+ filtered = @controller.send(:filter_parameters, {key.to_s => key.to_s})
115
+ assert_equal '[FILTERED]', filtered[key.to_s],
116
+ "The key #{key} is not filtered"
119
117
  end
120
118
  end
119
+ end
121
120
 
122
- # Macro that creates a test asserting that the controller assigned to
123
- # each of the named instance variable(s).
124
- #
125
- # Options:
126
- # * <tt>:class</tt> - The expected class of the instance variable being checked.
127
- # * <tt>:equals</tt> - A string which is evaluated and compared for equality with
128
- # the instance variable being checked.
129
- #
130
- # Example:
131
- #
132
- # should_assign_to :user, :posts
133
- # should_assign_to :user, :class => User
134
- # should_assign_to :user, :equals => '@user'
135
- def should_assign_to(*names)
136
- opts = names.extract_options!
137
- names.each do |name|
138
- test_name = "assign @#{name}"
139
- test_name << " as class #{opts[:class]}" if opts[:class]
140
- test_name << " which is equal to #{opts[:equals]}" if opts[:equals]
141
- should test_name do
142
- assigned_value = assigns(name.to_sym)
143
- assert assigned_value, "The action isn't assigning to @#{name}"
144
- assert_kind_of opts[:class], assigned_value if opts[:class]
145
- if opts[:equals]
146
- instantiate_variables_from_assigns do
147
- expected_value = eval(opts[:equals], self.send(:binding), __FILE__, __LINE__)
148
- assert_equal expected_value, assigned_value,
149
- "Instance variable @#{name} expected to be #{expected_value}" +
150
- " but was #{assigned_value}"
151
- end
121
+ # Macro that creates a test asserting that the controller assigned to
122
+ # each of the named instance variable(s).
123
+ #
124
+ # Options:
125
+ # * <tt>:class</tt> - The expected class of the instance variable being checked.
126
+ # * <tt>:equals</tt> - A string which is evaluated and compared for equality with
127
+ # the instance variable being checked.
128
+ #
129
+ # Example:
130
+ #
131
+ # should_assign_to :user, :posts
132
+ # should_assign_to :user, :class => User
133
+ # should_assign_to :user, :equals => '@user'
134
+ def should_assign_to(*names)
135
+ opts = names.extract_options!
136
+ names.each do |name|
137
+ test_name = "assign @#{name}"
138
+ test_name << " as class #{opts[:class]}" if opts[:class]
139
+ test_name << " which is equal to #{opts[:equals]}" if opts[:equals]
140
+ should test_name do
141
+ assigned_value = assigns(name.to_sym)
142
+ assert_not_nil assigned_value, "The action isn't assigning to @#{name}"
143
+ assert_kind_of opts[:class], assigned_value if opts[:class]
144
+ if opts[:equals]
145
+ instantiate_variables_from_assigns do
146
+ expected_value = eval(opts[:equals], self.send(:binding), __FILE__, __LINE__)
147
+ assert_equal expected_value, assigned_value,
148
+ "Instance variable @#{name} expected to be #{expected_value}" +
149
+ " but was #{assigned_value}"
152
150
  end
153
151
  end
154
152
  end
155
153
  end
154
+ end
156
155
 
157
- # Macro that creates a test asserting that the controller did not assign to
158
- # any of the named instance variable(s).
159
- #
160
- # Example:
161
- #
162
- # should_not_assign_to :user, :posts
163
- def should_not_assign_to(*names)
164
- names.each do |name|
165
- should "not assign to @#{name}" do
166
- assert !assigns(name.to_sym), "@#{name} was visible"
167
- end
156
+ # Macro that creates a test asserting that the controller did not assign to
157
+ # any of the named instance variable(s).
158
+ #
159
+ # Example:
160
+ #
161
+ # should_not_assign_to :user, :posts
162
+ def should_not_assign_to(*names)
163
+ names.each do |name|
164
+ should "not assign to @#{name}" do
165
+ assert !assigns(name.to_sym), "@#{name} was visible"
168
166
  end
169
167
  end
168
+ end
170
169
 
171
- # Macro that creates a test asserting that the controller responded with a 'response' status code.
172
- # Example:
173
- #
174
- # should_respond_with :success
175
- def should_respond_with(response)
176
- should "respond with #{response}" do
177
- assert_response response
178
- end
170
+ # Macro that creates a test asserting that the controller responded with a 'response' status code.
171
+ # Example:
172
+ #
173
+ # should_respond_with :success
174
+ def should_respond_with(response)
175
+ should "respond with #{response}" do
176
+ assert_response response
179
177
  end
178
+ end
180
179
 
181
- # Macro that creates a test asserting that the response content type was 'content_type'.
182
- # Example:
183
- #
184
- # should_respond_with_content_type 'application/rss+xml'
185
- # should_respond_with_content_type :rss
186
- # should_respond_with_content_type /rss/
187
- def should_respond_with_content_type(content_type)
188
- should "respond with content type of #{content_type}" do
189
- content_type = Mime::EXTENSION_LOOKUP[content_type.to_s].to_s if content_type.is_a? Symbol
190
- if content_type.is_a? Regexp
191
- assert_match content_type, @response.content_type, "Expected to match #{content_type} but was actually #{@response.content_type}"
192
- else
193
- assert_equal content_type, @response.content_type, "Expected #{content_type} but was actually #{@response.content_type}"
194
- end
180
+ # Macro that creates a test asserting that the response content type was 'content_type'.
181
+ # Example:
182
+ #
183
+ # should_respond_with_content_type 'application/rss+xml'
184
+ # should_respond_with_content_type :rss
185
+ # should_respond_with_content_type /rss/
186
+ def should_respond_with_content_type(content_type)
187
+ should "respond with content type of #{content_type}" do
188
+ content_type = Mime::EXTENSION_LOOKUP[content_type.to_s].to_s if content_type.is_a? Symbol
189
+ if content_type.is_a? Regexp
190
+ assert_match content_type, @response.content_type, "Expected to match #{content_type} but was actually #{@response.content_type}"
191
+ else
192
+ assert_equal content_type, @response.content_type, "Expected #{content_type} but was actually #{@response.content_type}"
195
193
  end
196
194
  end
195
+ end
197
196
 
198
- # Macro that creates a test asserting that a value returned from the session is correct.
199
- # The given string is evaled to produce the resulting redirect path. All of the instance variables
200
- # set by the controller are available to the evaled string.
201
- # Example:
202
- #
203
- # should_return_from_session :user_id, '@user.id'
204
- # should_return_from_session :message, '"Free stuff"'
205
- def should_return_from_session(key, expected)
206
- should "return the correct value from the session for key #{key}" do
207
- instantiate_variables_from_assigns do
208
- expected_value = eval(expected, self.send(:binding), __FILE__, __LINE__)
209
- assert_equal expected_value, session[key], "Expected #{expected_value.inspect} but was #{session[key]}"
210
- end
197
+ # Macro that creates a test asserting that a value returned from the session is correct.
198
+ # The given string is evaled to produce the resulting redirect path. All of the instance variables
199
+ # set by the controller are available to the evaled string.
200
+ # Example:
201
+ #
202
+ # should_return_from_session :user_id, '@user.id'
203
+ # should_return_from_session :message, '"Free stuff"'
204
+ def should_return_from_session(key, expected)
205
+ should "return the correct value from the session for key #{key}" do
206
+ instantiate_variables_from_assigns do
207
+ expected_value = eval(expected, self.send(:binding), __FILE__, __LINE__)
208
+ assert_equal expected_value, session[key], "Expected #{expected_value.inspect} but was #{session[key]}"
211
209
  end
212
210
  end
211
+ end
212
+
213
+ # Macro that creates a test asserting that the controller rendered the given template.
214
+ # Example:
215
+ #
216
+ # should_render_template :new
217
+ def should_render_template(template)
218
+ should "render template #{template.inspect}" do
219
+ assert_template template.to_s
220
+ end
221
+ end
213
222
 
214
- # Macro that creates a test asserting that the controller rendered the given template.
215
- # Example:
216
- #
217
- # should_render_template :new
218
- def should_render_template(template)
219
- should "render template #{template.inspect}" do
220
- assert_template template.to_s
223
+ # Macro that creates a test asserting that the controller rendered with the given layout.
224
+ # Example:
225
+ #
226
+ # should_render_with_layout 'special'
227
+ def should_render_with_layout(expected_layout = 'application')
228
+ if expected_layout
229
+ should "render with #{expected_layout.inspect} layout" do
230
+ response_layout = @response.layout.blank? ? "" : @response.layout.split('/').last
231
+ assert_equal expected_layout.to_s,
232
+ response_layout,
233
+ "Expected to render with layout #{expected_layout} but was rendered with #{response_layout}"
234
+ end
235
+ else
236
+ should "render without layout" do
237
+ assert_nil @response.layout,
238
+ "Expected no layout, but was rendered using #{@response.layout}"
221
239
  end
222
240
  end
241
+ end
223
242
 
224
- # Macro that creates a test asserting that the controller rendered with the given layout.
225
- # Example:
226
- #
227
- # should_render_with_layout 'special'
228
- def should_render_with_layout(expected_layout = 'application')
229
- if expected_layout
230
- should "render with #{expected_layout.inspect} layout" do
231
- response_layout = @response.layout.blank? ? "" : @response.layout.split('/').last
232
- assert_equal expected_layout.to_s,
233
- response_layout,
234
- "Expected to render with layout #{expected_layout} but was rendered with #{response_layout}"
235
- end
236
- else
237
- should "render without layout" do
238
- assert_nil @response.layout,
239
- "Expected no layout, but was rendered using #{@response.layout}"
240
- end
243
+ # Macro that creates a test asserting that the controller rendered without a layout.
244
+ # Same as @should_render_with_layout false@
245
+ def should_render_without_layout
246
+ should_render_with_layout nil
247
+ end
248
+
249
+ # Macro that creates a test asserting that the controller returned a redirect to the given path.
250
+ # The given string is evaled to produce the resulting redirect path. All of the instance variables
251
+ # set by the controller are available to the evaled string.
252
+ # Example:
253
+ #
254
+ # should_redirect_to '"/"'
255
+ # should_redirect_to "user_url(@user)"
256
+ # should_redirect_to "users_url"
257
+ def should_redirect_to(url)
258
+ should "redirect to #{url.inspect}" do
259
+ instantiate_variables_from_assigns do
260
+ assert_redirected_to eval(url, self.send(:binding), __FILE__, __LINE__)
241
261
  end
242
262
  end
263
+ end
243
264
 
244
- # Macro that creates a test asserting that the controller rendered without a layout.
245
- # Same as @should_render_with_layout false@
246
- def should_render_without_layout
247
- should_render_with_layout nil
265
+ # Macro that creates a test asserting that the rendered view contains a <form> element.
266
+ def should_render_a_form
267
+ should "display a form" do
268
+ assert_select "form", true, "The template doesn't contain a <form> element"
248
269
  end
270
+ end
249
271
 
250
- # Macro that creates a test asserting that the controller returned a redirect to the given path.
251
- # The given string is evaled to produce the resulting redirect path. All of the instance variables
252
- # set by the controller are available to the evaled string.
253
- # Example:
254
- #
255
- # should_redirect_to '"/"'
256
- # should_redirect_to "user_url(@user)"
257
- # should_redirect_to "users_url"
258
- def should_redirect_to(url)
259
- should "redirect to #{url.inspect}" do
260
- instantiate_variables_from_assigns do
261
- assert_redirected_to eval(url, self.send(:binding), __FILE__, __LINE__)
272
+ # Macro that creates a test asserting that the rendered view contains the selected metatags.
273
+ # Values can be string or Regexps.
274
+ # Example:
275
+ #
276
+ # should_render_page_with_metadata :description => "Description of this page", :keywords => /post/
277
+ #
278
+ # You can also use this method to test the rendered views title.
279
+ #
280
+ # Example:
281
+ # should_render_page_with_metadata :title => /index/
282
+ def should_render_page_with_metadata(options)
283
+ options.each do |key, value|
284
+ should "have metatag #{key}" do
285
+ if key.to_sym == :title
286
+ assert_select "title", value
287
+ else
288
+ assert_select "meta[name=?][content#{"*" if value.is_a?(Regexp)}=?]", key, value
262
289
  end
263
290
  end
264
291
  end
292
+ end
265
293
 
266
- # Macro that creates a test asserting that the rendered view contains a <form> element.
267
- def should_render_a_form
268
- should "display a form" do
269
- assert_select "form", true, "The template doesn't contain a <form> element"
270
- end
294
+ # Macro that creates a routing test. It tries to use the given HTTP
295
+ # +method+ on the given +path+, and asserts that it routes to the
296
+ # given +options+.
297
+ #
298
+ # If you don't specify a :controller, it will try to guess the controller
299
+ # based on the current test.
300
+ #
301
+ # +to_param+ is called on the +options+ given.
302
+ #
303
+ # Examples:
304
+ #
305
+ # should_route :get, "/posts", :controller => :posts, :action => :index
306
+ # should_route :get, "/posts/new", :action => :new
307
+ # should_route :post, "/posts", :action => :create
308
+ # should_route :get, "/posts/1", :action => :show, :id => 1
309
+ # should_route :edit, "/posts/1", :action => :show, :id => 1
310
+ # should_route :put, "/posts/1", :action => :update, :id => 1
311
+ # should_route :delete, "/posts/1", :action => :destroy, :id => 1
312
+ # should_route :get, "/users/1/posts/1",
313
+ # :action => :show, :id => 1, :user_id => 1
314
+ #
315
+ def should_route(method, path, options)
316
+ unless options[:controller]
317
+ options[:controller] = self.name.gsub(/ControllerTest$/, '').tableize
271
318
  end
319
+ options[:controller] = options[:controller].to_s
320
+ options[:action] = options[:action].to_s
272
321
 
273
- # Macro that creates a routing test. It tries to use the given HTTP
274
- # +method+ on the given +path+, and asserts that it routes to the
275
- # given +options+.
276
- #
277
- # If you don't specify a :controller, it will try to guess the controller
278
- # based on the current test.
279
- #
280
- # +to_param+ is called on the +options+ given.
281
- #
282
- # Examples:
283
- #
284
- # should_route :get, "/posts", :controller => :posts, :action => :index
285
- # should_route :get, "/posts/new", :action => :new
286
- # should_route :post, "/posts", :action => :create
287
- # should_route :get, "/posts/1", :action => :show, :id => 1
288
- # should_route :edit, "/posts/1", :action => :show, :id => 1
289
- # should_route :put, "/posts/1", :action => :update, :id => 1
290
- # should_route :delete, "/posts/1", :action => :destroy, :id => 1
291
- # should_route :get, "/users/1/posts/1",
292
- # :action => :show, :id => 1, :user_id => 1
293
- #
294
- def should_route(method, path, options)
295
- unless options[:controller]
296
- options[:controller] = self.name.gsub(/ControllerTest$/, '').tableize
297
- end
298
- options[:controller] = options[:controller].to_s
299
- options[:action] = options[:action].to_s
300
-
301
- populated_path = path.dup
302
- options.each do |key, value|
303
- options[key] = value.to_param if value.respond_to? :to_param
304
- populated_path.gsub!(key.inspect, value.to_s)
305
- end
322
+ populated_path = path.dup
323
+ options.each do |key, value|
324
+ options[key] = value.to_param if value.respond_to? :to_param
325
+ populated_path.gsub!(key.inspect, value.to_s)
326
+ end
306
327
 
307
- should_name = "route #{method.to_s.upcase} #{populated_path} to/from #{options.inspect}"
328
+ should_name = "route #{method.to_s.upcase} #{populated_path} to/from #{options.inspect}"
308
329
 
309
- should should_name do
310
- assert_routing({:method => method, :path => populated_path}, options)
311
- end
330
+ should should_name do
331
+ assert_routing({:method => method, :path => populated_path}, options)
312
332
  end
313
333
  end
314
334
  end