technicalpickles-shoulda 2.0.0 → 2.0.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/Rakefile CHANGED
@@ -3,7 +3,7 @@ require 'rake/testtask'
3
3
  require 'rake/rdoctask'
4
4
  require 'rake/gempackagetask'
5
5
  require 'lib/shoulda/context'
6
- require 'lib/shoulda/tasks'
6
+ load 'tasks/shoulda.rake'
7
7
 
8
8
  # Test::Unit::UI::VERBOSE
9
9
  test_files_pattern = 'test/{unit,functional,other}/**/*_test.rb'
@@ -56,7 +56,8 @@ module ThoughtBot # :nodoc:
56
56
  #
57
57
  # @product = Product.new(:tangible => true)
58
58
  # assert_bad_value(Product, :price, "0")
59
- def assert_bad_value(object_or_klass, attribute, value, error_message_to_expect = /invalid/)
59
+ def assert_bad_value(object_or_klass, attribute, value,
60
+ error_message_to_expect = DEFAULT_ERROR_MESSAGES[:invalid])
60
61
  object = get_instance_of(object_or_klass)
61
62
  object.send("#{attribute}=", value)
62
63
  assert !object.valid?, "#{object.class} allowed #{value.inspect} as a value for #{attribute}"
@@ -1,6 +1,13 @@
1
1
  module ThoughtBot # :nodoc:
2
2
  module Shoulda # :nodoc:
3
3
  module ActiveRecord # :nodoc:
4
+ DEFAULT_ERROR_MESSAGES =
5
+ if Object.const_defined?(:I18n)
6
+ I18n.translate('active_record.error_messages')
7
+ else
8
+ ::ActiveRecord::Errors.default_error_messages
9
+ end
10
+
4
11
  # = Macro test helpers for your active record models
5
12
  #
6
13
  # These helpers will test most of the validations and associations for your ActiveRecord models.
@@ -36,14 +43,14 @@ module ThoughtBot # :nodoc:
36
43
  #
37
44
  # Options:
38
45
  # * <tt>:message</tt> - value the test expects to find in <tt>errors.on(:attribute)</tt>.
39
- # Regexp or string. Default = <tt>/blank/</tt>
46
+ # Regexp or string. Default = <tt>I18n.translate('active_record.error_messages')[:blank]</tt>
40
47
  #
41
48
  # Example:
42
49
  # should_require_attributes :name, :phone_number
43
50
  #
44
51
  def should_require_attributes(*attributes)
45
52
  message = get_options!(attributes, :message)
46
- message ||= /blank/
53
+ message ||= DEFAULT_ERROR_MESSAGES[:blank]
47
54
  klass = model_class
48
55
 
49
56
  attributes.each do |attribute|
@@ -58,7 +65,7 @@ module ThoughtBot # :nodoc:
58
65
  #
59
66
  # Options:
60
67
  # * <tt>:message</tt> - value the test expects to find in <tt>errors.on(:attribute)</tt>.
61
- # Regexp or string. Default = <tt>/taken/</tt>
68
+ # Regexp or string. Default = <tt>I18n.translate('active_record.error_messages')[:taken]</tt>
62
69
  # * <tt>:scoped_to</tt> - field(s) to scope the uniqueness to.
63
70
  #
64
71
  # Examples:
@@ -70,7 +77,7 @@ module ThoughtBot # :nodoc:
70
77
  def should_require_unique_attributes(*attributes)
71
78
  message, scope = get_options!(attributes, :message, :scoped_to)
72
79
  scope = [*scope].compact
73
- message ||= /taken/
80
+ message ||= DEFAULT_ERROR_MESSAGES[:taken]
74
81
 
75
82
  klass = model_class
76
83
  attributes.each do |attribute|
@@ -118,7 +125,8 @@ module ThoughtBot # :nodoc:
118
125
  protected = klass.protected_attributes || []
119
126
  accessible = klass.accessible_attributes || []
120
127
 
121
- assert protected.include?(attribute.to_s) || !accessible.include?(attribute.to_s),
128
+ assert protected.include?(attribute.to_s) ||
129
+ (!accessible.empty? && !accessible.include?(attribute.to_s)),
122
130
  (accessible.empty? ?
123
131
  "#{klass} is protecting #{protected.to_a.to_sentence}, but not #{attribute}." :
124
132
  "#{klass} has made #{attribute} accessible")
@@ -155,14 +163,14 @@ module ThoughtBot # :nodoc:
155
163
  #
