thoughtbot-shoulda 2.9.1 → 2.9.2

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 (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 +43 -24
  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
data/README.rdoc CHANGED
@@ -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"
data/lib/shoulda.rb CHANGED
@@ -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