francois-shoulda 2.0.5.4 → 2.10.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.
- data/README.rdoc +60 -10
- data/Rakefile +7 -7
- data/lib/shoulda.rb +7 -15
- data/lib/shoulda/action_controller.rb +28 -0
- data/lib/shoulda/action_controller/helpers.rb +47 -0
- 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 +87 -0
- data/lib/shoulda/action_controller/matchers/set_the_flash_matcher.rb +85 -0
- data/lib/shoulda/action_mailer.rb +1 -1
- data/lib/shoulda/action_mailer/assertions.rb +32 -33
- data/lib/shoulda/action_view.rb +10 -0
- data/lib/shoulda/action_view/macros.rb +56 -0
- data/lib/shoulda/active_record.rb +6 -2
- data/lib/shoulda/active_record/assertions.rb +62 -89
- data/lib/shoulda/active_record/helpers.rb +40 -0
- data/lib/shoulda/active_record/macros.rb +520 -684
- 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/helpers.rb +5 -7
- data/lib/shoulda/macros.rb +63 -64
- data/lib/shoulda/private_helpers.rb +16 -18
- data/lib/shoulda/rails.rb +5 -11
- data/lib/shoulda/rspec.rb +11 -0
- data/lib/shoulda/tasks/list_tests.rake +6 -1
- data/lib/shoulda/test_unit.rb +19 -0
- data/rails/init.rb +7 -1
- data/test/README +2 -2
- data/test/fail_macros.rb +15 -15
- data/test/fixtures/tags.yml +1 -1
- data/test/functional/posts_controller_test.rb +46 -26
- data/test/functional/users_controller_test.rb +0 -19
- data/test/matchers/active_record/allow_mass_assignment_of_matcher_test.rb +68 -0
- data/test/matchers/active_record/allow_value_matcher_test.rb +41 -0
- data/test/matchers/active_record/association_matcher_test.rb +258 -0
- data/test/matchers/active_record/ensure_inclusion_of_matcher_test.rb +80 -0
- data/test/matchers/active_record/ensure_length_of_matcher_test.rb +158 -0
- data/test/matchers/active_record/have_db_column_matcher_test.rb +169 -0
- data/test/matchers/active_record/have_index_matcher_test.rb +74 -0
- data/test/matchers/active_record/have_named_scope_matcher_test.rb +65 -0
- data/test/matchers/active_record/have_readonly_attributes_matcher_test.rb +29 -0
- data/test/matchers/active_record/validate_acceptance_of_matcher_test.rb +44 -0
- data/test/matchers/active_record/validate_numericality_of_matcher_test.rb +52 -0
- data/test/matchers/active_record/validate_presence_of_matcher_test.rb +86 -0
- data/test/matchers/active_record/validate_uniqueness_of_matcher_test.rb +147 -0
- 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 +31 -0
- data/test/matchers/controller/set_the_flash_matcher.rb +41 -0
- data/test/model_builder.rb +106 -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 +4 -3
- 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/environment.rb +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/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/rspec_test.rb +207 -0
- data/test/test_helper.rb +3 -1
- data/test/unit/address_test.rb +1 -23
- 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 +25 -9
- metadata +84 -23
- data/lib/shoulda/controller.rb +0 -30
- data/lib/shoulda/controller/formats/html.rb +0 -201
- data/lib/shoulda/controller/formats/xml.rb +0 -170
- data/lib/shoulda/controller/helpers.rb +0 -64
- data/lib/shoulda/controller/macros.rb +0 -316
- data/lib/shoulda/controller/resource_options.rb +0 -236
- data/test/rails_root/app/models/dog.rb +0 -5
@@ -1,170 +0,0 @@
|
|
1
|
-
module ThoughtBot # :nodoc:
|
2
|
-
module Shoulda # :nodoc:
|
3
|
-
module Controller # :nodoc:
|
4
|
-
module XML
|
5
|
-
def self.included(other) #:nodoc:
|
6
|
-
other.class_eval do
|
7
|
-
extend ThoughtBot::Shoulda::Controller::XML::ClassMethods
|
8
|
-
end
|
9
|
-
end
|
10
|
-
|
11
|
-
module ClassMethods
|
12
|
-
# Macro that creates a test asserting that the controller responded with an XML content-type
|
13
|
-
# and that the XML contains +<name/>+ as the root element.
|
14
|
-
def should_respond_with_xml_for(name = nil)
|
15
|
-
should "have ContentType set to 'application/xml'" do
|
16
|
-
assert_xml_response
|
17
|
-
end
|
18
|
-
|
19
|
-
if name
|
20
|
-
should "return <#{name}/> as the root element" do
|
21
|
-
body = @response.body.first(100).map {|l| " #{l}"}
|
22
|
-
assert_select name.to_s.dasherize, 1, "Body:\n#{body}...\nDoes not have <#{name}/> as the root element."
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
alias should_respond_with_xml should_respond_with_xml_for
|
27
|
-
|
28
|
-
protected
|
29
|
-
|
30
|
-
def make_show_xml_tests(res) # :nodoc:
|
31
|
-
context "on GET to #{controller_name_from_class}#show as xml" do
|
32
|
-
setup do
|
33
|
-
request_xml
|
34
|
-
record = get_existing_record(res)
|
35
|
-
parent_params = make_parent_params(res, record)
|
36
|
-
get :show, parent_params.merge({ res.identifier => record.to_param })
|
37
|
-
end
|
38
|
-
|
39
|
-
if res.denied.actions.include?(:show)
|
40
|
-
should_not_assign_to res.object
|
41
|
-
should_respond_with 401
|
42
|
-
else
|
43
|
-
should_assign_to res.object
|
44
|
-
should_respond_with :success
|
45
|
-
should_respond_with_xml_for res.object
|
46
|
-
end
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
def make_edit_xml_tests(res) # :nodoc:
|
51
|
-
# XML doesn't need an :edit action
|
52
|
-
end
|
53
|
-
|
54
|
-
def make_new_xml_tests(res) # :nodoc:
|
55
|
-
# XML doesn't need a :new action
|
56
|
-
end
|
57
|
-
|
58
|
-
def make_index_xml_tests(res) # :nodoc:
|
59
|
-
context "on GET to #{controller_name_from_class}#index as xml" do
|
60
|
-
setup do
|
61
|
-
request_xml
|
62
|
-
parent_params = make_parent_params(res)
|
63
|
-
get(:index, parent_params)
|
64
|
-
end
|
65
|
-
|
66
|
-
if res.denied.actions.include?(:index)
|
67
|
-
should_not_assign_to res.object.to_s.pluralize
|
68
|
-
should_respond_with 401
|
69
|
-
else
|
70
|
-
should_respond_with :success
|
71
|
-
should_respond_with_xml_for res.object.to_s.pluralize
|
72
|
-
should_assign_to res.object.to_s.pluralize
|
73
|
-
end
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|
77
|
-
def make_destroy_xml_tests(res) # :nodoc:
|
78
|
-
context "on DELETE to #{controller_name_from_class}#destroy as xml" do
|
79
|
-
setup do
|
80
|
-
request_xml
|
81
|
-
@record = get_existing_record(res)
|
82
|
-
parent_params = make_parent_params(res, @record)
|
83
|
-
delete :destroy, parent_params.merge({ res.identifier => @record.to_param })
|
84
|
-
end
|
85
|
-
|
86
|
-
if res.denied.actions.include?(:destroy)
|
87
|
-
should_respond_with 401
|
88
|
-
|
89
|
-
should "not destroy record" do
|
90
|
-
assert @record.reload
|
91
|
-
end
|
92
|
-
else
|
93
|
-
should "destroy record" do
|
94
|
-
assert_raises(::ActiveRecord::RecordNotFound, "@#{res.object} was not destroyed.") do
|
95
|
-
@record.reload
|
96
|
-
end
|
97
|
-
end
|
98
|
-
end
|
99
|
-
end
|
100
|
-
end
|
101
|
-
|
102
|
-
def make_create_xml_tests(res) # :nodoc:
|
103
|
-
context "on POST to #{controller_name_from_class}#create as xml" do
|
104
|
-
setup do
|
105
|
-
request_xml
|
106
|
-
parent_params = make_parent_params(res)
|
107
|
-
@count = res.klass.count
|
108
|
-
post :create, parent_params.merge(res.object => res.create.params)
|
109
|
-
end
|
110
|
-
|
111
|
-
if res.denied.actions.include?(:create)
|
112
|
-
should_respond_with 401
|
113
|
-
should_not_assign_to res.object
|
114
|
-
|
115
|
-
should "not create new record" do
|
116
|
-
assert_equal @count, res.klass.count
|
117
|
-
end
|
118
|
-
else
|
119
|
-
should_assign_to res.object
|
120
|
-
|
121
|
-
should "not have errors on @#{res.object}" do
|
122
|
-
assert_equal [], pretty_error_messages(assigns(res.object)), "@#{res.object} has errors:"
|
123
|
-
end
|
124
|
-
end
|
125
|
-
end
|
126
|
-
end
|
127
|
-
|
128
|
-
def make_update_xml_tests(res) # :nodoc:
|
129
|
-
context "on PUT to #{controller_name_from_class}#update as xml" do
|
130
|
-
setup do
|
131
|
-
request_xml
|
132
|
-
@record = get_existing_record(res)
|
133
|
-
parent_params = make_parent_params(res, @record)
|
134
|
-
put :update, parent_params.merge(res.identifier => @record.to_param, res.object => res.update.params)
|
135
|
-
end
|
136
|
-
|
137
|
-
if res.denied.actions.include?(:update)
|
138
|
-
should_not_assign_to res.object
|
139
|
-
should_respond_with 401
|
140
|
-
else
|
141
|
-
should_assign_to res.object
|
142
|
-
|
143
|
-
should "not have errors on @#{res.object}" do
|
144
|
-
assert_equal [], assigns(res.object).errors.full_messages, "@#{res.object} has errors:"
|
145
|
-
end
|
146
|
-
end
|
147
|
-
end
|
148
|
-
end
|
149
|
-
end
|
150
|
-
|
151
|
-
# Sets the next request's format to 'application/xml'
|
152
|
-
def request_xml
|
153
|
-
@request.accept = "application/xml"
|
154
|
-
end
|
155
|
-
|
156
|
-
# Asserts that the controller's response was 'application/xml'
|
157
|
-
def assert_xml_response
|
158
|
-
content_type = (@response.headers["Content-Type"] || @response.headers["type"]).to_s
|
159
|
-
regex = %r{\bapplication/xml\b}
|
160
|
-
|
161
|
-
msg = "Content Type '#{content_type.inspect}' doesn't match '#{regex.inspect}'\n"
|
162
|
-
msg += "Body: #{@response.body.first(100).chomp} ..."
|
163
|
-
|
164
|
-
assert_match regex, content_type, msg
|
165
|
-
end
|
166
|
-
|
167
|
-
end
|
168
|
-
end
|
169
|
-
end
|
170
|
-
end
|
@@ -1,64 +0,0 @@
|
|
1
|
-
module ThoughtBot # :nodoc:
|
2
|
-
module Shoulda # :nodoc:
|
3
|
-
module Controller # :nodoc:
|
4
|
-
module Helpers # :nodoc:
|
5
|
-
private # :enddoc:
|
6
|
-
|
7
|
-
SPECIAL_INSTANCE_VARIABLES = %w{
|
8
|
-
_cookies
|
9
|
-
_flash
|
10
|
-
_headers
|
11
|
-
_params
|
12
|
-
_request
|
13
|
-
_response
|
14
|
-
_session
|
15
|
-
action_name
|
16
|
-
before_filter_chain_aborted
|
17
|
-
cookies
|
18
|
-
flash
|
19
|
-
headers
|
20
|
-
ignore_missing_templates
|
21
|
-
logger
|
22
|
-
params
|
23
|
-
request
|
24
|
-
request_origin
|
25
|
-
response
|
26
|
-
session
|
27
|
-
template
|
28
|
-
template_class
|
29
|
-
template_root
|
30
|
-
url
|
31
|
-
variables_added
|
32
|
-
}.map(&:to_s)
|
33
|
-
|
34
|
-
def instantiate_variables_from_assigns(*names, &blk)
|
35
|
-
old = {}
|
36
|
-
names = (@response.template.assigns.keys - SPECIAL_INSTANCE_VARIABLES) if names.empty?
|
37
|
-
names.each do |name|
|
38
|
-
old[name] = instance_variable_get("@#{name}")
|
39
|
-
instance_variable_set("@#{name}", assigns(name.to_sym))
|
40
|
-
end
|
41
|
-
blk.call
|
42
|
-
names.each do |name|
|
43
|
-
instance_variable_set("@#{name}", old[name])
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
def get_existing_record(res) # :nodoc:
|
48
|
-
returning(instance_variable_get("@#{res.object}")) do |record|
|
49
|
-
assert(record, "This test requires you to set @#{res.object} in your setup block")
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
def make_parent_params(resource, record = nil, parent_names = nil) # :nodoc:
|
54
|
-
parent_names ||= resource.parents.reverse
|
55
|
-
return {} if parent_names == [] # Base case
|
56
|
-
parent_name = parent_names.shift
|
57
|
-
parent = record ? record.send(parent_name) : parent_name.to_s.classify.constantize.find(:first)
|
58
|
-
|
59
|
-
{ :"#{parent_name}_id" => parent.to_param }.merge(make_parent_params(resource, parent, parent_names))
|
60
|
-
end
|
61
|
-
end
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|
@@ -1,316 +0,0 @@
|
|
1
|
-
module ThoughtBot # :nodoc:
|
2
|
-
module Shoulda # :nodoc:
|
3
|
-
module Controller # :nodoc:
|
4
|
-
# = Macro test helpers for your controllers
|
5
|
-
#
|
6
|
-
# By using the macro helpers you can quickly and easily create concise and easy to read test suites.
|
7
|
-
#
|
8
|
-
# This code segment:
|
9
|
-
# context "on GET to :show for first record" do
|
10
|
-
# setup do
|
11
|
-
# get :show, :id => 1
|
12
|
-
# end
|
13
|
-
#
|
14
|
-
# should_assign_to :user
|
15
|
-
# should_respond_with :success
|
16
|
-
# should_render_template :show
|
17
|
-
# should_not_set_the_flash
|
18
|
-
#
|
19
|
-
# should "do something else really cool" do
|
20
|
-
# assert_equal 1, assigns(:user).id
|
21
|
-
# end
|
22
|
-
# end
|
23
|
-
#
|
24
|
-
# Would produce 5 tests for the +show+ action
|
25
|
-
#
|
26
|
-
# Furthermore, the should_be_restful helper will create an entire set of tests which will verify that your
|
27
|
-
# controller responds restfully to a variety of requested formats.
|
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."
|
59
|
-
|
60
|
-
resource = ResourceOptions.new
|
61
|
-
blk.call(resource)
|
62
|
-
resource.normalize!(self)
|
63
|
-
|
64
|
-
resource.formats.each do |format|
|
65
|
-
resource.actions.each do |action|
|
66
|
-
if self.respond_to? :"make_#{action}_#{format}_tests"
|
67
|
-
self.send(:"make_#{action}_#{format}_tests", resource)
|
68
|
-
else
|
69
|
-
should "test #{action} #{format}" do
|
70
|
-
flunk "Test for #{action} as #{format} not implemented"
|
71
|
-
end
|
72
|
-
end
|
73
|
-
end
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|
77
|
-
# :section: Test macros
|
78
|
-
# Macro that creates a test asserting that the flash contains the given value.
|
79
|
-
# val can be a String, a Regex, or nil (indicating that the flash should not be set)
|
80
|
-
#
|
81
|
-
# Example:
|
82
|
-
#
|
83
|
-
# should_set_the_flash_to "Thank you for placing this order."
|
84
|
-
# should_set_the_flash_to /created/i
|
85
|
-
# should_set_the_flash_to nil
|
86
|
-
def should_set_the_flash_to(val)
|
87
|
-
if val
|
88
|
-
should "have #{val.inspect} in the flash" do
|
89
|
-
assert_contains flash.values, val, ", Flash: #{flash.inspect}"
|
90
|
-
end
|
91
|
-
else
|
92
|
-
should "not set the flash" do
|
93
|
-
assert_equal({}, flash, "Flash was set to:\n#{flash.inspect}")
|
94
|
-
end
|
95
|
-
end
|
96
|
-
end
|
97
|
-
|
98
|
-
# Macro that creates a test asserting that the flash is empty. Same as
|
99
|
-
# @should_set_the_flash_to nil@
|
100
|
-
def should_not_set_the_flash
|
101
|
-
should_set_the_flash_to nil
|
102
|
-
end
|
103
|
-
|
104
|
-
# Macro that creates a test asserting that filter_parameter_logging
|
105
|
-
# is set for the specified keys
|
106
|
-
#
|
107
|
-
# Example:
|
108
|
-
#
|
109
|
-
# should_filter_params :password, :ssn
|
110
|
-
def should_filter_params(*keys)
|
111
|
-
keys.each do |key|
|
112
|
-
should "filter #{key}" do
|
113
|
-
assert @controller.respond_to?(:filter_parameters),
|
114
|
-
"The key #{key} is not filtered"
|
115
|
-
filtered = @controller.send(:filter_parameters, {key.to_s => key.to_s})
|
116
|
-
assert_equal '[FILTERED]', filtered[key.to_s],
|
117
|
-
"The key #{key} is not filtered"
|
118
|
-
end
|
119
|
-
end
|
120
|
-
end
|
121
|
-
|
122
|
-
# Macro that creates a test asserting that the controller assigned to
|
123
|
-
# each of the named instance variable(s).
|
124
|
-
#
|
125
|
-
# Options:
|
126
|
-
# * <tt>:class</tt> - The expected class of the instance variable being checked.
|
127
|
-
# * <tt>:equals</tt> - A string which is evaluated and compared for equality with
|
128
|
-
# the instance variable being checked.
|
129
|
-
#
|
130
|
-
# Example:
|
131
|
-
#
|
132
|
-
# should_assign_to :user, :posts
|
133
|
-
# should_assign_to :user, :class => User
|
134
|
-
# should_assign_to :user, :equals => '@user'
|
135
|
-
def should_assign_to(*names)
|
136
|
-
opts = names.extract_options!
|
137
|
-
names.each do |name|
|
138
|
-
test_name = "assign @#{name}"
|
139
|
-
test_name << " as class #{opts[:class]}" if opts[:class]
|
140
|
-
test_name << " which is equal to #{opts[:equals]}" if opts[:equals]
|
141
|
-
should test_name do
|
142
|
-
assigned_value = assigns(name.to_sym)
|
143
|
-
assert assigned_value, "The action isn't assigning to @#{name}"
|
144
|
-
assert_kind_of opts[:class], assigned_value if opts[:class]
|
145
|
-
if opts[:equals]
|
146
|
-
instantiate_variables_from_assigns do
|
147
|
-
expected_value = eval(opts[:equals], self.send(:binding), __FILE__, __LINE__)
|
148
|
-
assert_equal expected_value, assigned_value,
|
149
|
-
"Instance variable @#{name} expected to be #{expected_value}" +
|
150
|
-
" but was #{assigned_value}"
|
151
|
-
end
|
152
|
-
end
|
153
|
-
end
|
154
|
-
end
|
155
|
-
end
|
156
|
-
|
157
|
-
# Macro that creates a test asserting that the controller did not assign to
|
158
|
-
# any of the named instance variable(s).
|
159
|
-
#
|
160
|
-
# Example:
|
161
|
-
#
|
162
|
-
# should_not_assign_to :user, :posts
|
163
|
-
def should_not_assign_to(*names)
|
164
|
-
names.each do |name|
|
165
|
-
should "not assign to @#{name}" do
|
166
|
-
assert !assigns(name.to_sym), "@#{name} was visible"
|
167
|
-
end
|
168
|
-
end
|
169
|
-
end
|
170
|
-
|
171
|
-
# Macro that creates a test asserting that the controller responded with a 'response' status code.
|
172
|
-
# Example:
|
173
|
-
#
|
174
|
-
# should_respond_with :success
|
175
|
-
def should_respond_with(response)
|
176
|
-
should "respond with #{response}" do
|
177
|
-
assert_response response
|
178
|
-
end
|
179
|
-
end
|
180
|
-
|
181
|
-
# Macro that creates a test asserting that the response content type was 'content_type'.
|
182
|
-
# Example:
|
183
|
-
#
|
184
|
-
# should_respond_with_content_type 'application/rss+xml'
|
185
|
-
# should_respond_with_content_type :rss
|
186
|
-
# should_respond_with_content_type /rss/
|
187
|
-
def should_respond_with_content_type(content_type)
|
188
|
-
should "respond with content type of #{content_type}" do
|
189
|
-
content_type = Mime::EXTENSION_LOOKUP[content_type.to_s].to_s if content_type.is_a? Symbol
|
190
|
-
if content_type.is_a? Regexp
|
191
|
-
assert_match content_type, @response.content_type, "Expected to match #{content_type} but was actually #{@response.content_type}"
|
192
|
-
else
|
193
|
-
assert_equal content_type, @response.content_type, "Expected #{content_type} but was actually #{@response.content_type}"
|
194
|
-
end
|
195
|
-
end
|
196
|
-
end
|
197
|
-
|
198
|
-
# Macro that creates a test asserting that a value returned from the session is correct.
|
199
|
-
# The given string is evaled to produce the resulting redirect path. All of the instance variables
|
200
|
-
# set by the controller are available to the evaled string.
|
201
|
-
# Example:
|
202
|
-
#
|
203
|
-
# should_return_from_session :user_id, '@user.id'
|
204
|
-
# should_return_from_session :message, '"Free stuff"'
|
205
|
-
def should_return_from_session(key, expected)
|
206
|
-
should "return the correct value from the session for key #{key}" do
|
207
|
-
instantiate_variables_from_assigns do
|
208
|
-
expected_value = eval(expected, self.send(:binding), __FILE__, __LINE__)
|
209
|
-
assert_equal expected_value, session[key], "Expected #{expected_value.inspect} but was #{session[key]}"
|
210
|
-
end
|
211
|
-
end
|
212
|
-
end
|
213
|
-
|
214
|
-
# Macro that creates a test asserting that the controller rendered the given template.
|
215
|
-
# Example:
|
216
|
-
#
|
217
|
-
# should_render_template :new
|
218
|
-
def should_render_template(template)
|
219
|
-
should "render template #{template.inspect}" do
|
220
|
-
assert_template template.to_s
|
221
|
-
end
|
222
|
-
end
|
223
|
-
|
224
|
-
# Macro that creates a test asserting that the controller rendered with the given layout.
|
225
|
-
# Example:
|
226
|
-
#
|
227
|
-
# should_render_with_layout 'special'
|
228
|
-
def should_render_with_layout(expected_layout = 'application')
|
229
|
-
if expected_layout
|
230
|
-
should "render with #{expected_layout.inspect} layout" do
|
231
|
-
response_layout = @response.layout.blank? ? "" : @response.layout.split('/').last
|
232
|
-
assert_equal expected_layout.to_s,
|
233
|
-
response_layout,
|
234
|
-
"Expected to render with layout #{expected_layout} but was rendered with #{response_layout}"
|
235
|
-
end
|
236
|
-
else
|
237
|
-
should "render without layout" do
|
238
|
-
assert_nil @response.layout,
|
239
|
-
"Expected no layout, but was rendered using #{@response.layout}"
|
240
|
-
end
|
241
|
-
end
|
242
|
-
end
|
243
|
-
|
244
|
-
# Macro that creates a test asserting that the controller rendered without a layout.
|
245
|
-
# Same as @should_render_with_layout false@
|
246
|
-
def should_render_without_layout
|
247
|
-
should_render_with_layout nil
|
248
|
-
end
|
249
|
-
|
250
|
-
# Macro that creates a test asserting that the controller returned a redirect to the given path.
|
251
|
-
# The given string is evaled to produce the resulting redirect path. All of the instance variables
|
252
|
-
# set by the controller are available to the evaled string.
|
253
|
-
# Example:
|
254
|
-
#
|
255
|
-
# should_redirect_to '"/"'
|
256
|
-
# should_redirect_to "user_url(@user)"
|
257
|
-
# should_redirect_to "users_url"
|
258
|
-
def should_redirect_to(url)
|
259
|
-
should "redirect to #{url.inspect}" do
|
260
|
-
instantiate_variables_from_assigns do
|
261
|
-
assert_redirected_to eval(url, self.send(:binding), __FILE__, __LINE__)
|
262
|
-
end
|
263
|
-
end
|
264
|
-
end
|
265
|
-
|
266
|
-
# Macro that creates a test asserting that the rendered view contains a <form> element.
|
267
|
-
def should_render_a_form
|
268
|
-
should "display a form" do
|
269
|
-
assert_select "form", true, "The template doesn't contain a <form> element"
|
270
|
-
end
|
271
|
-
end
|
272
|
-
|
273
|
-
# Macro that creates a routing test. It tries to use the given HTTP
|
274
|
-
# +method+ on the given +path+, and asserts that it routes to the
|
275
|
-
# given +options+.
|
276
|
-
#
|
277
|
-
# If you don't specify a :controller, it will try to guess the controller
|
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
|
306
|
-
|
307
|
-
should_name = "route #{method.to_s.upcase} #{populated_path} to/from #{options.inspect}"
|
308
|
-
|
309
|
-
should should_name do
|
310
|
-
assert_routing({:method => method, :path => populated_path}, options)
|
311
|
-
end
|
312
|
-
end
|
313
|
-
end
|
314
|
-
end
|
315
|
-
end
|
316
|
-
end
|