156
164
  # Options:
157
165
  # * <tt>:message</tt> - value the test expects to find in <tt>errors.on(:attribute)</tt>.
158
- # Regexp or string. Default = <tt>/invalid/</tt>
166
+ # Regexp or string. Default = <tt>I18n.translate('active_record.error_messages')[:invalid]</tt>
159
167
  #
160
168
  # Example:
161
169
  # should_not_allow_values_for :isbn, "bad 1", "bad 2"
162
170
  #
163
171
  def should_not_allow_values_for(attribute, *bad_values)
164
172
  message = get_options!(bad_values, :message)
165
- message ||= /invalid/
173
+ message ||= DEFAULT_ERROR_MESSAGES[:invalid]
166
174
  klass = model_class
167
175
  bad_values.each do |v|
168
176
  should "not allow #{attribute} to be set to #{v.inspect}" do
@@ -198,17 +206,17 @@ module ThoughtBot # :nodoc:
198
206
  #
199
207
  # Options:
200
208
  # * <tt>:short_message</tt> - value the test expects to find in <tt>errors.on(:attribute)</tt>.
201
- # Regexp or string. Default = <tt>/short/</tt>
209
+ # Regexp or string. Default = <tt>I18n.translate('active_record.error_messages')[:too_short] % range.first</tt>
202
210
  # * <tt>:long_message</tt> - value the test expects to find in <tt>errors.on(:attribute)</tt>.
203
- # Regexp or string. Default = <tt>/long/</tt>
211
+ # Regexp or string. Default = <tt>I18n.translate('active_record.error_messages')[:too_long] % range.last</tt>
204
212
  #
205
213
  # Example:
206
214
  # should_ensure_length_in_range :password, (6..20)
207
215
  #
208
216
  def should_ensure_length_in_range(attribute, range, opts = {})
209
217
  short_message, long_message = get_options!([opts], :short_message, :long_message)
210
- short_message ||= /short/
211
- long_message ||= /long/
218
+ short_message ||= DEFAULT_ERROR_MESSAGES[:too_short] % range.first
219
+ long_message ||= DEFAULT_ERROR_MESSAGES[:too_long] % range.last
212
220
 
213
221
  klass = model_class
214
222
  min_length = range.first
@@ -250,14 +258,14 @@ module ThoughtBot # :nodoc:
250
258
  #
251
259
  # Options:
252
260
  # * <tt>:short_message</tt> - value the test expects to find in <tt>errors.on(:attribute)</tt>.
253
- # Regexp or string. Default = <tt>/short/</tt>
261
+ # Regexp or string. Default = <tt>I18n.translate('active_record.error_messages')[:too_short] % min_length</tt>
254
262
  #
255
263
  # Example:
256
264
  # should_ensure_length_at_least :name, 3
257
265
  #
258
266
  def should_ensure_length_at_least(attribute, min_length, opts = {})
259
267
  short_message = get_options!([opts], :short_message)
260
- short_message ||= /short/
268
+ short_message ||= DEFAULT_ERROR_MESSAGES[:too_short] % min_length
261
269
 
262
270
  klass = model_class
263
271
 
@@ -281,14 +289,14 @@ module ThoughtBot # :nodoc:
281
289
  #
282
290
  # Options:
283
291
  # * <tt>:message</tt> - value the test expects to find in <tt>errors.on(:attribute)</tt>.
284
- # Regexp or string. Default = <tt>/short/</tt>
292
+ # Regexp or string. Default = <tt>I18n.translate('active_record.error_messages')[:wrong_length] % length</tt>
285
293
  #
286
294
  # Example:
287
295
  # should_ensure_length_is :ssn, 9
288
296
  #
289
297
  def should_ensure_length_is(attribute, length, opts = {})
290
298
  message = get_options!([opts], :message)
291
- message ||= /wrong length/
299
+ message ||= DEFAULT_ERROR_MESSAGES[:wrong_length] % length
292
300
 
293
301
  klass = model_class
294
302
 
@@ -316,17 +324,17 @@ module ThoughtBot # :nodoc:
316
324
  #
317
325
  # Options:
318
326
  # * <tt>:low_message</tt> - value the test expects to find in <tt>errors.on(:attribute)</tt>.
