thoughtbot-shoulda 2.10.1 → 2.10.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (83) hide show
  1. data/CONTRIBUTION_GUIDELINES.rdoc +4 -6
  2. data/README.rdoc +14 -12
  3. data/lib/shoulda.rb +1 -1
  4. data/lib/shoulda/action_controller.rb +0 -2
  5. data/lib/shoulda/action_controller/macros.rb +38 -75
  6. data/lib/shoulda/action_controller/matchers/respond_with_content_type_matcher.rb +4 -0
  7. data/lib/shoulda/action_controller/matchers/set_session_matcher.rb +1 -1
  8. data/lib/shoulda/action_view/macros.rb +6 -1
  9. data/lib/shoulda/active_record/assertions.rb +4 -4
  10. data/lib/shoulda/active_record/helpers.rb +0 -13
  11. data/lib/shoulda/active_record/macros.rb +50 -127
  12. data/lib/shoulda/active_record/matchers.rb +2 -1
  13. data/lib/shoulda/active_record/matchers/allow_mass_assignment_of_matcher.rb +1 -1
  14. data/lib/shoulda/active_record/matchers/allow_value_matcher.rb +5 -5
  15. data/lib/shoulda/active_record/matchers/association_matcher.rb +3 -3
  16. data/lib/shoulda/active_record/matchers/{have_index_matcher.rb → have_db_index_matcher.rb} +15 -8
  17. data/lib/shoulda/active_record/matchers/have_named_scope_matcher.rb +3 -0
  18. data/lib/shoulda/active_record/matchers/validate_format_of_matcher.rb +67 -0
  19. data/lib/shoulda/active_record/matchers/validation_matcher.rb +1 -0
  20. data/lib/shoulda/assertions.rb +18 -6
  21. data/lib/shoulda/context.rb +99 -1
  22. data/lib/shoulda/macros.rb +83 -23
  23. data/lib/shoulda/private_helpers.rb +1 -8
  24. data/lib/shoulda/test_unit.rb +3 -0
  25. data/test/fail_macros.rb +6 -1
  26. data/test/functional/posts_controller_test.rb +17 -21
  27. data/test/functional/users_controller_test.rb +1 -1
  28. data/test/matchers/active_record/allow_mass_assignment_of_matcher_test.rb +1 -1
  29. data/test/matchers/active_record/allow_value_matcher_test.rb +24 -1
  30. data/test/matchers/active_record/association_matcher_test.rb +8 -3
  31. data/test/matchers/active_record/ensure_inclusion_of_matcher_test.rb +1 -1
  32. data/test/matchers/active_record/ensure_length_of_matcher_test.rb +1 -1
  33. data/test/matchers/active_record/have_db_column_matcher_test.rb +1 -1
  34. data/test/matchers/active_record/{have_index_matcher_test.rb → have_db_index_matcher_test.rb} +24 -7
  35. data/test/matchers/active_record/have_named_scope_matcher_test.rb +1 -1
  36. data/test/matchers/active_record/have_readonly_attributes_matcher_test.rb +1 -1
  37. data/test/matchers/active_record/validate_acceptance_of_matcher_test.rb +1 -1
  38. data/test/matchers/active_record/validate_format_of_matcher_test.rb +39 -0
  39. data/test/matchers/active_record/validate_numericality_of_matcher_test.rb +1 -1
  40. data/test/matchers/active_record/validate_presence_of_matcher_test.rb +1 -1
  41. data/test/matchers/active_record/validate_uniqueness_of_matcher_test.rb +1 -1
  42. data/test/matchers/controller/assign_to_matcher_test.rb +1 -1
  43. data/test/matchers/controller/filter_param_matcher_test.rb +1 -1
  44. data/test/matchers/controller/render_with_layout_matcher_test.rb +1 -1
  45. data/test/matchers/controller/respond_with_content_type_matcher_test.rb +12 -7
  46. data/test/matchers/controller/respond_with_matcher_test.rb +1 -1
  47. data/test/matchers/controller/route_matcher_test.rb +1 -1
  48. data/test/matchers/controller/set_session_matcher_test.rb +9 -2
  49. data/test/matchers/controller/set_the_flash_matcher.rb +1 -1
  50. data/test/model_builder.rb +1 -1
  51. data/test/other/autoload_macro_test.rb +1 -1
  52. data/test/other/context_test.rb +45 -1
  53. data/test/other/convert_to_should_syntax_test.rb +3 -3
  54. data/test/other/helpers_test.rb +102 -3
  55. data/test/other/private_helpers_test.rb +6 -8
  56. data/test/other/should_test.rb +8 -3
  57. data/test/rails_root/app/controllers/{application.rb → application_controller.rb} +0 -0
  58. data/test/rails_root/app/controllers/posts_controller.rb +1 -0
  59. data/test/rails_root/app/models/pets/cat.rb +7 -0
  60. data/test/rails_root/app/models/profile.rb +2 -0
  61. data/test/rails_root/app/models/registration.rb +2 -0
  62. data/test/rails_root/app/models/user.rb +3 -0
  63. data/test/rails_root/config/boot.rb +6 -5
  64. data/test/rails_root/config/environment.rb +5 -1
  65. data/test/rails_root/db/migrate/20090506203502_create_profiles.rb +12 -0
  66. data/test/rails_root/db/migrate/20090506203536_create_registrations.rb +14 -0
  67. data/test/rails_root/db/migrate/20090513104502_create_cats.rb +12 -0
  68. data/test/rails_root/test/shoulda_macros/custom_macro.rb +1 -1
  69. data/test/rails_root/vendor/gems/gem_with_macro-0.0.1/shoulda_macros/gem_macro.rb +1 -1
  70. data/test/rails_root/vendor/plugins/plugin_with_macro/shoulda_macros/plugin_macro.rb +1 -1
  71. data/test/rspec_test.rb +1 -1
  72. data/test/test_helper.rb +3 -10
  73. data/test/unit/address_test.rb +2 -2
  74. data/test/unit/cat_test.rb +7 -0
  75. data/test/unit/dog_test.rb +2 -3
  76. data/test/unit/flea_test.rb +1 -1
  77. data/test/unit/post_test.rb +2 -2
  78. data/test/unit/product_test.rb +2 -6
  79. data/test/unit/tag_test.rb +2 -2
  80. data/test/unit/tagging_test.rb +1 -1
  81. data/test/unit/user_test.rb +18 -8
  82. metadata +16 -10
  83. data/lib/shoulda/action_controller/helpers.rb +0 -47
