shoulda-matchers 2.6.2 → 2.7.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (68) hide show
  1. checksums.yaml +4 -4
  2. data/Appraisals +6 -1
  3. data/Gemfile +1 -1
  4. data/Gemfile.lock +26 -22
  5. data/NEWS.md +52 -1
  6. data/README.md +8 -6
  7. data/Rakefile +1 -1
  8. data/doc_config/gh-pages/index.html.erb +1 -1
  9. data/doc_config/yard/templates/default/fulldoc/html/css/global.css +1 -1
  10. data/doc_config/yard/templates/default/fulldoc/html/css/style.css +26 -0
  11. data/features/rails_integration.feature +18 -3
  12. data/features/step_definitions/rails_steps.rb +21 -3
  13. data/gemfiles/3.0.gemfile +1 -1
  14. data/gemfiles/3.0.gemfile.lock +30 -24
  15. data/gemfiles/3.1.gemfile +1 -1
  16. data/gemfiles/3.1.gemfile.lock +32 -26
  17. data/gemfiles/3.1_1.9.2.gemfile +1 -1
  18. data/gemfiles/3.1_1.9.2.gemfile.lock +22 -19
  19. data/gemfiles/3.2.gemfile +1 -1
  20. data/gemfiles/3.2.gemfile.lock +32 -26
  21. data/gemfiles/3.2_1.9.2.gemfile +1 -1
  22. data/gemfiles/3.2_1.9.2.gemfile.lock +8 -8
  23. data/gemfiles/4.0.0.gemfile +2 -2
  24. data/gemfiles/4.0.0.gemfile.lock +35 -31
  25. data/gemfiles/4.0.1.gemfile +2 -2
  26. data/gemfiles/4.0.1.gemfile.lock +24 -22
  27. data/gemfiles/4.1.gemfile +1 -1
  28. data/gemfiles/4.1.gemfile.lock +26 -22
  29. data/lib/shoulda/matchers/action_controller/filter_param_matcher.rb +10 -3
  30. data/lib/shoulda/matchers/action_controller/set_session_matcher.rb +24 -6
  31. data/lib/shoulda/matchers/active_model.rb +2 -2
  32. data/lib/shoulda/matchers/active_model/allow_value_matcher.rb +1 -1
  33. data/lib/shoulda/matchers/active_model/ensure_length_of_matcher.rb +1 -1
  34. data/lib/shoulda/matchers/active_model/validate_absence_of_matcher.rb +5 -3
  35. data/lib/shoulda/matchers/active_model/{ensure_exclusion_of_matcher.rb → validate_exclusion_of_matcher.rb} +20 -10
  36. data/lib/shoulda/matchers/active_model/{ensure_inclusion_of_matcher.rb → validate_inclusion_of_matcher.rb} +52 -28
  37. data/lib/shoulda/matchers/active_model/validate_uniqueness_of_matcher.rb +28 -19
  38. data/lib/shoulda/matchers/active_record.rb +18 -16
  39. data/lib/shoulda/matchers/active_record/accept_nested_attributes_for_matcher.rb +4 -4
  40. data/lib/shoulda/matchers/active_record/association_matcher.rb +17 -12
  41. data/lib/shoulda/matchers/active_record/association_matchers/join_table_matcher.rb +86 -0
  42. data/lib/shoulda/matchers/active_record/association_matchers/model_reflection.rb +19 -0
  43. data/lib/shoulda/matchers/active_record/association_matchers/model_reflector.rb +2 -1
  44. data/lib/shoulda/matchers/active_record/define_enum_for_matcher.rb +138 -0
  45. data/lib/shoulda/matchers/independent.rb +3 -2
  46. data/lib/shoulda/matchers/independent/{delegate_matcher.rb → delegate_method_matcher.rb} +69 -49
  47. data/lib/shoulda/matchers/independent/delegate_method_matcher/stubbed_target.rb +37 -0
  48. data/lib/shoulda/matchers/independent/delegate_method_matcher/target_not_defined_error.rb +15 -0
  49. data/lib/shoulda/matchers/version.rb +1 -1
  50. data/lib/shoulda/matchers/warn.rb +30 -2
  51. data/spec/shoulda/matchers/action_controller/filter_param_matcher_spec.rb +6 -0
  52. data/spec/shoulda/matchers/action_controller/set_session_matcher_spec.rb +67 -5
  53. data/spec/shoulda/matchers/action_controller/strong_parameters_matcher_spec.rb +9 -9
  54. data/spec/shoulda/matchers/active_model/validate_absence_of_matcher_spec.rb +30 -3
  55. data/spec/shoulda/matchers/active_model/{ensure_exclusion_of_matcher_spec.rb → validate_exclusion_of_matcher_spec.rb} +29 -13
  56. data/spec/shoulda/matchers/active_model/{ensure_inclusion_of_matcher_spec.rb → validate_inclusion_of_matcher_spec.rb} +34 -16
  57. data/spec/shoulda/matchers/active_model/validate_uniqueness_of_matcher_spec.rb +35 -0
  58. data/spec/shoulda/matchers/active_record/association_matcher_spec.rb +56 -1
  59. data/spec/shoulda/matchers/active_record/define_enum_for_matcher_spec.rb +101 -0
  60. data/spec/shoulda/matchers/doublespeak/object_double_spec.rb +6 -6
  61. data/spec/shoulda/matchers/independent/{delegate_matcher → delegate_method_matcher}/stubbed_target_spec.rb +1 -1
  62. data/spec/shoulda/matchers/independent/{delegate_matcher_spec.rb → delegate_method_matcher_spec.rb} +88 -29
  63. data/spec/spec_helper.rb +2 -3
  64. data/spec/support/fail_with_message_including_matcher.rb +14 -3
  65. data/spec/support/fail_with_message_matcher.rb +14 -2
  66. data/spec/support/rails_versions.rb +4 -0
  67. metadata +19 -14
  68. data/lib/shoulda/matchers/independent/delegate_matcher/stubbed_target.rb +0 -35