319
- # Regexp or string. Default = <tt>/included/</tt>
327
+ # Regexp or string. Default = <tt>I18n.translate('active_record.error_messages')[:inclusion]</tt>
320
328
  # * <tt>:high_message</tt> - value the test expects to find in <tt>errors.on(:attribute)</tt>.
321
- # Regexp or string. Default = <tt>/included/</tt>
329
+ # Regexp or string. Default = <tt>I18n.translate('active_record.error_messages')[:inclusion]</tt>
322
330
  #
323
331
  # Example:
324
332
  # should_ensure_value_in_range :age, (0..100)
325
333
  #
326
334
  def should_ensure_value_in_range(attribute, range, opts = {})
327
335
  low_message, high_message = get_options!([opts], :low_message, :high_message)
328
- low_message ||= /included/
329
- high_message ||= /included/
336
+ low_message ||= DEFAULT_ERROR_MESSAGES[:inclusion]
337
+ high_message ||= DEFAULT_ERROR_MESSAGES[:inclusion]
330
338
 
331
339
  klass = model_class
332
340
  min = range.first
@@ -361,14 +369,14 @@ module ThoughtBot # :nodoc:
361
369
  #
362
370
  # Options:
363
371
  # * <tt>:message</tt> - value the test expects to find in <tt>errors.on(:attribute)</tt>.
364
- # Regexp or string. Default = <tt>/number/</tt>
372
+ # Regexp or string. Default = <tt>I18n.translate('active_record.error_messages')[:not_a_number]</tt>
365
373
  #
366
374
  # Example:
367
375
  # should_only_allow_numeric_values_for :age
368
376
  #
369
377
  def should_only_allow_numeric_values_for(*attributes)
370
378
  message = get_options!(attributes, :message)
371
- message ||= /number/
379
+ message ||= DEFAULT_ERROR_MESSAGES[:not_a_number]
372
380
  klass = model_class
373
381
  attributes.each do |attribute|
374
382
  attribute = attribute.to_sym
@@ -439,14 +447,19 @@ module ThoughtBot # :nodoc:
439
447
  # associated table has the required columns. Works with polymorphic
440
448
  # associations.
441
449
  #
450
+ # Options:
451
+ # * <tt>:dependent</tt> - tests that the association makes use of the dependent option.
452
+ #
442
453
  # Example:
443
454
  # should_have_one :god # unless hindu
444
455
  #
445
456
  def should_have_one(*associations)
446
- get_options!(associations)
457
+ dependent = get_options!(associations, :dependent)
447
458
  klass = model_class
448
459
  associations.each do |association|
449
- should "have one #{association}" do
460
+ name = "have one #{association}"
461
+ name += " dependent => #{dependent}" if dependent
462
+ should name do
450
463
  reflection = klass.reflect_on_association(association)
451
464
  assert reflection, "#{klass.name} does not have any relationship to #{association}"
452
465
  assert_equal :has_one, reflection.macro
@@ -465,6 +478,12 @@ module ThoughtBot # :nodoc:
465
478
  end
466
479
  assert associated_klass.column_names.include?(fk.to_s),
467
480
  "#{associated_klass.name} does not have a #{fk} foreign key."
481
+
482
+ if dependent
483
+ assert_equal dependent.to_s,
484
+ reflection.options[:dependent].to_s,
485
+ "#{association} should have #{dependent} dependency"
486
+ end
468
487
  end
469
488
  end
470
489
  end
@@ -604,14 +623,14 @@ module ThoughtBot # :nodoc:
604
623
  #
605
624
  # Options:
606
625
  # * <tt>:message</tt> - value the test expects to find in <tt>errors.on(:attribute)</tt>.
607
- # Regexp or string. Default = <tt>/must be accepted/</tt>
626
+ # Regexp or string. Default = <tt>I18n.translate('active_record.error_messages')[:accepted]</tt>
608
627
  #
609
628
  # Example:
610
629
  # should_require_acceptance_of :eula
611
630
  #
612
631
  def should_require_acceptance_of(*attributes)
613
632
  message = get_options!(attributes, :message)
614
- message ||= /must be accepted/
633
+ message ||= DEFAULT_ERROR_MESSAGES[:accepted]
615
634
  klass = model_class
616
635
 
617
636
  attributes.each do |attribute|
@@ -1,6 +1,6 @@
1
1
  module Thoughtbot # :nodoc:
2
2
  module Shoulda
3
- VERSION = '2.0.0'
3
+ VERSION = '2.0.1'
4
4
 
5
5
  class << self
6
6
  attr_accessor :contexts
