shoulda-matchers 1.0.0.beta2 → 1.0.0.beta3

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.
Files changed (26) hide show
  1. data/Appraisals +12 -0
  2. data/Gemfile +1 -0
  3. data/README.rdoc +12 -4
  4. data/Rakefile +7 -2
  5. data/lib/shoulda/matchers/action_controller/assign_to_matcher.rb +2 -2
  6. data/lib/shoulda/matchers/action_controller/set_the_flash_matcher.rb +2 -2
  7. data/lib/shoulda/matchers/action_mailer/have_sent_email.rb +135 -9
  8. data/lib/shoulda/matchers/active_model.rb +33 -0
  9. data/lib/shoulda/matchers/{active_record → active_model}/allow_mass_assignment_of_matcher.rb +23 -6
  10. data/lib/shoulda/matchers/{active_record → active_model}/allow_value_matcher.rb +1 -1
  11. data/lib/shoulda/matchers/{active_record → active_model}/ensure_inclusion_of_matcher.rb +1 -1
  12. data/lib/shoulda/matchers/{active_record → active_model}/ensure_length_of_matcher.rb +1 -1
  13. data/lib/shoulda/matchers/{active_record → active_model}/helpers.rb +1 -1
  14. data/lib/shoulda/matchers/{active_record → active_model}/validate_acceptance_of_matcher.rb +1 -1
  15. data/lib/shoulda/matchers/{active_record → active_model}/validate_format_of_matcher.rb +1 -1
  16. data/lib/shoulda/matchers/{active_record → active_model}/validate_numericality_of_matcher.rb +1 -1
  17. data/lib/shoulda/matchers/{active_record → active_model}/validate_presence_of_matcher.rb +1 -1
  18. data/lib/shoulda/matchers/{active_record → active_model}/validate_uniqueness_of_matcher.rb +1 -1
  19. data/lib/shoulda/matchers/{active_record → active_model}/validation_matcher.rb +1 -1
  20. data/lib/shoulda/matchers/active_record.rb +1 -19
  21. data/lib/shoulda/matchers/active_record/association_matcher.rb +17 -1
  22. data/lib/shoulda/matchers/integrations/rspec.rb +7 -0
  23. data/lib/shoulda/matchers/integrations/test_unit.rb +14 -1
  24. data/lib/shoulda/matchers/version.rb +1 -1
  25. metadata +36 -48
  26. data/Gemfile.lock +0 -134
@@ -0,0 +1,12 @@
1
+ appraise "3.0.3" do
2
+ gem "rails", "3.0.3"
3
+ gem "rake", "~> 0.8.7"
4
+ end
5
+
6
+ appraise "3.1.0.rc1" do
7
+ gem "rails", "3.1.0.rc1"
8
+ gem 'sass'
9
+ gem 'coffee-script'
10
+ gem 'uglifier'
11
+ gem 'jquery-rails'
12
+ end
data/Gemfile CHANGED
@@ -1,4 +1,5 @@
1
1
  source 'http://rubygems.org'
2
2
 
3
3
  gemspec
4
+ gem 'rake', '~> 0.8.7'
4
5
 
@@ -10,12 +10,22 @@ about using shoulda with Test::Unit.
10
10
 
11
11
  === ActiveRecord Matchers
12
12
 
13
- Matchers to test associations and validations:
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 = true
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 => [:spec, :cucumber]
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 #{@variable.inspect} " <<
86
- "(#{@variable.class.name})"
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 with_subject(email_subject)
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
- @body_failed = !regexp_or_string_match(mail.body, @body) if @body
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
@@ -1,12 +1,16 @@
1
1
  module Shoulda # :nodoc:
2
2
  module Matchers
3
- module ActiveRecord # :nodoc:
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
- !accessible_attributes.empty?
75
+ authorizer.kind_of?(::ActiveModel::MassAssignmentSecurity::WhiteList)
65
76
  end
66
77
 
67
78
  def attr_mass_assignable?
