shoulda 2.9.1 → 2.9.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. data/README.rdoc +27 -5
  2. data/Rakefile +2 -2
  3. data/lib/shoulda.rb +1 -1
  4. data/lib/shoulda/{controller.rb → action_controller.rb} +6 -8
  5. data/lib/shoulda/{controller → action_controller}/helpers.rb +1 -16
  6. data/lib/shoulda/action_controller/macros.rb +277 -0
  7. data/lib/shoulda/action_controller/matchers.rb +37 -0
  8. data/lib/shoulda/action_controller/matchers/assign_to_matcher.rb +109 -0
  9. data/lib/shoulda/action_controller/matchers/filter_param_matcher.rb +57 -0
  10. data/lib/shoulda/action_controller/matchers/render_with_layout_matcher.rb +81 -0
  11. data/lib/shoulda/action_controller/matchers/respond_with_content_type_matcher.rb +70 -0
  12. data/lib/shoulda/action_controller/matchers/respond_with_matcher.rb +81 -0
  13. data/lib/shoulda/action_controller/matchers/route_matcher.rb +93 -0
  14. data/lib/shoulda/action_controller/matchers/set_session_matcher.rb +83 -0
  15. data/lib/shoulda/action_controller/matchers/set_the_flash_matcher.rb +85 -0
  16. data/lib/shoulda/action_view.rb +10 -0
  17. data/lib/shoulda/action_view/macros.rb +56 -0
  18. data/lib/shoulda/active_record/macros.rb +8 -13
  19. data/lib/shoulda/active_record/matchers/validate_uniqueness_of_matcher.rb +1 -1
  20. data/lib/shoulda/rails.rb +4 -3
  21. data/lib/shoulda/rspec.rb +7 -5
  22. data/test/functional/posts_controller_test.rb +28 -22
  23. data/test/functional/users_controller_test.rb +0 -19
  24. data/test/matchers/{allow_mass_assignment_of_matcher_test.rb → active_record/allow_mass_assignment_of_matcher_test.rb} +1 -1
  25. data/test/matchers/{allow_value_matcher_test.rb → active_record/allow_value_matcher_test.rb} +1 -1
  26. data/test/matchers/{association_matcher_test.rb → active_record/association_matcher_test.rb} +1 -1
  27. data/test/matchers/{ensure_inclusion_of_matcher_test.rb → active_record/ensure_inclusion_of_matcher_test.rb} +1 -1
  28. data/test/matchers/{ensure_length_of_matcher_test.rb → active_record/ensure_length_of_matcher_test.rb} +1 -1
  29. data/test/matchers/{have_db_column_matcher_test.rb → active_record/have_db_column_matcher_test.rb} +1 -1
  30. data/test/matchers/{have_index_matcher_test.rb → active_record/have_index_matcher_test.rb} +1 -1
  31. data/test/matchers/{have_named_scope_matcher_test.rb → active_record/have_named_scope_matcher_test.rb} +1 -1
  32. data/test/matchers/{have_readonly_attributes_matcher_test.rb → active_record/have_readonly_attributes_matcher_test.rb} +1 -1
  33. data/test/matchers/{validate_acceptance_of_matcher_test.rb → active_record/validate_acceptance_of_matcher_test.rb} +1 -1
  34. data/test/matchers/{validate_numericality_of_matcher_test.rb → active_record/validate_numericality_of_matcher_test.rb} +1 -1
  35. data/test/matchers/{validate_presence_of_matcher_test.rb → active_record/validate_presence_of_matcher_test.rb} +1 -1
  36. data/test/matchers/{validate_uniqueness_of_matcher_test.rb → active_record/validate_uniqueness_of_matcher_test.rb} +8 -2
  37. data/test/matchers/controller/assign_to_matcher_test.rb +35 -0
  38. data/test/matchers/controller/filter_param_matcher_test.rb +32 -0
  39. data/test/matchers/controller/render_with_layout_matcher_test.rb +33 -0
  40. data/test/matchers/controller/respond_with_content_type_matcher_test.rb +27 -0
  41. data/test/matchers/controller/respond_with_matcher_test.rb +106 -0
  42. data/test/matchers/controller/route_matcher_test.rb +58 -0
  43. data/test/matchers/controller/set_session_matcher_test.rb +27 -0
  44. data/test/matchers/controller/set_the_flash_matcher.rb +41 -0
  45. data/test/model_builder.rb +47 -2
  46. data/test/rails_root/app/models/user.rb +2 -1
  47. data/test/rails_root/config/environment.rb +1 -1
  48. data/test/rspec_test.rb +207 -0
  49. data/test/unit/user_test.rb +10 -1
  50. metadata +38 -22
  51. data/lib/shoulda/controller/formats/html.rb +0 -199
  52. data/lib/shoulda/controller/formats/xml.rb +0 -168
  53. data/lib/shoulda/controller/macros.rb +0 -336
  54. data/lib/shoulda/controller/resource_options.rb +0 -233