@@ -134,6 +134,37 @@ module ThoughtBot # :nodoc:
134
134
  end
135
135
  end
136
136
 
137
+ # Macro that creates a test asserting that the response content type was 'content_type'.
138
+ # Example:
139
+ #
140
+ # should_respond_with_content_type 'application/rss+xml'
141
+ def should_respond_with_content_type(content_type)
142
+ should "respond with content type of #{content_type}" do
143
+ content_type = Mime::EXTENSION_LOOKUP[content_type.to_s].to_s if content_type.is_a? Symbol
144
+ if content_type.is_a? Regexp
145
+ assert_match content_type, @response.content_type, "Expected to match #{content_type} but was actually #{@response.content_type}"
146
+ else
147
+ assert_equal content_type, @response.content_type, "Expected #{content_type} but was actually #{@response.content_type}"
148
+ end
149
+ end
150
+ end
151
+
152
+ # Macro that creates a test asserting that a value returned from the session is correct.
153
+ # The given string is evaled to produce the resulting redirect path. All of the instance variables
154
+ # set by the controller are available to the evaled string.
155
+ # Example:
156
+ #
157
+ # should_return_from_session :user_id, '@user.id'
158
+ # should_return_from_session :message, '"Free stuff"'
159
+ def should_return_from_session(key, expected)
160
+ should "return the correct value from the session for key #{key}" do
161
+ instantiate_variables_from_assigns do
162
+ expected_value = eval(expected, self.send(:binding), __FILE__, __LINE__)
163
+ assert_equal expected_value, session[key], "Expected #{expected_value.inspect} but was #{session[key]}"
164
+ end
165
+ end
166
+ end
167
+
137
168
  # Macro that creates a test asserting that the controller rendered the given template.
138
169
  # Example:
139
170
  #
@@ -144,6 +175,32 @@ module ThoughtBot # :nodoc:
144
175
  end
145
176
  end
146
177
 
178
+ # Macro that creates a test asserting that the controller rendered with the given layout.
179
+ # Example:
180
+ #
181
+ # should_render_with_layout 'special'
182
+ def should_render_with_layout(expected_layout = 'application')
183
+ if expected_layout
184
+ should "render with #{expected_layout} layout" do
185
+ response_layout = @response.layout.blank? ? "" : @response.layout.split('/').last
186
+ assert_equal expected_layout,
187
+ response_layout,
188
+ "Expected to render with layout #{expected_layout} but was rendered with #{response_layout}"
189
+ end
190
+ else
191
+ should "render without layout" do
192
+ assert_nil @response.layout,
193
+ "Expected no layout, but was rendered using #{@response.layout}"
194
+ end
195
+ end
196
+ end
197
+
198
+ # Macro that creates a test asserting that the controller rendered without a layout.
199
+ # Same as @should_render_with_layout false@
200
+ def should_render_without_layout
201
+ should_render_with_layout nil
202
+ end
203
+
147
204
  # Macro that creates a test asserting that the controller returned a redirect to the given path.
148
205
  # The given string is evaled to produce the resulting redirect path. All of the instance variables
149
206
  # set by the controller are available to the evaled string.
@@ -165,6 +222,44 @@ module ThoughtBot # :nodoc:
165
222
  assert_select "form", true, "The template doesn't contain a <form> element"
166
223
  end
167
224
  end
225
+
226
+ # Macro that creates a routing test. It tries to use the given HTTP
227
+ # +method+ on the given +path+, and asserts that it routes to the
228
+ # given +options+.
229
+ #
230
+ # If you don't specify a :controller, it will try to guess the controller
231
+ # based on the current test.
232
+ #
233
+ # +to_param+ is called on the +options+ given.
234
+ #
235
+ # Examples:
236
+ #
237
+ # should_route :get, '/posts', :action => :index
238
+ # should_route :post, '/posts', :controller => :posts, :action => :create
239
+ # should_route :get, '/posts/1', :action => :show, :id => 1
240
+ # should_route :put, '/posts/1', :action => :update, :id => "1"
241
+ # should_route :delete, '/posts/1', :action => :destroy, :id => 1
242
+ # should_route :get, '/posts/new', :action => :new
243
+ #
244
+ def should_route(method, path, options)
245
+ unless options[:controller]
246
+ options[:controller] = self.name.gsub(/ControllerTest$/, '').tableize
247
+ end
248
+ options[:controller] = options[:controller].to_s
249
+ options[:action] = options[:action].to_s
250
+
251
+ populated_path = path.dup
252
+ options.each do |key, value|
253
+ options[key] = value.to_param if value.respond_to? :to_param
254
+ populated_path.gsub!(key.inspect, value.to_s)
255
+ end
256
+
257
+ should_name = "route #{method.to_s.upcase} #{populated_path} to/from #{options.inspect}"
258
+
259
+ should should_name do
260
+ assert_routing({:method => method, :path => populated_path}, options)
261
+ end
262
+ end
168
263
  end