@@ -1,19 +1,21 @@
1
- require 'shoulda/matchers/active_record/association_matcher'
2
- require 'shoulda/matchers/active_record/association_matchers'
3
- require 'shoulda/matchers/active_record/association_matchers/counter_cache_matcher'
4
- require 'shoulda/matchers/active_record/association_matchers/inverse_of_matcher'
5
- require 'shoulda/matchers/active_record/association_matchers/order_matcher'
6
- require 'shoulda/matchers/active_record/association_matchers/through_matcher'
7
- require 'shoulda/matchers/active_record/association_matchers/dependent_matcher'
8
- require 'shoulda/matchers/active_record/association_matchers/source_matcher'
9
- require 'shoulda/matchers/active_record/association_matchers/model_reflector'
10
- require 'shoulda/matchers/active_record/association_matchers/model_reflection'
11
- require 'shoulda/matchers/active_record/association_matchers/option_verifier'
12
- require 'shoulda/matchers/active_record/have_db_column_matcher'
13
- require 'shoulda/matchers/active_record/have_db_index_matcher'
14
- require 'shoulda/matchers/active_record/have_readonly_attribute_matcher'
15
- require 'shoulda/matchers/active_record/serialize_matcher'
16
- require 'shoulda/matchers/active_record/accept_nested_attributes_for_matcher'
1
+ require "shoulda/matchers/active_record/association_matcher"
2
+ require "shoulda/matchers/active_record/association_matchers"
3
+ require "shoulda/matchers/active_record/association_matchers/counter_cache_matcher"
4
+ require "shoulda/matchers/active_record/association_matchers/inverse_of_matcher"
5
+ require "shoulda/matchers/active_record/association_matchers/join_table_matcher"
6
+ require "shoulda/matchers/active_record/association_matchers/order_matcher"
7
+ require "shoulda/matchers/active_record/association_matchers/through_matcher"
8
+ require "shoulda/matchers/active_record/association_matchers/dependent_matcher"
9
+ require "shoulda/matchers/active_record/association_matchers/source_matcher"
10
+ require "shoulda/matchers/active_record/association_matchers/model_reflector"
11
+ require "shoulda/matchers/active_record/association_matchers/model_reflection"
12
+ require "shoulda/matchers/active_record/association_matchers/option_verifier"
13
+ require "shoulda/matchers/active_record/have_db_column_matcher"
14
+ require "shoulda/matchers/active_record/have_db_index_matcher"
15
+ require "shoulda/matchers/active_record/have_readonly_attribute_matcher"
16
+ require "shoulda/matchers/active_record/serialize_matcher"
17
+ require "shoulda/matchers/active_record/accept_nested_attributes_for_matcher"
18
+ require "shoulda/matchers/active_record/define_enum_for_matcher"
17
19
 
