ratnikov-shoulda 2.0.6.1

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 (103) hide show
  1. data/CONTRIBUTION_GUIDELINES.rdoc +12 -0
  2. data/MIT-LICENSE +22 -0
  3. data/README.rdoc +146 -0
  4. data/Rakefile +72 -0
  5. data/bin/convert_to_should_syntax +42 -0
  6. data/lib/shoulda/action_mailer/assertions.rb +38 -0
  7. data/lib/shoulda/action_mailer.rb +10 -0
  8. data/lib/shoulda/active_record/assertions.rb +90 -0
  9. data/lib/shoulda/active_record/macros.rb +748 -0
  10. data/lib/shoulda/active_record.rb +12 -0
  11. data/lib/shoulda/assertions.rb +47 -0
  12. data/lib/shoulda/context.rb +326 -0
  13. data/lib/shoulda/controller/formats/html.rb +199 -0
  14. data/lib/shoulda/controller/formats/xml.rb +168 -0
  15. data/lib/shoulda/controller/helpers.rb +62 -0
  16. data/lib/shoulda/controller/macros.rb +336 -0
  17. data/lib/shoulda/controller/resource_options.rb +233 -0
  18. data/lib/shoulda/controller.rb +30 -0
  19. data/lib/shoulda/helpers.rb +8 -0
  20. data/lib/shoulda/macros.rb +73 -0
  21. data/lib/shoulda/private_helpers.rb +20 -0
  22. data/lib/shoulda/proc_extensions.rb +14 -0
  23. data/lib/shoulda/rails.rb +19 -0
  24. data/lib/shoulda/tasks/list_tests.rake +24 -0
  25. data/lib/shoulda/tasks/yaml_to_shoulda.rake +28 -0
  26. data/lib/shoulda/tasks.rb +3 -0
  27. data/lib/shoulda.rb +21 -0
  28. data/rails/init.rb +1 -0
  29. data/test/README +36 -0
  30. data/test/fail_macros.rb +34 -0
  31. data/test/fixtures/addresses.yml +3 -0
  32. data/test/fixtures/friendships.yml +0 -0
  33. data/test/fixtures/posts.yml +5 -0
  34. data/test/fixtures/products.yml +0 -0
  35. data/test/fixtures/taggings.yml +0 -0
  36. data/test/fixtures/tags.yml +9 -0
  37. data/test/fixtures/users.yml +6 -0
  38. data/test/functional/posts_controller_test.rb +108 -0
  39. data/test/functional/users_controller_test.rb +38 -0
  40. data/test/other/context_test.rb +161 -0
  41. data/test/other/convert_to_should_syntax_test.rb +63 -0
  42. data/test/other/helpers_test.rb +183 -0
  43. data/test/other/private_helpers_test.rb +34 -0
  44. data/test/other/should_test.rb +266 -0
  45. data/test/rails_root/app/controllers/application.rb +25 -0
  46. data/test/rails_root/app/controllers/posts_controller.rb +86 -0
  47. data/test/rails_root/app/controllers/users_controller.rb +84 -0
  48. data/test/rails_root/app/helpers/application_helper.rb +3 -0
  49. data/test/rails_root/app/helpers/posts_helper.rb +2 -0
  50. data/test/rails_root/app/helpers/users_helper.rb +2 -0
  51. data/test/rails_root/app/models/address.rb +7 -0
  52. data/test/rails_root/app/models/flea.rb +3 -0
  53. data/test/rails_root/app/models/friendship.rb +4 -0
  54. data/test/rails_root/app/models/post.rb +12 -0
  55. data/test/rails_root/app/models/product.rb +12 -0
  56. data/test/rails_root/app/models/tag.rb +8 -0
  57. data/test/rails_root/app/models/tagging.rb +4 -0
  58. data/test/rails_root/app/models/user.rb +28 -0
  59. data/test/rails_root/app/views/layouts/posts.rhtml +19 -0
  60. data/test/rails_root/app/views/layouts/users.rhtml +17 -0
  61. data/test/rails_root/app/views/layouts/wide.html.erb +1 -0
  62. data/test/rails_root/app/views/posts/edit.rhtml +27 -0
  63. data/test/rails_root/app/views/posts/index.rhtml +25 -0
  64. data/test/rails_root/app/views/posts/new.rhtml +26 -0
  65. data/test/rails_root/app/views/posts/show.rhtml +18 -0
  66. data/test/rails_root/app/views/users/edit.rhtml +22 -0
  67. data/test/rails_root/app/views/users/index.rhtml +22 -0
  68. data/test/rails_root/app/views/users/new.rhtml +21 -0
  69. data/test/rails_root/app/views/users/show.rhtml +13 -0
  70. data/test/rails_root/config/boot.rb +109 -0
  71. data/test/rails_root/config/database.yml +4 -0
  72. data/test/rails_root/config/environment.rb +14 -0
  73. data/test/rails_root/config/environments/sqlite3.rb +0 -0
  74. data/test/rails_root/config/initializers/new_rails_defaults.rb +15 -0
  75. data/test/rails_root/config/initializers/shoulda.rb +8 -0
  76. data/test/rails_root/config/routes.rb +6 -0
  77. data/test/rails_root/db/migrate/001_create_users.rb +19 -0
  78. data/test/rails_root/db/migrate/002_create_posts.rb +13 -0
  79. data/test/rails_root/db/migrate/003_create_taggings.rb +12 -0
  80. data/test/rails_root/db/migrate/004_create_tags.rb +11 -0
  81. data/test/rails_root/db/migrate/005_create_dogs.rb +12 -0
  82. data/test/rails_root/db/migrate/006_create_addresses.rb +14 -0
  83. data/test/rails_root/db/migrate/007_create_fleas.rb +11 -0
  84. data/test/rails_root/db/migrate/008_create_dogs_fleas.rb +12 -0
  85. data/test/rails_root/db/migrate/009_create_products.rb +17 -0
  86. data/test/rails_root/db/migrate/010_create_friendships.rb +14 -0
  87. data/test/rails_root/db/schema.rb +0 -0
  88. data/test/rails_root/public/404.html +30 -0
  89. data/test/rails_root/public/422.html +30 -0
  90. data/test/rails_root/public/500.html +30 -0
  91. data/test/rails_root/script/console +3 -0
  92. data/test/rails_root/script/generate +3 -0
  93. data/test/test_helper.rb +33 -0
  94. data/test/unit/address_test.rb +10 -0
  95. data/test/unit/dog_test.rb +10 -0
  96. data/test/unit/flea_test.rb +6 -0
  97. data/test/unit/friendship_test.rb +6 -0
  98. data/test/unit/post_test.rb +19 -0
  99. data/test/unit/product_test.rb +27 -0
  100. data/test/unit/tag_test.rb +14 -0
  101. data/test/unit/tagging_test.rb +6 -0
  102. data/test/unit/user_test.rb +60 -0
  103. metadata +189 -0
