shoulda-matchers 1.5.6 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
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