@@ -1,6 +1,6 @@
1
1
  require File.join(File.dirname(__FILE__), '..', '..', 'test_helper')
2
2
 
3
- class RespondWithMatcherTest < Test::Unit::TestCase # :nodoc:
3
+ class RespondWithMatcherTest < ActionController::TestCase # :nodoc:
4
4
 
5
5
  context "a controller responding with success" do
6
6
  setup do
@@ -1,6 +1,6 @@
1
1
  require File.join(File.dirname(__FILE__), '..', '..', 'test_helper')
2
2
 
3
- class RouteToMatcherTest < Test::Unit::TestCase # :nodoc:
3
+ class RouteToMatcherTest < ActionController::TestCase # :nodoc:
4
4
 
5
5
  context "given a controller with a defined route" do
6
6
  setup do
@@ -1,10 +1,13 @@
1
1
  require File.join(File.dirname(__FILE__), '..', '..', 'test_helper')
2
2
 
3
- class SetSessionMatcherTest < Test::Unit::TestCase # :nodoc:
3
+ class SetSessionMatcherTest < ActionController::TestCase # :nodoc:
4
4
 
5
5
  context "a controller that sets a session variable" do
6
6
  setup do
7
- @controller = build_response { session[:var] = 'value' }
7
+ @controller = build_response do
8
+ session[:var] = 'value'
9
+ session[:false_var] = false
10
+ end
8
11
  end
9
12
 
10
13
  should "accept assigning to that variable" do
@@ -26,6 +29,10 @@ class SetSessionMatcherTest < Test::Unit::TestCase # :nodoc:
26
29
  should "accept assigning nil to another variable" do
27
30
  assert_accepts set_session(:other).to(nil), @controller
28
31
  end
32
+
33
+ should "accept assigning false to that variable" do
34
+ assert_accepts set_session(:false_var).to(false), @controller
35
+ end
29
36
  end
30
37
 
31
38
  end
@@ -1,6 +1,6 @@
1
1
  require File.join(File.dirname(__FILE__), '..', '..', 'test_helper')