18
20
  module Shoulda
19
21
  module Matchers
@@ -5,7 +5,7 @@ module Shoulda
5
5
  # `accepts_nested_attributes_for` macro.
6
6
  #
7
7
  # class Car < ActiveRecord::Base
8
- # accept_nested_attributes_for :doors
8
+ # accepts_nested_attributes_for :doors
9
9
  # end
10
10
  #
11
11
  # # RSpec
@@ -26,7 +26,7 @@ module Shoulda
26
26
  # specified.
27
27
  #
28
28
  # class Car < ActiveRecord::Base
29
- # accept_nested_attributes_for :mirrors, allow_destroy: true
29
+ # accepts_nested_attributes_for :mirrors, allow_destroy: true
30
30
  # end
31
31
  #
32
32
  # # RSpec
@@ -48,7 +48,7 @@ module Shoulda
48
48
  # Use `limit` to assert that the `:limit` option was specified.
49
49
  #
50
50
  # class Car < ActiveRecord::Base
51
- # accept_nested_attributes_for :windows, limit: 3
51
+ # accepts_nested_attributes_for :windows, limit: 3
52
52
  # end
53
53
  #
54
54
  # # RSpec
@@ -71,7 +71,7 @@ module Shoulda
71
71
  # specified.
72
72
  #
73
73
  # class Car < ActiveRecord::Base
74
- # accept_nested_attributes_for :engine, update_only: true
74
+ # accepts_nested_attributes_for :engine, update_only: true
75
75
  # end
76
76
  #
77
77
  # # RSpec
@@ -847,9 +847,9 @@ module Shoulda
847
847
  (polymorphic? || class_exists?) &&
848
848
  foreign_key_exists? &&
849
849
  class_name_correct? &&
850
+ join_table_correct? &&
850
851
  autosave_correct? &&
851
852
  conditions_correct? &&
852
- join_table_exists? &&
853
853
  validate_correct? &&
854
854
  touch_correct? &&
855
855
  submatchers_match?
@@ -889,7 +889,8 @@ module Shoulda
889
889
  end
890
890
 
891
891
  def missing_options
892
- [missing, failing_submatchers.map(&:missing_option)].flatten.join
892
+ missing_options = [missing, failing_submatchers.map(&:missing_option)]
893
+ missing_options.flatten.compact.join(', ')
893
894
  end
894
895
 
895
896
  def failing_submatchers
@@ -946,6 +947,20 @@ module Shoulda
946
947
  end
947
948
  end
948
949
 
950
+ def join_table_correct?
951
+ if macro != :has_and_belongs_to_many || join_table_matcher.matches?(@subject)
952
+ true
953
+ else
954
+ @missing = join_table_matcher.failure_message
955
+ false
956
+ end
957
+ end
958
+
959
+ def join_table_matcher
960
+ @join_table_matcher ||=
961
+ AssociationMatchers::JoinTableMatcher.new(self, reflector)
962
+ end
963
+
949
964
  def class_exists?
950
965
  associated_class
951
966
  true
@@ -980,16 +995,6 @@ module Shoulda
980
995
  end
981
996
  end
982
997
 
