shoulda 2.0.6 → 2.9.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/README.rdoc +35 -7
- data/Rakefile +5 -3
- data/lib/shoulda.rb +7 -15
- data/lib/shoulda/action_mailer.rb +1 -1
- data/lib/shoulda/action_mailer/assertions.rb +32 -33
- data/lib/shoulda/active_record.rb +6 -2
- data/lib/shoulda/active_record/assertions.rb +62 -81
- data/lib/shoulda/active_record/helpers.rb +40 -0
- data/lib/shoulda/active_record/macros.rb +518 -639
- data/lib/shoulda/active_record/matchers.rb +42 -0
- data/lib/shoulda/active_record/matchers/allow_mass_assignment_of_matcher.rb +83 -0
- data/lib/shoulda/active_record/matchers/allow_value_matcher.rb +102 -0
- data/lib/shoulda/active_record/matchers/association_matcher.rb +226 -0
- data/lib/shoulda/active_record/matchers/ensure_inclusion_of_matcher.rb +87 -0
- data/lib/shoulda/active_record/matchers/ensure_length_of_matcher.rb +141 -0
- data/lib/shoulda/active_record/matchers/have_db_column_matcher.rb +169 -0
- data/lib/shoulda/active_record/matchers/have_index_matcher.rb +105 -0
- data/lib/shoulda/active_record/matchers/have_named_scope_matcher.rb +125 -0
- data/lib/shoulda/active_record/matchers/have_readonly_attribute_matcher.rb +59 -0
- data/lib/shoulda/active_record/matchers/validate_acceptance_of_matcher.rb +41 -0
- data/lib/shoulda/active_record/matchers/validate_numericality_of_matcher.rb +39 -0
- data/lib/shoulda/active_record/matchers/validate_presence_of_matcher.rb +60 -0
- data/lib/shoulda/active_record/matchers/validate_uniqueness_of_matcher.rb +148 -0
- data/lib/shoulda/active_record/matchers/validation_matcher.rb +56 -0
- data/lib/shoulda/assertions.rb +50 -40
- data/lib/shoulda/autoload_macros.rb +46 -0
- data/lib/shoulda/context.rb +124 -126
- data/lib/shoulda/controller.rb +8 -8
- data/lib/shoulda/controller/formats/html.rb +158 -160
- data/lib/shoulda/controller/formats/xml.rb +132 -134
- data/lib/shoulda/controller/helpers.rb +51 -53
- data/lib/shoulda/controller/macros.rb +278 -258
- data/lib/shoulda/controller/resource_options.rb +211 -214
- data/lib/shoulda/helpers.rb +5 -7
- data/lib/shoulda/macros.rb +63 -64
- data/lib/shoulda/private_helpers.rb +16 -18
- data/lib/shoulda/rails.rb +1 -8
- data/lib/shoulda/rspec.rb +5 -0
- data/lib/shoulda/tasks/list_tests.rake +6 -1
- data/lib/shoulda/test_unit.rb +19 -0
- data/rails/init.rb +1 -1
- data/test/README +2 -2
- data/test/fail_macros.rb +16 -16
- data/test/functional/posts_controller_test.rb +5 -2
- data/test/matchers/allow_mass_assignment_of_matcher_test.rb +68 -0
- data/test/matchers/allow_value_matcher_test.rb +41 -0
- data/test/matchers/association_matcher_test.rb +258 -0
- data/test/matchers/ensure_inclusion_of_matcher_test.rb +80 -0
- data/test/matchers/ensure_length_of_matcher_test.rb +158 -0
- data/test/matchers/have_db_column_matcher_test.rb +169 -0
- data/test/matchers/have_index_matcher_test.rb +74 -0
- data/test/matchers/have_named_scope_matcher_test.rb +65 -0
- data/test/matchers/have_readonly_attributes_matcher_test.rb +29 -0
- data/test/matchers/validate_acceptance_of_matcher_test.rb +44 -0
- data/test/matchers/validate_numericality_of_matcher_test.rb +52 -0
- data/test/matchers/validate_presence_of_matcher_test.rb +86 -0
- data/test/matchers/validate_uniqueness_of_matcher_test.rb +141 -0
- data/test/model_builder.rb +61 -0
- data/test/other/autoload_macro_test.rb +18 -0
- data/test/other/helpers_test.rb +58 -0
- data/test/other/private_helpers_test.rb +1 -1
- data/test/other/should_test.rb +16 -16
- data/test/rails_root/app/controllers/posts_controller.rb +6 -5
- data/test/rails_root/app/models/pets/dog.rb +10 -0
- data/test/rails_root/app/models/treat.rb +3 -0
- data/test/rails_root/app/models/user.rb +2 -2
- data/test/rails_root/app/views/layouts/posts.rhtml +2 -0
- data/test/rails_root/config/database.yml +1 -1
- data/test/rails_root/config/environments/{sqlite3.rb → test.rb} +0 -0
- data/test/rails_root/db/migrate/001_create_users.rb +3 -2
- data/test/rails_root/db/migrate/011_create_treats.rb +12 -0
- data/test/rails_root/log/test.log +0 -0
- data/test/rails_root/test/shoulda_macros/custom_macro.rb +6 -0
- data/test/rails_root/vendor/gems/gem_with_macro-0.0.1/shoulda_macros/gem_macro.rb +6 -0
- data/test/rails_root/vendor/plugins/plugin_with_macro/shoulda_macros/plugin_macro.rb +6 -0
- data/test/test_helper.rb +3 -1
- data/test/unit/address_test.rb +1 -1
- data/test/unit/dog_test.rb +5 -2
- data/test/unit/post_test.rb +7 -3
- data/test/unit/product_test.rb +2 -2
- data/test/unit/tag_test.rb +2 -1
- data/test/unit/user_test.rb +17 -8
- metadata +44 -4
- data/test/rails_root/app/models/dog.rb +0 -5
@@ -1,63 +1,61 @@
|
|
1
|
-
module
|
2
|
-
module
|
3
|
-
module
|
4
|
-
|
5
|
-
private # :enddoc:
|
1
|
+
module Shoulda # :nodoc:
|
2
|
+
module Controller # :nodoc:
|
3
|
+
module Helpers # :nodoc:
|
4
|
+
private # :enddoc:
|
6
5
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
6
|
+
SPECIAL_INSTANCE_VARIABLES = %w{
|
7
|
+
_cookies
|
8
|
+
_flash
|
9
|
+
_headers
|
10
|
+
_params
|
11
|
+
_request
|
12
|
+
_response
|
13
|
+
_session
|
14
|
+
action_name
|
15
|
+
before_filter_chain_aborted
|
16
|
+
cookies
|
17
|
+
flash
|
18
|
+
headers
|
19
|
+
ignore_missing_templates
|
20
|
+
logger
|
21
|
+
params
|
22
|
+
request
|
23
|
+
request_origin
|
24
|
+
response
|
25
|
+
session
|
26
|
+
template
|
27
|
+
template_class
|
28
|
+
template_root
|
29
|
+
url
|
30
|
+
variables_added
|
31
|
+
}.map(&:to_s)
|
33
32
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
end
|
41
|
-
blk.call
|
42
|
-
names.each do |name|
|
43
|
-
instance_variable_set("@#{name}", old[name])
|
44
|
-
end
|
33
|
+
def instantiate_variables_from_assigns(*names, &blk)
|
34
|
+
old = {}
|
35
|
+
names = (@response.template.assigns.keys - SPECIAL_INSTANCE_VARIABLES) if names.empty?
|
36
|
+
names.each do |name|
|
37
|
+
old[name] = instance_variable_get("@#{name}")
|
38
|
+
instance_variable_set("@#{name}", assigns(name.to_sym))
|
45
39
|
end
|
40
|
+
blk.call
|
41
|
+
names.each do |name|
|
42
|
+
instance_variable_set("@#{name}", old[name])
|
43
|
+
end
|
44
|
+
end
|
46
45
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
end
|
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")
|
51
49
|
end
|
50
|
+
end
|
52
51
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
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)
|
58
57
|
|
59
|
-
|
60
|
-
end
|
58
|
+
{ :"#{parent_name}_id" => parent.to_param }.merge(make_parent_params(resource, parent, parent_names))
|
61
59
|
end
|
62
60
|
end
|
63
61
|
end
|
@@ -1,314 +1,334 @@
|
|
1
|
-
module
|
2
|
-
module
|
3
|
-
|
4
|
-
|
1
|
+
module Shoulda # :nodoc:
|
2
|
+
module Controller # :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
|
+
#
|
25
|
+
# Furthermore, the should_be_restful helper will create an entire set of tests which will verify that your
|
26
|
+
# controller responds restfully to a variety of requested formats.
|
27
|
+
module Macros
|
28
|
+
# <b>DEPRECATED:</b> Please see
|
29
|
+
# http://thoughtbot.lighthouseapp.com/projects/5807/tickets/78 for more
|
30
|
+
# information.
|
5
31
|
#
|
6
|
-
#
|
32
|
+
# Generates a full suite of tests for a restful controller.
|
7
33
|
#
|
8
|
-
#
|
9
|
-
#
|
10
|
-
# setup do
|
11
|
-
# get :show, :id => 1
|
12
|
-
# end
|
34
|
+
# The following definition will generate tests for the +index+, +show+, +new+,
|
35
|
+
# +edit+, +create+, +update+ and +destroy+ actions, in both +html+ and +xml+ formats:
|
13
36
|
#
|
14
|
-
#
|
15
|
-
#
|
16
|
-
# should_render_template :show
|
17
|
-
# should_not_set_the_flash
|
37
|
+
# should_be_restful do |resource|
|
38
|
+
# resource.parent = :user
|
18
39
|
#
|
19
|
-
#
|
20
|
-
#
|
21
|
-
# end
|
40
|
+
# resource.create.params = { :title => "first post", :body => 'blah blah blah'}
|
41
|
+
# resource.update.params = { :title => "changed" }
|
22
42
|
# end
|
23
43
|
#
|
24
|
-
#
|
44
|
+
# This generates about 40 tests, all of the format:
|
45
|
+
# "on GET to :show should assign @user."
|
46
|
+
# "on GET to :show should not set the flash."
|
47
|
+
# "on GET to :show should render 'show' template."
|
48
|
+
# "on GET to :show should respond with success."
|
49
|
+
# "on GET to :show as xml should assign @user."
|
50
|
+
# "on GET to :show as xml should have ContentType set to 'application/xml'."
|
51
|
+
# "on GET to :show as xml should respond with success."
|
52
|
+
# "on GET to :show as xml should return <user/> as the root element."
|
53
|
+
# The +resource+ parameter passed into the block is a ResourceOptions object, and
|
54
|
+
# is used to configure the tests for the details of your resources.
|
25
55
|
#
|
26
|
-
|
27
|
-
|
28
|
-
module Macros
|
29
|
-
# <b>DEPRECATED:</b> Please see
|
30
|
-
# http://thoughtbot.lighthouseapp.com/projects/5807/tickets/78 for more
|
31
|
-
# information.
|
32
|
-
#
|
33
|
-
# Generates a full suite of tests for a restful controller.
|
34
|
-
#
|
35
|
-
# The following definition will generate tests for the +index+, +show+, +new+,
|
36
|
-
# +edit+, +create+, +update+ and +destroy+ actions, in both +html+ and +xml+ formats:
|
37
|
-
#
|
38
|
-
# should_be_restful do |resource|
|
39
|
-
# resource.parent = :user
|
40
|
-
#
|
41
|
-
# resource.create.params = { :title => "first post", :body => 'blah blah blah'}
|
42
|
-
# resource.update.params = { :title => "changed" }
|
43
|
-
# end
|
44
|
-
#
|
45
|
-
# This generates about 40 tests, all of the format:
|
46
|
-
# "on GET to :show should assign @user."
|
47
|
-
# "on GET to :show should not set the flash."
|
48
|
-
# "on GET to :show should render 'show' template."
|
49
|
-
# "on GET to :show should respond with success."
|
50
|
-
# "on GET to :show as xml should assign @user."
|
51
|
-
# "on GET to :show as xml should have ContentType set to 'application/xml'."
|
52
|
-
# "on GET to :show as xml should respond with success."
|
53
|
-
# "on GET to :show as xml should return <user/> as the root element."
|
54
|
-
# The +resource+ parameter passed into the block is a ResourceOptions object, and
|
55
|
-
# is used to configure the tests for the details of your resources.
|
56
|
-
#
|
57
|
-
def should_be_restful(&blk) # :yields: resource
|
58
|
-
warn "[DEPRECATION] should_be_restful is deprecated. Please see http://thoughtbot.lighthouseapp.com/projects/5807/tickets/78 for more information."
|
56
|
+
def should_be_restful(&blk) # :yields: resource
|
57
|
+
warn "[DEPRECATION] should_be_restful is deprecated. Please see http://thoughtbot.lighthouseapp.com/projects/5807/tickets/78 for more information."
|
59
58
|
|
60
|
-
|
61
|
-
|
62
|
-
|
59
|
+
resource = ResourceOptions.new
|
60
|
+
blk.call(resource)
|
61
|
+
resource.normalize!(self)
|
63
62
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
end
|
63
|
+
resource.formats.each do |format|
|
64
|
+
resource.actions.each do |action|
|
65
|
+
if self.respond_to? :"make_#{action}_#{format}_tests"
|
66
|
+
self.send(:"make_#{action}_#{format}_tests", resource)
|
67
|
+
else
|
68
|
+
should "test #{action} #{format}" do
|
69
|
+
flunk "Test for #{action} as #{format} not implemented"
|
72
70
|
end
|
73
71
|
end
|
74
72
|
end
|
75
73
|
end
|
74
|
+
end
|
76
75
|
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
end
|
76
|
+
# :section: Test macros
|
77
|
+
# Macro that creates a test asserting that the flash contains the given value.
|
78
|
+
# val can be a String, a Regex, or nil (indicating that the flash should not be set)
|
79
|
+
#
|
80
|
+
# Example:
|
81
|
+
#
|
82
|
+
# should_set_the_flash_to "Thank you for placing this order."
|
83
|
+
# should_set_the_flash_to /created/i
|
84
|
+
# should_set_the_flash_to nil
|
85
|
+
def should_set_the_flash_to(val)
|
86
|
+
if val
|
87
|
+
should "have #{val.inspect} in the flash" do
|
88
|
+
assert_contains flash.values, val, ", Flash: #{flash.inspect}"
|
89
|
+
end
|
90
|
+
else
|
91
|
+
should "not set the flash" do
|
92
|
+
assert_equal({}, flash, "Flash was set to:\n#{flash.inspect}")
|
95
93
|
end
|
96
94
|
end
|
95
|
+
end
|
97
96
|
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
97
|
+
# Macro that creates a test asserting that the flash is empty. Same as
|
98
|
+
# @should_set_the_flash_to nil@
|
99
|
+
def should_not_set_the_flash
|
100
|
+
should_set_the_flash_to nil
|
101
|
+
end
|
103
102
|
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
end
|
103
|
+
# Macro that creates a test asserting that filter_parameter_logging
|
104
|
+
# is set for the specified keys
|
105
|
+
#
|
106
|
+
# Example:
|
107
|
+
#
|
108
|
+
# should_filter_params :password, :ssn
|
109
|
+
def should_filter_params(*keys)
|
110
|
+
keys.each do |key|
|
111
|
+
should "filter #{key}" do
|
112
|
+
assert @controller.respond_to?(:filter_parameters),
|
113
|
+
"The key #{key} is not filtered"
|
114
|
+
filtered = @controller.send(:filter_parameters, {key.to_s => key.to_s})
|
115
|
+
assert_equal '[FILTERED]', filtered[key.to_s],
|
116
|
+
"The key #{key} is not filtered"
|
119
117
|
end
|
120
118
|
end
|
119
|
+
end
|
121
120
|
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
end
|
121
|
+
# Macro that creates a test asserting that the controller assigned to
|
122
|
+
# each of the named instance variable(s).
|
123
|
+
#
|
124
|
+
# Options:
|
125
|
+
# * <tt>:class</tt> - The expected class of the instance variable being checked.
|
126
|
+
# * <tt>:equals</tt> - A string which is evaluated and compared for equality with
|
127
|
+
# the instance variable being checked.
|
128
|
+
#
|
129
|
+
# Example:
|
130
|
+
#
|
131
|
+
# should_assign_to :user, :posts
|
132
|
+
# should_assign_to :user, :class => User
|
133
|
+
# should_assign_to :user, :equals => '@user'
|
134
|
+
def should_assign_to(*names)
|
135
|
+
opts = names.extract_options!
|
136
|
+
names.each do |name|
|
137
|
+
test_name = "assign @#{name}"
|
138
|
+
test_name << " as class #{opts[:class]}" if opts[:class]
|
139
|
+
test_name << " which is equal to #{opts[:equals]}" if opts[:equals]
|
140
|
+
should test_name do
|
141
|
+
assigned_value = assigns(name.to_sym)
|
142
|
+
assert_not_nil assigned_value, "The action isn't assigning to @#{name}"
|
143
|
+
assert_kind_of opts[:class], assigned_value if opts[:class]
|
144
|
+
if opts[:equals]
|
145
|
+
instantiate_variables_from_assigns do
|
146
|
+
expected_value = eval(opts[:equals], self.send(:binding), __FILE__, __LINE__)
|
147
|
+
assert_equal expected_value, assigned_value,
|
148
|
+
"Instance variable @#{name} expected to be #{expected_value}" +
|
149
|
+
" but was #{assigned_value}"
|
152
150
|
end
|
153
151
|
end
|
154
152
|
end
|
155
153
|
end
|
154
|
+
end
|
156
155
|
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
end
|
156
|
+
# Macro that creates a test asserting that the controller did not assign to
|
157
|
+
# any of the named instance variable(s).
|
158
|
+
#
|
159
|
+
# Example:
|
160
|
+
#
|
161
|
+
# should_not_assign_to :user, :posts
|
162
|
+
def should_not_assign_to(*names)
|
163
|
+
names.each do |name|
|
164
|
+
should "not assign to @#{name}" do
|
165
|
+
assert !assigns(name.to_sym), "@#{name} was visible"
|
168
166
|
end
|
169
167
|
end
|
168
|
+
end
|
170
169
|
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
end
|
170
|
+
# Macro that creates a test asserting that the controller responded with a 'response' status code.
|
171
|
+
# Example:
|
172
|
+
#
|
173
|
+
# should_respond_with :success
|
174
|
+
def should_respond_with(response)
|
175
|
+
should "respond with #{response}" do
|
176
|
+
assert_response response
|
179
177
|
end
|
178
|
+
end
|
180
179
|
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
end
|
180
|
+
# Macro that creates a test asserting that the response content type was 'content_type'.
|
181
|
+
# Example:
|
182
|
+
#
|
183
|
+
# should_respond_with_content_type 'application/rss+xml'
|
184
|
+
# should_respond_with_content_type :rss
|
185
|
+
# should_respond_with_content_type /rss/
|
186
|
+
def should_respond_with_content_type(content_type)
|
187
|
+
should "respond with content type of #{content_type}" do
|
188
|
+
content_type = Mime::EXTENSION_LOOKUP[content_type.to_s].to_s if content_type.is_a? Symbol
|
189
|
+
if content_type.is_a? Regexp
|
190
|
+
assert_match content_type, @response.content_type, "Expected to match #{content_type} but was actually #{@response.content_type}"
|
191
|
+
else
|
192
|
+
assert_equal content_type, @response.content_type, "Expected #{content_type} but was actually #{@response.content_type}"
|
195
193
|
end
|
196
194
|
end
|
195
|
+
end
|
197
196
|
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
end
|
197
|
+
# Macro that creates a test asserting that a value returned from the session is correct.
|
198
|
+
# The given string is evaled to produce the resulting redirect path. All of the instance variables
|
199
|
+
# set by the controller are available to the evaled string.
|
200
|
+
# Example:
|
201
|
+
#
|
202
|
+
# should_return_from_session :user_id, '@user.id'
|
203
|
+
# should_return_from_session :message, '"Free stuff"'
|
204
|
+
def should_return_from_session(key, expected)
|
205
|
+
should "return the correct value from the session for key #{key}" do
|
206
|
+
instantiate_variables_from_assigns do
|
207
|
+
expected_value = eval(expected, self.send(:binding), __FILE__, __LINE__)
|
208
|
+
assert_equal expected_value, session[key], "Expected #{expected_value.inspect} but was #{session[key]}"
|
211
209
|
end
|
212
210
|
end
|
211
|
+
end
|
212
|
+
|
213
|
+
# Macro that creates a test asserting that the controller rendered the given template.
|
214
|
+
# Example:
|
215
|
+
#
|
216
|
+
# should_render_template :new
|
217
|
+
def should_render_template(template)
|
218
|
+
should "render template #{template.inspect}" do
|
219
|
+
assert_template template.to_s
|
220
|
+
end
|
221
|
+
end
|
213
222
|
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
223
|
+
# Macro that creates a test asserting that the controller rendered with the given layout.
|
224
|
+
# Example:
|
225
|
+
#
|
226
|
+
# should_render_with_layout 'special'
|
227
|
+
def should_render_with_layout(expected_layout = 'application')
|
228
|
+
if expected_layout
|
229
|
+
should "render with #{expected_layout.inspect} layout" do
|
230
|
+
response_layout = @response.layout.blank? ? "" : @response.layout.split('/').last
|
231
|
+
assert_equal expected_layout.to_s,
|
232
|
+
response_layout,
|
233
|
+
"Expected to render with layout #{expected_layout} but was rendered with #{response_layout}"
|
234
|
+
end
|
235
|
+
else
|
236
|
+
should "render without layout" do
|
237
|
+
assert_nil @response.layout,
|
238
|
+
"Expected no layout, but was rendered using #{@response.layout}"
|
221
239
|
end
|
222
240
|
end
|
241
|
+
end
|
223
242
|
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
243
|
+
# Macro that creates a test asserting that the controller rendered without a layout.
|
244
|
+
# Same as @should_render_with_layout false@
|
245
|
+
def should_render_without_layout
|
246
|
+
should_render_with_layout nil
|
247
|
+
end
|
248
|
+
|
249
|
+
# Macro that creates a test asserting that the controller returned a redirect to the given path.
|
250
|
+
# The given string is evaled to produce the resulting redirect path. All of the instance variables
|
251
|
+
# set by the controller are available to the evaled string.
|
252
|
+
# Example:
|
253
|
+
#
|
254
|
+
# should_redirect_to '"/"'
|
255
|
+
# should_redirect_to "user_url(@user)"
|
256
|
+
# should_redirect_to "users_url"
|
257
|
+
def should_redirect_to(url)
|
258
|
+
should "redirect to #{url.inspect}" do
|
259
|
+
instantiate_variables_from_assigns do
|
260
|
+
assert_redirected_to eval(url, self.send(:binding), __FILE__, __LINE__)
|
241
261
|
end
|
242
262
|
end
|
263
|
+
end
|
243
264
|
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
265
|
+
# Macro that creates a test asserting that the rendered view contains a <form> element.
|
266
|
+
def should_render_a_form
|
267
|
+
should "display a form" do
|
268
|
+
assert_select "form", true, "The template doesn't contain a <form> element"
|
248
269
|
end
|
270
|
+
end
|
249
271
|
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
272
|
+
# Macro that creates a test asserting that the rendered view contains the selected metatags.
|
273
|
+
# Values can be string or Regexps.
|
274
|
+
# Example:
|
275
|
+
#
|
276
|
+
# should_render_page_with_metadata :description => "Description of this page", :keywords => /post/
|
277
|
+
#
|
278
|
+
# You can also use this method to test the rendered views title.
|
279
|
+
#
|
280
|
+
# Example:
|
281
|
+
# should_render_page_with_metadata :title => /index/
|
282
|
+
def should_render_page_with_metadata(options)
|
283
|
+
options.each do |key, value|
|
284
|
+
should "have metatag #{key}" do
|
285
|
+
if key.to_sym == :title
|
286
|
+
assert_select "title", value
|
287
|
+
else
|
288
|
+
assert_select "meta[name=?][content#{"*" if value.is_a?(Regexp)}=?]", key, value
|
262
289
|
end
|
263
290
|
end
|
264
291
|
end
|
292
|
+
end
|
265
293
|
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
294
|
+
# Macro that creates a routing test. It tries to use the given HTTP
|
295
|
+
# +method+ on the given +path+, and asserts that it routes to the
|
296
|
+
# given +options+.
|
297
|
+
#
|
298
|
+
# If you don't specify a :controller, it will try to guess the controller
|
299
|
+
# based on the current test.
|
300
|
+
#
|
301
|
+
# +to_param+ is called on the +options+ given.
|
302
|
+
#
|
303
|
+
# Examples:
|
304
|
+
#
|
305
|
+
# should_route :get, "/posts", :controller => :posts, :action => :index
|
306
|
+
# should_route :get, "/posts/new", :action => :new
|
307
|
+
# should_route :post, "/posts", :action => :create
|
308
|
+
# should_route :get, "/posts/1", :action => :show, :id => 1
|
309
|
+
# should_route :edit, "/posts/1", :action => :show, :id => 1
|
310
|
+
# should_route :put, "/posts/1", :action => :update, :id => 1
|
311
|
+
# should_route :delete, "/posts/1", :action => :destroy, :id => 1
|
312
|
+
# should_route :get, "/users/1/posts/1",
|
313
|
+
# :action => :show, :id => 1, :user_id => 1
|
314
|
+
#
|
315
|
+
def should_route(method, path, options)
|
316
|
+
unless options[:controller]
|
317
|
+
options[:controller] = self.name.gsub(/ControllerTest$/, '').tableize
|
271
318
|
end
|
319
|
+
options[:controller] = options[:controller].to_s
|
320
|
+
options[:action] = options[:action].to_s
|
272
321
|
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
# based on the current test.
|
279
|
-
#
|
280
|
-
# +to_param+ is called on the +options+ given.
|
281
|
-
#
|
282
|
-
# Examples:
|
283
|
-
#
|
284
|
-
# should_route :get, "/posts", :controller => :posts, :action => :index
|
285
|
-
# should_route :get, "/posts/new", :action => :new
|
286
|
-
# should_route :post, "/posts", :action => :create
|
287
|
-
# should_route :get, "/posts/1", :action => :show, :id => 1
|
288
|
-
# should_route :edit, "/posts/1", :action => :show, :id => 1
|
289
|
-
# should_route :put, "/posts/1", :action => :update, :id => 1
|
290
|
-
# should_route :delete, "/posts/1", :action => :destroy, :id => 1
|
291
|
-
# should_route :get, "/users/1/posts/1",
|
292
|
-
# :action => :show, :id => 1, :user_id => 1
|
293
|
-
#
|
294
|
-
def should_route(method, path, options)
|
295
|
-
unless options[:controller]
|
296
|
-
options[:controller] = self.name.gsub(/ControllerTest$/, '').tableize
|
297
|
-
end
|
298
|
-
options[:controller] = options[:controller].to_s
|
299
|
-
options[:action] = options[:action].to_s
|
300
|
-
|
301
|
-
populated_path = path.dup
|
302
|
-
options.each do |key, value|
|
303
|
-
options[key] = value.to_param if value.respond_to? :to_param
|
304
|
-
populated_path.gsub!(key.inspect, value.to_s)
|
305
|
-
end
|
322
|
+
populated_path = path.dup
|
323
|
+
options.each do |key, value|
|
324
|
+
options[key] = value.to_param if value.respond_to? :to_param
|
325
|
+
populated_path.gsub!(key.inspect, value.to_s)
|
326
|
+
end
|
306
327
|
|
307
|
-
|
328
|
+
should_name = "route #{method.to_s.upcase} #{populated_path} to/from #{options.inspect}"
|
308
329
|
|
309
|
-
|
310
|
-
|
311
|
-
end
|
330
|
+
should should_name do
|
331
|
+
assert_routing({:method => method, :path => populated_path}, options)
|
312
332
|
end
|
313
333
|
end
|
314
334
|
end
|