@@ -0,0 +1,108 @@
1
+ require File.dirname(__FILE__) + '/../test_helper'
2
+ require 'posts_controller'
3
+
4
+ # Re-raise errors caught by the controller.
5
+ class PostsController; def rescue_action(e) raise e end; end
6
+
7
+ class PostsControllerTest < Test::Unit::TestCase
8
+ fixtures :all
9
+
10
+ def setup
11
+ @controller = PostsController.new
12
+ @request = ActionController::TestRequest.new
13
+ @response = ActionController::TestResponse.new
14
+ @post = Post.find(:first)
15
+ end
16
+
17
+ # autodetects the :controller
18
+ should_route :get, '/posts', :action => :index
19
+ # explicitly specify :controller
20
+ should_route :post, '/posts', :controller => :posts, :action => :create
21
+ # non-string parameter
22
+ should_route :get, '/posts/1', :action => :show, :id => 1
23
+ # string-parameter
24
+ should_route :put, '/posts/1', :action => :update, :id => "1"
25
+ should_route :delete, '/posts/1', :action => :destroy, :id => 1
26
+ should_route :get, '/posts/new', :action => :new
27
+
28
+ # Test the nested routes
29
+ should_route :get, '/users/5/posts', :action => :index, :user_id => 5
30
+ should_route :post, '/users/5/posts', :action => :create, :user_id => 5
31
+ should_route :get, '/users/5/posts/1', :action => :show, :id => 1, :user_id => 5
32
+ should_route :delete, '/users/5/posts/1', :action => :destroy, :id => 1, :user_id => 5
33
+ should_route :get, '/users/5/posts/new', :action => :new, :user_id => 5
34
+ should_route :put, '/users/5/posts/1', :action => :update, :id => 1, :user_id => 5
35
+
36
+ context "The public" do
37
+ setup do
38
+ @request.session[:logged_in] = false
39
+ end
40
+
41
+ should_be_restful do |resource|
42
+ resource.parent = :user
43
+
44
+ resource.denied.actions = [:index, :show, :edit, :new, :create, :update, :destroy]
45
+ resource.denied.flash = /what/i
46
+ resource.denied.redirect = '"/"'
47
+ end
48
+ end
49
+
50
+ context "Logged in" do
51
+ setup do
52
+ @request.session[:logged_in] = true
53
+ end
54
+
55
+ should_be_restful do |resource|
56
+ resource.parent = :user
57
+
58
+ resource.create.params = { :title => "first post", :body => 'blah blah blah'}
59
+ resource.update.params = { :title => "changed" }
60
+ end
61
+
62
+ context "viewing posts for a user" do
63
+ setup do
64
+ get :index, :user_id => users(:first)
65
+ end
66
+ should_respond_with :success
67
+ should_assign_to :user, :class => User, :equals => 'users(:first)'
68
+ should_fail do
69
+ should_assign_to :user, :class => Post
70
+ end
71
+ should_fail do
72
+ should_assign_to :user, :equals => 'posts(:first)'
73
+ end
74
+ should_assign_to :posts
75
+ should_not_assign_to :foo, :bar
76
+ should_render_page_with_metadata :description => /Posts/, :title => /index/
77
+ should_render_page_with_metadata :keywords => "posts"
78
+ end
79
+
80
+ context "viewing posts for a user with rss format" do
81
+ setup do
82
+ get :index, :user_id => users(:first), :format => 'rss'
83
+ @user = users(:first)
84
+ end
85
+ should_respond_with :success
86
+ should_respond_with_content_type 'application/rss+xml'
87
+ should_respond_with_content_type :rss
88
+ should_respond_with_content_type /rss/
89
+ should_return_from_session :special, "'$2 off your next purchase'"
90
+ should_return_from_session :special_user_id, '@user.id'
91
+ should_assign_to :user, :posts
92
+ should_not_assign_to :foo, :bar
93
+ end
94
+
95
+ context "viewing a post on GET to #show" do
96
+ setup { get :show, :user_id => users(:first), :id => posts(:first) }
97
+ should_render_with_layout 'wide'
98
+ should_render_with_layout :wide
99
+ should_assign_to :false_flag
100
+ end
101
+
102
+ context "on GET to #new" do
103
+ setup { get :new, :user_id => users(:first) }
104
+ should_render_without_layout
105
+ end
106
+ end
107
+
108
+ end
@@ -0,0 +1,38 @@
1
+ require File.dirname(__FILE__) + '/../test_helper'
2
+ require 'users_controller'
3
+
4
+ # Re-raise errors caught by the controller.
5
+ class UsersController; def rescue_action(e) raise e end; end
6
+
7
+ class UsersControllerTest < Test::Unit::TestCase
8
+ fixtures :all
9
+
10
+ def setup
11
+ @controller = UsersController.new
12
+ @request = ActionController::TestRequest.new
13
+ @response = ActionController::TestResponse.new
14
+ @user = User.find(:first)
15
+ end
16
+
17
+ should_filter_params :ssn
18
+
19
+ should_be_restful do |resource|
20
+ resource.identifier = :id
21
+ resource.klass = User
22
+ resource.object = :user
23
+ resource.parent = []
24
+ resource.actions = [:index, :show, :new, :edit, :update, :create, :destroy]
25
+ resource.formats = [:html, :xml]
26
+
27
+ resource.create.params = { :name => "bob", :email => 'bob@bob.com', :age => 13, :ssn => "123456789"}
28
+ resource.update.params = { :name => "sue" }
29
+
30
+ resource.create.redirect = "user_url(@user)"
31
+ resource.update.redirect = "user_url(@user)"
32
+ resource.destroy.redirect = "users_url"
33
+
34
+ resource.create.flash = /created/i
35
+ resource.update.flash = /updated/i
36
+ resource.destroy.flash = /removed/i
37
+ end
38
+ end
@@ -0,0 +1,161 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'test_helper')
2
+
3
+ class ContextTest < Test::Unit::TestCase # :nodoc:
4
+
5
+ def self.context_macro(&blk)
6
+ context "with a subcontext made by a macro" do
7
+ setup { @context_macro = :foo }
8
+
9
+ merge_block &blk
10
+ end
11
+ end
12
+
13
+ # def self.context_macro(&blk)
14
+ # context "with a subcontext made by a macro" do
15
+ # setup { @context_macro = :foo }
16
+ # yield # <- this doesn't work.
17
+ # end
18
+ # end
19
+
20
+ context "context with evaluate block" do
21
+ setup { @blah = "blah" }
22
+ evaluate { @evaluated = @blah }
23
+
24
+ should "correctly evaluate @evaluated by using the settings in current and parent setups" do
25
+ assert_equal @evaluated, "blah"
26
+ end
27
+
28
+ context "in sub-context" do
29
+ setup { @blah = "bleh" }
30
+ should "correctly evaluate by using current setup as well" do
31
+ assert_equal @evaluated, "bleh"
32
+ end
33
+ end
34
+ end
35
+
36
+ context "context with setup block" do
37
+ setup do
38
+ @blah = "blah"
39
+ end
40
+
41
+ should "run the setup block" do
42
+ assert_equal "blah", @blah
43
+ end
44
+
45
+ should "have name set right" do
46
+ assert_match(/^test: context with setup block/, self.to_s)
47
+ end
48
+
49
+ context "and a subcontext" do
50
+ setup do
51
+ @blah = "#{@blah} twice"
52
+ end
53
+
54
+ should "be named correctly" do
55
+ assert_match(/^test: context with setup block and a subcontext should be named correctly/, self.to_s)
56
+ end
57
+
58
+ should "run the setup blocks in order" do
59
+ assert_equal @blah, "blah twice"
60
+ end
61
+ end
62
+
63
+ context_macro do
64
+ should "have name set right" do
65
+ assert_match(/^test: context with setup block with a subcontext made by a macro should have name set right/, self.to_s)
66
+ end
67
+
68
+ should "run the setup block of that context macro" do
69
+ assert_equal :foo, @context_macro
70
+ end
71
+
72
+ should "run the setup block of the main context" do
73
+ assert_equal "blah", @blah
74
+ end
75
+ end
76
+
77
+ end
78
+
79
+ context "another context with setup block" do
80
+ setup do
81
+ @blah = "foo"
82
+ end
83
+
84
+ should "have @blah == 'foo'" do
85
+ assert_equal "foo", @blah
86
+ end
87
+
88
+ should "have name set right" do
89
+ assert_match(/^test: another context with setup block/, self.to_s)
90
+ end
91
+ end
92
+
93
+ context "context with method definition" do
94
+ setup do
95
+ def hello; "hi"; end
96
+ end
97
+
98
+ should "be able to read that method" do
99
+ assert_equal "hi", hello
100
+ end
101
+
102
+ should "have name set right" do
103
+ assert_match(/^test: context with method definition/, self.to_s)
104
+ end
105
+ end
106
+
107
+ context "another context" do
108
+ should "not define @blah" do
109
+ assert_nil @blah
110
+ end
111
+ end
112
+
113
+ context "context with multiple setups and/or teardowns" do
114
+
115
+ cleanup_count = 0
116
+
117
+ 2.times do |i|
118
+ setup { cleanup_count += 1 }
119
+ teardown { cleanup_count -= 1 }
120
+ end
121
+
122
+ 2.times do |i|
123
+ should "call all setups and all teardowns (check ##{i + 1})" do
124
+ assert_equal 2, cleanup_count
125
+ end
126
+ end
127
+
128
+ context "subcontexts" do
129
+
130
+ 2.times do |i|
131
+ setup { cleanup_count += 1 }
132
+ teardown { cleanup_count -= 1 }
133
+ end
134
+
135
+ 2.times do |i|
136
+ should "also call all setups and all teardowns in parent and subcontext (check ##{i + 1})" do
137
+ assert_equal 4, cleanup_count
138
+ end
139
+ end
140
+
141
+ end
142
+
143
+ end
144
+
145
+ should_eventually "pass, since it's unimplemented" do
146
+ flunk "what?"
147
+ end
148
+
149
+ should_eventually "not require a block when using should_eventually"
150
+ should "pass without a block, as that causes it to piggyback to should_eventually"
151
+
152
+ context "context for testing should piggybacking" do
153
+ should "call should_eventually as we are not passing a block"
154
+ end
155
+
156
+ context "context" do
157
+ context "with nested subcontexts" do
158
+ should_eventually "only print this statement once for a should_eventually"
159
+ end
160
+ end
161
+ end
@@ -0,0 +1,63 @@
1
+ require 'test/unit'
2
+
3
+ class ConvertToShouldSyntaxTest < Test::Unit::TestCase # :nodoc:
4
+
5
+ BEFORE_FIXTURE = <<-EOS
6
+ class DummyTest < Test::Unit::TestCase
7
+
8
+ should "Not change this_word_with_underscores" do
9
+ end
10
+
11
+ def test_should_be_working
12
+ assert true
13
+ end
14
+
15
+ def test_some_cool_stuff
16
+ assert true
17
+ end
18
+
19
+ def non_test_method
20
+ end
21
+
22
+ end
23
+ EOS
24
+
25
+ AFTER_FIXTURE = <<-EOS
26
+ class DummyTest < Test::Unit::TestCase
27
+
28
+ should "Not change this_word_with_underscores" do
29
+ end
30
+
31
+ should "be working" do
32
+ assert true
33
+ end
34
+
35
+ should "RENAME ME: test some cool stuff" do
36
+ assert true
37
+ end
38
+
39
+ def non_test_method
40
+ end
41
+
42
+ end
43
+ EOS
44
+
45
+ FIXTURE_PATH = "./convert_to_should_syntax_fixture.dat"
46
+
47
+ RUBY = ENV['RUBY'] || 'ruby'
48
+
49
+ def test_convert_to_should_syntax
50
+ File.open(FIXTURE_PATH, "w") {|f| f.write(BEFORE_FIXTURE)}
51
+ cmd = "#{RUBY} #{File.join(File.dirname(__FILE__), '../../bin/convert_to_should_syntax')} #{FIXTURE_PATH}"
52
+ output = `#{cmd}`
53
+ File.unlink($1) if output.match(/has been stored in '([^']+)/)
54
+ assert_match(/has been converted/, output)
55
+ result = IO.read(FIXTURE_PATH)
56
+ assert_equal result, AFTER_FIXTURE
57
+ end
58
+
59
+ def teardown
60
+ File.unlink(FIXTURE_PATH)
61
+ end
62
+
63
+ end
@@ -0,0 +1,183 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'test_helper')
2
+ require 'action_mailer'
3
+ require 'mocha'
4
+
5
+ class HelpersTest < Test::Unit::TestCase # :nodoc:
6
+
7
+ context "given delivered emails" do
8
+ setup do
9
+ email1 = stub(:subject => "one", :to => ["none1@email.com"])
10
+ email2 = stub(:subject => "two", :to => ["none2@email.com"])
11
+ ActionMailer::Base.stubs(:deliveries).returns([email1, email2])
12
+ end
13
+
14
+ should "have sent an email" do
15
+ assert_sent_email
16
+
17
+ assert_raises(Test::Unit::AssertionFailedError) do
18
+ assert_did_not_send_email
19
+ end
20
+ end
21
+
22
+ should "find email one" do
23
+ assert_sent_email do |e|
24
+ e.subject =~ /one/
25
+ end
26
+ end
27
+
28
+ should "not find an email that doesn't exist" do
29
+ assert_raises(Test::Unit::AssertionFailedError) do
30
+ assert_sent_email do |e|
31
+ e.subject =~ /whatever/
32
+ end
33
+ end
34
+ end
35
+ end
36
+
37
+ context "when there are no emails" do
38
+ setup do
39
+ ActionMailer::Base.stubs(:deliveries).returns([])
40
+ end
41
+
42
+ should "not have sent an email" do
43
+ assert_did_not_send_email
44
+
45
+ assert_raises(Test::Unit::AssertionFailedError) do
46
+ assert_sent_email
47
+ end
48
+ end
49
+ end
50
+
51
+ context "an array of values" do
52
+ setup do
53
+ @a = ['abc', 'def', 3]
54
+ end
55
+
56
+ [/b/, 'abc', 3].each do |x|
57
+ should "contain #{x.inspect}" do
58
+ assert_raises(Test::Unit::AssertionFailedError) do
59
+ assert_does_not_contain @a, x
60
+ end
61
+ assert_contains @a, x
62
+ end
63
+ end
64
+
65
+ should "not contain 'wtf'" do
66
+ assert_raises(Test::Unit::AssertionFailedError) {assert_contains @a, 'wtf'}
67
+ assert_does_not_contain @a, 'wtf'
68
+ end
69
+
70
+ should "be the same as another array, ordered differently" do
71
+ assert_same_elements(@a, [3, "def", "abc"])
72
+ assert_raises(Test::Unit::AssertionFailedError) do
73
+ assert_same_elements(@a, [3, 3, "def", "abc"])
74
+ end
75
+ assert_raises(Test::Unit::AssertionFailedError) do
76
+ assert_same_elements([@a, "abc"].flatten, [3, 3, "def", "abc"])
77
+ end
78
+ end
79
+ end
80
+
81
+ context "an array of values" do
82
+ setup do
83
+ @a = [1, 2, "(3)"]
84
+ end
85
+
86
+ context "after adding another value" do
87
+ setup do
88
+ @a.push(4)
89
+ end
90
+
91
+ should_change "@a.length", :by => 1
92
+ should_change "@a.length", :from => 3
93
+ should_change "@a.length", :to => 4
94
+ should_change "@a[0]", :by => 0
95
+ should_not_change "@a[0]"
96
+ end
97
+
98
+ context "after replacing it with an array of strings" do
99
+ setup do
100
+ @a = %w(a b c d e f)
101
+ end
102
+
103
+ should_change "@a.length", :by => 3
104
+ should_change "@a.length", :from => 3, :to => 6, :by => 3
105
+ should_change "@a[0]"
106
+ should_change "@a[1]", :from => 2, :to => "b"
107
+ should_change "@a[2]", :from => /\d/, :to => /\w/
108
+ should_change "@a[3]", :to => String
109
+ end
110
+ end
111
+
112
+ context "assert_good_value" do
113
+ should "validate a good email address" do
114
+ assert_good_value User.new, :email, "good@example.com"
115
+ end
116
+
117
+ should "validate a good SSN with a custom message" do
118
+ assert_good_value User.new, :ssn, "xxxxxxxxx", /length/
119
+ end
120
+
121
+ should "fail to validate a bad email address" do
122
+ assert_raises Test::Unit::AssertionFailedError do
123
+ assert_good_value User.new, :email, "bad"
124
+ end
125
+ end
126
+
127
+ should "fail to validate a bad SSN that is too short" do
128
+ assert_raises Test::Unit::AssertionFailedError do
129
+ assert_good_value User.new, :ssn, "x", /length/
130
+ end
131
+ end
132
+
133
+ should "accept a class as the first argument" do
134
+ assert_good_value User, :email, "good@example.com"
135
+ end
136
+
137
+ context "with an instance variable" do
138
+ setup do
139
+ @product = Product.new(:tangible => true)
140
+ end
141
+
142
+ should "use that instance variable" do
143
+ assert_good_value Product, :price, "9999", /included/
144
+ end
145
+ end
146
+ end
147
+
148
+ context "assert_bad_value" do
149
+ should "invalidate a bad email address" do
150
+ assert_bad_value User.new, :email, "bad"
151
+ end
152
+
153
+ should "invalidate a bad SSN with a custom message" do
154
+ assert_bad_value User.new, :ssn, "x", /length/
155
+ end
156
+
157
+ should "fail to invalidate a good email address" do
158
+ assert_raises Test::Unit::AssertionFailedError do
159
+ assert_bad_value User.new, :email, "good@example.com"
160
+ end
161
+ end
162
+
163
+ should "fail to invalidate a good SSN" do
164
+ assert_raises Test::Unit::AssertionFailedError do
165
+ assert_bad_value User.new, :ssn, "xxxxxxxxx", /length/
166
+ end
167
+ end
168
+
169
+ should "accept a class as the first argument" do
170
+ assert_bad_value User, :email, "bad"
171
+ end
172
+
173
+ context "with an instance variable" do
174
+ setup do
175
+ @product = Product.new(:tangible => true)
176
+ end
177
+
178
+ should "use that instance variable" do
179
+ assert_bad_value Product, :price, "0", /included/
180
+ end
181
+ end
182
+ end
183
+ end
@@ -0,0 +1,34 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'test_helper')
2
+
3
+ class PrivateHelpersTest < Test::Unit::TestCase # :nodoc:
4
+ include Shoulda::Private
5
+ context "get_options!" do
6
+ should "remove opts from args" do
7
+ args = [:a, :b, {}]
8
+ get_options!(args)
9
+ assert_equal [:a, :b], args
10
+ end
11
+
12
+ should "return wanted opts in order" do
13
+ args = [{:one => 1, :two => 2}]
14
+ one, two = get_options!(args, :one, :two)
15
+ assert_equal 1, one
16
+ assert_equal 2, two
17
+ end
18
+
19
+ should "raise ArgumentError if given unwanted option" do
20
+ args = [{:one => 1, :two => 2}]
21
+ assert_raises ArgumentError do
22
+ get_options!(args, :one)
23
+ end
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
32
+ end
33
+ end
34
+ end