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.
- checksums.yaml +15 -0
- data/Gemfile.lock +2 -2
- data/NEWS.md +12 -0
- data/README.md +0 -11
- data/features/rails_integration.feature +6 -8
- data/gemfiles/3.0.gemfile.lock +2 -2
- data/gemfiles/3.1.gemfile.lock +2 -2
- data/gemfiles/3.2.gemfile.lock +2 -2
- data/lib/shoulda/matchers/action_controller.rb +0 -4
- data/lib/shoulda/matchers/active_model.rb +0 -2
- data/lib/shoulda/matchers/active_record.rb +0 -1
- data/lib/shoulda/matchers/integrations/rspec.rb +0 -8
- data/lib/shoulda/matchers/integrations/test_unit.rb +0 -23
- data/lib/shoulda/matchers/version.rb +1 -1
- data/shoulda-matchers.gemspec +1 -1
- data/spec/spec_helper.rb +0 -2
- data/spec/support/controller_builder.rb +0 -24
- metadata +19 -70
- data/lib/shoulda/matchers/action_controller/assign_to_matcher.rb +0 -130
- data/lib/shoulda/matchers/action_controller/respond_with_content_type_matcher.rb +0 -83
- data/lib/shoulda/matchers/action_controller/strong_parameters_matcher.rb +0 -121
- data/lib/shoulda/matchers/action_mailer.rb +0 -22
- data/lib/shoulda/matchers/action_mailer/have_sent_email_matcher.rb +0 -260
- data/lib/shoulda/matchers/active_model/validate_format_of_matcher.rb +0 -108
- data/lib/shoulda/matchers/active_record/query_the_database_matcher.rb +0 -111
- data/lib/shoulda/matchers/independent.rb +0 -9
- data/lib/shoulda/matchers/independent/delegate_matcher.rb +0 -134
- data/spec/shoulda/matchers/action_controller/assign_to_matcher_spec.rb +0 -66
- data/spec/shoulda/matchers/action_controller/respond_with_content_type_matcher_spec.rb +0 -31
- data/spec/shoulda/matchers/action_controller/strong_parameters_matcher_spec.rb +0 -142
- data/spec/shoulda/matchers/action_mailer/have_sent_email_spec.rb +0 -324
- data/spec/shoulda/matchers/active_model/validate_format_of_matcher_spec.rb +0 -75
- data/spec/shoulda/matchers/active_record/query_the_database_matcher_spec.rb +0 -45
- data/spec/shoulda/matchers/independent/delegate_matcher_spec.rb +0 -204
@@ -1,108 +0,0 @@
|
|
1
|
-
require 'active_support/deprecation'
|
2
|
-
|
3
|
-
module Shoulda # :nodoc:
|
4
|
-
module Matchers
|
5
|
-
module ActiveModel # :nodoc:
|
6
|
-
# Ensures that the model is not valid if the given attribute is not
|
7
|
-
# formatted correctly.
|
8
|
-
#
|
9
|
-
# Options:
|
10
|
-
# * <tt>with_message</tt> - value the test expects to find in
|
11
|
-
# <tt>allow_blank</tt> - allows a blank value
|
12
|
-
# <tt>allow_nil</tt> - allows a nil value
|
13
|
-
# <tt>errors.on(:attribute)</tt>. <tt>Regexp</tt> or <tt>String</tt>.
|
14
|
-
# Defaults to the translation for <tt>:invalid</tt>.
|
15
|
-
# * <tt>with(string to test against)</tt>
|
16
|
-
# * <tt>not_with(string to test against)</tt>
|
17
|
-
#
|
18
|
-
# Examples:
|
19
|
-
# it { should validate_format_of(:name).
|
20
|
-
# with('12345').
|
21
|
-
# with_message(/is not optional/) }
|
22
|
-
# it { should validate_format_of(:name).
|
23
|
-
# not_with('12D45').
|
24
|
-
# with_message(/is not optional/) }
|
25
|
-
#
|
26
|
-
def validate_format_of(attr)
|
27
|
-
ValidateFormatOfMatcher.new(attr)
|
28
|
-
end
|
29
|
-
|
30
|
-
class ValidateFormatOfMatcher < ValidationMatcher # :nodoc:
|
31
|
-
def initialize(attribute)
|
32
|
-
ActiveSupport::Deprecation.warn 'The validate_format_of matcher is deprecated and will be removed in 2.0'
|
33
|
-
super
|
34
|
-
@options = {}
|
35
|
-
end
|
36
|
-
|
37
|
-
def allow_blank(allow_blank = true)
|
38
|
-
@options[:allow_blank] = allow_blank
|
39
|
-
self
|
40
|
-
end
|
41
|
-
|
42
|
-
def allow_nil(allow_nil = true)
|
43
|
-
@options[:allow_nil] = allow_nil
|
44
|
-
self
|
45
|
-
end
|
46
|
-
|
47
|
-
def with_message(message)
|
48
|
-
if message
|
49
|
-
@expected_message = message
|
50
|
-
end
|
51
|
-
self
|
52
|
-
end
|
53
|
-
|
54
|
-
def with(value)
|
55
|
-
if @value_to_fail
|
56
|
-
raise 'You may not call both with and not_with'
|
57
|
-
else
|
58
|
-
@value_to_pass = value
|
59
|
-
self
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
def not_with(value)
|
64
|
-
if @value_to_pass
|
65
|
-
raise 'You may not call both with and not_with'
|
66
|
-
else
|
67
|
-
@value_to_fail = value
|
68
|
-
self
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
|
-
def matches?(subject)
|
73
|
-
super(subject)
|
74
|
-
@expected_message ||= :invalid
|
75
|
-
|
76
|
-
if @value_to_fail
|
77
|
-
disallows_value_of(@value_to_fail, @expected_message) && allows_blank_value? && allows_nil_value?
|
78
|
-
else
|
79
|
-
allows_value_of(@value_to_pass, @expected_message) && allows_blank_value? && allows_nil_value?
|
80
|
-
end
|
81
|
-
end
|
82
|
-
|
83
|
-
def description
|
84
|
-
"have a valid format for #{@attribute}"
|
85
|
-
end
|
86
|
-
|
87
|
-
private
|
88
|
-
|
89
|
-
def allows_blank_value?
|
90
|
-
if @options.key?(:allow_blank)
|
91
|
-
@options[:allow_blank] == allows_value_of('')
|
92
|
-
else
|
93
|
-
true
|
94
|
-
end
|
95
|
-
end
|
96
|
-
|
97
|
-
def allows_nil_value?
|
98
|
-
if @options.key?(:allow_nil)
|
99
|
-
@options[:allow_nil] == allows_value_of(nil)
|
100
|
-
else
|
101
|
-
true
|
102
|
-
end
|
103
|
-
end
|
104
|
-
end
|
105
|
-
|
106
|
-
end
|
107
|
-
end
|
108
|
-
end
|
@@ -1,111 +0,0 @@
|
|
1
|
-
require 'active_support/deprecation'
|
2
|
-
|
3
|
-
module Shoulda # :nodoc:
|
4
|
-
module Matchers
|
5
|
-
module ActiveRecord # :nodoc:
|
6
|
-
|
7
|
-
# Ensures that the number of database queries is known. Rails 3.1 or greater is required.
|
8
|
-
#
|
9
|
-
# Options:
|
10
|
-
# * <tt>when_calling</tt> - Required, the name of the method to examine.
|
11
|
-
# * <tt>with</tt> - Used in conjunction with <tt>when_calling</tt> to pass parameters to the method to examine.
|
12
|
-
# * <tt>or_less</tt> - Pass if the database is queried no more than the number of times specified, as opposed to exactly that number of times.
|
13
|
-
#
|
14
|
-
# Examples:
|
15
|
-
# it { should query_the_database(4.times).when_calling(:complicated_counting_method)
|
16
|
-
# it { should query_the_database(4.times).or_less.when_calling(:generate_big_report)
|
17
|
-
# it { should_not query_the_database.when_calling(:cached_count)
|
18
|
-
#
|
19
|
-
def query_the_database(times = nil)
|
20
|
-
QueryTheDatabaseMatcher.new(times)
|
21
|
-
end
|
22
|
-
|
23
|
-
class QueryTheDatabaseMatcher # :nodoc:
|
24
|
-
def initialize(times)
|
25
|
-
ActiveSupport::Deprecation.warn 'The query_the_database matcher is deprecated and will be removed in 2.0'
|
26
|
-
@queries = []
|
27
|
-
@options = {}
|
28
|
-
|
29
|
-
if times.respond_to?(:count)
|
30
|
-
@options[:expected_query_count] = times.count
|
31
|
-
else
|
32
|
-
@options[:expected_query_count] = times
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
def when_calling(method_name)
|
37
|
-
@options[:method_name] = method_name
|
38
|
-
self
|
39
|
-
end
|
40
|
-
|
41
|
-
def with(*method_arguments)
|
42
|
-
@options[:method_arguments] = method_arguments
|
43
|
-
self
|
44
|
-
end
|
45
|
-
|
46
|
-
def or_less
|
47
|
-
@options[:expected_count_is_maximum] = true
|
48
|
-
self
|
49
|
-
end
|
50
|
-
|
51
|
-
def matches?(subject)
|
52
|
-
subscriber = ActiveSupport::Notifications.subscribe('sql.active_record') do |name, started, finished, id, payload|
|
53
|
-
@queries << payload unless filter_query(payload)
|
54
|
-
end
|
55
|
-
|
56
|
-
if @options[:method_arguments]
|
57
|
-
subject.send(@options[:method_name], *@options[:method_arguments])
|
58
|
-
else
|
59
|
-
subject.send(@options[:method_name])
|
60
|
-
end
|
61
|
-
|
62
|
-
ActiveSupport::Notifications.unsubscribe(subscriber)
|
63
|
-
|
64
|
-
if @options[:expected_count_is_maximum]
|
65
|
-
@queries.length <= @options[:expected_query_count]
|
66
|
-
elsif @options[:expected_query_count].present?
|
67
|
-
@queries.length == @options[:expected_query_count]
|
68
|
-
else
|
69
|
-
@queries.length > 0
|
70
|
-
end
|
71
|
-
end
|
72
|
-
|
73
|
-
def failure_message_for_should
|
74
|
-
if @options.key?(:expected_query_count)
|
75
|
-
"Expected ##{@options[:method_name]} to cause #{@options[:expected_query_count]} database queries but it actually caused #{@queries.length} queries:" + friendly_queries
|
76
|
-
else
|
77
|
-
"Expected ##{@options[:method_name]} to query the database but it actually caused #{@queries.length} queries:" + friendly_queries
|
78
|
-
end
|
79
|
-
end
|
80
|
-
|
81
|
-
def failure_message_for_should_not
|
82
|
-
if @options[:expected_query_count]
|
83
|
-
"Expected ##{@options[:method_name]} to not cause #{@options[:expected_query_count]} database queries but it actually caused #{@queries.length} queries:" + friendly_queries
|
84
|
-
else
|
85
|
-
"Expected ##{@options[:method_name]} to not query the database but it actually caused #{@queries.length} queries:" + friendly_queries
|
86
|
-
end
|
87
|
-
end
|
88
|
-
|
89
|
-
private
|
90
|
-
|
91
|
-
def friendly_queries
|
92
|
-
@queries.map do |query|
|
93
|
-
"\n (#{query[:name]}) #{query[:sql]}"
|
94
|
-
end.join
|
95
|
-
end
|
96
|
-
|
97
|
-
def filter_query(query)
|
98
|
-
query[:name] == 'SCHEMA' || looks_like_schema?(query[:sql])
|
99
|
-
end
|
100
|
-
|
101
|
-
def schema_terms
|
102
|
-
['FROM sqlite_master', 'PRAGMA', 'SHOW TABLES', 'SHOW KEYS FROM', 'SHOW FIELDS FROM', 'begin transaction', 'commit transaction']
|
103
|
-
end
|
104
|
-
|
105
|
-
def looks_like_schema?(sql)
|
106
|
-
schema_terms.any? { |term| sql.include?(term) }
|
107
|
-
end
|
108
|
-
end
|
109
|
-
end
|
110
|
-
end
|
111
|
-
end
|
@@ -1,134 +0,0 @@
|
|
1
|
-
require 'bourne'
|
2
|
-
require 'active_support/deprecation'
|
3
|
-
|
4
|
-
module Shoulda # :nodoc:
|
5
|
-
module Matchers
|
6
|
-
module Independent # :nodoc:
|
7
|
-
|
8
|
-
# Ensure that a given method is delegated properly.
|
9
|
-
#
|
10
|
-
# Basic Syntax:
|
11
|
-
# it { should delegate_method(:deliver_mail).to(:mailman) }
|
12
|
-
#
|
13
|
-
# Options:
|
14
|
-
# * <tt>:as</tt> - tests that the object being delegated to is called with a certain method
|
15
|
-
# (defaults to same name as delegating method)
|
16
|
-
# * <tt>:with_arguments</tt> - tests that the method on the object being delegated to is
|
17
|
-
# called with certain arguments
|
18
|
-
#
|
19
|
-
# Examples:
|
20
|
-
# it { should delegate_method(:deliver_mail).to(:mailman).as(:deliver_with_haste)
|
21
|
-
# it { should delegate_method(:deliver_mail).to(:mailman).
|
22
|
-
# with_arguments('221B Baker St.', :hastily => true) }
|
23
|
-
#
|
24
|
-
def delegate_method(delegating_method)
|
25
|
-
DelegateMatcher.new(delegating_method)
|
26
|
-
end
|
27
|
-
|
28
|
-
class DelegateMatcher
|
29
|
-
def initialize(delegating_method)
|
30
|
-
ActiveSupport::Deprecation.warn 'The delegate_method matcher is deprecated and will be removed in 2.0'
|
31
|
-
@delegating_method = delegating_method
|
32
|
-
end
|
33
|
-
|
34
|
-
def matches?(subject)
|
35
|
-
@subject = subject
|
36
|
-
ensure_target_method_is_present!
|
37
|
-
|
38
|
-
begin
|
39
|
-
extend Mocha::API
|
40
|
-
|
41
|
-
stubbed_object = stub(method_on_target)
|
42
|
-
subject.stubs(@target_method).returns(stubbed_object)
|
43
|
-
subject.send(@delegating_method)
|
44
|
-
|
45
|
-
matcher = Mocha::API::HaveReceived.new(method_on_target).with(*@delegated_arguments)
|
46
|
-
matcher.matches?(stubbed_object)
|
47
|
-
rescue NoMethodError, Mocha::ExpectationError
|
48
|
-
false
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
def description
|
53
|
-
add_clarifications_to("delegate method ##{@delegating_method} to :#{@target_method}")
|
54
|
-
end
|
55
|
-
|
56
|
-
def does_not_match?(subject)
|
57
|
-
raise InvalidDelegateMatcher
|
58
|
-
end
|
59
|
-
|
60
|
-
def to(target_method)
|
61
|
-
@target_method = target_method
|
62
|
-
self
|
63
|
-
end
|
64
|
-
|
65
|
-
def as(method_on_target)
|
66
|
-
@method_on_target = method_on_target
|
67
|
-
self
|
68
|
-
end
|
69
|
-
|
70
|
-
def with_arguments(*arguments)
|
71
|
-
@delegated_arguments = arguments
|
72
|
-
self
|
73
|
-
end
|
74
|
-
|
75
|
-
def failure_message_for_should
|
76
|
-
base = "Expected #{delegating_method_name} to delegate to #{target_method_name}"
|
77
|
-
add_clarifications_to(base)
|
78
|
-
end
|
79
|
-
|
80
|
-
private
|
81
|
-
|
82
|
-
def add_clarifications_to(message)
|
83
|
-
if @delegated_arguments.present?
|
84
|
-
message << " with arguments: #{@delegated_arguments.inspect}"
|
85
|
-
end
|
86
|
-
|
87
|
-
if @method_on_target.present?
|
88
|
-
message << " as ##{@method_on_target}"
|
89
|
-
end
|
90
|
-
|
91
|
-
message
|
92
|
-
end
|
93
|
-
|
94
|
-
def delegating_method_name
|
95
|
-
method_name_with_class(@delegating_method)
|
96
|
-
end
|
97
|
-
|
98
|
-
def target_method_name
|
99
|
-
method_name_with_class(@target_method)
|
100
|
-
end
|
101
|
-
|
102
|
-
def method_name_with_class(method)
|
103
|
-
if Class === @subject
|
104
|
-
@subject.name + '.' + method.to_s
|
105
|
-
else
|
106
|
-
@subject.class.name + '#' + method.to_s
|
107
|
-
end
|
108
|
-
end
|
109
|
-
|
110
|
-
def method_on_target
|
111
|
-
@method_on_target || @delegating_method
|
112
|
-
end
|
113
|
-
|
114
|
-
def ensure_target_method_is_present!
|
115
|
-
if @target_method.blank?
|
116
|
-
raise TargetNotDefinedError
|
117
|
-
end
|
118
|
-
end
|
119
|
-
end
|
120
|
-
|
121
|
-
class DelegateMatcher::TargetNotDefinedError < StandardError
|
122
|
-
def message
|
123
|
-
'Delegation needs a target. Use the #to method to define one, e.g. `post_office.should delegate(:deliver_mail).to(:mailman)`'
|
124
|
-
end
|
125
|
-
end
|
126
|
-
|
127
|
-
class DelegateMatcher::InvalidDelegateMatcher < StandardError
|
128
|
-
def message
|
129
|
-
'#delegate_to does not support #should_not syntax.'
|
130
|
-
end
|
131
|
-
end
|
132
|
-
end
|
133
|
-
end
|
134
|
-
end
|
@@ -1,66 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe Shoulda::Matchers::ActionController::AssignToMatcher do
|
4
|
-
it 'includes the actual class in the failure message' do
|
5
|
-
define_class(:WrongClass) do
|
6
|
-
def to_s
|
7
|
-
'wrong class'
|
8
|
-
end
|
9
|
-
end
|
10
|
-
|
11
|
-
controller = build_response { @var = WrongClass.new }
|
12
|
-
matcher = assign_to(:var).with_kind_of(Fixnum)
|
13
|
-
matcher.matches?(controller)
|
14
|
-
|
15
|
-
matcher.failure_message_for_should.should =~ /but got wrong class \(WrongClass\)$/
|
16
|
-
end
|
17
|
-
|
18
|
-
context 'a controller that assigns to an instance variable' do
|
19
|
-
it 'accepts assigning to that variable' do
|
20
|
-
controller.should assign_to(:var)
|
21
|
-
end
|
22
|
-
|
23
|
-
it 'accepts assigning to that variable with the correct class' do
|
24
|
-
controller.should assign_to(:var).with_kind_of(String)
|
25
|
-
end
|
26
|
-
|
27
|
-
it 'rejects assigning to that variable with another class' do
|
28
|
-
controller.should_not assign_to(:var).with_kind_of(Fixnum)
|
29
|
-
end
|
30
|
-
|
31
|
-
it 'accepts assigning the correct value to that variable' do
|
32
|
-
controller.should assign_to(:var).with('value')
|
33
|
-
end
|
34
|
-
|
35
|
-
it 'rejects assigning another value to that variable' do
|
36
|
-
controller.should_not assign_to(:var).with('other')
|
37
|
-
end
|
38
|
-
|
39
|
-
it 'rejects assigning to another variable' do
|
40
|
-
controller.should_not assign_to(:other)
|
41
|
-
end
|
42
|
-
|
43
|
-
it 'accepts assigning to the same value in the test context' do
|
44
|
-
expected = 'value'
|
45
|
-
controller.should assign_to(:var).in_context(self).with { expected }
|
46
|
-
end
|
47
|
-
|
48
|
-
it 'rejects assigning to the another value in the test context' do
|
49
|
-
expected = 'other'
|
50
|
-
controller.should_not assign_to(:var).in_context(self).with { expected }
|
51
|
-
end
|
52
|
-
|
53
|
-
def controller
|
54
|
-
build_response { @var = 'value' }
|
55
|
-
end
|
56
|
-
end
|
57
|
-
|
58
|
-
context 'a controller that assigns a nil value to an instance variable' do
|
59
|
-
it 'accepts assigning to that variable' do
|
60
|
-
controller = build_response do
|
61
|
-
@var = nil
|
62
|
-
end
|
63
|
-
controller.should assign_to(:var)
|
64
|
-
end
|
65
|
-
end
|
66
|
-
end
|
@@ -1,31 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe Shoulda::Matchers::ActionController::RespondWithContentTypeMatcher do
|
4
|
-
it 'generates the correct description' do
|
5
|
-
expected = 'respond with content type of application/xml'
|
6
|
-
|
7
|
-
respond_with_content_type(:xml).description.should == expected
|
8
|
-
end
|
9
|
-
|
10
|
-
it 'accepts responding with content type as symbol' do
|
11
|
-
xml_controller.should respond_with_content_type(:xml)
|
12
|
-
end
|
13
|
-
|
14
|
-
it 'accepts responding with qualified MIME-style content type' do
|
15
|
-
xml_controller.should respond_with_content_type('application/xml')
|
16
|
-
end
|
17
|
-
|
18
|
-
it 'accepts responding with a regex matching the content type' do
|
19
|
-
xml_controller.should respond_with_content_type(/xml/)
|
20
|
-
end
|
21
|
-
|
22
|
-
it 'rejects responding with another content type' do
|
23
|
-
xml_controller.should_not respond_with_content_type(:json)
|
24
|
-
end
|
25
|
-
|
26
|
-
def xml_controller
|
27
|
-
build_response do
|
28
|
-
render :xml => { :user => 'thoughtbot' }.to_xml
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|