169
264
  end
170
265
  end
@@ -2,7 +2,6 @@ require 'shoulda'
2
2
  require 'shoulda/controller/helpers'
3
3
  require 'shoulda/controller/resource_options'
4
4
  require 'shoulda/controller/macros'
5
- require 'shoulda/controller/routing'
6
5
 
7
6
  module Test # :nodoc: all
8
7
  module Unit
@@ -67,6 +67,31 @@ class PostsControllerTest < Test::Unit::TestCase
67
67
  should_assign_to :user, :posts
68
68
  should_not_assign_to :foo, :bar
69
69
  end
70
+
71
+ context "viewing posts for a user with rss format" do
72
+ setup do
73
+ get :index, :user_id => users(:first), :format => 'rss'
74
+ @user = users(:first)
75
+ end
76
+ should_respond_with :success
77
+ should_respond_with_content_type 'application/rss+xml'
78
+ should_respond_with_content_type :rss
79
+ should_respond_with_content_type /rss/
80
+ should_return_from_session :special, "'$2 off your next purchase'"
81
+ should_return_from_session :special_user_id, '@user.id'
82
+ should_assign_to :user, :posts
83
+ should_not_assign_to :foo, :bar
84
+ end
85
+
86
+ context "viewing a post on GET to #show" do
87
+ setup { get :show, :user_id => users(:first), :id => posts(:first) }
88
+ should_render_with_layout 'wide'
89
+ end
90
+
91
+ context "on GET to #new" do
92
+ setup { get :new, :user_id => users(:first) }
93
+ should_render_without_layout
94
+ end
70
95
  end
71
96
 
72
97
  end
@@ -8,6 +8,12 @@ class PostsController < ApplicationController
8
8
  respond_to do |format|
9
9
  format.html # index.rhtml
10
10
  format.xml { render :xml => @posts.to_xml }
11
+ format.rss do
12
+ headers['Content-Type'] = 'application/rss+xml'
13
+ session[:special] = '$2 off your next purchase'
14
+ session[:special_user_id] = @user.id
15
+ head :ok
16
+ end
11
17
  end
12
18
  end
13
19
 
@@ -15,13 +21,14 @@ class PostsController < ApplicationController
15
21
  @post = @user.posts.find(params[:id])
16
22
 
17
23
  respond_to do |format|
18
- format.html # show.rhtml
24
+ format.html { render :layout => 'wide' }
19
25
  format.xml { render :xml => @post.to_xml }
20
26
  end
21
27
  end
22
28
 
23
29
  def new
24
30
  @post = @user.posts.build
31
+ render :layout => false
25
32
  end
26
33
 
27
34
  def edit
@@ -5,7 +5,7 @@ class User < ActiveRecord::Base
5
5
  has_many :friendships
6
6
  has_many :friends, :through => :friendships
7
7
 
8
- has_one :address, :as => :addressable
8
+ has_one :address, :as => :addressable, :dependent => :destroy
9
9
 
10
10
  named_scope :old, :conditions => "age > 50"
11
11
  named_scope :eighteen, :conditions => { :age => 18 }
@@ -1,6 +1,6 @@
1
1
  # Specifies gem version of Rails to use when vendor/rails is not present
2
2
  old_verbose, $VERBOSE = $VERBOSE, nil
3
- RAILS_GEM_VERSION = '2.1.0' unless defined? RAILS_GEM_VERSION
3
+ RAILS_GEM_VERSION = '>= 2.1.0' unless defined? RAILS_GEM_VERSION
4
4
  $VERBOSE = old_verbose
5
5
 
6
6
  require File.join(File.dirname(__FILE__), 'boot')
@@ -10,5 +10,5 @@ Rails::Initializer.run do |config|
10
10
  config.cache_classes = false
11
11
  config.whiny_nils = true
12
12
  end
13
-
13
+
14
14
  # Dependencies.log_activity = true
