shoulda-matchers 1.5.6 → 2.0.0

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 (34) hide show
  1. checksums.yaml +15 -0
  2. data/Gemfile.lock +2 -2
  3. data/NEWS.md +12 -0
  4. data/README.md +0 -11
  5. data/features/rails_integration.feature +6 -8
  6. data/gemfiles/3.0.gemfile.lock +2 -2
  7. data/gemfiles/3.1.gemfile.lock +2 -2
  8. data/gemfiles/3.2.gemfile.lock +2 -2
  9. data/lib/shoulda/matchers/action_controller.rb +0 -4
  10. data/lib/shoulda/matchers/active_model.rb +0 -2
  11. data/lib/shoulda/matchers/active_record.rb +0 -1
  12. data/lib/shoulda/matchers/integrations/rspec.rb +0 -8
  13. data/lib/shoulda/matchers/integrations/test_unit.rb +0 -23
  14. data/lib/shoulda/matchers/version.rb +1 -1
  15. data/shoulda-matchers.gemspec +1 -1
  16. data/spec/spec_helper.rb +0 -2
  17. data/spec/support/controller_builder.rb +0 -24
  18. metadata +19 -70
  19. data/lib/shoulda/matchers/action_controller/assign_to_matcher.rb +0 -130
  20. data/lib/shoulda/matchers/action_controller/respond_with_content_type_matcher.rb +0 -83
  21. data/lib/shoulda/matchers/action_controller/strong_parameters_matcher.rb +0 -121
  22. data/lib/shoulda/matchers/action_mailer.rb +0 -22
  23. data/lib/shoulda/matchers/action_mailer/have_sent_email_matcher.rb +0 -260
  24. data/lib/shoulda/matchers/active_model/validate_format_of_matcher.rb +0 -108
  25. data/lib/shoulda/matchers/active_record/query_the_database_matcher.rb +0 -111
  26. data/lib/shoulda/matchers/independent.rb +0 -9
  27. data/lib/shoulda/matchers/independent/delegate_matcher.rb +0 -134
  28. data/spec/shoulda/matchers/action_controller/assign_to_matcher_spec.rb +0 -66
  29. data/spec/shoulda/matchers/action_controller/respond_with_content_type_matcher_spec.rb +0 -31
  30. data/spec/shoulda/matchers/action_controller/strong_parameters_matcher_spec.rb +0 -142
  31. data/spec/shoulda/matchers/action_mailer/have_sent_email_spec.rb +0 -324
  32. data/spec/shoulda/matchers/active_model/validate_format_of_matcher_spec.rb +0 -75
  33. data/spec/shoulda/matchers/active_record/query_the_database_matcher_spec.rb +0 -45
  34. data/spec/shoulda/matchers/independent/delegate_matcher_spec.rb +0 -204