2
2
 
3
- class SetTheFlashMatcherTest < Test::Unit::TestCase # :nodoc:
3
+ class SetTheFlashMatcherTest < ActionController::TestCase # :nodoc:
4
4
 
5
5
  context "a controller that sets a flash message" do
6
6
  setup do
@@ -1,4 +1,4 @@
1
- class Test::Unit::TestCase
1
+ class ActiveSupport::TestCase
2
2
  def create_table(table_name, &block)
3
3
  connection = ActiveRecord::Base.connection
4
4
 
@@ -1,6 +1,6 @@
1
1
  require File.join(File.dirname(__FILE__), '..', 'test_helper')
2
2
 
3
- class AutoloadMacroTest < Test::Unit::TestCase # :nodoc:
3
+ class AutoloadMacroTest < ActiveSupport::TestCase # :nodoc:
4
4
  context "The macro auto-loader" do
5
5
  should "load macros from the plugins" do
6
6
  assert self.class.respond_to?('plugin_macro')
@@ -1,6 +1,6 @@
1
1
  require File.join(File.dirname(__FILE__), '..', 'test_helper')
2
2
 
3
- class ContextTest < Test::Unit::TestCase # :nodoc:
3
+ class ContextTest < ActiveSupport::TestCase # :nodoc:
4
4
 
5
5
  def self.context_macro(&blk)
6
6
  context "with a subcontext made by a macro" do
@@ -142,4 +142,48 @@ class ContextTest < Test::Unit::TestCase # :nodoc:
142
142
  should_eventually "only print this statement once for a should_eventually"
143
143
  end
144
144
  end
145
+
146
+ class ::SomeModel; end
147
+
148
+ context "given a test named after a class" do
149
+ setup do
150
+ self.class.stubs(:name).returns("SomeModelTest")
151
+ end
152
+
153
+ should "determine the described type" do
154
+ assert_equal SomeModel, self.class.described_type
155
+ end
156
+
157
+ should "return a new instance of the described type as the subject if none exists" do
158
+ assert_kind_of SomeModel, subject
159
+ end
160
+
161
+ should "return an existing instance of the described type as the subject" do
162
+ @some_model = SomeModel.new
163
+ assert_equal @some_model, subject
164
+ end
165
+
166
+ context "with an explicit subject block" do
167
+ setup { @expected = SomeModel.new }
168
+ subject { @expected }
169
+ should "return the result of the block as the subject" do
170
+ assert_equal @expected, subject
171
+ end
172
+ end
173
+ end
174
+ end
175
+
176
+ class Subject; end
177
+
178
+ class SubjectTest < ActiveSupport::TestCase
179
+
180
+ def setup
181
+ @expected = Subject.new
182
+ end
183
+
184
+ subject { @expected }
185
+
186
+ should "return a specified subject" do
187
+ assert_equal @expected, subject
188
+ end
145
189
  end
@@ -1,9 +1,9 @@
1
1
  require 'test/unit'
2
2
 
3
- class ConvertToShouldSyntaxTest < Test::Unit::TestCase # :nodoc:
3
+ class ConvertToShouldSyntaxTest < ActiveSupport::TestCase # :nodoc:
4
4
 
5
5
  BEFORE_FIXTURE = <<-EOS
6
- class DummyTest < Test::Unit::TestCase
6
+ class DummyTest < ActiveSupport::TestCase
7
7
 
8
8
  should "Not change this_word_with_underscores" do
9
9
  end
@@ -23,7 +23,7 @@ class ConvertToShouldSyntaxTest < Test::Unit::TestCase # :nodoc:
23
23
  EOS
24
24
 
25
25
  AFTER_FIXTURE = <<-EOS
26
- class DummyTest < Test::Unit::TestCase
26
+ class DummyTest < ActiveSupport::TestCase
27
27
 
28
28
  should "Not change this_word_with_underscores" do
29
29
  end
@@ -2,7 +2,7 @@ require File.join(File.dirname(__FILE__), '..', 'test_helper')
2
2
  require 'action_mailer'
3
3
  require 'mocha'
4
4
 
5
- class HelpersTest < Test::Unit::TestCase # :nodoc:
5
+ class HelpersTest < ActiveSupport::TestCase # :nodoc:
6
6
 