@@ -2,7 +2,7 @@
2
2
 
3
3
  Shoulda makes it easy to write elegant, understandable, and maintainable tests. Shoulda consists of test macros, assertions, and helpers added on to the Test::Unit framework. It's fully compatible with your existing tests, and requires no retooling to use.
4
4
 
5
- Helpers:: #context and #should give you rSpec like test blocks.
5
+ Helpers:: #context and #should give you RSpec like test blocks.
6
6
  In addition, you get nested contexts and a much more readable syntax.
7
7
  Macros:: Generate hundreds of lines of Controller and ActiveRecord tests with these powerful macros.
8
8
  They get you started quickly, and can help you ensure that your application is conforming to best practices.
@@ -54,10 +54,10 @@ Quick macro tests for your ActiveRecord associations and validations:
54
54
  should_belong_to :user
55
55
  should_have_many :tags, :through => :taggings
56
56
 
57
- should_require_unique_attributes :title
57
+ should_validate_uniqueness_of :title
58
58
  should_validate_presence_of :body, :message => /wtf/
59
59
  should_validate_presence_of :title
60
- should_only_allow_numeric_values_for :user_id
60
+ should_validate_numericality_of :user_id
61
61
  end
62
62
 
63
63
  class UserTest < Test::Unit::TestCase
@@ -67,7 +67,7 @@ Quick macro tests for your ActiveRecord associations and validations:
67
67
  should_allow_values_for :email, "a@b.com", "asdf@asdf.com"
68
68
  should_ensure_length_in_range :email, 1..100
69
69
  should_ensure_value_in_range :age, 1..100
70
- should_protect_attributes :password
70
+ should_not_allow_mass_assignment_of :password
71
71
  end
72
72
 
73
73
  Makes TDD so much easier.
@@ -111,7 +111,7 @@ Any *.rb file under RAILS_ROOT/test/shoulda_macros/ or vendor/(plugins|gems)/gem
111
111
  end
112
112
  end
113
113
 
114
- = Rails Installation
114
+ = Rails Installation (Test::Unit)
115
115
 
116
116
  === As a Gem
117
117
 
@@ -138,6 +138,28 @@ Use this if you prefer the idea of being able to easily switch between using edg
138
138
 
139
139
  $ git submodule add git://github.com/thoughtbot/shoulda.git vendor/plugins/shoulda
140
140
 
141
+ = Rails Installation (RSpec)
142
+
143
+ If you're using Shoulda with RSpec, we recommend that you add config.gem lines
144
+ for RSpec and Shoulda in your config/environment/test.rb file, but do not ask
145
+ Rails to load the RSpec and Shoulda libraries:
146
+
147
+ config.gem 'rspec', :lib => false
148
+ config.gem 'rspec-rails', :lib => false
149
+ config.gem 'thoughtbot-shoulda',
150
+ :lib => false,
151
+ :source => 'http://gems.github.com'
152
+
153
+ Then require shoulda from your spec/spec_helper.rb file, before Spec::Runner is
154
+ configured:
155
+
156
+ # requires for RSpec
157
+ require 'shoulda'
158
+ Spec::Runner.configure do |config|
159
+ # ...
160
+
161
+ You should not need to require anything besides the top-level shoulda library.
162
+
141
163
  = Credits
142
164
 