data/test/test_helper.rb CHANGED
@@ -5,15 +5,15 @@ ENV['RAILS_ENV'] = 'sqlite3'
5
5
  rails_root = File.dirname(__FILE__) + '/rails_root'
6
6
 
7
7
  require "#{rails_root}/config/environment.rb"
8
-
8
+
9
9
  # Load the testing framework
10
10
  require 'test_help'
11
11
  silence_warnings { RAILS_ENV = ENV['RAILS_ENV'] }
12
-
12
+
13
13
  # Run the migrations
14
14
  ActiveRecord::Migration.verbose = false
15
15
  ActiveRecord::Migrator.migrate("#{RAILS_ROOT}/db/migrate")
16
-
16
+
17
17
  # Setup the fixtures path
18
18
  Test::Unit::TestCase.fixture_path = File.join(File.dirname(__FILE__), "fixtures")
19
19
 
@@ -25,7 +25,9 @@ class Test::Unit::TestCase #:nodoc:
25
25
  Fixtures.create_fixtures(Test::Unit::TestCase.fixture_path, table_names)
26
26
  end
27
27
  end
28
-
28
+
29
29
  self.use_transactional_fixtures = false
30
30
  self.use_instantiated_fixtures = false
31
31
  end
32
+
33
+ require 'test/fail_macros'
@@ -7,4 +7,8 @@ class TagTest < Test::Unit::TestCase
7
7
  should_ensure_length_at_least :name, 2
8
8
 
9
9
  should_protect_attributes :secret
10
+
11
+ should_fail do
12
+ should_protect_attributes :name
13
+ end
10
14
  end
@@ -10,6 +10,7 @@ class UserTest < Test::Unit::TestCase
10
10
  should_have_many :friends
11
11
 
12
12
  should_have_one :address
13
+ should_have_one :address, :dependent => :destroy
13
14
 
14
15
  should_have_indices :email, :name, [:email, :name]
15
16
  should_have_index :age
@@ -44,4 +45,8 @@ class UserTest < Test::Unit::TestCase
44
45
  should_only_allow_numeric_values_for :ssn
45
46
 
46
47
  should_have_readonly_attributes :name
48
+
49
+ should_fail do
50
+ should_protect_attributes :name, :age
51
+ end
47
52
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: technicalpickles-shoulda
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0
4
+ version: 2.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tammer Saleh
@@ -1,47 +0,0 @@
1
- module ThoughtBot
2
- module Shoulda
3
- module Controller
4
- module Routing
5
- module Macros
6
- # Macro that creates a routing test. It tries to use the given HTTP
7
- # +method+ on the given +path+, and asserts that it routes to the
8
- # given +options+.
9
- #
10
- # If you don't specify a :controller, it will try to guess the controller
11
- # based on the current test.
12
- #
13
- # +to_param+ is called on the +options+ given.
14
- #
15
- # Examples:
16
- #
17
- # should_route :get, '/posts', :action => :index
18
- # should_route :post, '/posts', :controller => :posts, :action => :create
19
- # should_route :get, '/posts/1', :action => :show, :id => 1
20
- # should_route :put, '/posts/1', :action => :update, :id => "1"
21
- # should_route :delete, '/posts/1', :action => :destroy, :id => 1
22
- # should_route :get, '/posts/new', :action => :new
23
- #
24
- def should_route(method, path, options)
25
- unless options[:controller]
26
- options[:controller] = self.name.gsub(/ControllerTest$/, '').tableize
27
- end
28
- options[:controller] = options[:controller].to_s
29
- options[:action] = options[:action].to_s
30
-
31
- populated_path = path.dup
32
- options.each do |key, value|
33
- options[key] = value.to_param if value.respond_to? :to_param
34
- populated_path.gsub!(key.inspect, value.to_s)
35
- end
36
-
37
- should_name = "route #{method.to_s.upcase} #{populated_path} to/from #{options.inspect}"
38
-
39
- should should_name do
40
- assert_routing({:method => method, :path => populated_path}, options)
41
- end
42
- end
43
- end
44
- end
45
- end
46
- end
47
- end
@@ -1,10 +0,0 @@
1
- require 'shoulda'
2
- require 'shoulda/controller/routing/macros'
3
-
4
- module Test # :nodoc: all
5
- module Unit
6
- class TestCase
7
- extend ThoughtBot::Shoulda::Controller::Routing::Macros
8
- end
9
- end
10
- end