7
7
  context "given delivered emails" do
8
8
  setup do
@@ -88,6 +88,13 @@ class HelpersTest < Test::Unit::TestCase # :nodoc:
88
88
  @a.push(4)
89
89
  end
90
90
 
91
+ should_change("the number of elements", :by => 1) { @a.length }
92
+ should_change("the number of elements", :from => 3) { @a.length }
93
+ should_change("the number of elements", :to => 4) { @a.length }
94
+ should_change("the first element", :by => 0) { @a[0] }
95
+ should_not_change("the first element") { @a[0] }
96
+
97
+ # tests for deprecated behavior
91
98
  should_change "@a.length", :by => 1
92
99
  should_change "@a.length", :from => 3
93
100
  should_change "@a.length", :to => 4
@@ -100,6 +107,14 @@ class HelpersTest < Test::Unit::TestCase # :nodoc:
100
107
  @a = %w(a b c d e f)
101
108
  end
102
109
 
110
+ should_change("the number of elements", :by => 3) { @a.length }
111
+ should_change("the number of elements", :from => 3, :to => 6, :by => 3) { @a.length }
112
+ should_change("the first element") { @a[0] }
113
+ should_change("the second element", :from => 2, :to => "b") { @a[1] }
114
+ should_change("the third element", :from => /\d/, :to => /\w/) { @a[2] }
115
+ should_change("the last element", :to => String) { @a[3] }
116
+
117
+ # tests for deprecated behavior
103
118
  should_change "@a.length", :by => 3
104
119
  should_change "@a.length", :from => 3, :to => 6, :by => 3
105
120
  should_change "@a[0]"
@@ -188,10 +203,20 @@ class HelpersTest < Test::Unit::TestCase # :nodoc:
188
203
  :negative_failure_message => 'big time failure')
189
204
  end
190
205
 
191
- should "pass when given to assert_accepts" do
206
+ should "pass when given to assert_accepts with no message expectation" do
192
207
  assert_accepts @matcher, 'target'
193
208
  end
194
209
 
210
+ should "pass when given to assert_accepts with a matching message" do
211
+ assert_accepts @matcher, 'target', :message => /big time/
212
+ end
213
+
214
+ should "fail when given to assert_accepts with non-matching message" do
215
+ assert_raise Test::Unit::AssertionFailedError do
216
+ assert_accepts @matcher, 'target', :message => /small time/
217
+ end
218
+ end
219
+
195
220
  context "when given to assert_rejects" do
196
221
  setup do
197
222
  begin
@@ -217,10 +242,20 @@ class HelpersTest < Test::Unit::TestCase # :nodoc:
217
242
  :negative_failure_message => 'bad failure message')
218
243
  end
219
244
 
220
- should "pass when given to assert_rejects" do
245
+ should "pass when given to assert_rejects with no message expectation" do
221
246
  assert_rejects @matcher, 'target'
222
247
  end
223
248
 
249
+ should "pass when given to assert_rejects with a matching message" do
250
+ assert_rejects @matcher, 'target', :message => /big time/
251
+ end
252
+
253
+ should "fail when given to assert_rejects with a non-matching message" do
254
+ assert_raise Test::Unit::AssertionFailedError do
255
+ assert_rejects @matcher, 'target', :message => /small time/
256
+ end
257
+ end
258
+
224
259
  context "when given to assert_accepts" do
225
260
  setup do
226
261
  begin
@@ -238,4 +273,68 @@ class HelpersTest < Test::Unit::TestCase # :nodoc:
238
273
  end
239
274
  end
240
275
  end