983
- def join_table_exists?
984
- if macro != :has_and_belongs_to_many ||
985
- model_class.connection.tables.include?(join_table)
986
- true
987
- else
988
- @missing = "join table #{join_table} doesn't exist"
989
- false
990
- end
991
- end
992
-
993
998
  def validate_correct?
994
999
  if option_verifier.correct_for_boolean?(:validate, options[:validate])
995
1000
  true
@@ -0,0 +1,86 @@
1
+ module Shoulda
2
+ module Matchers
3
+ module ActiveRecord
4
+ module AssociationMatchers
5
+ # @private
6
+ class JoinTableMatcher
7
+ attr_reader :failure_message
8
+
9
+ alias :missing_option :failure_message
10
+
11
+ delegate :model_class, :join_table, :associated_class,
12
+ to: :association_matcher
13
+
14
+ delegate :connection, to: :model_class
15
+
16
+ def initialize(association_matcher, reflector)
17
+ @association_matcher = association_matcher
18
+ @reflector = reflector
19
+ end
20
+
21
+ def matches?(subject)
22
+ join_table_exists? &&
23
+ join_table_has_correct_columns?
24
+ end
25
+
26
+ def join_table_exists?
27
+ if connection.tables.include?(join_table)
28
+ true
29
+ else
30
+ @failure_message = missing_table_message
31
+ false
32
+ end
33
+ end
34
+
35
+ def join_table_has_correct_columns?
36
+ if missing_columns.empty?
37
+ true
38
+ else
39
+ @failure_message = missing_columns_message
40
+ false
41
+ end
42
+ end
43
+
44
+ protected
45
+
46
+ attr_reader :association_matcher, :reflector
47
+
48
+ private
49
+
50
+ delegate :foreign_key, :association_foreign_key, to: :reflector
51
+
52
+ def missing_columns
53
+ @missing_columns ||= expected_join_table_columns.select do |key|
54
+ !actual_join_table_columns.include?(key)
55
+ end
56
+ end
57
+
58
+ def expected_join_table_columns
59
+ [foreign_key, association_foreign_key]
60
+ end
61
+
62
+ def actual_join_table_columns
63
+ connection.columns(join_table).map(&:name)
64
+ end
65
+
66
+ def missing_table_message
67
+ "join table #{join_table} doesn't exist"
68
+ end
69
+
70
+ def missing_columns_message
71
+ missing = missing_columns.join(', ')
72
+ "join table #{join_table} missing #{column_label}: #{missing}"
73
+ end
74
+
75
+ def column_label
76
+ if missing_columns.count > 1
77
+ 'columns'
78
+ else
79
+ 'column'
80
+ end
81
+ end
82
+ end
83
+ end
84
+ end
85
+ end
86
+ end
@@ -45,6 +45,25 @@ module Shoulda
45
45
  end
46
46
  end
47
47
 
48
+ def foreign_key
49
+ if has_and_belongs_to_many_reflection
50
+ has_and_belongs_to_many_reflection.foreign_key
51
+ elsif reflection.respond_to?(:primary_key_name)
52
+ reflection.primary_key_name
53
+ else
54
+ reflection.foreign_key
55
+ end
56
+ end
57
+
58
+ def association_foreign_key
59
+ if has_and_belongs_to_many_reflection
60
+ join_model = has_and_belongs_to_many_reflection.options[:class]
61
+ join_model.right_reflection.foreign_key
62
+ else
63
+ reflection.association_foreign_key
64
+ end
65
+ end
66
+
48
67
  protected
49
68
 
50
69
  attr_reader :reflection, :subject
@@ -5,7 +5,8 @@ module Shoulda
5
5
  # @private
6
6
  class ModelReflector
7
7
  delegate :associated_class, :through?, :join_table,
8
- :association_relation, :polymorphic?, to: :reflection
8
+ :association_relation, :polymorphic?, :foreign_key,
9
+ :association_foreign_key, to: :reflection
9
10
 
10
11
  def initialize(subject, name)