143
165
  Shoulda is maintained by {Tammer Saleh}[mailto:tsaleh@thoughtbot.com], and is funded by Thoughtbot[http://www.thoughtbot.com], inc.
data/Rakefile CHANGED
@@ -18,7 +18,7 @@ end
18
18
  Rake::RDocTask.new { |rdoc|
19
19
  rdoc.rdoc_dir = 'doc'
20
20
  rdoc.title = "Shoulda -- Making tests easy on the fingers and eyes"
21
- rdoc.options << '--line-numbers' << '--inline-source'
21
+ rdoc.options << '--line-numbers'
22
22
  rdoc.template = "#{ENV['template']}.rb" if ENV['template']
23
23
  rdoc.rdoc_files.include('README.rdoc', 'CONTRIBUTION_GUIDELINES.rdoc', 'lib/**/*.rb')
24
24
  }
@@ -50,7 +50,7 @@ spec = Gem::Specification.new do |s|
50
50
 
51
51
  s.has_rdoc = true
52
52
  s.extra_rdoc_files = ["README.rdoc", "CONTRIBUTION_GUIDELINES.rdoc"]
53
- s.rdoc_options = ["--line-numbers", "--inline-source", "--main", "README.rdoc"]
53
+ s.rdoc_options = ["--line-numbers", "--main", "README.rdoc"]
54
54
 
55
55
  s.authors = ["Tammer Saleh"]
56
56
  s.email = "tsaleh@thoughtbot.com"
@@ -1,5 +1,5 @@
1
1
  module Shoulda
2
- VERSION = "2.9.1"
2
+ VERSION = "2.9.2"
3
3
  end
4
4
 
5
5
  if defined? Spec
@@ -1,16 +1,14 @@
1
1
  require 'shoulda'
2
- require 'shoulda/controller/helpers'
3
- require 'shoulda/controller/resource_options'
4
- require 'shoulda/controller/macros'
2
+ require 'shoulda/action_controller/helpers'
3
+ require 'shoulda/action_controller/matchers'
4
+ require 'shoulda/action_controller/macros'
5
5
 
6
6
  module Test # :nodoc: all
7
7
  module Unit
8
8
  class TestCase
9
- extend Shoulda::Controller::Macros
10
- include Shoulda::Controller::Helpers
11
- Shoulda::Controller::VALID_FORMATS.each do |format|
12
- include "Shoulda::Controller::#{format.to_s.upcase}".constantize
13
- end
9
+ include Shoulda::ActionController::Matchers
10
+ include Shoulda::ActionController::Helpers
11
+ extend Shoulda::ActionController::Macros
14
12
  end
15
13
  end
16
14
  end
@@ -1,5 +1,5 @@
1
1
  module Shoulda # :nodoc:
2
- module Controller # :nodoc:
2
+ module ActionController # :nodoc:
3
3
  module Helpers # :nodoc:
4
4
  private # :enddoc:
5
5
 
@@ -42,21 +42,6 @@ module Shoulda # :nodoc:
42
42
  instance_variable_set("@#{name}", old[name])
43
43
  end
44
44
  end
45
-
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")
49
- end
50
- end
51
-
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)
57
-
58
- { :"#{parent_name}_id" => parent.to_param }.merge(make_parent_params(resource, parent, parent_names))
59
- end
60
45
  end
61
46
  end
62
47
  end
