shoulda-matchers 1.0.0.beta2 → 1.0.0.beta3
Sign up to get free protection for your applications and to get access to all the features.
- data/Appraisals +12 -0
- data/Gemfile +1 -0
- data/README.rdoc +12 -4
- data/Rakefile +7 -2
- data/lib/shoulda/matchers/action_controller/assign_to_matcher.rb +2 -2
- data/lib/shoulda/matchers/action_controller/set_the_flash_matcher.rb +2 -2
- data/lib/shoulda/matchers/action_mailer/have_sent_email.rb +135 -9
- data/lib/shoulda/matchers/active_model.rb +33 -0
- data/lib/shoulda/matchers/{active_record → active_model}/allow_mass_assignment_of_matcher.rb +23 -6
- data/lib/shoulda/matchers/{active_record → active_model}/allow_value_matcher.rb +1 -1
- data/lib/shoulda/matchers/{active_record → active_model}/ensure_inclusion_of_matcher.rb +1 -1
- data/lib/shoulda/matchers/{active_record → active_model}/ensure_length_of_matcher.rb +1 -1
- data/lib/shoulda/matchers/{active_record → active_model}/helpers.rb +1 -1
- data/lib/shoulda/matchers/{active_record → active_model}/validate_acceptance_of_matcher.rb +1 -1
- data/lib/shoulda/matchers/{active_record → active_model}/validate_format_of_matcher.rb +1 -1
- data/lib/shoulda/matchers/{active_record → active_model}/validate_numericality_of_matcher.rb +1 -1
- data/lib/shoulda/matchers/{active_record → active_model}/validate_presence_of_matcher.rb +1 -1
- data/lib/shoulda/matchers/{active_record → active_model}/validate_uniqueness_of_matcher.rb +1 -1
- data/lib/shoulda/matchers/{active_record → active_model}/validation_matcher.rb +1 -1
- data/lib/shoulda/matchers/active_record.rb +1 -19
- data/lib/shoulda/matchers/active_record/association_matcher.rb +17 -1
- data/lib/shoulda/matchers/integrations/rspec.rb +7 -0
- data/lib/shoulda/matchers/integrations/test_unit.rb +14 -1
- data/lib/shoulda/matchers/version.rb +1 -1
- metadata +36 -48
- data/Gemfile.lock +0 -134
data/Appraisals
ADDED
data/Gemfile
CHANGED
data/README.rdoc
CHANGED
@@ -10,12 +10,22 @@ about using shoulda with Test::Unit.
|
|
10
10
|
|
11
11
|
=== ActiveRecord Matchers
|
12
12
|
|
13
|
-
Matchers to test associations
|
13
|
+
Matchers to test associations:
|
14
14
|
|
15
15
|
describe Post do
|
16
16
|
it { should belong_to(:user) }
|
17
17
|
it { should have_many(:tags).through(:taggings) }
|
18
|
+
end
|
19
|
+
|
20
|
+
describe User do
|
21
|
+
it { should have_many(:posts) }
|
22
|
+
end
|
23
|
+
|
24
|
+
=== ActiveModel Matchers
|
18
25
|
|
26
|
+
Matchers to test validations and mass assignments:
|
27
|
+
|
28
|
+
describe Post do
|
19
29
|
it { should validate_uniqueness_of(:title) }
|
20
30
|
it { should validate_presence_of(:body).with_message(/wtf/) }
|
21
31
|
it { should validate_presence_of(:title) }
|
@@ -23,8 +33,6 @@ Matchers to test associations and validations:
|
|
23
33
|
end
|
24
34
|
|
25
35
|
describe User do
|
26
|
-
it { should have_many(:posts) }
|
27
|
-
|
28
36
|
it { should_not allow_value("blah").for(:email) }
|
29
37
|
it { should allow_value("a@b.com").for(:email) }
|
30
38
|
it { should ensure_inclusion_of(:age).in_range(1..100) }
|
@@ -53,8 +61,8 @@ Matchers to test common patterns:
|
|
53
61
|
In Rails 3 and Bundler, add the following to your Gemfile:
|
54
62
|
|
55
63
|
group :test do
|
56
|
-
gem "shoulda-matchers"
|
57
64
|
gem "rspec-rails"
|
65
|
+
gem "shoulda-matchers"
|
58
66
|
end
|
59
67
|
|
60
68
|
Shoulda will automatically include matchers into the appropriate example groups.
|
data/Rakefile
CHANGED
@@ -5,6 +5,7 @@ require 'rake/rdoctask'
|
|
5
5
|
require 'rake/gempackagetask'
|
6
6
|
require 'rspec/core/rake_task'
|
7
7
|
require 'cucumber/rake/task'
|
8
|
+
require 'appraisal'
|
8
9
|
|
9
10
|
$LOAD_PATH.unshift("lib")
|
10
11
|
require 'shoulda/matchers/version'
|
@@ -41,10 +42,14 @@ desc "Clean files generated by rake tasks"
|
|
41
42
|
task :clobber => [:clobber_rdoc, :clobber_package]
|
42
43
|
|
43
44
|
Cucumber::Rake::Task.new do |t|
|
44
|
-
t.fork =
|
45
|
+
t.fork = false
|
45
46
|
t.cucumber_opts = ['--format', (ENV['CUCUMBER_FORMAT'] || 'progress')]
|
46
47
|
end
|
47
48
|
|
48
49
|
desc 'Default: run specs and cucumber features'
|
49
|
-
task :default => [:
|
50
|
+
task :default => [:all]
|
50
51
|
|
52
|
+
desc 'Test the plugin under all supported Rails versions.'
|
53
|
+
task :all => ["appraisal:cleanup", "appraisal:install"] do |t|
|
54
|
+
exec('rake appraisal spec cucumber')
|
55
|
+
end
|
@@ -82,8 +82,8 @@ module Shoulda # :nodoc:
|
|
82
82
|
else
|
83
83
|
@failure_message =
|
84
84
|
"Expected action to assign a kind of #{@expected_class} " <<
|
85
|
-
"for #{@variable}, but got #{
|
86
|
-
"(#{
|
85
|
+
"for #{@variable}, but got #{assigned_value.inspect} " <<
|
86
|
+
"(#{assigned_value.class.name})"
|
87
87
|
false
|
88
88
|
end
|
89
89
|
end
|
@@ -57,12 +57,12 @@ module Shoulda # :nodoc:
|
|
57
57
|
|
58
58
|
def string_value_matches?
|
59
59
|
return true unless String === @value
|
60
|
-
flash.values.any? {|value| value == @value }
|
60
|
+
flash.to_hash.values.any? {|value| value == @value }
|
61
61
|
end
|
62
62
|
|
63
63
|
def regexp_value_matches?
|
64
64
|
return true unless Regexp === @value
|
65
|
-
flash.values.any? {|value| value =~ @value }
|
65
|
+
flash.to_hash.values.any? {|value| value =~ @value }
|
66
66
|
end
|
67
67
|
|
68
68
|
def flash
|
@@ -8,45 +8,103 @@ module Shoulda # :nodoc:
|
|
8
8
|
# it { should have_sent_email.from('do-not-reply@example.com') }
|
9
9
|
# it { should have_sent_email.with_body(/is spam\./) }
|
10
10
|
# it { should have_sent_email.to('myself@me.com') }
|
11
|
+
# it { should have_sent_email.with_part('text/html', /HTML spam/) }
|
11
12
|
# it { should have_sent_email.with_subject(/spam/).
|
12
13
|
# from('do-not-reply@example.com').
|
13
14
|
# with_body(/spam/).
|
14
15
|
# to('myself@me.com') }
|
16
|
+
#
|
17
|
+
# Use values of instance variables
|
18
|
+
# it {should have_sent_email.to {@user.email} }
|
15
19
|
def have_sent_email
|
16
|
-
HaveSentEmailMatcher.new
|
20
|
+
HaveSentEmailMatcher.new(self)
|
17
21
|
end
|
18
22
|
|
19
23
|
class HaveSentEmailMatcher # :nodoc:
|
20
24
|
|
21
|
-
def initialize
|
25
|
+
def initialize(context)
|
26
|
+
@context = context
|
22
27
|
end
|
23
28
|
|
24
|
-
def
|
29
|
+
def in_context(context)
|
30
|
+
@context = context
|
31
|
+
self
|
32
|
+
end
|
33
|
+
|
34
|
+
def with_subject(email_subject = nil, &block)
|
25
35
|
@email_subject = email_subject
|
36
|
+
@email_subject_block = block
|
26
37
|
self
|
27
38
|
end
|
28
39
|
|
29
|
-
def from(sender)
|
40
|
+
def from(sender = nil, &block)
|
30
41
|
@sender = sender
|
42
|
+
@sender_block = block
|
31
43
|
self
|
32
44
|
end
|
33
45
|
|
34
|
-
def with_body(body)
|
46
|
+
def with_body(body = nil, &block)
|
35
47
|
@body = body
|
48
|
+
@body_block = block
|
49
|
+
self
|
50
|
+
end
|
51
|
+
|
52
|
+
def with_part(content_type, body = nil, &block)
|
53
|
+
@parts ||= []
|
54
|
+
@parts << [/#{Regexp.escape(content_type)}/, body, content_type]
|
55
|
+
@parts_blocks ||= []
|
56
|
+
@parts_blocks << block
|
36
57
|
self
|
37
58
|
end
|
38
59
|
|
39
|
-
def to(recipient)
|
60
|
+
def to(recipient = nil, &block)
|
40
61
|
@recipient = recipient
|
62
|
+
@recipient_block = block
|
63
|
+
self
|
64
|
+
end
|
65
|
+
|
66
|
+
def cc(recipient = nil, &block)
|
67
|
+
@cc = recipient
|
68
|
+
@cc_block = block
|
69
|
+
self
|
70
|
+
end
|
71
|
+
|
72
|
+
def with_cc(recipients = nil, &block)
|
73
|
+
@cc_recipients = recipients
|
74
|
+
@cc_recipients_block = block
|
75
|
+
self
|
76
|
+
end
|
77
|
+
|
78
|
+
def bcc(recipient = nil, &block)
|
79
|
+
@bcc = recipient
|
80
|
+
@bcc_block = block
|
81
|
+
self
|
82
|
+
end
|
83
|
+
|
84
|
+
def with_bcc(recipients = nil, &block)
|
85
|
+
@bcc_recipients = recipients
|
86
|
+
@bcc_recipients_block = block
|
87
|
+
self
|
88
|
+
end
|
89
|
+
|
90
|
+
def multipart(flag = true)
|
91
|
+
@multipart = !!flag
|
41
92
|
self
|
42
93
|
end
|
43
94
|
|
44
95
|
def matches?(subject)
|
96
|
+
normalize_blocks
|
45
97
|
::ActionMailer::Base.deliveries.each do |mail|
|
46
98
|
@subject_failed = !regexp_or_string_match(mail.subject, @email_subject) if @email_subject
|
47
|
-
@
|
99
|
+
@parts_failed = !parts_match(mail, @parts) if @parts
|
100
|
+
@body_failed = !body_match(mail, @body) if @body
|
48
101
|
@sender_failed = !regexp_or_string_match_in_array(mail.from, @sender) if @sender
|
49
102
|
@recipient_failed = !regexp_or_string_match_in_array(mail.to, @recipient) if @recipient
|
103
|
+
@cc_failed = !regexp_or_string_match_in_array(mail.cc, @cc) if @cc
|
104
|
+
@cc_recipients_failed = !match_array_in_array(mail.cc, @cc_recipients) if @cc_recipients
|
105
|
+
@bcc_failed = !regexp_or_string_match_in_array(mail.bcc, @bcc) if @bcc
|
106
|
+
@bcc_recipients_failed = !match_array_in_array(mail.bcc, @bcc_recipients) if @bcc_recipients
|
107
|
+
@multipart_failed = (mail.multipart? != @multipart) if defined?(@multipart)
|
50
108
|
return true unless anything_failed?
|
51
109
|
end
|
52
110
|
|
@@ -65,8 +123,15 @@ module Shoulda # :nodoc:
|
|
65
123
|
description = "send an email"
|
66
124
|
description << " with a subject of #{@email_subject.inspect}" if @email_subject
|
67
125
|
description << " containing #{@body.inspect}" if @body
|
126
|
+
@parts.each do |_, body, content_type|
|
127
|
+
description << " having a #{content_type} part containing #{body.inspect}"
|
128
|
+
end if @parts
|
68
129
|
description << " from #{@sender.inspect}" if @sender
|
69
130
|
description << " to #{@recipient.inspect}" if @recipient
|
131
|
+
description << " cc #{@cc.inspect}" if @cc
|
132
|
+
description << " with cc #{@cc_recipients.inspect}" if @cc_recipients
|
133
|
+
description << " bcc #{@bcc.inspect}" if @bcc
|
134
|
+
description << " with bcc #{@bcc_recipients.inspect}" if @bcc_recipients
|
70
135
|
description
|
71
136
|
end
|
72
137
|
|
@@ -76,8 +141,16 @@ module Shoulda # :nodoc:
|
|
76
141
|
expectation = "sent email"
|
77
142
|
expectation << " with subject #{@email_subject.inspect}" if @subject_failed
|
78
143
|
expectation << " with body #{@body.inspect}" if @body_failed
|
144
|
+
@parts.each do |_, body, content_type|
|
145
|
+
expectation << " with a #{content_type} part containing #{body}"
|
146
|
+
end if @parts && @parts_failed
|
79
147
|
expectation << " from #{@sender.inspect}" if @sender_failed
|
80
148
|
expectation << " to #{@recipient.inspect}" if @recipient_failed
|
149
|
+
expectation << " cc #{@cc.inspect}" if @cc_failed
|
150
|
+
expectation << " with cc #{@cc_recipients.inspect}" if @cc_recipients_failed
|
151
|
+
expectation << " bcc #{@bcc.inspect}" if @bcc_failed
|
152
|
+
expectation << " with bcc #{@bcc_recipients.inspect}" if @bcc_recipients_failed
|
153
|
+
expectation << " #{'not ' if !@multipart}being multipart" if @multipart_failed
|
81
154
|
expectation << "\nDeliveries:\n#{inspect_deliveries}"
|
82
155
|
end
|
83
156
|
|
@@ -88,7 +161,26 @@ module Shoulda # :nodoc:
|
|
88
161
|
end
|
89
162
|
|
90
163
|
def anything_failed?
|
91
|
-
@subject_failed || @body_failed || @sender_failed || @recipient_failed
|
164
|
+
@subject_failed || @body_failed || @sender_failed || @recipient_failed ||
|
165
|
+
@cc_failed || @cc_recipients_failed || @bcc_failed || @bcc_recipients_failed ||
|
166
|
+
@parts_failed || @multipart_failed
|
167
|
+
end
|
168
|
+
|
169
|
+
def normalize_blocks
|
170
|
+
@email_subject = @context.instance_eval(&@email_subject_block) if @email_subject_block
|
171
|
+
@sender = @context.instance_eval(&@sender_block) if @sender_block
|
172
|
+
@body = @context.instance_eval(&@body_block) if @body_block
|
173
|
+
@recipient = @context.instance_eval(&@recipient_block) if @recipient_block
|
174
|
+
@cc = @context.instance_eval(&@cc_block) if @cc_block
|
175
|
+
@cc_recipients = @context.instance_eval(&@cc_recipients_block) if @cc_recipients_block
|
176
|
+
@bcc = @context.instance_eval(&@bcc_block) if @bcc_block
|
177
|
+
@bcc_recipients = @context.instance_eval(&@bcc_recipients_block) if @bcc_recipients_block
|
178
|
+
|
179
|
+
if @parts
|
180
|
+
@parts.each_with_index do |part, i|
|
181
|
+
part[1] = @context.instance_eval(&@parts_blocks[i]) if @parts_blocks[i]
|
182
|
+
end
|
183
|
+
end
|
92
184
|
end
|
93
185
|
|
94
186
|
def regexp_or_string_match(a_string, a_regexp_or_string)
|
@@ -108,8 +200,42 @@ module Shoulda # :nodoc:
|
|
108
200
|
an_array.include?(a_regexp_or_string)
|
109
201
|
end
|
110
202
|
end
|
203
|
+
|
204
|
+
def match_array_in_array(target_array, match_array)
|
205
|
+
target_array.sort!
|
206
|
+
match_array.sort!
|
207
|
+
|
208
|
+
target_array.each_cons(match_array.size).include? match_array
|
209
|
+
end
|
210
|
+
|
211
|
+
def body_match(mail, a_regexp_or_string)
|
212
|
+
# Mail objects instantiated by ActionMailer3 return a blank
|
213
|
+
# body if the e-mail is multipart. TMail concatenates the
|
214
|
+
# String representation of each part instead.
|
215
|
+
if mail.body.blank? && mail.multipart?
|
216
|
+
part_match(mail, /^text\//, a_regexp_or_string)
|
217
|
+
else
|
218
|
+
regexp_or_string_match(mail.body, a_regexp_or_string)
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
222
|
+
def parts_match(mail, parts)
|
223
|
+
return false if mail.parts.empty?
|
224
|
+
|
225
|
+
parts.all? do |content_type, match, _|
|
226
|
+
part_match(mail, content_type, match)
|
227
|
+
end
|
228
|
+
end
|
229
|
+
|
230
|
+
def part_match(mail, content_type, a_regexp_or_string)
|
231
|
+
matching = mail.parts.select {|p| p.content_type =~ content_type}
|
232
|
+
return false if matching.empty?
|
233
|
+
|
234
|
+
matching.all? do |part|
|
235
|
+
regexp_or_string_match(part.body, a_regexp_or_string)
|
236
|
+
end
|
237
|
+
end
|
111
238
|
end
|
112
239
|
end
|
113
240
|
end
|
114
|
-
|
115
241
|
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'shoulda/matchers/active_model/helpers'
|
2
|
+
require 'shoulda/matchers/active_model/validation_matcher'
|
3
|
+
require 'shoulda/matchers/active_model/allow_value_matcher'
|
4
|
+
require 'shoulda/matchers/active_model/ensure_length_of_matcher'
|
5
|
+
require 'shoulda/matchers/active_model/ensure_inclusion_of_matcher'
|
6
|
+
require 'shoulda/matchers/active_model/validate_presence_of_matcher'
|
7
|
+
require 'shoulda/matchers/active_model/validate_format_of_matcher'
|
8
|
+
require 'shoulda/matchers/active_model/validate_uniqueness_of_matcher'
|
9
|
+
require 'shoulda/matchers/active_model/validate_acceptance_of_matcher'
|
10
|
+
require 'shoulda/matchers/active_model/validate_numericality_of_matcher'
|
11
|
+
require 'shoulda/matchers/active_model/allow_mass_assignment_of_matcher'
|
12
|
+
|
13
|
+
|
14
|
+
module Shoulda
|
15
|
+
module Matchers
|
16
|
+
# = Matchers for your active record models
|
17
|
+
#
|
18
|
+
# These matchers will test most of the validations of ActiveModel::Validations.
|
19
|
+
#
|
20
|
+
# describe User do
|
21
|
+
# it { should validate_presence_of(:name) }
|
22
|
+
# it { should validate_presence_of(:phone_number) }
|
23
|
+
# %w(abcd 1234).each do |value|
|
24
|
+
# it { should_not allow_value(value).for(:phone_number) }
|
25
|
+
# end
|
26
|
+
# it { should allow_value("(123) 456-7890").for(:phone_number) }
|
27
|
+
# it { should_not allow_mass_assignment_of(:password) }
|
28
|
+
# end
|
29
|
+
#
|
30
|
+
module ActiveModel
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
data/lib/shoulda/matchers/{active_record → active_model}/allow_mass_assignment_of_matcher.rb
RENAMED
@@ -1,12 +1,16 @@
|
|
1
1
|
module Shoulda # :nodoc:
|
2
2
|
module Matchers
|
3
|
-
module
|
3
|
+
module ActiveModel # :nodoc:
|
4
4
|
|
5
5
|
# Ensures that the attribute can be set on mass update.
|
6
6
|
#
|
7
7
|
# it { should_not allow_mass_assignment_of(:password) }
|
8
8
|
# it { should allow_mass_assignment_of(:first_name) }
|
9
9
|
#
|
10
|
+
# In Rails 3.1 you can check role as well:
|
11
|
+
#
|
12
|
+
# it { should allow_mass_assigment_of(:first_name).as(:admin) }
|
13
|
+
#
|
10
14
|
def allow_mass_assignment_of(value)
|
11
15
|
AllowMassAssignmentOfMatcher.new(value)
|
12
16
|
end
|
@@ -17,8 +21,15 @@ module Shoulda # :nodoc:
|
|
17
21
|
@attribute = attribute.to_s
|
18
22
|
end
|
19
23
|
|
24
|
+
def as(role)
|
25
|
+
raise "You can specify role only in Rails 3.1 or greater" unless rails_3_1?
|
26
|
+
@role = role
|
27
|
+
self
|
28
|
+
end
|
29
|
+
|
20
30
|
def matches?(subject)
|
21
31
|
@subject = subject
|
32
|
+
@role ||= :default
|
22
33
|
if attr_mass_assignable?
|
23
34
|
if whitelisting?
|
24
35
|
@negative_failure_message = "#{@attribute} was made accessible"
|
@@ -61,14 +72,18 @@ module Shoulda # :nodoc:
|
|
61
72
|
end
|
62
73
|
|
63
74
|
def whitelisting?
|
64
|
-
|
75
|
+
authorizer.kind_of?(::ActiveModel::MassAssignmentSecurity::WhiteList)
|
65
76
|
end
|
66
77
|
|
67
78
|
def attr_mass_assignable?
|
68
|
-
|
69
|
-
|
79
|
+
!authorizer.deny?(@attribute)
|
80
|
+
end
|
81
|
+
|
82
|
+
def authorizer
|
83
|
+
if rails_3_1?
|
84
|
+
@subject.class.active_authorizer[@role]
|
70
85
|
else
|
71
|
-
|
86
|
+
@subject.class.active_authorizer
|
72
87
|
end
|
73
88
|
end
|
74
89
|
|
@@ -76,8 +91,10 @@ module Shoulda # :nodoc:
|
|
76
91
|
@subject.class.name
|
77
92
|
end
|
78
93
|
|
94
|
+
def rails_3_1?
|
95
|
+
::ActiveModel::VERSION::MAJOR == 3 && ::ActiveModel::VERSION::MINOR >= 1
|
96
|
+
end
|
79
97
|
end
|
80
|
-
|
81
98
|
end
|
82
99
|
end
|
83
100
|
end
|
@@ -1,35 +1,17 @@
|
|
1
|
-
require 'shoulda/matchers/active_record/helpers'
|
2
|
-
require 'shoulda/matchers/active_record/validation_matcher'
|
3
|
-
require 'shoulda/matchers/active_record/allow_value_matcher'
|
4
|
-
require 'shoulda/matchers/active_record/ensure_length_of_matcher'
|
5
|
-
require 'shoulda/matchers/active_record/ensure_inclusion_of_matcher'
|
6
|
-
require 'shoulda/matchers/active_record/validate_presence_of_matcher'
|
7
|
-
require 'shoulda/matchers/active_record/validate_format_of_matcher'
|
8
|
-
require 'shoulda/matchers/active_record/validate_uniqueness_of_matcher'
|
9
|
-
require 'shoulda/matchers/active_record/validate_acceptance_of_matcher'
|
10
|
-
require 'shoulda/matchers/active_record/validate_numericality_of_matcher'
|
11
1
|
require 'shoulda/matchers/active_record/association_matcher'
|
12
2
|
require 'shoulda/matchers/active_record/have_db_column_matcher'
|
13
3
|
require 'shoulda/matchers/active_record/have_db_index_matcher'
|
14
4
|
require 'shoulda/matchers/active_record/have_readonly_attribute_matcher'
|
15
|
-
require 'shoulda/matchers/active_record/allow_mass_assignment_of_matcher'
|
16
5
|
|
17
6
|
|
18
7
|
module Shoulda
|
19
8
|
module Matchers
|
20
9
|
# = Matchers for your active record models
|
21
10
|
#
|
22
|
-
# These matchers will test
|
11
|
+
# These matchers will test the associations for your
|
23
12
|
# ActiveRecord models.
|
24
13
|
#
|
25
14
|
# describe User do
|
26
|
-
# it { should validate_presence_of(:name) }
|
27
|
-
# it { should validate_presence_of(:phone_number) }
|
28
|
-
# %w(abcd 1234).each do |value|
|
29
|
-
# it { should_not allow_value(value).for(:phone_number) }
|
30
|
-
# end
|
31
|
-
# it { should allow_value("(123) 456-7890").for(:phone_number) }
|
32
|
-
# it { should_not allow_mass_assignment_of(:password) }
|
33
15
|
# it { should have_one(:profile) }
|
34
16
|
# it { should have_many(:dogs) }
|
35
17
|
# it { should have_many(:messes).through(:dogs) }
|
@@ -68,6 +68,11 @@ module Shoulda # :nodoc:
|
|
68
68
|
self
|
69
69
|
end
|
70
70
|
|
71
|
+
def order(order)
|
72
|
+
@order = order
|
73
|
+
self
|
74
|
+
end
|
75
|
+
|
71
76
|
def matches?(subject)
|
72
77
|
@subject = subject
|
73
78
|
association_exists? &&
|
@@ -75,6 +80,7 @@ module Shoulda # :nodoc:
|
|
75
80
|
foreign_key_exists? &&
|
76
81
|
through_association_valid? &&
|
77
82
|
dependent_correct? &&
|
83
|
+
order_correct? &&
|
78
84
|
join_table_exists?
|
79
85
|
end
|
80
86
|
|
@@ -90,6 +96,7 @@ module Shoulda # :nodoc:
|
|
90
96
|
description = "#{macro_description} #{@name}"
|
91
97
|
description += " through #{@through}" if @through
|
92
98
|
description += " dependent => #{@dependent}" if @dependent
|
99
|
+
description += " order => #{@order}" if @order
|
93
100
|
description
|
94
101
|
end
|
95
102
|
|
@@ -159,6 +166,15 @@ module Shoulda # :nodoc:
|
|
159
166
|
end
|
160
167
|
end
|
161
168
|
|
169
|
+
def order_correct?
|
170
|
+
if @order.nil? || @order.to_s == reflection.options[:order].to_s
|
171
|
+
true
|
172
|
+
else
|
173
|
+
@missing = "#{@name} should be ordered by #{@order}"
|
174
|
+
false
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
162
178
|
def join_table_exists?
|
163
179
|
if @macro != :has_and_belongs_to_many ||
|
164
180
|
::ActiveRecord::Base.connection.tables.include?(join_table.to_s)
|
@@ -191,7 +207,7 @@ module Shoulda # :nodoc:
|
|
191
207
|
end
|
192
208
|
|
193
209
|
def foreign_key
|
194
|
-
reflection.primary_key_name
|
210
|
+
reflection.respond_to?(:foreign_key) ? reflection.foreign_key : reflection.primary_key_name
|
195
211
|
end
|
196
212
|
|
197
213
|
def through?
|
@@ -2,8 +2,15 @@
|
|
2
2
|
|
3
3
|
if defined?(::ActiveRecord)
|
4
4
|
require 'shoulda/matchers/active_record'
|
5
|
+
require 'shoulda/matchers/active_model'
|
5
6
|
module RSpec::Matchers
|
6
7
|
include Shoulda::Matchers::ActiveRecord
|
8
|
+
include Shoulda::Matchers::ActiveModel
|
9
|
+
end
|
10
|
+
elsif defined?(::ActiveModel)
|
11
|
+
require 'shoulda/matchers/active_model'
|
12
|
+
module RSpec::Matchers
|
13
|
+
include Shoulda::Matchers::ActiveModel
|
7
14
|
end
|
8
15
|
end
|
9
16
|
|
@@ -28,14 +28,27 @@ end
|
|
28
28
|
|
29
29
|
if defined?(ActiveRecord)
|
30
30
|
require 'shoulda/matchers/active_record'
|
31
|
+
require 'shoulda/matchers/active_model'
|
31
32
|
|
32
33
|
module Test
|
33
34
|
module Unit
|
34
35
|
class TestCase
|
35
36
|
include Shoulda::Matchers::ActiveRecord
|
36
37
|
extend Shoulda::Matchers::ActiveRecord
|
38
|
+
include Shoulda::Matchers::ActiveModel
|
39
|
+
extend Shoulda::Matchers::ActiveModel
|
37
40
|
end
|
38
41
|
end
|
39
42
|
end
|
40
|
-
|
43
|
+
elsif defined?(ActiveModel)
|
44
|
+
require 'shoulda/matchers/active_model'
|
41
45
|
|
46
|
+
module Test
|
47
|
+
module Unit
|
48
|
+
class TestCase
|
49
|
+
include Shoulda::Matchers::ActiveModel
|
50
|
+
extend Shoulda::Matchers::ActiveModel
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: shoulda-matchers
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease: 6
|
5
|
-
version: 1.0.0.
|
5
|
+
version: 1.0.0.beta3
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Tammer Saleh
|
@@ -10,90 +10,80 @@ authors:
|
|
10
10
|
- Ryan McGeary
|
11
11
|
- Dan Croak
|
12
12
|
- Matt Jankowski
|
13
|
+
- Stafford Brunk
|
13
14
|
autorequire:
|
14
15
|
bindir: bin
|
15
16
|
cert_chain: []
|
16
17
|
|
17
|
-
date: 2011-
|
18
|
+
date: 2011-07-18 00:00:00 -04:00
|
18
19
|
default_executable:
|
19
20
|
dependencies:
|
20
21
|
- !ruby/object:Gem::Dependency
|
21
|
-
name:
|
22
|
+
name: sqlite3-ruby
|
23
|
+
prerelease: false
|
22
24
|
requirement: &id001 !ruby/object:Gem::Requirement
|
23
25
|
none: false
|
24
26
|
requirements:
|
25
|
-
- -
|
27
|
+
- - ~>
|
26
28
|
- !ruby/object:Gem::Version
|
27
|
-
version: 3.
|
29
|
+
version: 1.3.2
|
28
30
|
type: :development
|
29
|
-
prerelease: false
|
30
31
|
version_requirements: *id001
|
31
32
|
- !ruby/object:Gem::Dependency
|
32
|
-
name:
|
33
|
+
name: mocha
|
34
|
+
prerelease: false
|
33
35
|
requirement: &id002 !ruby/object:Gem::Requirement
|
34
36
|
none: false
|
35
37
|
requirements:
|
36
38
|
- - ~>
|
37
39
|
- !ruby/object:Gem::Version
|
38
|
-
version:
|
40
|
+
version: 0.9.10
|
39
41
|
type: :development
|
40
|
-
prerelease: false
|
41
42
|
version_requirements: *id002
|
42
43
|
- !ruby/object:Gem::Dependency
|
43
|
-
name:
|
44
|
+
name: rspec-rails
|
45
|
+
prerelease: false
|
44
46
|
requirement: &id003 !ruby/object:Gem::Requirement
|
45
47
|
none: false
|
46
48
|
requirements:
|
47
49
|
- - ~>
|
48
50
|
- !ruby/object:Gem::Version
|
49
|
-
version:
|
51
|
+
version: 2.6.1.beta1
|
50
52
|
type: :development
|
51
|
-
prerelease: false
|
52
53
|
version_requirements: *id003
|
53
54
|
- !ruby/object:Gem::Dependency
|
54
|
-
name:
|
55
|
+
name: cucumber
|
56
|
+
prerelease: false
|
55
57
|
requirement: &id004 !ruby/object:Gem::Requirement
|
56
58
|
none: false
|
57
59
|
requirements:
|
58
60
|
- - ~>
|
59
61
|
- !ruby/object:Gem::Version
|
60
|
-
version:
|
62
|
+
version: 0.10.0
|
61
63
|
type: :development
|
62
|
-
prerelease: false
|
63
64
|
version_requirements: *id004
|
64
65
|
- !ruby/object:Gem::Dependency
|
65
|
-
name:
|
66
|
+
name: appraisal
|
67
|
+
prerelease: false
|
66
68
|
requirement: &id005 !ruby/object:Gem::Requirement
|
67
69
|
none: false
|
68
70
|
requirements:
|
69
71
|
- - ~>
|
70
72
|
- !ruby/object:Gem::Version
|
71
|
-
version: 0.
|
73
|
+
version: 0.3.4
|
72
74
|
type: :development
|
73
|
-
prerelease: false
|
74
75
|
version_requirements: *id005
|
75
|
-
- !ruby/object:Gem::Dependency
|
76
|
-
name: aruba
|
77
|
-
requirement: &id006 !ruby/object:Gem::Requirement
|
78
|
-
none: false
|
79
|
-
requirements:
|
80
|
-
- - ~>
|
81
|
-
- !ruby/object:Gem::Version
|
82
|
-
version: 0.2.7
|
83
|
-
type: :development
|
84
|
-
prerelease: false
|
85
|
-
version_requirements: *id006
|
86
76
|
- !ruby/object:Gem::Dependency
|
87
77
|
name: ruby-debug19
|
88
|
-
|
78
|
+
prerelease: false
|
79
|
+
requirement: &id006 !ruby/object:Gem::Requirement
|
89
80
|
none: false
|
90
81
|
requirements:
|
91
82
|
- - ~>
|
92
83
|
- !ruby/object:Gem::Version
|
93
84
|
version: 0.11.6
|
94
85
|
type: :development
|
95
|
-
|
96
|
-
version_requirements: *id007
|
86
|
+
version_requirements: *id006
|
97
87
|
description: Making tests easy on the fingers and eyes
|
98
88
|
email: support@thoughtbot.com
|
99
89
|
executables: []
|
@@ -104,9 +94,9 @@ extra_rdoc_files:
|
|
104
94
|
- README.rdoc
|
105
95
|
- CONTRIBUTION_GUIDELINES.rdoc
|
106
96
|
files:
|
97
|
+
- Appraisals
|
107
98
|
- CONTRIBUTION_GUIDELINES.rdoc
|
108
99
|
- Gemfile
|
109
|
-
- Gemfile.lock
|
110
100
|
- MIT-LICENSE
|
111
101
|
- Rakefile
|
112
102
|
- README.rdoc
|
@@ -123,21 +113,22 @@ files:
|
|
123
113
|
- lib/shoulda/matchers/action_controller.rb
|
124
114
|
- lib/shoulda/matchers/action_mailer/have_sent_email.rb
|
125
115
|
- lib/shoulda/matchers/action_mailer.rb
|
126
|
-
- lib/shoulda/matchers/
|
127
|
-
- lib/shoulda/matchers/
|
116
|
+
- lib/shoulda/matchers/active_model/allow_mass_assignment_of_matcher.rb
|
117
|
+
- lib/shoulda/matchers/active_model/allow_value_matcher.rb
|
118
|
+
- lib/shoulda/matchers/active_model/ensure_inclusion_of_matcher.rb
|
119
|
+
- lib/shoulda/matchers/active_model/ensure_length_of_matcher.rb
|
120
|
+
- lib/shoulda/matchers/active_model/helpers.rb
|
121
|
+
- lib/shoulda/matchers/active_model/validate_acceptance_of_matcher.rb
|
122
|
+
- lib/shoulda/matchers/active_model/validate_format_of_matcher.rb
|
123
|
+
- lib/shoulda/matchers/active_model/validate_numericality_of_matcher.rb
|
124
|
+
- lib/shoulda/matchers/active_model/validate_presence_of_matcher.rb
|
125
|
+
- lib/shoulda/matchers/active_model/validate_uniqueness_of_matcher.rb
|
126
|
+
- lib/shoulda/matchers/active_model/validation_matcher.rb
|
127
|
+
- lib/shoulda/matchers/active_model.rb
|
128
128
|
- lib/shoulda/matchers/active_record/association_matcher.rb
|
129
|
-
- lib/shoulda/matchers/active_record/ensure_inclusion_of_matcher.rb
|
130
|
-
- lib/shoulda/matchers/active_record/ensure_length_of_matcher.rb
|
131
129
|
- lib/shoulda/matchers/active_record/have_db_column_matcher.rb
|
132
130
|
- lib/shoulda/matchers/active_record/have_db_index_matcher.rb
|
133
131
|
- lib/shoulda/matchers/active_record/have_readonly_attribute_matcher.rb
|
134
|
-
- lib/shoulda/matchers/active_record/helpers.rb
|
135
|
-
- lib/shoulda/matchers/active_record/validate_acceptance_of_matcher.rb
|
136
|
-
- lib/shoulda/matchers/active_record/validate_format_of_matcher.rb
|
137
|
-
- lib/shoulda/matchers/active_record/validate_numericality_of_matcher.rb
|
138
|
-
- lib/shoulda/matchers/active_record/validate_presence_of_matcher.rb
|
139
|
-
- lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb
|
140
|
-
- lib/shoulda/matchers/active_record/validation_matcher.rb
|
141
132
|
- lib/shoulda/matchers/active_record.rb
|
142
133
|
- lib/shoulda/matchers/assertion_error.rb
|
143
134
|
- lib/shoulda/matchers/integrations/rspec.rb
|
@@ -161,9 +152,6 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
161
152
|
requirements:
|
162
153
|
- - ">="
|
163
154
|
- !ruby/object:Gem::Version
|
164
|
-
hash: 3667913558593923355
|
165
|
-
segments:
|
166
|
-
- 0
|
167
155
|
version: "0"
|
168
156
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
169
157
|
none: false
|
@@ -174,7 +162,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
174
162
|
requirements: []
|
175
163
|
|
176
164
|
rubyforge_project:
|
177
|
-
rubygems_version: 1.6.
|
165
|
+
rubygems_version: 1.6.2
|
178
166
|
signing_key:
|
179
167
|
specification_version: 3
|
180
168
|
summary: Making tests easy on the fingers and eyes
|
data/Gemfile.lock
DELETED
@@ -1,134 +0,0 @@
|
|
1
|
-
PATH
|
2
|
-
remote: .
|
3
|
-
specs:
|
4
|
-
shoulda-matchers (1.0.0.beta2)
|
5
|
-
|
6
|
-
GEM
|
7
|
-
remote: http://rubygems.org/
|
8
|
-
specs:
|
9
|
-
abstract (1.0.0)
|
10
|
-
actionmailer (3.0.3)
|
11
|
-
actionpack (= 3.0.3)
|
12
|
-
mail (~> 2.2.9)
|
13
|
-
actionpack (3.0.3)
|
14
|
-
activemodel (= 3.0.3)
|
15
|
-
activesupport (= 3.0.3)
|
16
|
-
builder (~> 2.1.2)
|
17
|
-
erubis (~> 2.6.6)
|
18
|
-
i18n (~> 0.4)
|
19
|
-
rack (~> 1.2.1)
|
20
|
-
rack-mount (~> 0.6.13)
|
21
|
-
rack-test (~> 0.5.6)
|
22
|
-
tzinfo (~> 0.3.23)
|
23
|
-
activemodel (3.0.3)
|
24
|
-
activesupport (= 3.0.3)
|
25
|
-
builder (~> 2.1.2)
|
26
|
-
i18n (~> 0.4)
|
27
|
-
activerecord (3.0.3)
|
28
|
-
activemodel (= 3.0.3)
|
29
|
-
activesupport (= 3.0.3)
|
30
|
-
arel (~> 2.0.2)
|
31
|
-
tzinfo (~> 0.3.23)
|
32
|
-
activeresource (3.0.3)
|
33
|
-
activemodel (= 3.0.3)
|
34
|
-
activesupport (= 3.0.3)
|
35
|
-
activesupport (3.0.3)
|
36
|
-
archive-tar-minitar (0.5.2)
|
37
|
-
arel (2.0.8)
|
38
|
-
aruba (0.2.8)
|
39
|
-
childprocess (~> 0.1.6)
|
40
|
-
cucumber (~> 0.10.0)
|
41
|
-
rspec (~> 2.3.0)
|
42
|
-
builder (2.1.2)
|
43
|
-
childprocess (0.1.6)
|
44
|
-
ffi (~> 0.6.3)
|
45
|
-
columnize (0.3.2)
|
46
|
-
cucumber (0.10.0)
|
47
|
-
builder (>= 2.1.2)
|
48
|
-
diff-lcs (~> 1.1.2)
|
49
|
-
gherkin (~> 2.3.2)
|
50
|
-
json (~> 1.4.6)
|
51
|
-
term-ansicolor (~> 1.0.5)
|
52
|
-
diff-lcs (1.1.2)
|
53
|
-
erubis (2.6.6)
|
54
|
-
abstract (>= 1.0.0)
|
55
|
-
ffi (0.6.3)
|
56
|
-
rake (>= 0.8.7)
|
57
|
-
gherkin (2.3.3)
|
58
|
-
json (~> 1.4.6)
|
59
|
-
i18n (0.5.0)
|
60
|
-
json (1.4.6)
|
61
|
-
linecache19 (0.5.11)
|
62
|
-
ruby_core_source (>= 0.1.4)
|
63
|
-
mail (2.2.15)
|
64
|
-
activesupport (>= 2.3.6)
|
65
|
-
i18n (>= 0.4.0)
|
66
|
-
mime-types (~> 1.16)
|
67
|
-
treetop (~> 1.4.8)
|
68
|
-
mime-types (1.16)
|
69
|
-
mocha (0.9.10)
|
70
|
-
rake
|
71
|
-
polyglot (0.3.1)
|
72
|
-
rack (1.2.1)
|
73
|
-
rack-mount (0.6.13)
|
74
|
-
rack (>= 1.0.0)
|
75
|
-
rack-test (0.5.7)
|
76
|
-
rack (>= 1.0)
|
77
|
-
rails (3.0.3)
|
78
|
-
actionmailer (= 3.0.3)
|
79
|
-
actionpack (= 3.0.3)
|
80
|
-
activerecord (= 3.0.3)
|
81
|
-
activeresource (= 3.0.3)
|
82
|
-
activesupport (= 3.0.3)
|
83
|
-
bundler (~> 1.0)
|
84
|
-
railties (= 3.0.3)
|
85
|
-
railties (3.0.3)
|
86
|
-
actionpack (= 3.0.3)
|
87
|
-
activesupport (= 3.0.3)
|
88
|
-
rake (>= 0.8.7)
|
89
|
-
thor (~> 0.14.4)
|
90
|
-
rake (0.8.7)
|
91
|
-
rspec (2.3.0)
|
92
|
-
rspec-core (~> 2.3.0)
|
93
|
-
rspec-expectations (~> 2.3.0)
|
94
|
-
rspec-mocks (~> 2.3.0)
|
95
|
-
rspec-core (2.3.1)
|
96
|
-
rspec-expectations (2.3.0)
|
97
|
-
diff-lcs (~> 1.1.2)
|
98
|
-
rspec-mocks (2.3.0)
|
99
|
-
rspec-rails (2.3.1)
|
100
|
-
actionpack (~> 3.0)
|
101
|
-
activesupport (~> 3.0)
|
102
|
-
railties (~> 3.0)
|
103
|
-
rspec (~> 2.3.0)
|
104
|
-
ruby-debug-base19 (0.11.24)
|
105
|
-
columnize (>= 0.3.1)
|
106
|
-
linecache19 (>= 0.5.11)
|
107
|
-
ruby_core_source (>= 0.1.4)
|
108
|
-
ruby-debug19 (0.11.6)
|
109
|
-
columnize (>= 0.3.1)
|
110
|
-
linecache19 (>= 0.5.11)
|
111
|
-
ruby-debug-base19 (>= 0.11.19)
|
112
|
-
ruby_core_source (0.1.4)
|
113
|
-
archive-tar-minitar (>= 0.5.2)
|
114
|
-
sqlite3 (1.3.3)
|
115
|
-
sqlite3-ruby (1.3.3)
|
116
|
-
sqlite3 (>= 1.3.3)
|
117
|
-
term-ansicolor (1.0.5)
|
118
|
-
thor (0.14.6)
|
119
|
-
treetop (1.4.9)
|
120
|
-
polyglot (>= 0.3.1)
|
121
|
-
tzinfo (0.3.24)
|
122
|
-
|
123
|
-
PLATFORMS
|
124
|
-
ruby
|
125
|
-
|
126
|
-
DEPENDENCIES
|
127
|
-
aruba (~> 0.2.7)
|
128
|
-
cucumber (~> 0.10.0)
|
129
|
-
mocha (~> 0.9.10)
|
130
|
-
rails (= 3.0.3)
|
131
|
-
rspec-rails (~> 2.3.0)
|
132
|
-
ruby-debug19 (~> 0.11.6)
|
133
|
-
shoulda-matchers!
|
134
|
-
sqlite3-ruby (~> 1.3.2)
|