shoulda 2.9.1 → 2.9.2
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +27 -5
- data/Rakefile +2 -2
- data/lib/shoulda.rb +1 -1
- data/lib/shoulda/{controller.rb → action_controller.rb} +6 -8
- data/lib/shoulda/{controller → action_controller}/helpers.rb +1 -16
- data/lib/shoulda/action_controller/macros.rb +277 -0
- data/lib/shoulda/action_controller/matchers.rb +37 -0
- data/lib/shoulda/action_controller/matchers/assign_to_matcher.rb +109 -0
- data/lib/shoulda/action_controller/matchers/filter_param_matcher.rb +57 -0
- data/lib/shoulda/action_controller/matchers/render_with_layout_matcher.rb +81 -0
- data/lib/shoulda/action_controller/matchers/respond_with_content_type_matcher.rb +70 -0
- data/lib/shoulda/action_controller/matchers/respond_with_matcher.rb +81 -0
- data/lib/shoulda/action_controller/matchers/route_matcher.rb +93 -0
- data/lib/shoulda/action_controller/matchers/set_session_matcher.rb +83 -0
- data/lib/shoulda/action_controller/matchers/set_the_flash_matcher.rb +85 -0
- data/lib/shoulda/action_view.rb +10 -0
- data/lib/shoulda/action_view/macros.rb +56 -0
- data/lib/shoulda/active_record/macros.rb +8 -13
- data/lib/shoulda/active_record/matchers/validate_uniqueness_of_matcher.rb +1 -1
- data/lib/shoulda/rails.rb +4 -3
- data/lib/shoulda/rspec.rb +7 -5
- data/test/functional/posts_controller_test.rb +28 -22
- data/test/functional/users_controller_test.rb +0 -19
- data/test/matchers/{allow_mass_assignment_of_matcher_test.rb → active_record/allow_mass_assignment_of_matcher_test.rb} +1 -1
- data/test/matchers/{allow_value_matcher_test.rb → active_record/allow_value_matcher_test.rb} +1 -1
- data/test/matchers/{association_matcher_test.rb → active_record/association_matcher_test.rb} +1 -1
- data/test/matchers/{ensure_inclusion_of_matcher_test.rb → active_record/ensure_inclusion_of_matcher_test.rb} +1 -1
- data/test/matchers/{ensure_length_of_matcher_test.rb → active_record/ensure_length_of_matcher_test.rb} +1 -1
- data/test/matchers/{have_db_column_matcher_test.rb → active_record/have_db_column_matcher_test.rb} +1 -1
- data/test/matchers/{have_index_matcher_test.rb → active_record/have_index_matcher_test.rb} +1 -1
- data/test/matchers/{have_named_scope_matcher_test.rb → active_record/have_named_scope_matcher_test.rb} +1 -1
- data/test/matchers/{have_readonly_attributes_matcher_test.rb → active_record/have_readonly_attributes_matcher_test.rb} +1 -1
- data/test/matchers/{validate_acceptance_of_matcher_test.rb → active_record/validate_acceptance_of_matcher_test.rb} +1 -1
- data/test/matchers/{validate_numericality_of_matcher_test.rb → active_record/validate_numericality_of_matcher_test.rb} +1 -1
- data/test/matchers/{validate_presence_of_matcher_test.rb → active_record/validate_presence_of_matcher_test.rb} +1 -1
- data/test/matchers/{validate_uniqueness_of_matcher_test.rb → active_record/validate_uniqueness_of_matcher_test.rb} +8 -2
- data/test/matchers/controller/assign_to_matcher_test.rb +35 -0
- data/test/matchers/controller/filter_param_matcher_test.rb +32 -0
- data/test/matchers/controller/render_with_layout_matcher_test.rb +33 -0
- data/test/matchers/controller/respond_with_content_type_matcher_test.rb +27 -0
- data/test/matchers/controller/respond_with_matcher_test.rb +106 -0
- data/test/matchers/controller/route_matcher_test.rb +58 -0
- data/test/matchers/controller/set_session_matcher_test.rb +27 -0
- data/test/matchers/controller/set_the_flash_matcher.rb +41 -0
- data/test/model_builder.rb +47 -2
- data/test/rails_root/app/models/user.rb +2 -1
- data/test/rails_root/config/environment.rb +1 -1
- data/test/rspec_test.rb +207 -0
- data/test/unit/user_test.rb +10 -1
- metadata +38 -22
- data/lib/shoulda/controller/formats/html.rb +0 -199
- data/lib/shoulda/controller/formats/xml.rb +0 -168
- data/lib/shoulda/controller/macros.rb +0 -336
- data/lib/shoulda/controller/resource_options.rb +0 -233
@@ -0,0 +1,83 @@
|
|
1
|
+
module Shoulda # :nodoc:
|
2
|
+
module ActionController # :nodoc:
|
3
|
+
module Matchers
|
4
|
+
|
5
|
+
# Ensures that a session key was set to the expected value.
|
6
|
+
#
|
7
|
+
# Example:
|
8
|
+
#
|
9
|
+
# it { should set_session(:message) }
|
10
|
+
# it { should set_session(:user_id).to(@user.id) }
|
11
|
+
# it { should_not set_session(:user_id) }
|
12
|
+
def set_session(key)
|
13
|
+
SetSessionMatcher.new(key)
|
14
|
+
end
|
15
|
+
|
16
|
+
class SetSessionMatcher # :nodoc:
|
17
|
+
|
18
|
+
def initialize(key)
|
19
|
+
@key = key.to_s
|
20
|
+
end
|
21
|
+
|
22
|
+
def to(value)
|
23
|
+
@value = value
|
24
|
+
self
|
25
|
+
end
|
26
|
+
|
27
|
+
def matches?(controller)
|
28
|
+
@controller = controller
|
29
|
+
assigned_value? && assigned_correct_value?
|
30
|
+
end
|
31
|
+
|
32
|
+
def failure_message
|
33
|
+
"Expected #{expectation}, but #{result}"
|
34
|
+
end
|
35
|
+
|
36
|
+
def negative_failure_message
|
37
|
+
"Didn't expect #{expectation}, but #{result}"
|
38
|
+
end
|
39
|
+
|
40
|
+
def description
|
41
|
+
description = "set session variable #{@key.inspect}"
|
42
|
+
description << " to #{@value.inspect}" if @value
|
43
|
+
description
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
def assigned_value?
|
49
|
+
!assigned_value.blank?
|
50
|
+
end
|
51
|
+
|
52
|
+
def assigned_correct_value?
|
53
|
+
return true if @value.nil?
|
54
|
+
assigned_value == @value
|
55
|
+
end
|
56
|
+
|
57
|
+
def assigned_value
|
58
|
+
session[@key]
|
59
|
+
end
|
60
|
+
|
61
|
+
def session
|
62
|
+
@controller.response.session.data
|
63
|
+
end
|
64
|
+
|
65
|
+
def expectation
|
66
|
+
expectation = "session variable #{@key} to be set"
|
67
|
+
expectation << " to #{@value.inspect}" if @value
|
68
|
+
expectation
|
69
|
+
end
|
70
|
+
|
71
|
+
def result
|
72
|
+
if session.empty?
|
73
|
+
"no session variables were set"
|
74
|
+
else
|
75
|
+
"the session was #{session.inspect}"
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
module Shoulda # :nodoc:
|
2
|
+
module ActionController # :nodoc:
|
3
|
+
module Matchers
|
4
|
+
|
5
|
+
# Ensures that the flash contains the given value. Can be a String, a
|
6
|
+
# Regexp, or nil (indicating that the flash should not be set).
|
7
|
+
#
|
8
|
+
# Example:
|
9
|
+
#
|
10
|
+
# it { should set_the_flash }
|
11
|
+
# it { should set_the_flash.to("Thank you for placing this order.") }
|
12
|
+
# it { should set_the_flash.to(/created/i) }
|
13
|
+
# it { should_not set_the_flash }
|
14
|
+
def set_the_flash
|
15
|
+
SetTheFlashMatcher.new
|
16
|
+
end
|
17
|
+
|
18
|
+
class SetTheFlashMatcher # :nodoc:
|
19
|
+
|
20
|
+
def to(value)
|
21
|
+
@value = value
|
22
|
+
self
|
23
|
+
end
|
24
|
+
|
25
|
+
def matches?(controller)
|
26
|
+
@controller = controller
|
27
|
+
sets_the_flash? && string_value_matches? && regexp_value_matches?
|
28
|
+
end
|
29
|
+
|
30
|
+
attr_reader :failure_message, :negative_failure_message
|
31
|
+
|
32
|
+
def description
|
33
|
+
description = "set the flash"
|
34
|
+
description << " to #{@value.inspect}" unless @value.nil?
|
35
|
+
description
|
36
|
+
end
|
37
|
+
|
38
|
+
def failure_message
|
39
|
+
"Expected #{expectation}"
|
40
|
+
end
|
41
|
+
|
42
|
+
def negative_failure_message
|
43
|
+
"Did not expect #{expectation}"
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
def sets_the_flash?
|
49
|
+
!flash.blank?
|
50
|
+
end
|
51
|
+
|
52
|
+
def string_value_matches?
|
53
|
+
return true unless String === @value
|
54
|
+
flash.values.any? {|value| value == @value }
|
55
|
+
end
|
56
|
+
|
57
|
+
def regexp_value_matches?
|
58
|
+
return true unless Regexp === @value
|
59
|
+
flash.values.any? {|value| value =~ @value }
|
60
|
+
end
|
61
|
+
|
62
|
+
def flash
|
63
|
+
@controller.response.session['flash']
|
64
|
+
end
|
65
|
+
|
66
|
+
def expectation
|
67
|
+
expectation = "the flash to be set"
|
68
|
+
expectation << " to #{@value.inspect}" unless @value.nil?
|
69
|
+
expectation << ", but #{flash_description}"
|
70
|
+
expectation
|
71
|
+
end
|
72
|
+
|
73
|
+
def flash_description
|
74
|
+
if flash.blank?
|
75
|
+
"no flash was set"
|
76
|
+
else
|
77
|
+
"was #{flash.inspect}"
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
82
|
+
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
module Shoulda # :nodoc:
|
2
|
+
module ActionView # :nodoc:
|
3
|
+
# = Macro test helpers for your view
|
4
|
+
#
|
5
|
+
# By using the macro helpers you can quickly and easily create concise and
|
6
|
+
# easy to read test suites.
|
7
|
+
#
|
8
|
+
# This code segment:
|
9
|
+
# context "on GET to :new" do
|
10
|
+
# setup do
|
11
|
+
# get :new
|
12
|
+
# end
|
13
|
+
#
|
14
|
+
# should_render_a_form
|
15
|
+
# should_render_page_with_metadata :title => /index/
|
16
|
+
#
|
17
|
+
# should "do something else really cool" do
|
18
|
+
# assert_select '#really_cool'
|
19
|
+
# end
|
20
|
+
# end
|
21
|
+
#
|
22
|
+
# Would produce 3 tests for the +show+ action
|
23
|
+
module Macros
|
24
|
+
|
25
|
+
# Macro that creates a test asserting that the rendered view contains a <form> element.
|
26
|
+
def should_render_a_form
|
27
|
+
should "display a form" do
|
28
|
+
assert_select "form", true, "The template doesn't contain a <form> element"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
# Macro that creates a test asserting that the rendered view contains the selected metatags.
|
33
|
+
# Values can be string or Regexps.
|
34
|
+
# Example:
|
35
|
+
#
|
36
|
+
# should_render_page_with_metadata :description => "Description of this page", :keywords => /post/
|
37
|
+
#
|
38
|
+
# You can also use this method to test the rendered views title.
|
39
|
+
#
|
40
|
+
# Example:
|
41
|
+
# should_render_page_with_metadata :title => /index/
|
42
|
+
def should_render_page_with_metadata(options)
|
43
|
+
options.each do |key, value|
|
44
|
+
should "have metatag #{key}" do
|
45
|
+
if key.to_sym == :title
|
46
|
+
assert_select "title", value
|
47
|
+
else
|
48
|
+
assert_select "meta[name=?][content#{"*" if value.is_a?(Regexp)}=?]", key, value
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
@@ -23,14 +23,6 @@ module Shoulda # :nodoc:
|
|
23
23
|
include Helpers
|
24
24
|
include Matchers
|
25
25
|
|
26
|
-
# <b>DEPRECATED:</b> Use <tt>fixtures :all</tt> instead
|
27
|
-
#
|
28
|
-
# Loads all fixture files (<tt>test/fixtures/*.yml</tt>)
|
29
|
-
def load_all_fixtures
|
30
|
-
warn "[DEPRECATION] load_all_fixtures is deprecated. Use `fixtures :all` instead."
|
31
|
-
fixtures :all
|
32
|
-
end
|
33
|
-
|
34
26
|
# Ensures that the model cannot be saved if one of the attributes listed is not present.
|
35
27
|
#
|
36
28
|
# If an instance variable has been created in the setup named after the
|
@@ -304,13 +296,16 @@ module Shoulda # :nodoc:
|
|
304
296
|
# should_ensure_value_in_range :age, (0..100)
|
305
297
|
#
|
306
298
|
def should_ensure_value_in_range(attribute, range, opts = {})
|
307
|
-
message = get_options!([opts],
|
308
|
-
|
309
|
-
|
299
|
+
message, low_message, high_message = get_options!([opts],
|
300
|
+
:message,
|
301
|
+
:low_message,
|
302
|
+
:high_message)
|
310
303
|
klass = model_class
|
311
304
|
matcher = ensure_inclusion_of(attribute).
|
312
305
|
in_range(range).
|
313
|
-
with_message(message)
|
306
|
+
with_message(message).
|
307
|
+
with_low_message(low_message).
|
308
|
+
with_high_message(high_message)
|
314
309
|
should matcher.description do
|
315
310
|
assert_accepts matcher, get_instance_of(klass)
|
316
311
|
end
|
@@ -341,7 +336,7 @@ module Shoulda # :nodoc:
|
|
341
336
|
end
|
342
337
|
end
|
343
338
|
|
344
|
-
# Deprecated. See
|
339
|
+
# Deprecated. See should_validate_numericality_of
|
345
340
|
def should_only_allow_numeric_values_for(*attributes)
|
346
341
|
warn "[DEPRECATION] should_only_allow_numeric_values_for is " <<
|
347
342
|
"deprecated. Use should_validate_numericality_of instead."
|
data/lib/shoulda/rails.rb
CHANGED
@@ -2,9 +2,10 @@ require 'rubygems'
|
|
2
2
|
require 'active_support'
|
3
3
|
require 'shoulda'
|
4
4
|
|
5
|
-
require 'shoulda/active_record'
|
6
|
-
require 'shoulda/
|
7
|
-
require 'shoulda/
|
5
|
+
require 'shoulda/active_record' if defined? ActiveRecord::Base
|
6
|
+
require 'shoulda/action_controller' if defined? ActionController::Base
|
7
|
+
require 'shoulda/action_view' if defined? ActionView::Base
|
8
|
+
require 'shoulda/action_mailer' if defined? ActionMailer::Base
|
8
9
|
|
9
10
|
if defined?(RAILS_ROOT)
|
10
11
|
# load in the 3rd party macros from vendorized plugins and gems
|
data/lib/shoulda/rspec.rb
CHANGED
@@ -1,9 +1,11 @@
|
|
1
1
|
require 'shoulda/active_record/matchers'
|
2
|
+
require 'shoulda/action_controller/matchers'
|
3
|
+
require 'active_support/test_case'
|
2
4
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
5
|
+
# :enddoc:
|
6
|
+
module ActiveSupport
|
7
|
+
class TestCase
|
8
|
+
include Shoulda::ActiveRecord::Matchers
|
9
|
+
include Shoulda::ActionController::Matchers
|
8
10
|
end
|
9
11
|
end
|
@@ -33,44 +33,27 @@ class PostsControllerTest < Test::Unit::TestCase
|
|
33
33
|
should_route :get, '/users/5/posts/new', :action => :new, :user_id => 5
|
34
34
|
should_route :put, '/users/5/posts/1', :action => :update, :id => 1, :user_id => 5
|
35
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
36
|
context "Logged in" do
|
51
37
|
setup do
|
52
38
|
@request.session[:logged_in] = true
|
53
39
|
end
|
54
40
|
|
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
41
|
context "viewing posts for a user" do
|
63
42
|
setup do
|
64
43
|
get :index, :user_id => users(:first)
|
65
44
|
end
|
66
45
|
should_respond_with :success
|
67
46
|
should_assign_to :user, :class => User, :equals => 'users(:first)'
|
47
|
+
should_assign_to(:user) { users(:first) }
|
68
48
|
should_fail do
|
69
49
|
should_assign_to :user, :class => Post
|
70
50
|
end
|
71
51
|
should_fail do
|
72
52
|
should_assign_to :user, :equals => 'posts(:first)'
|
73
53
|
end
|
54
|
+
should_fail do
|
55
|
+
should_assign_to(:user) { posts(:first) }
|
56
|
+
end
|
74
57
|
should_assign_to :posts
|
75
58
|
should_not_assign_to :foo, :bar
|
76
59
|
should_render_page_with_metadata :description => /Posts/, :title => /index/
|
@@ -87,7 +70,12 @@ class PostsControllerTest < Test::Unit::TestCase
|
|
87
70
|
should_respond_with_content_type :rss
|
88
71
|
should_respond_with_content_type /rss/
|
89
72
|
should_return_from_session :special, "'$2 off your next purchase'"
|
90
|
-
|
73
|
+
should_set_session :special, "'$2 off your next purchase'"
|
74
|
+
should_set_session :special_user_id, '@user.id'
|
75
|
+
should_set_session(:special_user_id) { @user.id }
|
76
|
+
should_fail do
|
77
|
+
should_set_session(:special_user_id) { 'value' }
|
78
|
+
end
|
91
79
|
should_assign_to :user, :posts
|
92
80
|
should_not_assign_to :foo, :bar
|
93
81
|
end
|
@@ -103,6 +91,24 @@ class PostsControllerTest < Test::Unit::TestCase
|
|
103
91
|
setup { get :new, :user_id => users(:first) }
|
104
92
|
should_render_without_layout
|
105
93
|
end
|
94
|
+
|
95
|
+
context "on POST to #create" do
|
96
|
+
setup do
|
97
|
+
post :create, :user_id => users(:first),
|
98
|
+
:post => { :title => "first post",
|
99
|
+
:body => 'blah blah blah' }
|
100
|
+
end
|
101
|
+
|
102
|
+
should_redirect_to 'user_post_url(@post.user, @post)'
|
103
|
+
should_redirect_to('the created post') { user_post_url(users(:first),
|
104
|
+
assigns(:post)) }
|
105
|
+
should_fail do
|
106
|
+
should_redirect_to 'user_posts_url(@post.user)'
|
107
|
+
end
|
108
|
+
should_fail do
|
109
|
+
should_redirect_to('elsewhere') { user_posts_url(users(:first)) }
|
110
|
+
end
|
111
|
+
end
|
106
112
|
end
|
107
113
|
|
108
114
|
end
|
@@ -16,23 +16,4 @@ class UsersControllerTest < Test::Unit::TestCase
|
|
16
16
|
|
17
17
|
should_filter_params :ssn
|
18
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
19
|
end
|