11
12
  @subject = subject
@@ -0,0 +1,138 @@
1
+ module Shoulda
2
+ module Matchers
3
+ module ActiveRecord
4
+ # The `define_enum_for` matcher is used to test that the `enum` macro has
5
+ # been used to decorate an attribute with enum methods.
6
+ #
7
+ # class Process < ActiveRecord::Base
8
+ # enum status: [:running, :stopped, :suspended]
9
+ # end
10
+ #
11
+ # # RSpec
12
+ # describe Process do
13
+ # it { should define_enum_for(:status) }
14
+ # end
15
+ # end
16
+ #
17
+ # # Test::Unit
18
+ # class ProcessTest < ActiveSupport::TestCase
19
+ # should define_enum_for(:status)
20
+ # end
21
+ #
22
+ # #### Qualifiers
23
+ #
24
+ # ##### with
25
+ #
26
+ # Use `with` to test that the enum has been defined with a certain set of
27
+ # known values.
28
+ #
29
+ # class Process < ActiveRecord::Base
30
+ # enum status: [:running, :stopped, :suspended]
31
+ # end
32
+ #
33
+ # # RSpec
34
+ # describe Process do
35
+ # it do
36
+ # should define_enum_for(:status).
37
+ # with([:running, :stopped, :suspended])
38
+ # end
39
+ # end
40
+ #
41
+ # # Test::Unit
42
+ # class ProcessTest < ActiveSupport::TestCase
43
+ # should define_enum_for(:status).
44
+ # with([:running, :stopped, :suspended])
45
+ # end
46
+ #
47
+ # @return [DefineEnumForMatcher]
48
+ #
49
+ def define_enum_for(attribute_name)
50
+ DefineEnumForMatcher.new(attribute_name)
51
+ end
52
+
53
+ # @private
54
+ class DefineEnumForMatcher
55
+ def initialize(attribute_name)
56
+ @attribute_name = attribute_name
57
+ @options = {}
58
+ end
59
+
60
+ def with(expected_enum_values)
61
+ options[:expected_enum_values] = expected_enum_values
62
+ self
63
+ end
64
+
65
+ def matches?(subject)
66
+ @model = subject
67
+ enum_defined? && enum_values_match?
68
+ end
69
+
70
+ def failure_message
71
+ "Expected #{expectation}"
72
+ end
73
+ alias :failure_message_for_should :failure_message
74
+
75
+ def failure_message_when_negated
76
+ "Did not expect #{expectation}"
77
+ end
78
+ alias :failure_message_for_should_not :failure_message_when_negated
79
+
80
+ def description
81
+ desc = "define :#{attribute_name} as an enum"
82
+
83
+ if options[:expected_enum_values]
84
+ desc << " with #{options[:expected_enum_values]}"
85
+ end
86
+
87
+ desc
88
+ end
89
+
90
+ protected
91
+
92
+ attr_reader :model, :attribute_name, :options
93
+
94
+ def expectation
95
+ "#{model.class.name} to #{description}"
96
+ end
97
+
98
+ def expected_enum_values
99
+ hashify(options[:expected_enum_values]).with_indifferent_access
100
+ end
101
+
102
+ def enum_method
103
+ attribute_name.to_s.pluralize
104
+ end
105
+
106
+ def actual_enum_values
107
+ model.class.send(enum_method)
108
+ end
109
+
110
+ def enum_defined?
111
+ model.class.respond_to?(enum_method)
112
+ end
113
+
114
+ def enum_values_match?
115
+ expected_enum_values.empty? || actual_enum_values == expected_enum_values
116
+ end
117
+
118
+ def hashify(value)
119
+ if value.nil?
120
+ return {}
121
+ end
122
+
123
+ if value.is_a?(Array)
124
+ new_value = {}
125
+
126
+ value.each_with_index do |v, i|
127
+ new_value[v] = i
128
+ end
129
+
130
+ new_value
131
+ else
132
+ value
133
+ end
134
+ end
135
+ end
136
+ end
137
+ end
138
+ end
@@ -1,5 +1,6 @@
1
- require 'shoulda/matchers/independent/delegate_matcher'
2
- require 'shoulda/matchers/independent/delegate_matcher/stubbed_target'
1
+ require 'shoulda/matchers/independent/delegate_method_matcher'
2
+ require 'shoulda/matchers/independent/delegate_method_matcher/stubbed_target'
3
+ require 'shoulda/matchers/independent/delegate_method_matcher/target_not_defined_error'
3
4
 
