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.
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)