276
+
277
+ context "given one treat exists and one post exists" do
278
+ setup do
279
+ Treat.create!
280
+ Post.create!(:title => 'title', :body => 'body', :user_id => 1)
281
+ end
282
+
283
+ teardown do
284
+ Treat.delete_all
285
+ Post.delete_all
286
+ end
287
+
288
+ context "creating a treat" do
289
+ setup do
290
+ Treat.create!
291
+ end
292
+
293
+ should_create :treat
294
+ should_fail do
295
+ should_create :post
296
+ end
297
+ end
298
+
299
+ context "creating a treat and a post" do
300
+ setup do
301
+ Treat.create!
302
+ Post.create!(:title => 'title 2', :body => 'body', :user_id => 1)
303
+ end
304
+
305
+ should_create :treat
306
+ should_create :post
307
+ end
308
+
309
+ context "destroying a treat" do
310
+ setup do
311
+ Treat.first.destroy
312
+ end
313
+
314
+ should_destroy :treat
315
+ should_fail do
316
+ should_destroy :post
317
+ end
318
+ end
319
+
320
+ context "destroying a treat and a post" do
321
+ setup do
322
+ Treat.first.destroy
323
+ Post.first.destroy
324
+ end
325
+
326
+ should_destroy :treat
327
+ should_destroy :post
328
+ end
329
+
330
+ context "doing nothing" do
331
+ should_fail do
332
+ should_create :treat
333
+ end
334
+
335
+ should_fail do
336
+ should_destroy :treat
337
+ end
338
+ end
339
+ end
241
340
  end
@@ -1,6 +1,6 @@
1
1
  require File.join(File.dirname(__FILE__), '..', 'test_helper')
2
2
 
3
- class PrivateHelpersTest < Test::Unit::TestCase # :nodoc:
3
+ class PrivateHelpersTest < ActiveSupport::TestCase # :nodoc:
4
4
  include Shoulda::Private
5
5
  context "get_options!" do
6
6
  should "remove opts from args" do
@@ -22,13 +22,11 @@ class PrivateHelpersTest < Test::Unit::TestCase # :nodoc:
22
22
  get_options!(args, :one)
23
23
  end
24
24
  end
25
- end
26
-
27
- class ::SomeModel; end
28
- context "model_class" do
29
- should "sniff the class constant from the test class" do
30
- self.expects(:name).returns("SomeModelTest")
31
- assert_equal SomeModel, model_class
25
+
26
+ should "return single wanted option" do
27
+ args = [:a, :b, {:class => Object}]
28
+ klass = get_options!(args,:class)
29
+ assert_equal Object, klass
32
30
  end
33
31
  end
34
32
  end
@@ -1,6 +1,6 @@
1
1
  require File.join(File.dirname(__FILE__), '..', 'test_helper')
2
2
 
3
- class ShouldTest < Test::Unit::TestCase # :nodoc:
3
+ class ShouldTest < ActiveSupport::TestCase # :nodoc:
4
4
  should "be able to define a should statement outside of a context" do
5
5
  assert true
6
6
  end
@@ -15,6 +15,10 @@ class ShouldTest < Test::Unit::TestCase # :nodoc:
15
15
  end
16
16
  end
17
17
 
18
+ def self.should_be_able_to_setup_a_should_eventually_in_a_class_method
19
+ should "be able to setup a should eventually in a class method"
20
+ end
21
+
18
22
  def self.should_see_a_context_block_like_a_Test_Unit_class
19
23
  should "see a context block as a Test::Unit class" do
20
24
  assert_equal "ShouldTest", self.class.name
@@ -46,6 +50,7 @@ class ShouldTest < Test::Unit::TestCase # :nodoc:
46
50
  should_see_class_methods
47
51
  should_see_a_context_block_like_a_Test_Unit_class
48
52
  should_be_able_to_make_context_macros("Context ")
53
+ should_be_able_to_setup_a_should_eventually_in_a_class_method
49
54
 
50
55
  should "not define @blah" do
51
56
  assert ! self.instance_variables.include?("@blah")
@@ -177,7 +182,7 @@ class ShouldTest < Test::Unit::TestCase # :nodoc:
177
182
  end
178
183
 
179
184
  def test_should_create_test_methods_on_build
180
- tu_class = Test::Unit::TestCase
185
+ tu_class = ActiveSupport::TestCase
181
186
  context = Shoulda::Context.new("A Context", tu_class) do
182
187
  should "define the test" do; end
183
188
  end
@@ -187,7 +192,7 @@ class ShouldTest < Test::Unit::TestCase # :nodoc:
187
192
  end
188
193
 
189
194
  def test_should_create_test_methods_on_build_when_subcontext
190
- tu_class = Test::Unit::TestCase
195
+ tu_class = ActiveSupport::TestCase
191
196
  context = Shoulda::Context.new("A Context", tu_class) do
192
197
  context "with a child" do
193
198
  should "define the test" do; end