4
5
  module Shoulda
5
6
  module Matchers
@@ -70,10 +70,12 @@ module Shoulda
70
70
  # ##### with_arguments
71
71
  #
72
72
  # Use `with_arguments` to assert that the delegate method is called with
73
- # certain arguments.
73
+ # certain arguments. Note that this qualifier can only be used when the
74
+ # delegating method takes no arguments; it does not support delegating
75
+ # or delegate methods that take arbitrary arguments.
74
76
  #
75
- # Here, when Courier#deliver calls PostOffice#ship, it adds an options
76
- # hash:
77
+ # Here, when Courier#deliver_package calls PostOffice#deliver_package, it
78
+ # adds an options hash:
77
79
  #
78
80
  # class Courier
79
81
  # attr_reader :post_office
@@ -82,39 +84,39 @@ module Shoulda
82
84
  # @post_office = PostOffice.new
83
85
  # end
84
86
  #
85
- # def deliver(package)
86
- # post_office.ship(package, expedited: true)
87
+ # def deliver_package
88
+ # post_office.deliver_package(expedited: true)
87
89
  # end
88
90
  # end
89
91
  #
90
92
  # # RSpec
91
93
  # describe Courier do
92
94
  # it do
93
- # should delegate_method(:deliver).
95
+ # should delegate_method(:deliver_package).
94
96
  # to(:post_office).
95
- # as(:ship).
96
97
  # with_arguments(expedited: true)
97
98
  # end
98
99
  # end
99
100
  #
100
101
  # # Test::Unit
101
102
  # class CourierTest < Test::Unit::TestCase
102
- # should delegate_method(:deliver).
103
+ # should delegate_method(:deliver_package).
103
104
  # to(:post_office).
104
- # as(:ship).
105
105
  # with_arguments(expedited: true)
106
106
  # end
107
107
  #
108
- # @return [DelegateMatcher]
108
+ # @return [DelegateMethodMatcher]
109
109
  #
110
110
  def delegate_method(delegating_method)
111
- DelegateMatcher.new(delegating_method)
111
+ DelegateMethodMatcher.new(delegating_method, self)
112
112
  end
113
113
 
114
114
  # @private
115
- class DelegateMatcher
116
- def initialize(delegating_method)
115
+ class DelegateMethodMatcher
116
+ def initialize(delegating_method, context)
117
117
  @delegating_method = delegating_method
118
+ @context = context
119
+
118
120
  @method_on_target = @delegating_method
119
121
  @target_double = Doublespeak::ObjectDouble.new
120
122
 
@@ -135,9 +137,18 @@ module Shoulda
135
137
  end
136
138
 
137
139
  def description
138
- add_clarifications_to(
139
- "delegate method ##{delegating_method} to :#{target_method}"
140
- )
140
+ string = "delegate #{formatted_delegating_method_name} to " +
141
+ "#{formatted_target_method_name} object"
142
+
143
+ if delegated_arguments.any?
144
+ string << " passing arguments #{delegated_arguments.inspect}"
145
+ end
146
+
147
+ if method_on_target != delegating_method
148
+ string << " as #{formatted_method_on_target}"
149
+ end
150
+
151
+ string
141
152
  end
142
153
 
143
154
  def to(target_method)
@@ -156,58 +167,73 @@ module Shoulda
156
167
  end
157
168
 
158
169
  def failure_message