@@ -0,0 +1,277 @@
1
+ module Shoulda # :nodoc:
2
+ module ActionController # :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
+ module Macros
25
+ include Matchers
26
+
27
+ # Macro that creates a test asserting that the flash contains the given value.
28
+ # val can be a String, a Regex, or nil (indicating that the flash should not be set)
29
+ #
30
+ # Example:
31
+ #
32
+ # should_set_the_flash_to "Thank you for placing this order."
33
+ # should_set_the_flash_to /created/i
34
+ # should_set_the_flash_to nil
35
+ def should_set_the_flash_to(val)
36
+ matcher = set_the_flash.to(val)
37
+ if val
38
+ should matcher.description do
39
+ assert_accepts matcher, @controller
40
+ end
41
+ else
42
+ should "not #{matcher.description}" do
43
+ assert_rejects matcher, @controller
44
+ end
45
+ end
46
+ end
47
+
48
+ # Macro that creates a test asserting that the flash is empty. Same as
49
+ # @should_set_the_flash_to nil@
50
+ def should_not_set_the_flash
51
+ should_set_the_flash_to nil
52
+ end
53
+
54
+ # Macro that creates a test asserting that filter_parameter_logging
55
+ # is set for the specified keys
56
+ #
57
+ # Example:
58
+ #
59
+ # should_filter_params :password, :ssn
60
+ def should_filter_params(*keys)
61
+ keys.each do |key|
62
+ matcher = filter_param(key)
63
+ should matcher.description do
64
+ assert_accepts matcher, @controller
65
+ end
66
+ end
67
+ end
68
+
69
+ # Macro that creates a test asserting that the controller assigned to
70
+ # each of the named instance variable(s).
71
+ #
72
+ # Options:
73
+ # * <tt>:class</tt> - The expected class of the instance variable being checked.
74
+ # * <tt>:equals</tt> - A string which is evaluated and compared for equality with
75
+ # the instance variable being checked.
76
+ #
77
+ # Example:
78
+ #
79
+ # should_assign_to :user, :posts
80
+ # should_assign_to :user, :class => User
81
+ # should_assign_to(:user) { @user }
82
+ def should_assign_to(*names, &block)
83
+ opts = names.extract_options!
84
+ if opts[:equals]
85
+ warn "[DEPRECATION] should_assign_to :var, :equals => 'val' " <<
86
+ "is deprecated. Use should_assign_to(:var) { 'val' } instead."
87
+ end
88
+ names.each do |name|
89
+ matcher = assign_to(name).with_kind_of(opts[:class])
90
+ test_name = matcher.description
91
+ test_name << " which is equal to #{opts[:equals]}" if opts[:equals]
92
+ should test_name do
93
+ if opts[:equals]
94
+ instantiate_variables_from_assigns do
95
+ expected_value = eval(opts[:equals],
96
+ self.send(:binding),
97
+ __FILE__,
98
+ __LINE__)
99
+ matcher = matcher.with(expected_value)
100
+ end
101
+ elsif block
102
+ expected_value = instance_eval(&block)
103
+ matcher = matcher.with(expected_value)
104
+ end
105
+
106
+ assert_accepts matcher, @controller
107
+ end
108
+ end
109
+ end
110
+
111
+ # Macro that creates a test asserting that the controller did not assign to
112
+ # any of the named instance variable(s).
113
+ #
114
+ # Example:
115
+ #
116
+ # should_not_assign_to :user, :posts
117
+ def should_not_assign_to(*names)
118
+ names.each do |name|
119
+ matcher = assign_to(name)
120
+ should "not #{matcher.description}" do
121
+ assert_rejects matcher, @controller
122
+ end
123
+ end
124
+ end
125
+
126
+ # Macro that creates a test asserting that the controller responded with a 'response' status code.
127
+ # Example:
128
+ #
129
+ # should_respond_with :success
130
+ def should_respond_with(response)
131
+ should "respond with #{response}" do
132
+ matcher = respond_with(response)
133
+ assert_accepts matcher, @controller
134
+ end
135
+ end
136
+
137
+ # Macro that creates a test asserting that the response content type was 'content_type'.
138
+ # Example:
139
+ #
140
+ # should_respond_with_content_type 'application/rss+xml'
141
+ # should_respond_with_content_type :rss
142
+ # should_respond_with_content_type /rss/
143
+ def should_respond_with_content_type(content_type)
144
+ should "respond with content type of #{content_type}" do
145
+ matcher = respond_with_content_type(content_type)
146
+ assert_accepts matcher, @controller
147
+ end
148
+ end
149
+
150
+ # Macro that creates a test asserting that a value returned from the session is correct.
151
+ # The given string is evaled to produce the resulting redirect path. All of the instance variables
152
+ # set by the controller are available to the evaled string.
153
+ # Example:
154
+ #
155
+ # should_set_session(:user_id) { '@user.id' }
156
+ # should_set_session(:message) { "Free stuff" }
157
+ def should_set_session(key, expected = nil, &block)
158
+ matcher = set_session(key)
159
+ if expected
160
+ warn "[DEPRECATION] should_set_session :key, 'val' is deprecated. " <<
161
+ "Use should_set_session(:key) { 'val' } instead."
162
+ end
163
+ should matcher.description do
164
+ if expected
165
+ instantiate_variables_from_assigns do
166
+ expected_value = eval(expected,
167
+ self.send(:binding),
168
+ __FILE__,
169
+ __LINE__)
170
+ matcher = matcher.to(expected_value)
171
+ end
172
+ else
173
+ expected_value = instance_eval(&block)
174
+ matcher = matcher.to(expected_value)
175
+ end
176
+ assert_accepts matcher, @controller
177
+ end
178
+ end
179
+
180
+ # Deprecated. See should_set_session
181
+ def should_return_from_session(key, expected)
182
+ warn "[DEPRECATION] should_require_attributes is deprecated. " <<
183
+ "Use should_set_session instead."
184
+ should_set_session(key, expected)
185
+ end
186
+
187
+ # Macro that creates a test asserting that the controller rendered the given template.
188
+ # Example:
189
+ #
190
+ # should_render_template :new
191
+ def should_render_template(template)
192
+ should "render template #{template.inspect}" do
193
+ assert_template template.to_s
194
+ end
195
+ end
196
+
197
+ # Macro that creates a test asserting that the controller rendered with the given layout.
198
+ # Example:
199
+ #
200
+ # should_render_with_layout 'special'
201
+ def should_render_with_layout(expected_layout = 'application')
202
+ matcher = render_with_layout(expected_layout)
203
+ if expected_layout
204
+ should matcher.description do
205
+ assert_accepts matcher, @controller
206
+ end
207
+ else
208
+ should "render without layout" do
209
+ assert_rejects matcher, @controller
210
+ end
211
+ end
212
+ end
213
+
214
+ # Macro that creates a test asserting that the controller rendered without a layout.
215
+ # Same as @should_render_with_layout false@
216
+ def should_render_without_layout
217
+ should_render_with_layout nil
218
+ end
219
+
220
+ # Macro that creates a test asserting that the controller returned a redirect to the given path.
221
+ # The given string is evaled to produce the resulting redirect path. All of the instance variables
222
+ # set by the controller are available to the evaled string.
223
+ # Example:
224
+ #
225
+ # should_redirect_to("the user's profile") { user_url(@user) }
226
+ def should_redirect_to(description, &block)
227
+ unless block
228
+ warn "[DEPRECATION] should_redirect_to without a block is " <<
229
+ "deprecated. Use should_redirect_to('somewhere') { } instead."
230
+ end
231
+ should "redirect to #{description}" do
232
+ if block
233
+ url = instance_eval(&block)
234
+ else
235
+ instantiate_variables_from_assigns do
236
+ url = eval(description, self.send(:binding), __FILE__, __LINE__)
237
+ end
238
+ end
239
+ assert_redirected_to url
240
+ end
241
+ end
242
+
243
+ # Macro that creates a routing test. It tries to use the given HTTP
244
+ # +method+ on the given +path+, and asserts that it routes to the
245
+ # given +options+.
246
+ #
247
+ # If you don't specify a :controller, it will try to guess the controller
248
+ # based on the current test.
249
+ #
250
+ # +to_param+ is called on the +options+ given.
251
+ #
252
+ # Examples:
253
+ #
254
+ # should_route :get, "/posts", :controller => :posts, :action => :index
255
+ # should_route :get, "/posts/new", :action => :new
256
+ # should_route :post, "/posts", :action => :create
257
+ # should_route :get, "/posts/1", :action => :show, :id => 1
258
+ # should_route :edit, "/posts/1", :action => :show, :id => 1
259
+ # should_route :put, "/posts/1", :action => :update, :id => 1
260
+ # should_route :delete, "/posts/1", :action => :destroy, :id => 1
261
+ # should_route :get, "/users/1/posts/1",
262
+ # :action => :show, :id => 1, :user_id => 1
263
+ #
264
+ def should_route(method, path, options)
265
+ unless options[:controller]
266
+ options[:controller] = self.name.gsub(/ControllerTest$/, '').tableize
267
+ end
268
+
269
+ matcher = route(method, path).to(options)
270
+
271
+ should matcher.description do
272
+ assert_accepts matcher.in_context(self), self
273
+ end
274
+ end
275
+ end
276
+ end
277
+ end
@@ -0,0 +1,37 @@
1
+ require 'shoulda/action_controller/matchers/assign_to_matcher'
2
+ require 'shoulda/action_controller/matchers/filter_param_matcher'
3
+ require 'shoulda/action_controller/matchers/set_the_flash_matcher'
4
+ require 'shoulda/action_controller/matchers/render_with_layout_matcher'
5
+ require 'shoulda/action_controller/matchers/respond_with_matcher'
6
+ require 'shoulda/action_controller/matchers/respond_with_content_type_matcher'
7
+ require 'shoulda/action_controller/matchers/set_session_matcher'
8
+ require 'shoulda/action_controller/matchers/route_matcher'
9
+
10
+ module Shoulda # :nodoc:
11
+ module ActionController # :nodoc:
12
+
13
+ # By using the macro helpers you can quickly and easily create concise and
14
+ # easy to read test suites.
15
+ #
16
+ # This code segment:
17
+ #
18
+ # describe UsersController, "on GET to show with a valid id" do
19
+ # before(:each) do
20
+ # get :show, :id => User.first.to_param
21
+ # end
22
+ #
23
+ # it { should assign_to(:user) }
24
+ # it { should respond_with(:success) }
25
+ # it { should render_template(:show) }
26
+ # it { should not_set_the_flash) }
27
+ #
28
+ # it "should do something else really cool" do
29
+ # assigns[:user].id.should == 1
30
+ # end
31
+ # end
32
+ #
33
+ # Would produce 5 tests for the show action
34
+ module Matchers
35
+ end
36
+ end
37
+ end