68
- if whitelisting?
69
- accessible_attributes.include?(@attribute)
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
- !protected_attributes.include?(@attribute)
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,6 +1,6 @@
1
1
  module Shoulda # :nodoc:
2
2
  module Matchers
3
- module ActiveRecord # :nodoc:
3
+ module ActiveModel # :nodoc:
4
4
 
5
5
  # Ensures that the attribute can be set to the given value.
6
6
  #
@@ -1,6 +1,6 @@
1
1
  module Shoulda # :nodoc:
2
2
  module Matchers
3
- module ActiveRecord # :nodoc:
3
+ module ActiveModel # :nodoc:
4
4
 
5
5
  # Ensure that the attribute's value is in the range specified
6
6
  #
@@ -1,6 +1,6 @@
1
1
  module Shoulda # :nodoc:
2
2
  module Matchers
3
- module ActiveRecord # :nodoc:
3
+ module ActiveModel # :nodoc:
4
4
 
5
5
  # Ensures that the length of the attribute is validated.
6
6
  #
@@ -1,6 +1,6 @@
1
1
  module Shoulda # :nodoc:
2
2
  module Matchers
3
- module ActiveRecord # :nodoc:
3
+ module ActiveModel # :nodoc:
4
4
  module Helpers
5
5
  def pretty_error_messages(obj) # :nodoc:
6
6
  obj.errors.map do |a, m|
@@ -1,6 +1,6 @@
1
1
  module Shoulda # :nodoc:
2
2
  module Matchers
3
- module ActiveRecord # :nodoc:
3
+ module ActiveModel # :nodoc:
4
4
 
5
5
  # Ensures that the model cannot be saved the given attribute is not
6
6
  # accepted.
@@ -1,6 +1,6 @@
1
1
  module Shoulda # :nodoc:
2
2
  module Matchers
3
- module ActiveRecord # :nodoc:
3
+ module ActiveModel # :nodoc:
4
4
 
5
5
  # Ensures that the model is not valid if the given attribute is not
6
6
  # formatted correctly.
@@ -1,6 +1,6 @@
1
1
  module Shoulda # :nodoc:
2
2
  module Matchers
3
- module ActiveRecord # :nodoc:
3
+ module ActiveModel # :nodoc:
4
4
 
5
5
  # Ensure that the attribute is numeric
6
6
  #
@@ -1,6 +1,6 @@
1
1
  module Shoulda # :nodoc:
2
2
  module Matchers
3
- module ActiveRecord # :nodoc:
3
+ module ActiveModel # :nodoc:
4
4
 
5
5
  # Ensures that the model is not valid if the given attribute is not
6
6
  # present.
@@ -1,6 +1,6 @@
1
1
  module Shoulda # :nodoc:
2
2
  module Matchers
3
- module ActiveRecord # :nodoc:
3
+ module ActiveModel # :nodoc:
4
4
 
5
5
  # Ensures that the model is invalid if the given attribute is not unique.
6
6
  #
@@ -1,6 +1,6 @@
1
1
  module Shoulda # :nodoc:
2
2
  module Matchers
3
- module ActiveRecord # :nodoc:
3
+ module ActiveModel # :nodoc:
4
4
 
5
5
  class ValidationMatcher # :nodoc:
6
6
 
@@ -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 most of the validations and associations for your
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
- end
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
@@ -1,5 +1,5 @@
1
1
  module Shoulda
2
2
  module Matchers
3
- VERSION = "1.0.0.beta2".dup
3
+ VERSION = "1.0.0.beta3".dup
4
4
  end
5
5
  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.beta2
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-03-17 00:00:00 -04:00
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: rails
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.0.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: sqlite3-ruby
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: 1.3.2
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: mocha
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: 0.9.10
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: rspec-rails
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: 2.3.0
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: cucumber
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.10.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
- requirement: &id007 !ruby/object:Gem::Requirement
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
- prerelease: false
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/active_record/allow_mass_assignment_of_matcher.rb
127
- - lib/shoulda/matchers/active_record/allow_value_matcher.rb
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.1
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
@@ -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)