shoulda 2.0.1 → 2.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +13 -0
- data/lib/shoulda.rb +1 -0
- data/lib/shoulda/active_record/macros.rb +3 -2
- data/lib/shoulda/context.rb +4 -7
- data/lib/shoulda/controller/macros.rb +86 -12
- data/lib/shoulda/controller/resource_options.rb +224 -0
- data/lib/shoulda/macros.rb +2 -8
- data/rails/init.rb +1 -0
- data/test/fail_macros.rb +34 -0
- data/test/functional/posts_controller_test.rb +21 -0
- data/test/functional/users_controller_test.rb +18 -23
- data/test/rails_root/app/controllers/users_controller.rb +3 -0
- data/test/rails_root/app/views/layouts/wide.html.erb +1 -0
- metadata +4 -2
- data/lib/shoulda/controller/routing.rb +0 -0
data/README.rdoc
CHANGED
@@ -90,6 +90,19 @@ Macros to test the most common controller patterns...
|
|
90
90
|
end
|
91
91
|
end
|
92
92
|
|
93
|
+
Test entire controllers in a few lines...
|
94
|
+
|
95
|
+
class PostsControllerTest < Test::Unit::TestCase
|
96
|
+
should_be_restful do |resource|
|
97
|
+
resource.parent = :user
|
98
|
+
|
99
|
+
resource.create.params = { :title => "first post", :body => 'blah blah blah'}
|
100
|
+
resource.update.params = { :title => "changed" }
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
should_be_restful generates 40 tests on the fly, for both html and xml requests.
|
105
|
+
|
93
106
|
=== Helpful Assertions (ThoughtBot::Shoulda::Assertions)
|
94
107
|
|
95
108
|
More to come here, but have fun with what's there.
|
data/lib/shoulda.rb
CHANGED
@@ -28,8 +28,9 @@ module ThoughtBot # :nodoc:
|
|
28
28
|
# For all of these helpers, the last parameter may be a hash of options.
|
29
29
|
#
|
30
30
|
module Macros
|
31
|
+
# <b>DEPRECATED:</b> Use <tt>fixtures :all</tt> instead
|
32
|
+
#
|
31
33
|
# Loads all fixture files (<tt>test/fixtures/*.yml</tt>)
|
32
|
-
# Deprecated: Use <tt>fixtures :all</tt> instead
|
33
34
|
def load_all_fixtures
|
34
35
|
warn "[DEPRECATION] load_all_fixtures is deprecated. Use `fixtures :all` instead."
|
35
36
|
fixtures :all
|
@@ -602,7 +603,7 @@ module ThoughtBot # :nodoc:
|
|
602
603
|
# should_have_index :age
|
603
604
|
#
|
604
605
|
def should_have_indices(*columns)
|
605
|
-
table = model_class.
|
606
|
+
table = model_class.table_name
|
606
607
|
indices = ::ActiveRecord::Base.connection.indexes(table).map(&:columns)
|
607
608
|
|
608
609
|
columns.each do |column|
|
data/lib/shoulda/context.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
module Thoughtbot # :nodoc:
|
2
2
|
module Shoulda
|
3
|
-
VERSION = '2.0.
|
3
|
+
VERSION = '2.0.2'
|
4
4
|
|
5
5
|
class << self
|
6
6
|
attr_accessor :contexts
|
@@ -73,12 +73,12 @@ module Thoughtbot # :nodoc:
|
|
73
73
|
|
74
74
|
# == Before statements
|
75
75
|
#
|
76
|
-
# Before statements are
|
76
|
+
# Before statements are should statements that run before the current
|
77
77
|
# context's setup. These are especially useful when setting expectations.
|
78
78
|
#
|
79
79
|
# === Example:
|
80
80
|
#
|
81
|
-
# class UserControllerTest
|
81
|
+
# class UserControllerTest < Test::Unit::TestCase
|
82
82
|
# context "the index action" do
|
83
83
|
# setup do
|
84
84
|
# @users = [Factory(:user)]
|
@@ -86,11 +86,8 @@ module Thoughtbot # :nodoc:
|
|
86
86
|
# end
|
87
87
|
#
|
88
88
|
# context "on GET" do
|
89
|
-
# setup
|
90
|
-
# get :index
|
91
|
-
# end
|
89
|
+
# setup { get :index }
|
92
90
|
#
|
93
|
-
# # normal should statement
|
94
91
|
# should_respond_with :success
|
95
92
|
#
|
96
93
|
# # runs before "get :index"
|
@@ -22,7 +22,58 @@ module ThoughtBot # :nodoc:
|
|
22
22
|
# end
|
23
23
|
#
|
24
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.
|
25
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
|
+
|
26
77
|
# :section: Test macros
|
27
78
|
# Macro that creates a test asserting that the flash contains the given value.
|
28
79
|
# val can be a String, a Regex, or nil (indicating that the flash should not be set)
|
@@ -49,6 +100,24 @@ module ThoughtBot # :nodoc:
|
|
49
100
|
def should_not_set_the_flash
|
50
101
|
should_set_the_flash_to nil
|
51
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
|
52
121
|
|
53
122
|
# Macro that creates a test asserting that the controller assigned to
|
54
123
|
# each of the named instance variable(s).
|
@@ -77,7 +146,7 @@ module ThoughtBot # :nodoc:
|
|
77
146
|
instantiate_variables_from_assigns do
|
78
147
|
expected_value = eval(opts[:equals], self.send(:binding), __FILE__, __LINE__)
|
79
148
|
assert_equal expected_value, assigned_value,
|
80
|
-
"Instance variable @#{name} expected to be #{expected_value}" +
|
149
|
+
"Instance variable @#{name} expected to be #{expected_value}" +
|
81
150
|
" but was #{assigned_value}"
|
82
151
|
end
|
83
152
|
end
|
@@ -113,6 +182,8 @@ module ThoughtBot # :nodoc:
|
|
113
182
|
# Example:
|
114
183
|
#
|
115
184
|
# should_respond_with_content_type 'application/rss+xml'
|
185
|
+
# should_respond_with_content_type :rss
|
186
|
+
# should_respond_with_content_type /rss/
|
116
187
|
def should_respond_with_content_type(content_type)
|
117
188
|
should "respond with content type of #{content_type}" do
|
118
189
|
content_type = Mime::EXTENSION_LOOKUP[content_type.to_s].to_s if content_type.is_a? Symbol
|
@@ -158,13 +229,13 @@ module ThoughtBot # :nodoc:
|
|
158
229
|
if expected_layout
|
159
230
|
should "render with #{expected_layout} layout" do
|
160
231
|
response_layout = @response.layout.blank? ? "" : @response.layout.split('/').last
|
161
|
-
assert_equal expected_layout,
|
162
|
-
response_layout,
|
232
|
+
assert_equal expected_layout,
|
233
|
+
response_layout,
|
163
234
|
"Expected to render with layout #{expected_layout} but was rendered with #{response_layout}"
|
164
235
|
end
|
165
236
|
else
|
166
237
|
should "render without layout" do
|
167
|
-
assert_nil @response.layout,
|
238
|
+
assert_nil @response.layout,
|
168
239
|
"Expected no layout, but was rendered using #{@response.layout}"
|
169
240
|
end
|
170
241
|
end
|
@@ -197,7 +268,7 @@ module ThoughtBot # :nodoc:
|
|
197
268
|
assert_select "form", true, "The template doesn't contain a <form> element"
|
198
269
|
end
|
199
270
|
end
|
200
|
-
|
271
|
+
|
201
272
|
# Macro that creates a routing test. It tries to use the given HTTP
|
202
273
|
# +method+ on the given +path+, and asserts that it routes to the
|
203
274
|
# given +options+.
|
@@ -209,13 +280,16 @@ module ThoughtBot # :nodoc:
|
|
209
280
|
#
|
210
281
|
# Examples:
|
211
282
|
#
|
212
|
-
# should_route :get,
|
213
|
-
# should_route :
|
214
|
-
# should_route :
|
215
|
-
# should_route :
|
216
|
-
# should_route :
|
217
|
-
# should_route :
|
218
|
-
#
|
283
|
+
# should_route :get, "/posts", :controller => :posts, :action => :index
|
284
|
+
# should_route :get, "/posts/new", :action => :new
|
285
|
+
# should_route :post, "/posts", :action => :create
|
286
|
+
# should_route :get, "/posts/1", :action => :show, :id => 1
|
287
|
+
# should_route :edit, "/posts/1", :action => :show, :id => 1
|
288
|
+
# should_route :put, "/posts/1", :action => :update, :id => 1
|
289
|
+
# should_route :delete, "/posts/1", :action => :destroy, :id => 1
|
290
|
+
# should_route :get, "/users/1/posts/1",
|
291
|
+
# :action => :show, :id => 1, :user_id => 1
|
292
|
+
#
|
219
293
|
def should_route(method, path, options)
|
220
294
|
unless options[:controller]
|
221
295
|
options[:controller] = self.name.gsub(/ControllerTest$/, '').tableize
|
@@ -1,10 +1,234 @@
|
|
1
1
|
module ThoughtBot # :nodoc:
|
2
2
|
module Shoulda # :nodoc:
|
3
3
|
module Controller
|
4
|
+
# Formats tested by #should_be_restful. Defaults to [:html, :xml]
|
4
5
|
VALID_FORMATS = Dir.glob(File.join(File.dirname(__FILE__), 'formats', '*.rb')).map { |f| File.basename(f, '.rb') }.map(&:to_sym) # :doc:
|
5
6
|
VALID_FORMATS.each {|f| require "shoulda/controller/formats/#{f}"}
|
6
7
|
|
8
|
+
# Actions tested by #should_be_restful
|
7
9
|
VALID_ACTIONS = [:index, :show, :new, :edit, :create, :update, :destroy] # :doc:
|
10
|
+
|
11
|
+
# A ResourceOptions object is passed into should_be_restful in order to configure the tests for your controller.
|
12
|
+
#
|
13
|
+
# Example:
|
14
|
+
# class UsersControllerTest < Test::Unit::TestCase
|
15
|
+
# fixtures :all
|
16
|
+
#
|
17
|
+
# def setup
|
18
|
+
# ...normal setup code...
|
19
|
+
# @user = User.find(:first)
|
20
|
+
# end
|
21
|
+
#
|
22
|
+
# should_be_restful do |resource|
|
23
|
+
# resource.identifier = :id
|
24
|
+
# resource.klass = User
|
25
|
+
# resource.object = :user
|
26
|
+
# resource.parent = []
|
27
|
+
# resource.actions = [:index, :show, :new, :edit, :update, :create, :destroy]
|
28
|
+
# resource.formats = [:html, :xml]
|
29
|
+
#
|
30
|
+
# resource.create.params = { :name => "bob", :email => 'bob@bob.com', :age => 13}
|
31
|
+
# resource.update.params = { :name => "sue" }
|
32
|
+
#
|
33
|
+
# resource.create.redirect = "user_url(@user)"
|
34
|
+
# resource.update.redirect = "user_url(@user)"
|
35
|
+
# resource.destroy.redirect = "users_url"
|
36
|
+
#
|
37
|
+
# resource.create.flash = /created/i
|
38
|
+
# resource.update.flash = /updated/i
|
39
|
+
# resource.destroy.flash = /removed/i
|
40
|
+
# end
|
41
|
+
# end
|
42
|
+
#
|
43
|
+
# Whenever possible, the resource attributes will be set to sensible defaults.
|
44
|
+
#
|
45
|
+
class ResourceOptions
|
46
|
+
# Configuration options for the create, update, destroy actions under should_be_restful
|
47
|
+
class ActionOptions
|
48
|
+
# String evaled to get the target of the redirection.
|
49
|
+
# All of the instance variables set by the controller will be available to the
|
50
|
+
# evaled code.
|
51
|
+
#
|
52
|
+
# Example:
|
53
|
+
# resource.create.redirect = "user_url(@user.company, @user)"
|
54
|
+
#
|
55
|
+
# Defaults to a generated url based on the name of the controller, the action, and the resource.parents list.
|
56
|
+
attr_accessor :redirect
|
57
|
+
|
58
|
+
# String or Regexp describing a value expected in the flash. Will match against any flash key.
|
59
|
+
#
|
60
|
+
# Defaults:
|
61
|
+
# destroy:: /removed/
|
62
|
+
# create:: /created/
|
63
|
+
# update:: /updated/
|
64
|
+
attr_accessor :flash
|
65
|
+
|
66
|
+
# Hash describing the params that should be sent in with this action.
|
67
|
+
attr_accessor :params
|
68
|
+
end
|
69
|
+
|
70
|
+
# Configuration options for the denied actions under should_be_restful
|
71
|
+
#
|
72
|
+
# Example:
|
73
|
+
# context "The public" do
|
74
|
+
# setup do
|
75
|
+
# @request.session[:logged_in] = false
|
76
|
+
# end
|
77
|
+
#
|
78
|
+
# should_be_restful do |resource|
|
79
|
+
# resource.parent = :user
|
80
|
+
#
|
81
|
+
# resource.denied.actions = [:index, :show, :edit, :new, :create, :update, :destroy]
|
82
|
+
# resource.denied.flash = /get outta here/i
|
83
|
+
# resource.denied.redirect = 'new_session_url'
|
84
|
+
# end
|
85
|
+
# end
|
86
|
+
#
|
87
|
+
class DeniedOptions
|
88
|
+
# String evaled to get the target of the redirection.
|
89
|
+
# All of the instance variables set by the controller will be available to the
|
90
|
+
# evaled code.
|
91
|
+
#
|
92
|
+
# Example:
|
93
|
+
# resource.create.redirect = "user_url(@user.company, @user)"
|
94
|
+
attr_accessor :redirect
|
95
|
+
|
96
|
+
# String or Regexp describing a value expected in the flash. Will match against any flash key.
|
97
|
+
#
|
98
|
+
# Example:
|
99
|
+
# resource.create.flash = /created/
|
100
|
+
attr_accessor :flash
|
101
|
+
|
102
|
+
# Actions that should be denied (only used by resource.denied). <i>Note that these actions will
|
103
|
+
# only be tested if they are also listed in +resource.actions+</i>
|
104
|
+
# The special value of :all will deny all of the REST actions.
|
105
|
+
attr_accessor :actions
|
106
|
+
end
|
107
|
+
|
108
|
+
# Name of key in params that references the primary key.
|
109
|
+
# Will almost always be :id (default), unless you are using a plugin or have patched rails.
|
110
|
+
attr_accessor :identifier
|
111
|
+
|
112
|
+
# Name of the ActiveRecord class this resource is responsible for. Automatically determined from
|
113
|
+
# test class if not explicitly set. UserTest => "User"
|
114
|
+
attr_accessor :klass
|
115
|
+
|
116
|
+
# Name of the instantiated ActiveRecord object that should be used by some of the tests.
|
117
|
+
# Defaults to the underscored name of the AR class. CompanyManager => :company_manager
|
118
|
+
attr_accessor :object
|
119
|
+
|
120
|
+
# Name of the parent AR objects. Can be set as parent= or parents=, and can take either
|
121
|
+
# the name of the parent resource (if there's only one), or an array of names (if there's
|
122
|
+
# more than one).
|
123
|
+
#
|
124
|
+
# Example:
|
125
|
+
# # in the routes...
|
126
|
+
# map.resources :companies do
|
127
|
+
# map.resources :people do
|
128
|
+
# map.resources :limbs
|
129
|
+
# end
|
130
|
+
# end
|
131
|
+
#
|
132
|
+
# # in the tests...
|
133
|
+
# class PeopleControllerTest < Test::Unit::TestCase
|
134
|
+
# should_be_restful do |resource|
|
135
|
+
# resource.parent = :companies
|
136
|
+
# end
|
137
|
+
# end
|
138
|
+
#
|
139
|
+
# class LimbsControllerTest < Test::Unit::TestCase
|
140
|
+
# should_be_restful do |resource|
|
141
|
+
# resource.parents = [:companies, :people]
|
142
|
+
# end
|
143
|
+
# end
|
144
|
+
attr_accessor :parent
|
145
|
+
alias parents parent
|
146
|
+
alias parents= parent=
|
147
|
+
|
148
|
+
# Actions that should be tested. Must be a subset of VALID_ACTIONS (default).
|
149
|
+
# Tests for each actionw will only be generated if the action is listed here.
|
150
|
+
# The special value of :all will test all of the REST actions.
|
151
|
+
#
|
152
|
+
# Example (for a read-only controller):
|
153
|
+
# resource.actions = [:show, :index]
|
154
|
+
attr_accessor :actions
|
155
|
+
|
156
|
+
# Formats that should be tested. Must be a subset of VALID_FORMATS (default).
|
157
|
+
# Each action will be tested against the formats listed here. The special value
|
158
|
+
# of :all will test all of the supported formats.
|
159
|
+
#
|
160
|
+
# Example:
|
161
|
+
# resource.actions = [:html, :xml]
|
162
|
+
attr_accessor :formats
|
163
|
+
|
164
|
+
# ActionOptions object specifying options for the create action.
|
165
|
+
attr_accessor :create
|
166
|
+
|
167
|
+
# ActionOptions object specifying options for the update action.
|
168
|
+
attr_accessor :update
|
169
|
+
|
170
|
+
# ActionOptions object specifying options for the desrtoy action.
|
171
|
+
attr_accessor :destroy
|
172
|
+
|
173
|
+
# DeniedOptions object specifying which actions should return deny a request, and what should happen in that case.
|
174
|
+
attr_accessor :denied
|
175
|
+
|
176
|
+
def initialize # :nodoc:
|
177
|
+
@create = ActionOptions.new
|
178
|
+
@update = ActionOptions.new
|
179
|
+
@destroy = ActionOptions.new
|
180
|
+
@denied = DeniedOptions.new
|
181
|
+
|
182
|
+
@create.flash ||= /created/i
|
183
|
+
@update.flash ||= /updated/i
|
184
|
+
@destroy.flash ||= /removed/i
|
185
|
+
@denied.flash ||= /denied/i
|
186
|
+
|
187
|
+
@create.params ||= {}
|
188
|
+
@update.params ||= {}
|
189
|
+
|
190
|
+
@actions = VALID_ACTIONS
|
191
|
+
@formats = VALID_FORMATS
|
192
|
+
@denied.actions = []
|
193
|
+
end
|
194
|
+
|
195
|
+
def normalize!(target) # :nodoc:
|
196
|
+
@denied.actions = VALID_ACTIONS if @denied.actions == :all
|
197
|
+
@actions = VALID_ACTIONS if @actions == :all
|
198
|
+
@formats = VALID_FORMATS if @formats == :all
|
199
|
+
|
200
|
+
@denied.actions = @denied.actions.map(&:to_sym)
|
201
|
+
@actions = @actions.map(&:to_sym)
|
202
|
+
@formats = @formats.map(&:to_sym)
|
203
|
+
|
204
|
+
ensure_valid_members(@actions, VALID_ACTIONS, 'actions')
|
205
|
+
ensure_valid_members(@denied.actions, VALID_ACTIONS, 'denied.actions')
|
206
|
+
ensure_valid_members(@formats, VALID_FORMATS, 'formats')
|
207
|
+
|
208
|
+
@identifier ||= :id
|
209
|
+
@klass ||= target.name.gsub(/ControllerTest$/, '').singularize.constantize
|
210
|
+
@object ||= @klass.name.tableize.singularize
|
211
|
+
@parent ||= []
|
212
|
+
@parent = [@parent] unless @parent.is_a? Array
|
213
|
+
|
214
|
+
collection_helper = [@parent, @object.to_s.pluralize, 'url'].flatten.join('_')
|
215
|
+
collection_args = @parent.map {|n| "@#{object}.#{n}"}.join(', ')
|
216
|
+
@destroy.redirect ||= "#{collection_helper}(#{collection_args})"
|
217
|
+
|
218
|
+
member_helper = [@parent, @object, 'url'].flatten.join('_')
|
219
|
+
member_args = [@parent.map {|n| "@#{object}.#{n}"}, "@#{object}"].flatten.join(', ')
|
220
|
+
@create.redirect ||= "#{member_helper}(#{member_args})"
|
221
|
+
@update.redirect ||= "#{member_helper}(#{member_args})"
|
222
|
+
@denied.redirect ||= "new_session_url"
|
223
|
+
end
|
224
|
+
|
225
|
+
private
|
226
|
+
|
227
|
+
def ensure_valid_members(ary, valid_members, name) # :nodoc:
|
228
|
+
invalid = ary - valid_members
|
229
|
+
raise ArgumentError, "Unsupported #{name}: #{invalid.inspect}" unless invalid.empty?
|
230
|
+
end
|
231
|
+
end
|
8
232
|
end
|
9
233
|
end
|
10
234
|
end
|
data/lib/shoulda/macros.rb
CHANGED
@@ -12,10 +12,7 @@ module ThoughtBot # :nodoc:
|
|
12
12
|
# Example:
|
13
13
|
#
|
14
14
|
# context "Creating a post"
|
15
|
-
# setup
|
16
|
-
# Post.create
|
17
|
-
# end
|
18
|
-
#
|
15
|
+
# setup { Post.create }
|
19
16
|
# should_change "Post.count", :by => 1
|
20
17
|
# end
|
21
18
|
#
|
@@ -57,10 +54,7 @@ module ThoughtBot # :nodoc:
|
|
57
54
|
# Example:
|
58
55
|
#
|
59
56
|
# context "Updating a post"
|
60
|
-
# setup
|
61
|
-
# @post.update_attributes(:title => "new")
|
62
|
-
# end
|
63
|
-
#
|
57
|
+
# setup { @post.update_attributes(:title => "new") }
|
64
58
|
# should_not_change "Post.count"
|
65
59
|
# end
|
66
60
|
def should_not_change(expression)
|
data/rails/init.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'shoulda/rails'
|
data/test/fail_macros.rb
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
module Thoughtbot
|
2
|
+
module Shoulda
|
3
|
+
class << self
|
4
|
+
attr_accessor :expected_exceptions
|
5
|
+
end
|
6
|
+
|
7
|
+
# Enables the core shoulda test suite to test for failure scenarios. For
|
8
|
+
# example, to ensure that a set of test macros should fail, do this:
|
9
|
+
#
|
10
|
+
# should_fail do
|
11
|
+
# should_require_attributes :comments
|
12
|
+
# should_protect_attributes :name
|
13
|
+
# end
|
14
|
+
def should_fail(&block)
|
15
|
+
context "should fail when trying to run:" do
|
16
|
+
Shoulda.expected_exceptions = [Test::Unit::AssertionFailedError]
|
17
|
+
yield block
|
18
|
+
Shoulda.expected_exceptions = nil
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
class Context
|
23
|
+
# alias_method_chain hack to allow the should_fail macro to work
|
24
|
+
def should_with_failure_scenario(name, options = {}, &block)
|
25
|
+
if Shoulda.expected_exceptions
|
26
|
+
expected_exceptions = Shoulda.expected_exceptions
|
27
|
+
failure_block = lambda { assert_raise(*expected_exceptions, &block.bind(self)) }
|
28
|
+
end
|
29
|
+
should_without_failure_scenario(name, options, &(failure_block || block))
|
30
|
+
end
|
31
|
+
alias_method_chain :should, :failure_scenario
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -33,11 +33,32 @@ 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
|
+
|
36
50
|
context "Logged in" do
|
37
51
|
setup do
|
38
52
|
@request.session[:logged_in] = true
|
39
53
|
end
|
40
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
|
+
|
41
62
|
context "viewing posts for a user" do
|
42
63
|
setup do
|
43
64
|
get :index, :user_id => users(:first)
|
@@ -13,31 +13,26 @@ class UsersControllerTest < Test::Unit::TestCase
|
|
13
13
|
@response = ActionController::TestResponse.new
|
14
14
|
@user = User.find(:first)
|
15
15
|
end
|
16
|
+
|
17
|
+
should_filter_params :ssn
|
16
18
|
|
17
|
-
|
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]
|
19
26
|
|
20
|
-
|
21
|
-
|
22
|
-
should_render_template :index
|
23
|
-
should_assign_to :users
|
24
|
-
end
|
25
|
-
|
26
|
-
context "on GET to #index.xml" do
|
27
|
-
setup { get :index, :format => 'xml' }
|
28
|
-
|
29
|
-
should_respond_with :success
|
30
|
-
should_respond_with_xml_for
|
31
|
-
should_assign_to :users
|
32
|
-
end
|
33
|
-
|
34
|
-
context "on GET to #show" do
|
35
|
-
setup { get :show, :id => @user }
|
27
|
+
resource.create.params = { :name => "bob", :email => 'bob@bob.com', :age => 13, :ssn => "123456789"}
|
28
|
+
resource.update.params = { :name => "sue" }
|
36
29
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
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
|
41
37
|
end
|
42
|
-
|
43
38
|
end
|
@@ -0,0 +1 @@
|
|
1
|
+
<html><%= yield %></html>
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: shoulda
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0.
|
4
|
+
version: 2.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tammer Saleh
|
@@ -49,7 +49,6 @@ files:
|
|
49
49
|
- lib/shoulda/controller/helpers.rb
|
50
50
|
- lib/shoulda/controller/macros.rb
|
51
51
|
- lib/shoulda/controller/resource_options.rb
|
52
|
-
- lib/shoulda/controller/routing.rb
|
53
52
|
- lib/shoulda/controller.rb
|
54
53
|
- lib/shoulda/helpers.rb
|
55
54
|
- lib/shoulda/macros.rb
|
@@ -60,6 +59,8 @@ files:
|
|
60
59
|
- lib/shoulda/tasks/yaml_to_shoulda.rake
|
61
60
|
- lib/shoulda/tasks.rb
|
62
61
|
- lib/shoulda.rb
|
62
|
+
- rails/init.rb
|
63
|
+
- test/fail_macros.rb
|
63
64
|
- test/fixtures/addresses.yml
|
64
65
|
- test/fixtures/friendships.yml
|
65
66
|
- test/fixtures/posts.yml
|
@@ -91,6 +92,7 @@ files:
|
|
91
92
|
- test/rails_root/app/models/user.rb
|
92
93
|
- test/rails_root/app/views/layouts/posts.rhtml
|
93
94
|
- test/rails_root/app/views/layouts/users.rhtml
|
95
|
+
- test/rails_root/app/views/layouts/wide.html.erb
|
94
96
|
- test/rails_root/app/views/posts/edit.rhtml
|
95
97
|
- test/rails_root/app/views/posts/index.rhtml
|
96
98
|
- test/rails_root/app/views/posts/new.rhtml
|
File without changes
|