159
- base = "Expected #{formatted_delegating_method_name} to delegate to #{formatted_target_method_name}"
160
- add_clarifications_to(base)
161
- base << "\nCalls on #{formatted_target_method_name}:"
162
- base << formatted_calls_on_target
163
- base.strip
170
+ "Expected #{class_under_test} to #{description}\n" +
171
+ "Method calls sent to " +
172
+ "#{formatted_target_method_name(include_module: true)}:" +
173
+ formatted_calls_on_target
164
174
  end
165
175
  alias failure_message_for_should failure_message
166
176
 
167
177
  def failure_message_when_negated
168
- base = "Expected #{formatted_delegating_method_name} not to delegate to #{formatted_target_method_name}"
169
- add_clarifications_to(base)
170
- base << ', but it did'
178
+ "Expected #{class_under_test} not to #{description}, but it did"
171
179
  end
172
180
  alias failure_message_for_should_not failure_message_when_negated
173
181
 
174
182
  protected
175
183
 
176
184
  attr_reader \
185
+ :context,
177
186
  :delegated_arguments,
178
187
  :delegating_method,
179
188
  :method,
180
189
  :method_on_target,
181
- :subject,
182
190
  :subject_double_collection,
183
191
  :target_double,
184
192
  :target_method
185
193
 
186
- def add_clarifications_to(message)
187
- if delegated_arguments.any?
188
- message << " with arguments: #{delegated_arguments.inspect}"
189
- end
194
+ def subject
195
+ @subject || context.subject
196
+ end
190
197
 
191
- if method_on_target != delegating_method
192
- message << " as ##{method_on_target}"
198
+ def class_under_test
199
+ if subject.is_a?(Class)
200
+ subject
201
+ else
202
+ subject.class
193
203
  end
204
+ end
194
205
 
195
- message
206
+ def formatted_method_on_target(options = {})
207
+ formatted_method_name_for(method_on_target, options)
196
208
  end
197
209
 
198
- def formatted_delegating_method_name
199
- formatted_method_name_for(delegating_method)
210
+ def formatted_delegating_method_name(options = {})
211
+ formatted_method_name_for(delegating_method, options)
200
212
  end
201
213
 
202
- def formatted_target_method_name
203
- formatted_method_name_for(target_method)
214
+ def formatted_target_method_name(options = {})
215
+ formatted_method_name_for(target_method, options)
204
216
  end
205
217
 
206
- def formatted_method_name_for(method_name)
218
+ def formatted_method_name_for(method_name, options)
219
+ possible_class_under_test(options) +
220
+ class_or_instance_method_indicator +
221
+ method_name.to_s
222
+ end
223
+
224
+ def possible_class_under_test(options)
225
+ if options[:include_module]
226
+ class_under_test.to_s
227
+ else
228
+ ""
229
+ end
230
+ end
231
+
232
+ def class_or_instance_method_indicator
207
233
  if subject.is_a?(Class)
208
- subject.name + '.' + method_name.to_s
234
+ '.'
209
235
  else
210
- subject.class.name + '#' + method_name.to_s
236
+ '#'
211
237
  end
212
238
  end
213
239
 
@@ -226,11 +252,11 @@ module Shoulda
226
252
  end
227
253
 
228
254
  def subject_has_target_method?
229
- subject.respond_to?(target_method)
255
+ subject.respond_to?(target_method, true)
230
256
  end
231
257
 
232
258
  def ensure_target_method_is_present!
233
- if target_method.blank?
259
+ if target_method.to_s.empty?
234
260
  raise TargetNotDefinedError
235
261
  end
236
262
  end
@@ -280,15 +306,9 @@ module Shoulda
280
306
  string << " (none)"
281
307
  end
282
308
 
283
- string
284
- end
309
+ string.rstrip!
285
310
 
286
- # @private
287
- class TargetNotDefinedError < StandardError
288
- def message
289
- 'Delegation needs a target. Use the #to method to define one, e.g.
290
- `post_office.should delegate(:deliver_mail).to(:mailman)`'.squish
291
- end
311
+ string
292
312
  end
293
313
  end
294
314
  end