@@ -1,130 +0,0 @@
1
- require 'active_support/deprecation'
2
-
3
- module Shoulda # :nodoc:
4
- module Matchers
5
- module ActionController # :nodoc:
6
- # Ensures that the controller assigned to the named instance variable.
7
- #
8
- # Options:
9
- # * <tt>with_kind_of</tt> - The expected class of the instance variable
10
- # being checked.
11
- # * <tt>with</tt> - The value that should be assigned.
12
- #
13
- # Example:
14
- #
15
- # it { should assign_to(:user) }
16
- # it { should_not assign_to(:user) }
17
- # it { should assign_to(:user).with_kind_of(User) }
18
- # it { should assign_to(:user).with(@user) }
19
- def assign_to(variable)
20
- AssignToMatcher.new(variable)
21
- end
22
-
23
- class AssignToMatcher # :nodoc:
24
- attr_reader :failure_message_for_should, :failure_message_for_should_not
25
-
26
- def initialize(variable)
27
- ActiveSupport::Deprecation.warn 'The assign_to matcher is deprecated and will be removed in 2.0'
28
- @variable = variable.to_s
29
- @options = {}
30
- @options[:check_value] = false
31
- end
32
-
33
- def with_kind_of(expected_class)
34
- @options[:expected_class] = expected_class
35
- self
36
- end
37
-
38
- def with(expected_value = nil, &block)
39
- @options[:check_value] = true
40
- @options[:expected_value] = expected_value
41
- @options[:expectation_block] = block
42
- self
43
- end
44
-
45
- def matches?(controller)
46
- @controller = controller
47
- normalize_expected_value!
48
- assigned_value? &&
49
- kind_of_expected_class? &&
50
- equal_to_expected_value?
51
- end
52
-
53
- def description
54
- description = "assign @#{@variable}"
55
- if @options.key?(:expected_class)
56
- description << " with a kind of #{@options[:expected_class]}"
57
- end
58
- description
59
- end
60
-
61
- def in_context(context)
62
- @context = context
63
- self
64
- end
65
-
66
- private
67
-
68
- def assigned_value?
69
- if @controller.instance_variables.map(&:to_s).include?("@#{@variable}")
70
- @failure_message_for_should_not =
71
- "Didn't expect action to assign a value for @#{@variable}, " <<
72
- "but it was assigned to #{assigned_value.inspect}"
73
- true
74
- else
75
- @failure_message_for_should =
76
- "Expected action to assign a value for @#{@variable}"
77
- false
78
- end
79
- end
80
-
81
- def kind_of_expected_class?
82
- if @options.key?(:expected_class)
83
- if assigned_value.kind_of?(@options[:expected_class])
84
- @failure_message_for_should_not =
85
- "Didn't expect action to assign a kind of #{@options[:expected_class]} " <<
86
- "for #{@variable}, but got one anyway"
87
- true
88
- else
89
- @failure_message_for_should =
90
- "Expected action to assign a kind of #{@options[:expected_class]} " <<
91
- "for #{@variable}, but got #{assigned_value.inspect} " <<
92
- "(#{assigned_value.class.name})"
93
- false
94
- end
95
- else
96
- true
97
- end
98
- end
99
-
100
- def equal_to_expected_value?
101
- if @options[:check_value]
102
- if @options[:expected_value] == assigned_value
103
- @failure_message_for_should_not =
104
- "Didn't expect action to assign #{@options[:expected_value].inspect} " <<
105
- "for #{@variable}, but got it anyway"
106
- true
107
- else
108
- @failure_message_for_should =
109
- "Expected action to assign #{@options[:expected_value].inspect} " <<
110
- "for #{@variable}, but got #{assigned_value.inspect}"
111
- false
112
- end
113
- else
114
- true
115
- end
116
- end
117
-
118
- def normalize_expected_value!
119
- if @options[:expectation_block]
120
- @options[:expected_value] = @context.instance_eval(&@options[:expectation_block])
121
- end
122
- end
123
-
124
- def assigned_value
125
- @controller.instance_variable_get("@#{@variable}")
126
- end
127
- end
128
- end
129
- end
130
- end
@@ -1,83 +0,0 @@
1
- require 'active_support/deprecation'
2
-
3
- module Shoulda # :nodoc:
4
- module Matchers
5
- module ActionController # :nodoc:
6
-
7
- # Ensures a controller responded with expected 'response' content type.
8
- #
9
- # You can pass an explicit content type such as 'application/rss+xml'
10
- # or its symbolic equivalent :rss
11
- # or a regular expression such as /rss/
12
- #
13
- # Example:
14
- #
15
- # it { should respond_with_content_type(:xml) }
16
- # it { should respond_with_content_type(:csv) }
17
- # it { should respond_with_content_type(:atom) }
18
- # it { should respond_with_content_type(:yaml) }
19
- # it { should respond_with_content_type(:text) }
20
- # it { should respond_with_content_type('application/rss+xml') }
21
- # it { should respond_with_content_type(/json/) }
22
- def respond_with_content_type(content_type)
23
- RespondWithContentTypeMatcher.new(content_type)
24
- end
25
-
26
- class RespondWithContentTypeMatcher # :nodoc:
27
- def initialize(content_type)
28
- ActiveSupport::Deprecation.warn 'The respond_with_content_type matcher is deprecated and will be removed in 2.0'
29
- @content_type = look_up_content_type(content_type)
30
- end
31
-
32
- def description
33
- "respond with content type of #{@content_type}"
34
- end
35
-
36
- def matches?(controller)
37
- @controller = controller
38
- content_type_matches_regexp? || content_type_matches_string?
39
- end
40
-
41
- def failure_message_for_should
42
- "Expected #{expectation}"
43
- end
44
-
45
- def failure_message_for_should_not
46
- "Did not expect #{expectation}"
47
- end
48
-
49
- protected
50
-
51
- def content_type_matches_regexp?
52
- if @content_type.is_a?(Regexp)
53
- response_content_type =~ @content_type
54
- end
55
- end
56
-
57
- def content_type_matches_string?
58
- response_content_type == @content_type
59
- end
60
-
61
- def response_content_type
62
- @controller.response.content_type.to_s
63
- end
64
-
65
- def look_up_by_extension(extension)
66
- Mime::Type.lookup_by_extension(extension.to_s).to_s
67
- end
68
-
69
- def look_up_content_type(content_type)
70
- if content_type.is_a?(Symbol)
71
- look_up_by_extension(content_type)
72
- else
73
- content_type
74
- end
75
- end
76
-
77
- def expectation
78
- "content type to be #{@content_type}, but was #{response_content_type}"
79
- end
80
- end
81
- end
82
- end
83
- end
@@ -1,121 +0,0 @@
1
- require 'bourne'
2
- require 'active_support/deprecation'
3
- begin
4
- require 'strong_parameters'
5
- rescue LoadError
6
- end
7
-
8
- module Shoulda
9
- module Matchers
10
- module ActionController
11
- def permit(*attributes)
12
- attributes_and_context = attributes + [self]
13
- StrongParametersMatcher.new(*attributes_and_context)
14
- end
15
-
16
- class StrongParametersMatcher
17
- def initialize(*attributes_and_context)
18
- ActiveSupport::Deprecation.warn 'The strong_parameters matcher is deprecated and will be removed in 2.0'
19
- @attributes = attributes_and_context[0...-1]
20
- @context = attributes_and_context.last
21
- @permitted_params = []
22
- end
23
-
24
- def for(action, options = {})
25
- @action = action
26
- @verb = options[:verb] || verb_for_action
27
- self
28
- end
29
-
30
- def in_context(context)
31
- @context = context
32
- self
33
- end
34
-
35
- def matches?(controller = nil)
36
- simulate_controller_action && parameters_difference.empty?
37
- end
38
-
39
- def does_not_match?(controller = nil)
40
- simulate_controller_action && parameters_difference.present?
41
- end
42
-
43
- def failure_message
44
- "Expected controller to permit #{parameters_difference.to_sentence}, but it did not."
45
- end
46
-
47
- def negative_failure_message
48
- "Expected controller not to permit #{parameters_difference.to_sentence}, but it did."
49
- end
50
-
51
- private
52
- attr_reader :verb, :action, :attributes, :context
53
- attr_accessor :permitted_params
54
-
55
- def simulate_controller_action
56
- ensure_action_and_verb_present!
57
- model_attrs = stubbed_model_attributes
58
-
59
- context.send(verb, action)
60
-
61
- verify_permit_call(model_attrs)
62
- end
63
-
64
- def verify_permit_call(model_attrs)
65
- matcher = Mocha::API::HaveReceived.new(:permit).with do |*params|
66
- self.permitted_params = params
67
- end
68
-
69
- matcher.matches?(model_attrs)
70
- rescue Mocha::ExpectationError
71
- false
72
- end
73
-
74
- def parameters_difference
75
- attributes - permitted_params
76
- end
77
-
78
- def stubbed_model_attributes
79
- extend Mocha::API
80
-
81
- model_attrs = ::ActionController::Parameters.new(arbitrary_attributes)
82
- model_attrs.stubs(:permit)
83
- ::ActionController::Parameters.any_instance.stubs(:[]).returns(model_attrs)
84
-
85
- model_attrs
86
- end
87
-
88
- def ensure_action_and_verb_present!
89
- if action.blank?
90
- raise ActionNotDefinedError
91
- end
92
- if verb.blank?
93
- raise VerbNotDefinedError
94
- end
95
- end
96
-
97
- def arbitrary_attributes
98
- {:any_key => 'any_value'}
99
- end
100
-
101
- def verb_for_action
102
- verb_lookup = { :create => :post, :update => :put }
103
- verb_lookup[action]
104
- end
105
- end
106
-
107
- class StrongParametersMatcher::ActionNotDefinedError < StandardError
108
- def message
109
- 'You must specify the controller action using the #for method.'
110
- end
111
- end
112
-
113
- class StrongParametersMatcher::VerbNotDefinedError < StandardError
114
- def message
115
- 'You must specify an HTTP verb when using a non-RESTful action.' +
116
- ' e.g. for(:authorize, :verb => :post)'
117
- end
118
- end
119
- end
120
- end
121
- end
@@ -1,22 +0,0 @@
1
- require 'shoulda/matchers/action_mailer/have_sent_email_matcher'
2
-
3
- module Shoulda
4
- module Matchers
5
- # = Matchers for your mailers
6
- #
7
- # This matcher will test that email is sent properly
8
- #
9
- # describe User do
10
- # it { should have_sent_email.with_subject(/is spam$/) }
11
- # it { should have_sent_email.from('do-not-reply@example.com') }
12
- # it { should have_sent_email.with_body(/is spam\./) }
13
- # it { should have_sent_email.to('myself@me.com') }
14
- # it { should have_sent_email.with_subject(/spam/).
15
- # from('do-not-reply@example.com').
16
- # with_body(/spam/).
17
- # to('myself@me.com') }
18
- # end
19
- module ActionMailer
20
- end
21
- end
22
- end
@@ -1,260 +0,0 @@
1
- require 'active_support/deprecation'
2
-
3
- module Shoulda # :nodoc:
4
- module Matchers
5
- module ActionMailer # :nodoc:
6
-
7
- # The right email is sent.
8
- #
9
- # it { should have_sent_email.with_subject(/is spam$/) }
10
- # it { should have_sent_email.from('do-not-reply@example.com') }
11
- # it { should have_sent_email.with_body(/is spam\./) }
12
- # it { should have_sent_email.to('myself@me.com') }
13
- # it { should have_sent_email.with_part('text/html', /HTML spam/) }
14
- # it { should have_sent_email.with_subject(/spam/).
15
- # from('do-not-reply@example.com').
16
- # reply_to('reply-to-me@example.com').
17
- # with_body(/spam/).
18
- # to('myself@me.com') }
19
- #
20
- # Use values of instance variables
21
- # it {should have_sent_email.to {@user.email} }
22
- def have_sent_email
23
- HaveSentEmailMatcher.new(self)
24
- end
25
-
26
- class HaveSentEmailMatcher # :nodoc:
27
-
28
- def initialize(context)
29
- ActiveSupport::Deprecation.warn 'The have_sent_email matcher is deprecated and will be removed in 2.0'
30
- @context = context
31
- end
32
-
33
- def in_context(context)
34
- @context = context
35
- self
36
- end
37
-
38
- def with_subject(email_subject = nil, &block)
39
- @email_subject = email_subject
40
- @email_subject_block = block
41
- self
42
- end
43
-
44
- def from(sender = nil, &block)
45
- @sender = sender
46
- @sender_block = block
47
- self
48
- end
49
-
50
- def reply_to(reply_to = nil, &block)
51
- @reply_to = reply_to
52
- @reply_to_block = block
53
- self
54
- end
55
-
56
- def with_body(body = nil, &block)
57
- @body = body
58
- @body_block = block
59
- self
60
- end
61
-
62
- def with_part(content_type, body = nil, &block)
63
- @parts ||= []
64
- @parts << [/#{Regexp.escape(content_type)}/, body, content_type]
65
- @parts_blocks ||= []
66
- @parts_blocks << block
67
- self
68
- end
69
-
70
- def to(recipient = nil, &block)
71
- @recipient = recipient
72
- @recipient_block = block
73
- self
74
- end
75
-
76
- def cc(recipient = nil, &block)
77
- @cc = recipient
78
- @cc_block = block
79
- self
80
- end
81
-
82
- def with_cc(recipients = nil, &block)
83
- @cc_recipients = recipients
84
- @cc_recipients_block = block
85
- self
86
- end
87
-
88
- def bcc(recipient = nil, &block)
89
- @bcc = recipient
90
- @bcc_block = block
91
- self
92
- end
93
-
94
- def with_bcc(recipients = nil, &block)
95
- @bcc_recipients = recipients
96
- @bcc_recipients_block = block
97
- self
98
- end
99
-
100
- def multipart(flag = true)
101
- @multipart = !!flag
102
- self
103
- end
104
-
105
- def matches?(subject)
106
- normalize_blocks
107
- ::ActionMailer::Base.deliveries.any? do |mail|
108
- mail_matches?(mail)
109
- end
110
- end
111
-
112
- def failure_message_for_should
113
- "Expected #{expectation}"
114
- end
115
-
116
- def failure_message_for_should_not
117
- "Did not expect #{expectation}"
118
- end
119
-
120
- def description
121
- description = 'send an email'
122
- description << " with a subject of #{@email_subject.inspect}" if @email_subject
123
- description << " containing #{@body.inspect}" if @body
124
- if @parts
125
- @parts.each do |_, body, content_type|
126
- description << " having a #{content_type} part containing #{body.inspect}"
127
- end
128
- end
129
- description << " from #{@sender.inspect}" if @sender
130
- description << " reply to #{@reply_to.inspect}" if @reply_to
131
- description << " to #{@recipient.inspect}" if @recipient
132
- description << " cc #{@cc.inspect}" if @cc
133
- description << " with cc #{@cc_recipients.inspect}" if @cc_recipients
134
- description << " bcc #{@bcc.inspect}" if @bcc
135
- description << " with bcc #{@bcc_recipients.inspect}" if @bcc_recipients
136
- description
137
- end
138
-
139
- private
140
-
141
- def expectation
142
- expectation = 'sent email'
143
- expectation << " with subject #{@email_subject.inspect}" if @subject_failed
144
- expectation << " with body #{@body.inspect}" if @body_failed
145
- @parts.each do |_, body, content_type|
146
- expectation << " with a #{content_type} part containing #{body}"
147
- end if @parts && @parts_failed
148
- expectation << " from #{@sender.inspect}" if @sender_failed
149
- expectation << " reply to #{@reply_to.inspect}" if @reply_to_failed
150
- expectation << " to #{@recipient.inspect}" if @recipient_failed
151
- expectation << " cc #{@cc.inspect}" if @cc_failed
152
- expectation << " with cc #{@cc_recipients.inspect}" if @cc_recipients_failed
153
- expectation << " bcc #{@bcc.inspect}" if @bcc_failed
154
- expectation << " with bcc #{@bcc_recipients.inspect}" if @bcc_recipients_failed
155
- expectation << " #{'not ' if !@multipart}being multipart" if @multipart_failed
156
- expectation << "\nDeliveries:\n#{inspect_deliveries}"
157
- end
158
-
159
- def inspect_deliveries
160
- ::ActionMailer::Base.deliveries.map do |delivery|
161
- "#{delivery.subject.inspect} to #{delivery.to.inspect}"
162
- end.join("\n")
163
- end
164
-
165
- def mail_matches?(mail)
166
- @subject_failed = !regexp_or_string_match(mail.subject, @email_subject) if @email_subject
167
- @parts_failed = !parts_match(mail, @parts) if @parts
168
- @body_failed = !body_match(mail, @body) if @body
169
- @sender_failed = !regexp_or_string_match_in_array(mail.from, @sender) if @sender
170
- @reply_to_failed = !regexp_or_string_match_in_array(mail.reply_to, @reply_to) if @reply_to
171
- @recipient_failed = !regexp_or_string_match_in_array(mail.to, @recipient) if @recipient
172
- @cc_failed = !regexp_or_string_match_in_array(mail.cc, @cc) if @cc
173
- @cc_recipients_failed = !match_array_in_array(mail.cc, @cc_recipients) if @cc_recipients
174
- @bcc_failed = !regexp_or_string_match_in_array(mail.bcc, @bcc) if @bcc
175
- @bcc_recipients_failed = !match_array_in_array(mail.bcc, @bcc_recipients) if @bcc_recipients
176
- @multipart_failed = (mail.multipart? != @multipart) if defined?(@multipart)
177
-
178
- ! anything_failed?
179
- end
180
-
181
- def anything_failed?
182
- @subject_failed || @body_failed || @sender_failed || @reply_to_failed ||
183
- @recipient_failed || @cc_failed || @cc_recipients_failed || @bcc_failed ||
184
- @bcc_recipients_failed || @parts_failed || @multipart_failed
185
- end
186
-
187
- def normalize_blocks
188
- @email_subject = @context.instance_eval(&@email_subject_block) if @email_subject_block
189
- @sender = @context.instance_eval(&@sender_block) if @sender_block
190
- @reply_to = @context.instance_eval(&@reply_to_block) if @reply_to_block
191
- @body = @context.instance_eval(&@body_block) if @body_block
192
- @recipient = @context.instance_eval(&@recipient_block) if @recipient_block
193
- @cc = @context.instance_eval(&@cc_block) if @cc_block
194
- @cc_recipients = @context.instance_eval(&@cc_recipients_block) if @cc_recipients_block
195
- @bcc = @context.instance_eval(&@bcc_block) if @bcc_block
196
- @bcc_recipients = @context.instance_eval(&@bcc_recipients_block) if @bcc_recipients_block
197
-
198
- if @parts
199
- @parts.each_with_index do |part, i|
200
- part[1] = @context.instance_eval(&@parts_blocks[i]) if @parts_blocks[i]
201
- end
202
- end
203
- end
204
-
205
- def regexp_or_string_match(a_string, a_regexp_or_string)
206
- case a_regexp_or_string
207
- when Regexp
208
- a_string =~ a_regexp_or_string
209
- when String
210
- a_string == a_regexp_or_string
211
- end
212
- end
213
-
214
- def regexp_or_string_match_in_array(an_array, a_regexp_or_string)
215
- case a_regexp_or_string
216
- when Regexp
217
- an_array.any? { |string| string =~ a_regexp_or_string }
218
- when String
219
- an_array.include?(a_regexp_or_string)
220
- end
221
- end
222
-
223
- def match_array_in_array(target_array, match_array)
224
- target_array.sort!
225
- match_array.sort!
226
-
227
- target_array.each_cons(match_array.size).include?(match_array)
228
- end
229
-
230
- def body_match(mail, a_regexp_or_string)
231
- # Mail objects instantiated by ActionMailer3 return a blank
232
- # body if the e-mail is multipart. TMail concatenates the
233
- # String representation of each part instead.
234
- if mail.body.blank? && mail.multipart?
235
- part_match(mail, /^text\//, a_regexp_or_string)
236
- else
237
- regexp_or_string_match(mail.body, a_regexp_or_string)
238
- end
239
- end
240
-
241
- def parts_match(mail, parts)
242
- return false if mail.parts.empty?
243
-
244
- parts.all? do |content_type, match, _|
245
- part_match(mail, content_type, match)
246
- end
247
- end
248
-
249
- def part_match(mail, content_type, a_regexp_or_string)
250
- matching = mail.parts.select {|p| p.content_type =~ content_type}
251
- return false if matching.empty?
252
-
253
- matching.all? do |part|
254
- regexp_or_string_match(part.body, a_regexp_or_string)
255
- end
256
- end
257
- end
258
- end
259
- end
260
- end