shoulda 2.0.0
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.
- data/CONTRIBUTION_GUIDELINES.rdoc +12 -0
- data/MIT-LICENSE +22 -0
- data/README.rdoc +132 -0
- data/Rakefile +72 -0
- data/bin/convert_to_should_syntax +42 -0
- data/lib/shoulda.rb +16 -0
- data/lib/shoulda/action_mailer.rb +10 -0
- data/lib/shoulda/action_mailer/assertions.rb +39 -0
- data/lib/shoulda/active_record.rb +12 -0
- data/lib/shoulda/active_record/assertions.rb +85 -0
- data/lib/shoulda/active_record/macros.rb +703 -0
- data/lib/shoulda/assertions.rb +45 -0
- data/lib/shoulda/context.rb +309 -0
- data/lib/shoulda/controller.rb +30 -0
- data/lib/shoulda/controller/formats/html.rb +201 -0
- data/lib/shoulda/controller/formats/xml.rb +170 -0
- data/lib/shoulda/controller/helpers.rb +64 -0
- data/lib/shoulda/controller/macros.rb +287 -0
- data/lib/shoulda/controller/resource_options.rb +236 -0
- data/lib/shoulda/controller/routing.rb +0 -0
- data/lib/shoulda/controller/routing/macros.rb +0 -0
- data/lib/shoulda/helpers.rb +10 -0
- data/lib/shoulda/macros.rb +80 -0
- data/lib/shoulda/private_helpers.rb +22 -0
- data/lib/shoulda/proc_extensions.rb +14 -0
- data/lib/shoulda/rails.rb +19 -0
- data/lib/shoulda/tasks.rb +3 -0
- data/lib/shoulda/tasks/list_tests.rake +24 -0
- data/lib/shoulda/tasks/yaml_to_shoulda.rake +28 -0
- data/test/README +36 -0
- data/test/fixtures/addresses.yml +3 -0
- data/test/fixtures/friendships.yml +0 -0
- data/test/fixtures/posts.yml +5 -0
- data/test/fixtures/products.yml +0 -0
- data/test/fixtures/taggings.yml +0 -0
- data/test/fixtures/tags.yml +9 -0
- data/test/fixtures/users.yml +6 -0
- data/test/functional/posts_controller_test.rb +104 -0
- data/test/functional/users_controller_test.rb +36 -0
- data/test/other/context_test.rb +145 -0
- data/test/other/convert_to_should_syntax_test.rb +63 -0
- data/test/other/helpers_test.rb +183 -0
- data/test/other/private_helpers_test.rb +34 -0
- data/test/other/should_test.rb +266 -0
- data/test/rails_root/app/controllers/application.rb +25 -0
- data/test/rails_root/app/controllers/posts_controller.rb +85 -0
- data/test/rails_root/app/controllers/users_controller.rb +81 -0
- data/test/rails_root/app/helpers/application_helper.rb +3 -0
- data/test/rails_root/app/helpers/posts_helper.rb +2 -0
- data/test/rails_root/app/helpers/users_helper.rb +2 -0
- data/test/rails_root/app/models/address.rb +7 -0
- data/test/rails_root/app/models/dog.rb +5 -0
- data/test/rails_root/app/models/flea.rb +3 -0
- data/test/rails_root/app/models/friendship.rb +4 -0
- data/test/rails_root/app/models/post.rb +12 -0
- data/test/rails_root/app/models/product.rb +12 -0
- data/test/rails_root/app/models/tag.rb +8 -0
- data/test/rails_root/app/models/tagging.rb +4 -0
- data/test/rails_root/app/models/user.rb +28 -0
- data/test/rails_root/app/views/layouts/posts.rhtml +17 -0
- data/test/rails_root/app/views/layouts/users.rhtml +17 -0
- data/test/rails_root/app/views/posts/edit.rhtml +27 -0
- data/test/rails_root/app/views/posts/index.rhtml +25 -0
- data/test/rails_root/app/views/posts/new.rhtml +26 -0
- data/test/rails_root/app/views/posts/show.rhtml +18 -0
- data/test/rails_root/app/views/users/edit.rhtml +22 -0
- data/test/rails_root/app/views/users/index.rhtml +22 -0
- data/test/rails_root/app/views/users/new.rhtml +21 -0
- data/test/rails_root/app/views/users/show.rhtml +13 -0
- data/test/rails_root/config/boot.rb +109 -0
- data/test/rails_root/config/database.yml +4 -0
- data/test/rails_root/config/environment.rb +14 -0
- data/test/rails_root/config/environments/sqlite3.rb +0 -0
- data/test/rails_root/config/initializers/new_rails_defaults.rb +15 -0
- data/test/rails_root/config/initializers/shoulda.rb +8 -0
- data/test/rails_root/config/routes.rb +6 -0
- data/test/rails_root/db/migrate/001_create_users.rb +18 -0
- data/test/rails_root/db/migrate/002_create_posts.rb +13 -0
- data/test/rails_root/db/migrate/003_create_taggings.rb +12 -0
- data/test/rails_root/db/migrate/004_create_tags.rb +11 -0
- data/test/rails_root/db/migrate/005_create_dogs.rb +12 -0
- data/test/rails_root/db/migrate/006_create_addresses.rb +14 -0
- data/test/rails_root/db/migrate/007_create_fleas.rb +11 -0
- data/test/rails_root/db/migrate/008_create_dogs_fleas.rb +12 -0
- data/test/rails_root/db/migrate/009_create_products.rb +17 -0
- data/test/rails_root/db/migrate/010_create_friendships.rb +14 -0
- data/test/rails_root/db/schema.rb +0 -0
- data/test/rails_root/log/sqlite3.log +0 -0
- data/test/rails_root/public/404.html +30 -0
- data/test/rails_root/public/422.html +30 -0
- data/test/rails_root/public/500.html +30 -0
- data/test/rails_root/script/console +3 -0
- data/test/rails_root/script/generate +3 -0
- data/test/test_helper.rb +33 -0
- data/test/unit/address_test.rb +10 -0
- data/test/unit/dog_test.rb +7 -0
- data/test/unit/flea_test.rb +6 -0
- data/test/unit/friendship_test.rb +6 -0
- data/test/unit/post_test.rb +15 -0
- data/test/unit/product_test.rb +27 -0
- data/test/unit/tag_test.rb +14 -0
- data/test/unit/tagging_test.rb +6 -0
- data/test/unit/user_test.rb +52 -0
- metadata +170 -0
data/test/README
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
The Shoulda test suite (in particular - the tests that test shoulda)
|
2
|
+
|
3
|
+
Quick overview:
|
4
|
+
|
5
|
+
The test directory contains the following files and subdirectories:
|
6
|
+
|
7
|
+
* rails_root - contains the stripped down rails application that the tests run against. The rails root contains:
|
8
|
+
** the models, controllers, and views defined under app/
|
9
|
+
** the sqlite3.rb environment file
|
10
|
+
** a migration file for each model
|
11
|
+
** a shoulda initializer that simulates loading the plugin but without relying on vendor/plugins
|
12
|
+
* fixtures - contain the sample DB data for each model
|
13
|
+
* functional - controller tests for each of the controllers under rails_root/app
|
14
|
+
* unit - model tests for each of the models under rails_root/app
|
15
|
+
* other - tests for the shoulda contexts, should statements, and assertions
|
16
|
+
* test_helper.rb - responsible for initializing the test environment
|
17
|
+
** sets the rails_env to sqlite3
|
18
|
+
** sets the rails_root
|
19
|
+
** runs all the migrations against the in-memory sqlite3 db
|
20
|
+
** adds some magic to load the right fixture files
|
21
|
+
|
22
|
+
In order to add a new model (or controller) to the test suite:
|
23
|
+
|
24
|
+
* add that model to rails_root/app/models
|
25
|
+
* add a migration for that model
|
26
|
+
* add a fixture file
|
27
|
+
* add a test for that file under test/units
|
28
|
+
|
29
|
+
Dependencies:
|
30
|
+
|
31
|
+
* Rails gem installed in the host system
|
32
|
+
* A working sqlite3 installation.
|
33
|
+
|
34
|
+
If you have problems running these tests, please notify the mailing list: shoulda@googlegroups.com
|
35
|
+
|
36
|
+
- Tammer Saleh <tsaleh@thoughtbot.com>
|
File without changes
|
File without changes
|
File without changes
|
@@ -0,0 +1,104 @@
|
|
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
|
+
end
|
77
|
+
|
78
|
+
context "viewing posts for a user with rss format" do
|
79
|
+
setup do
|
80
|
+
get :index, :user_id => users(:first), :format => 'rss'
|
81
|
+
@user = users(:first)
|
82
|
+
end
|
83
|
+
should_respond_with :success
|
84
|
+
should_respond_with_content_type 'application/rss+xml'
|
85
|
+
should_respond_with_content_type :rss
|
86
|
+
should_respond_with_content_type /rss/
|
87
|
+
should_return_from_session :special, "'$2 off your next purchase'"
|
88
|
+
should_return_from_session :special_user_id, '@user.id'
|
89
|
+
should_assign_to :user, :posts
|
90
|
+
should_not_assign_to :foo, :bar
|
91
|
+
end
|
92
|
+
|
93
|
+
context "viewing a post on GET to #show" do
|
94
|
+
setup { get :show, :user_id => users(:first), :id => posts(:first) }
|
95
|
+
should_render_with_layout 'wide'
|
96
|
+
end
|
97
|
+
|
98
|
+
context "on GET to #new" do
|
99
|
+
setup { get :new, :user_id => users(:first) }
|
100
|
+
should_render_without_layout
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
end
|
@@ -0,0 +1,36 @@
|
|
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_be_restful do |resource|
|
18
|
+
resource.identifier = :id
|
19
|
+
resource.klass = User
|
20
|
+
resource.object = :user
|
21
|
+
resource.parent = []
|
22
|
+
resource.actions = [:index, :show, :new, :edit, :update, :create, :destroy]
|
23
|
+
resource.formats = [:html, :xml]
|
24
|
+
|
25
|
+
resource.create.params = { :name => "bob", :email => 'bob@bob.com', :age => 13, :ssn => "123456789"}
|
26
|
+
resource.update.params = { :name => "sue" }
|
27
|
+
|
28
|
+
resource.create.redirect = "user_url(@user)"
|
29
|
+
resource.update.redirect = "user_url(@user)"
|
30
|
+
resource.destroy.redirect = "users_url"
|
31
|
+
|
32
|
+
resource.create.flash = /created/i
|
33
|
+
resource.update.flash = /updated/i
|
34
|
+
resource.destroy.flash = /removed/i
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,145 @@
|
|
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 setup block" do
|
21
|
+
setup do
|
22
|
+
@blah = "blah"
|
23
|
+
end
|
24
|
+
|
25
|
+
should "run the setup block" do
|
26
|
+
assert_equal "blah", @blah
|
27
|
+
end
|
28
|
+
|
29
|
+
should "have name set right" do
|
30
|
+
assert_match(/^test: context with setup block/, self.to_s)
|
31
|
+
end
|
32
|
+
|
33
|
+
context "and a subcontext" do
|
34
|
+
setup do
|
35
|
+
@blah = "#{@blah} twice"
|
36
|
+
end
|
37
|
+
|
38
|
+
should "be named correctly" do
|
39
|
+
assert_match(/^test: context with setup block and a subcontext should be named correctly/, self.to_s)
|
40
|
+
end
|
41
|
+
|
42
|
+
should "run the setup blocks in order" do
|
43
|
+
assert_equal @blah, "blah twice"
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
context_macro do
|
48
|
+
should "have name set right" do
|
49
|
+
assert_match(/^test: context with setup block with a subcontext made by a macro should have name set right/, self.to_s)
|
50
|
+
end
|
51
|
+
|
52
|
+
should "run the setup block of that context macro" do
|
53
|
+
assert_equal :foo, @context_macro
|
54
|
+
end
|
55
|
+
|
56
|
+
should "run the setup block of the main context" do
|
57
|
+
assert_equal "blah", @blah
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
|
63
|
+
context "another context with setup block" do
|
64
|
+
setup do
|
65
|
+
@blah = "foo"
|
66
|
+
end
|
67
|
+
|
68
|
+
should "have @blah == 'foo'" do
|
69
|
+
assert_equal "foo", @blah
|
70
|
+
end
|
71
|
+
|
72
|
+
should "have name set right" do
|
73
|
+
assert_match(/^test: another context with setup block/, self.to_s)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
context "context with method definition" do
|
78
|
+
setup do
|
79
|
+
def hello; "hi"; end
|
80
|
+
end
|
81
|
+
|
82
|
+
should "be able to read that method" do
|
83
|
+
assert_equal "hi", hello
|
84
|
+
end
|
85
|
+
|
86
|
+
should "have name set right" do
|
87
|
+
assert_match(/^test: context with method definition/, self.to_s)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
context "another context" do
|
92
|
+
should "not define @blah" do
|
93
|
+
assert_nil @blah
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
context "context with multiple setups and/or teardowns" do
|
98
|
+
|
99
|
+
cleanup_count = 0
|
100
|
+
|
101
|
+
2.times do |i|
|
102
|
+
setup { cleanup_count += 1 }
|
103
|
+
teardown { cleanup_count -= 1 }
|
104
|
+
end
|
105
|
+
|
106
|
+
2.times do |i|
|
107
|
+
should "call all setups and all teardowns (check ##{i + 1})" do
|
108
|
+
assert_equal 2, cleanup_count
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
context "subcontexts" do
|
113
|
+
|
114
|
+
2.times do |i|
|
115
|
+
setup { cleanup_count += 1 }
|
116
|
+
teardown { cleanup_count -= 1 }
|
117
|
+
end
|
118
|
+
|
119
|
+
2.times do |i|
|
120
|
+
should "also call all setups and all teardowns in parent and subcontext (check ##{i + 1})" do
|
121
|
+
assert_equal 4, cleanup_count
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
end
|
126
|
+
|
127
|
+
end
|
128
|
+
|
129
|
+
should_eventually "pass, since it's unimplemented" do
|
130
|
+
flunk "what?"
|
131
|
+
end
|
132
|
+
|
133
|
+
should_eventually "not require a block when using should_eventually"
|
134
|
+
should "pass without a block, as that causes it to piggyback to should_eventually"
|
135
|
+
|
136
|
+
context "context for testing should piggybacking" do
|
137
|
+
should "call should_eventually as we are not passing a block"
|
138
|
+
end
|
139
|
+
|
140
|
+
context "context" do
|
141
|
+
context "with nested subcontexts" do
|
142
|
+
should_eventually "only print this statement once for a should_eventually"
|
143
|
+
end
|
144
|
+
end
|
145
|
+
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
|