@@ -12,6 +12,7 @@ class PostsController < ApplicationController
12
12
  headers['Content-Type'] = 'application/rss+xml'
13
13
  session[:special] = '$2 off your next purchase'
14
14
  session[:special_user_id] = @user.id
15
+ session[:false_var] = false
15
16
  head :ok
16
17
  end
17
18
  end
@@ -0,0 +1,7 @@
1
+ module Pets
2
+ class Cat < ActiveRecord::Base
3
+ belongs_to :owner, :class_name => 'User'
4
+ belongs_to :address, :dependent => :destroy
5
+ validates_presence_of :owner_id
6
+ end
7
+ end
@@ -0,0 +1,2 @@
1
+ class Profile < ActiveRecord::Base
2
+ end
@@ -0,0 +1,2 @@
1
+ class Registration < ActiveRecord::Base
2
+ end
@@ -1,11 +1,14 @@
1
1
  class User < ActiveRecord::Base
2
2
  has_many :posts
3
3
  has_many :dogs, :foreign_key => :owner_id, :class_name => "Pets::Dog"
4
+ has_many :cats, :foreign_key => :owner_id, :class_name => "Pets::Cat"
4
5
 
5
6
  has_many :friendships
6
7
  has_many :friends, :through => :friendships
7
8
 
8
9
  has_one :address, :as => :addressable, :dependent => :destroy
10
+ has_one :registration
11
+ has_one :profile, :through => :registration
9
12
 
10
13
  named_scope :old, :conditions => "age > 50"
11
14
  named_scope :eighteen, :conditions => { :age => 18 }
@@ -44,6 +44,7 @@ module Rails
44
44
  def load_initializer
45
45
  require "#{RAILS_ROOT}/vendor/rails/railties/lib/initializer"
46
46
  Rails::Initializer.run(:install_gem_spec_stubs)
47
+ Rails::GemDependency.add_frozen_gem_path
47
48
  end
48
49
  end
49
50
 
@@ -67,7 +68,7 @@ module Rails
67
68
 
68
69
  class << self
69
70
  def rubygems_version
70
- Gem::RubyGemsVersion if defined? Gem::RubyGemsVersion
71
+ Gem::RubyGemsVersion rescue nil
71
72
  end
72
73
 
73
74
  def gem_version
@@ -82,14 +83,14 @@ module Rails
82
83
 
83
84
  def load_rubygems
84
85
  require 'rubygems'
85
-
86
- unless rubygems_version >= '0.9.4'
87
- $stderr.puts %(Rails requires RubyGems >= 0.9.4 (you have #{rubygems_version}). Please `gem update --system` and try again.)
86
+ min_version = '1.3.1'
87
+ unless rubygems_version >= min_version
88
+ $stderr.puts %Q(Rails requires RubyGems >= #{min_version} (you have #{rubygems_version}). Please `gem update --system` and try again.)
88
89
  exit 1
89
90
  end
90
91
 
91
92
  rescue LoadError
92
- $stderr.puts %(Rails requires RubyGems >= 0.9.4. Please install RubyGems and try again: http://rubygems.rubyforge.org)
93
+ $stderr.puts %Q(Rails requires RubyGems >= #{min_version}. Please install RubyGems and try again: http://rubygems.rubyforge.org)
93
94
  exit 1
94
95
  end
95
96
 
@@ -1,6 +1,6 @@
1
1
  # Specifies gem version of Rails to use when vendor/rails is not present
2
2
  old_verbose, $VERBOSE = $VERBOSE, nil
3
- RAILS_GEM_VERSION = '= 2.2.2' unless defined? RAILS_GEM_VERSION
3
+ RAILS_GEM_VERSION = '= 2.3.2' unless defined? RAILS_GEM_VERSION
4
4
  $VERBOSE = old_verbose
5
5
 
6
6
  require File.join(File.dirname(__FILE__), 'boot')
@@ -9,6 +9,10 @@ Rails::Initializer.run do |config|
9
9
  config.log_level = :debug
10
10
  config.cache_classes = false
11
11
  config.whiny_nils = true
12
+ config.action_controller.session = {
13
+ :key => 'shoulda_session',
14
+ :secret => 'ceae6058a816b1446e09ce90d8372511'
15
+ }
12
16
  end
13
17
 
14
18
  # Dependencies.log_activity = true