technicalpickles-shoulda 2.0.2 → 2.0.6
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 +0 -13
- data/Rakefile +1 -3
- data/lib/shoulda/active_record/assertions.rb +5 -2
- data/lib/shoulda/active_record/macros.rb +40 -29
- data/lib/shoulda/assertions.rb +8 -4
- data/lib/shoulda/context.rb +1 -1
- data/lib/shoulda/controller/macros.rb +6 -5
- data/lib/shoulda/macros.rb +4 -4
- data/test/functional/posts_controller_test.rb +1 -0
- data/test/rails_root/app/models/dog.rb +1 -1
- metadata +4 -13
data/README.rdoc
CHANGED
@@ -90,19 +90,6 @@ 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
|
-
|
106
93
|
=== Helpful Assertions (ThoughtBot::Shoulda::Assertions)
|
107
94
|
|
108
95
|
More to come here, but have fun with what's there.
|
data/Rakefile
CHANGED
@@ -43,7 +43,7 @@ spec = Gem::Specification.new do |s|
|
|
43
43
|
s.homepage = "http://thoughtbot.com/projects/shoulda"
|
44
44
|
s.rubyforge_project = "shoulda"
|
45
45
|
|
46
|
-
s.files = FileList["[A-Z]*", "{bin,lib,test}/**/*"]
|
46
|
+
s.files = FileList["[A-Z]*", "{bin,lib,rails,test}/**/*"]
|
47
47
|
s.executables = s.files.grep(/^bin/) { |f| File.basename(f) }
|
48
48
|
|
49
49
|
s.has_rdoc = true
|
@@ -52,8 +52,6 @@ spec = Gem::Specification.new do |s|
|
|
52
52
|
|
53
53
|
s.authors = ["Tammer Saleh"]
|
54
54
|
s.email = "tsaleh@thoughtbot.com"
|
55
|
-
|
56
|
-
s.add_dependency "activesupport", ">= 2.0"
|
57
55
|
end
|
58
56
|
|
59
57
|
Rake::GemPackageTask.new spec do |pkg|
|
@@ -57,7 +57,7 @@ module ThoughtBot # :nodoc:
|
|
57
57
|
# @product = Product.new(:tangible => true)
|
58
58
|
# assert_bad_value(Product, :price, "0")
|
59
59
|
def assert_bad_value(object_or_klass, attribute, value,
|
60
|
-
error_message_to_expect =
|
60
|
+
error_message_to_expect = self.class.default_error_message(:invalid))
|
61
61
|
object = get_instance_of(object_or_klass)
|
62
62
|
object.send("#{attribute}=", value)
|
63
63
|
assert !object.valid?, "#{object.class} allowed #{value.inspect} as a value for #{attribute}"
|
@@ -66,7 +66,10 @@ module ThoughtBot # :nodoc:
|
|
66
66
|
end
|
67
67
|
|
68
68
|
def pretty_error_messages(obj)
|
69
|
-
obj.errors.map
|
69
|
+
obj.errors.map do |a, m|
|
70
|
+
msg = "#{a} #{m}"
|
71
|
+
msg << " (#{obj.send(a).inspect})" unless a.to_sym == :base
|
72
|
+
end
|
70
73
|
end
|
71
74
|
|
72
75
|
private
|
@@ -1,12 +1,22 @@
|
|
1
1
|
module ThoughtBot # :nodoc:
|
2
2
|
module Shoulda # :nodoc:
|
3
3
|
module ActiveRecord # :nodoc:
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
4
|
+
module MacroHelpers # :nodoc:
|
5
|
+
# Helper method that determines the default error message used by Active
|
6
|
+
# Record. Works for both existing Rails 2.1 and Rails 2.2 with the newly
|
7
|
+
# introduced I18n module used for localization.
|
8
|
+
#
|
9
|
+
# default_error_message(:blank)
|
10
|
+
# default_error_message(:too_short, :count => 5)
|
11
|
+
# default_error_message(:too_long, :count => 60)
|
12
|
+
def default_error_message(key, values = {})
|
13
|
+
if Object.const_defined?(:I18n) # Rails >= 2.2
|
14
|
+
I18n.translate("activerecord.errors.messages.#{key}", values)
|
15
|
+
else # Rails <= 2.1.x
|
16
|
+
::ActiveRecord::Errors.default_error_messages[key] % values[:count]
|
17
|
+
end
|
9
18
|
end
|
19
|
+
end
|
10
20
|
|
11
21
|
# = Macro test helpers for your active record models
|
12
22
|
#
|
@@ -28,6 +38,8 @@ module ThoughtBot # :nodoc:
|
|
28
38
|
# For all of these helpers, the last parameter may be a hash of options.
|
29
39
|
#
|
30
40
|
module Macros
|
41
|
+
include MacroHelpers
|
42
|
+
|
31
43
|
# <b>DEPRECATED:</b> Use <tt>fixtures :all</tt> instead
|
32
44
|
#
|
33
45
|
# Loads all fixture files (<tt>test/fixtures/*.yml</tt>)
|
@@ -44,14 +56,14 @@ module ThoughtBot # :nodoc:
|
|
44
56
|
#
|
45
57
|
# Options:
|
46
58
|
# * <tt>:message</tt> - value the test expects to find in <tt>errors.on(:attribute)</tt>.
|
47
|
-
# Regexp or string. Default = <tt>I18n.translate('activerecord.errors.messages')
|
59
|
+
# Regexp or string. Default = <tt>I18n.translate('activerecord.errors.messages.blank')</tt>
|
48
60
|
#
|
49
61
|
# Example:
|
50
62
|
# should_require_attributes :name, :phone_number
|
51
63
|
#
|
52
64
|
def should_require_attributes(*attributes)
|
53
65
|
message = get_options!(attributes, :message)
|
54
|
-
message ||=
|
66
|
+
message ||= default_error_message(:blank)
|
55
67
|
klass = model_class
|
56
68
|
|
57
69
|
attributes.each do |attribute|
|
@@ -66,7 +78,7 @@ module ThoughtBot # :nodoc:
|
|
66
78
|
#
|
67
79
|
# Options:
|
68
80
|
# * <tt>:message</tt> - value the test expects to find in <tt>errors.on(:attribute)</tt>.
|
69
|
-
# Regexp or string. Default = <tt>I18n.translate('activerecord.errors.messages')
|
81
|
+
# Regexp or string. Default = <tt>I18n.translate('activerecord.errors.messages.taken')</tt>
|
70
82
|
# * <tt>:scoped_to</tt> - field(s) to scope the uniqueness to.
|
71
83
|
#
|
72
84
|
# Examples:
|
@@ -78,7 +90,7 @@ module ThoughtBot # :nodoc:
|
|
78
90
|
def should_require_unique_attributes(*attributes)
|
79
91
|
message, scope = get_options!(attributes, :message, :scoped_to)
|
80
92
|
scope = [*scope].compact
|
81
|
-
message ||=
|
93
|
+
message ||= default_error_message(:taken)
|
82
94
|
|
83
95
|
klass = model_class
|
84
96
|
attributes.each do |attribute|
|
@@ -164,14 +176,14 @@ module ThoughtBot # :nodoc:
|
|
164
176
|
#
|
165
177
|
# Options:
|
166
178
|
# * <tt>:message</tt> - value the test expects to find in <tt>errors.on(:attribute)</tt>.
|
167
|
-
# Regexp or string. Default = <tt>I18n.translate('activerecord.errors.messages')
|
179
|
+
# Regexp or string. Default = <tt>I18n.translate('activerecord.errors.messages.invalid')</tt>
|
168
180
|
#
|
169
181
|
# Example:
|
170
182
|
# should_not_allow_values_for :isbn, "bad 1", "bad 2"
|
171
183
|
#
|
172
184
|
def should_not_allow_values_for(attribute, *bad_values)
|
173
185
|
message = get_options!(bad_values, :message)
|
174
|
-
message ||=
|
186
|
+
message ||= default_error_message(:invalid)
|
175
187
|
klass = model_class
|
176
188
|
bad_values.each do |v|
|
177
189
|
should "not allow #{attribute} to be set to #{v.inspect}" do
|
@@ -207,17 +219,17 @@ module ThoughtBot # :nodoc:
|
|
207
219
|
#
|
208
220
|
# Options:
|
209
221
|
# * <tt>:short_message</tt> - value the test expects to find in <tt>errors.on(:attribute)</tt>.
|
210
|
-
# Regexp or string. Default = <tt>I18n.translate('activerecord.errors.messages')
|
222
|
+
# Regexp or string. Default = <tt>I18n.translate('activerecord.errors.messages.too_short') % range.first</tt>
|
211
223
|
# * <tt>:long_message</tt> - value the test expects to find in <tt>errors.on(:attribute)</tt>.
|
212
|
-
# Regexp or string. Default = <tt>I18n.translate('activerecord.errors.messages')
|
224
|
+
# Regexp or string. Default = <tt>I18n.translate('activerecord.errors.messages.too_long') % range.last</tt>
|
213
225
|
#
|
214
226
|
# Example:
|
215
227
|
# should_ensure_length_in_range :password, (6..20)
|
216
228
|
#
|
217
229
|
def should_ensure_length_in_range(attribute, range, opts = {})
|
218
230
|
short_message, long_message = get_options!([opts], :short_message, :long_message)
|
219
|
-
short_message ||=
|
220
|
-
long_message ||=
|
231
|
+
short_message ||= default_error_message(:too_short, :count => range.first)
|
232
|
+
long_message ||= default_error_message(:too_long, :count => range.last)
|
221
233
|
|
222
234
|
klass = model_class
|
223
235
|
min_length = range.first
|
@@ -259,14 +271,14 @@ module ThoughtBot # :nodoc:
|
|
259
271
|
#
|
260
272
|
# Options:
|
261
273
|
# * <tt>:short_message</tt> - value the test expects to find in <tt>errors.on(:attribute)</tt>.
|
262
|
-
# Regexp or string. Default = <tt>I18n.translate('activerecord.errors.messages')
|
274
|
+
# Regexp or string. Default = <tt>I18n.translate('activerecord.errors.messages.too_short') % min_length</tt>
|
263
275
|
#
|
264
276
|
# Example:
|
265
277
|
# should_ensure_length_at_least :name, 3
|
266
278
|
#
|
267
279
|
def should_ensure_length_at_least(attribute, min_length, opts = {})
|
268
280
|
short_message = get_options!([opts], :short_message)
|
269
|
-
short_message ||=
|
281
|
+
short_message ||= default_error_message(:too_short, :count => min_length)
|
270
282
|
|
271
283
|
klass = model_class
|
272
284
|
|
@@ -290,14 +302,14 @@ module ThoughtBot # :nodoc:
|
|
290
302
|
#
|
291
303
|
# Options:
|
292
304
|
# * <tt>:message</tt> - value the test expects to find in <tt>errors.on(:attribute)</tt>.
|
293
|
-
# Regexp or string. Default = <tt>I18n.translate('activerecord.errors.messages')
|
305
|
+
# Regexp or string. Default = <tt>I18n.translate('activerecord.errors.messages.wrong_length') % length</tt>
|
294
306
|
#
|
295
307
|
# Example:
|
296
308
|
# should_ensure_length_is :ssn, 9
|
297
309
|
#
|
298
310
|
def should_ensure_length_is(attribute, length, opts = {})
|
299
311
|
message = get_options!([opts], :message)
|
300
|
-
message ||=
|
312
|
+
message ||= default_error_message(:wrong_length, :count => length)
|
301
313
|
|
302
314
|
klass = model_class
|
303
315
|
|
@@ -325,17 +337,17 @@ module ThoughtBot # :nodoc:
|
|
325
337
|
#
|
326
338
|
# Options:
|
327
339
|
# * <tt>:low_message</tt> - value the test expects to find in <tt>errors.on(:attribute)</tt>.
|
328
|
-
# Regexp or string. Default = <tt>I18n.translate('activerecord.errors.messages')
|
340
|
+
# Regexp or string. Default = <tt>I18n.translate('activerecord.errors.messages.inclusion')</tt>
|
329
341
|
# * <tt>:high_message</tt> - value the test expects to find in <tt>errors.on(:attribute)</tt>.
|
330
|
-
# Regexp or string. Default = <tt>I18n.translate('activerecord.errors.messages')
|
342
|
+
# Regexp or string. Default = <tt>I18n.translate('activerecord.errors.messages.inclusion')</tt>
|
331
343
|
#
|
332
344
|
# Example:
|
333
345
|
# should_ensure_value_in_range :age, (0..100)
|
334
346
|
#
|
335
347
|
def should_ensure_value_in_range(attribute, range, opts = {})
|
336
348
|
low_message, high_message = get_options!([opts], :low_message, :high_message)
|
337
|
-
low_message ||=
|
338
|
-
high_message ||=
|
349
|
+
low_message ||= default_error_message(:inclusion)
|
350
|
+
high_message ||= default_error_message(:inclusion)
|
339
351
|
|
340
352
|
klass = model_class
|
341
353
|
min = range.first
|
@@ -370,14 +382,14 @@ module ThoughtBot # :nodoc:
|
|
370
382
|
#
|
371
383
|
# Options:
|
372
384
|
# * <tt>:message</tt> - value the test expects to find in <tt>errors.on(:attribute)</tt>.
|
373
|
-
# Regexp or string. Default = <tt>I18n.translate('activerecord.errors.messages')
|
385
|
+
# Regexp or string. Default = <tt>I18n.translate('activerecord.errors.messages.not_a_number')</tt>
|
374
386
|
#
|
375
387
|
# Example:
|
376
388
|
# should_only_allow_numeric_values_for :age
|
377
389
|
#
|
378
390
|
def should_only_allow_numeric_values_for(*attributes)
|
379
391
|
message = get_options!(attributes, :message)
|
380
|
-
message ||=
|
392
|
+
message ||= default_error_message(:not_a_number)
|
381
393
|
klass = model_class
|
382
394
|
attributes.each do |attribute|
|
383
395
|
attribute = attribute.to_sym
|
@@ -504,7 +516,7 @@ module ThoughtBot # :nodoc:
|
|
504
516
|
assert reflection, "#{klass.name} does not have any relationship to #{association}"
|
505
517
|
assert_equal :has_and_belongs_to_many, reflection.macro
|
506
518
|
table = reflection.options[:join_table]
|
507
|
-
assert ::ActiveRecord::Base.connection.tables.include?(table), "table #{table} doesn't exist"
|
519
|
+
assert ::ActiveRecord::Base.connection.tables.include?(table.to_s), "table #{table} doesn't exist"
|
508
520
|
end
|
509
521
|
end
|
510
522
|
end
|
@@ -624,14 +636,14 @@ module ThoughtBot # :nodoc:
|
|
624
636
|
#
|
625
637
|
# Options:
|
626
638
|
# * <tt>:message</tt> - value the test expects to find in <tt>errors.on(:attribute)</tt>.
|
627
|
-
# Regexp or string. Default = <tt>I18n.translate('activerecord.errors.messages')
|
639
|
+
# Regexp or string. Default = <tt>I18n.translate('activerecord.errors.messages.accepted')</tt>
|
628
640
|
#
|
629
641
|
# Example:
|
630
642
|
# should_require_acceptance_of :eula
|
631
643
|
#
|
632
644
|
def should_require_acceptance_of(*attributes)
|
633
645
|
message = get_options!(attributes, :message)
|
634
|
-
message ||=
|
646
|
+
message ||= default_error_message(:accepted)
|
635
647
|
klass = model_class
|
636
648
|
|
637
649
|
attributes.each do |attribute|
|
@@ -697,7 +709,6 @@ module ThoughtBot # :nodoc:
|
|
697
709
|
end
|
698
710
|
end
|
699
711
|
end
|
700
|
-
|
701
712
|
end
|
702
713
|
end
|
703
714
|
end
|
data/lib/shoulda/assertions.rb
CHANGED
@@ -25,8 +25,10 @@ module ThoughtBot # :nodoc:
|
|
25
25
|
collection = [collection] unless collection.is_a?(Array)
|
26
26
|
msg = "#{x.inspect} not found in #{collection.to_a.inspect} #{extra_msg}"
|
27
27
|
case x
|
28
|
-
when Regexp
|
29
|
-
|
28
|
+
when Regexp
|
29
|
+
assert(collection.detect { |e| e =~ x }, msg)
|
30
|
+
else
|
31
|
+
assert(collection.include?(x), msg)
|
30
32
|
end
|
31
33
|
end
|
32
34
|
|
@@ -36,8 +38,10 @@ module ThoughtBot # :nodoc:
|
|
36
38
|
collection = [collection] unless collection.is_a?(Array)
|
37
39
|
msg = "#{x.inspect} found in #{collection.to_a.inspect} " + extra_msg
|
38
40
|
case x
|
39
|
-
when Regexp
|
40
|
-
|
41
|
+
when Regexp
|
42
|
+
assert(!collection.detect { |e| e =~ x }, msg)
|
43
|
+
else
|
44
|
+
assert(!collection.include?(x), msg)
|
41
45
|
end
|
42
46
|
end
|
43
47
|
end
|
data/lib/shoulda/context.rb
CHANGED
@@ -100,7 +100,7 @@ module ThoughtBot # :nodoc:
|
|
100
100
|
def should_not_set_the_flash
|
101
101
|
should_set_the_flash_to nil
|
102
102
|
end
|
103
|
-
|
103
|
+
|
104
104
|
# Macro that creates a test asserting that filter_parameter_logging
|
105
105
|
# is set for the specified keys
|
106
106
|
#
|
@@ -227,9 +227,9 @@ module ThoughtBot # :nodoc:
|
|
227
227
|
# should_render_with_layout 'special'
|
228
228
|
def should_render_with_layout(expected_layout = 'application')
|
229
229
|
if expected_layout
|
230
|
-
should "render with #{expected_layout} layout" do
|
230
|
+
should "render with #{expected_layout.inspect} layout" do
|
231
231
|
response_layout = @response.layout.blank? ? "" : @response.layout.split('/').last
|
232
|
-
assert_equal expected_layout,
|
232
|
+
assert_equal expected_layout.to_s,
|
233
233
|
response_layout,
|
234
234
|
"Expected to render with layout #{expected_layout} but was rendered with #{response_layout}"
|
235
235
|
end
|
@@ -253,7 +253,8 @@ module ThoughtBot # :nodoc:
|
|
253
253
|
# Example:
|
254
254
|
#
|
255
255
|
# should_redirect_to '"/"'
|
256
|
-
# should_redirect_to "
|
256
|
+
# should_redirect_to "user_url(@user)"
|
257
|
+
# should_redirect_to "users_url"
|
257
258
|
def should_redirect_to(url)
|
258
259
|
should "redirect to #{url.inspect}" do
|
259
260
|
instantiate_variables_from_assigns do
|
@@ -287,7 +288,7 @@ module ThoughtBot # :nodoc:
|
|
287
288
|
# should_route :edit, "/posts/1", :action => :show, :id => 1
|
288
289
|
# should_route :put, "/posts/1", :action => :update, :id => 1
|
289
290
|
# should_route :delete, "/posts/1", :action => :destroy, :id => 1
|
290
|
-
# should_route :get, "/users/1/posts/1",
|
291
|
+
# should_route :get, "/users/1/posts/1",
|
291
292
|
# :action => :show, :id => 1, :user_id => 1
|
292
293
|
#
|
293
294
|
def should_route(method, path, options)
|
data/lib/shoulda/macros.rb
CHANGED
@@ -11,7 +11,7 @@ module ThoughtBot # :nodoc:
|
|
11
11
|
#
|
12
12
|
# Example:
|
13
13
|
#
|
14
|
-
# context "Creating a post"
|
14
|
+
# context "Creating a post" do
|
15
15
|
# setup { Post.create }
|
16
16
|
# should_change "Post.count", :by => 1
|
17
17
|
# end
|
@@ -26,8 +26,8 @@ module ThoughtBot # :nodoc:
|
|
26
26
|
# Combinations of <tt>:by</tt>, <tt>:from</tt>, and <tt>:to</tt> are allowed:
|
27
27
|
#
|
28
28
|
# should_change "@post.title" # => assert the value changed in some way
|
29
|
-
# should_change "@post.title" :from => "old" # => assert the value changed to anything other than "old"
|
30
|
-
# should_change "@post.title" :to => "new" # => assert the value changed from anything other than "new"
|
29
|
+
# should_change "@post.title", :from => "old" # => assert the value changed to anything other than "old"
|
30
|
+
# should_change "@post.title", :to => "new" # => assert the value changed from anything other than "new"
|
31
31
|
def should_change(expression, options = {})
|
32
32
|
by, from, to = get_options!([options], :by, :from, :to)
|
33
33
|
stmt = "change #{expression.inspect}"
|
@@ -53,7 +53,7 @@ module ThoughtBot # :nodoc:
|
|
53
53
|
#
|
54
54
|
# Example:
|
55
55
|
#
|
56
|
-
# context "Updating a post"
|
56
|
+
# context "Updating a post" do
|
57
57
|
# setup { @post.update_attributes(:title => "new") }
|
58
58
|
# should_not_change "Post.count"
|
59
59
|
# end
|
@@ -93,6 +93,7 @@ class PostsControllerTest < Test::Unit::TestCase
|
|
93
93
|
context "viewing a post on GET to #show" do
|
94
94
|
setup { get :show, :user_id => users(:first), :id => posts(:first) }
|
95
95
|
should_render_with_layout 'wide'
|
96
|
+
should_render_with_layout :wide
|
96
97
|
end
|
97
98
|
|
98
99
|
context "on GET to #new" do
|
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.
|
4
|
+
version: 2.0.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tammer Saleh
|
@@ -9,18 +9,10 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2008-
|
12
|
+
date: 2008-12-10 00:00:00 -08:00
|
13
13
|
default_executable: convert_to_should_syntax
|
14
|
-
dependencies:
|
15
|
-
|
16
|
-
name: activesupport
|
17
|
-
version_requirement:
|
18
|
-
version_requirements: !ruby/object:Gem::Requirement
|
19
|
-
requirements:
|
20
|
-
- - ">="
|
21
|
-
- !ruby/object:Gem::Version
|
22
|
-
version: "2.0"
|
23
|
-
version:
|
14
|
+
dependencies: []
|
15
|
+
|
24
16
|
description:
|
25
17
|
email: tsaleh@thoughtbot.com
|
26
18
|
executables:
|
@@ -64,7 +56,6 @@ files:
|
|
64
56
|
- lib/shoulda/tasks/yaml_to_shoulda.rake
|
65
57
|
- lib/shoulda/tasks.rb
|
66
58
|
- lib/shoulda.rb
|
67
|
-
- rails
|
68
59
|
- rails/init.rb
|
69
60
|
- test/fail_macros.rb
|
70
61
|
- test/fixtures
|