rspec-sleeping_king_studios 2.1.1 → 2.2.0.rc.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +52 -0
  3. data/DEVELOPMENT.md +26 -17
  4. data/LICENSE +1 -1
  5. data/README.md +198 -19
  6. data/lib/rspec/sleeping_king_studios/configuration.rb +63 -2
  7. data/lib/rspec/sleeping_king_studios/examples/property_examples.rb +115 -27
  8. data/lib/rspec/sleeping_king_studios/examples/rspec_matcher_examples.rb +66 -51
  9. data/lib/rspec/sleeping_king_studios/matchers/active_model/have_errors.rb +8 -269
  10. data/lib/rspec/sleeping_king_studios/matchers/active_model/have_errors_matcher.rb +268 -0
  11. data/lib/rspec/sleeping_king_studios/matchers/base_matcher.rb +5 -15
  12. data/lib/rspec/sleeping_king_studios/matchers/built_in/be_kind_of.rb +3 -63
  13. data/lib/rspec/sleeping_king_studios/matchers/built_in/be_kind_of_matcher.rb +65 -0
  14. data/lib/rspec/sleeping_king_studios/matchers/built_in/include.rb +3 -108
  15. data/lib/rspec/sleeping_king_studios/matchers/built_in/include_matcher.rb +134 -0
  16. data/lib/rspec/sleeping_king_studios/matchers/built_in/respond_to.rb +3 -258
  17. data/lib/rspec/sleeping_king_studios/matchers/built_in/respond_to_matcher.rb +116 -0
  18. data/lib/rspec/sleeping_king_studios/matchers/core/alias_method.rb +11 -0
  19. data/lib/rspec/sleeping_king_studios/matchers/core/alias_method_matcher.rb +107 -0
  20. data/lib/rspec/sleeping_king_studios/matchers/core/be_boolean.rb +9 -36
  21. data/lib/rspec/sleeping_king_studios/matchers/core/be_boolean_matcher.rb +37 -0
  22. data/lib/rspec/sleeping_king_studios/matchers/core/construct.rb +3 -210
  23. data/lib/rspec/sleeping_king_studios/matchers/core/construct_matcher.rb +113 -0
  24. data/lib/rspec/sleeping_king_studios/matchers/core/delegate_method.rb +11 -0
  25. data/lib/rspec/sleeping_king_studios/matchers/core/delegate_method_matcher.rb +311 -0
  26. data/lib/rspec/sleeping_king_studios/matchers/core/have_constant.rb +16 -0
  27. data/lib/rspec/sleeping_king_studios/matchers/core/have_constant_matcher.rb +225 -0
  28. data/lib/rspec/sleeping_king_studios/matchers/core/have_predicate.rb +11 -0
  29. data/lib/rspec/sleeping_king_studios/matchers/core/have_predicate_matcher.rb +97 -0
  30. data/lib/rspec/sleeping_king_studios/matchers/core/have_property.rb +3 -104
  31. data/lib/rspec/sleeping_king_studios/matchers/core/have_property_matcher.rb +108 -0
  32. data/lib/rspec/sleeping_king_studios/matchers/core/have_reader.rb +3 -74
  33. data/lib/rspec/sleeping_king_studios/matchers/core/have_reader_matcher.rb +96 -0
  34. data/lib/rspec/sleeping_king_studios/matchers/core/have_writer.rb +4 -59
  35. data/lib/rspec/sleeping_king_studios/matchers/core/have_writer_matcher.rb +55 -0
  36. data/lib/rspec/sleeping_king_studios/matchers/description.rb +62 -0
  37. data/lib/rspec/sleeping_king_studios/matchers/macros.rb +32 -0
  38. data/lib/rspec/sleeping_king_studios/matchers/shared/match_parameters.rb +168 -66
  39. data/lib/rspec/sleeping_king_studios/matchers/shared/match_property.rb +25 -0
  40. data/lib/rspec/sleeping_king_studios/matchers.rb +0 -4
  41. data/lib/rspec/sleeping_king_studios/support/method_signature.rb +51 -0
  42. data/lib/rspec/sleeping_king_studios/support/method_signature_expectation.rb +158 -0
  43. data/lib/rspec/sleeping_king_studios/support.rb +9 -0
  44. data/lib/rspec/sleeping_king_studios/version.rb +10 -4
  45. metadata +46 -30
@@ -0,0 +1,225 @@
1
+ # lib/rspec/sleeping_king_studios/matchers/core/have_constant_matcher.rb
2
+
3
+ require 'rspec/sleeping_king_studios/matchers/base_matcher'
4
+ require 'rspec/sleeping_king_studios/matchers/core'
5
+ require 'sleeping_king_studios/tools/array_tools'
6
+
7
+ module RSpec::SleepingKingStudios::Matchers::Core
8
+ # Matcher for testing whether an object has a specific constant. Includes
9
+ # functionality for testing the value of the constant and whether the
10
+ # constant is immutable.
11
+ #
12
+ # @since 2.2.0
13
+ class HaveConstantMatcher < RSpec::SleepingKingStudios::Matchers::BaseMatcher
14
+ # @param [String, Symbol] expected The name of the constant to check for on
15
+ # the actual object.
16
+ def initialize expected
17
+ @expected = expected.intern
18
+ end # method initialize
19
+
20
+ # (see BaseMatcher#description)
21
+ def description
22
+ message =
23
+ "have #{@immutable ? 'immutable ' : ''}constant #{@expected.inspect}"
24
+
25
+ message << ' with value ' << value_to_string if @value_set
26
+
27
+ message
28
+ end # method description
29
+
30
+ # (see BaseMatcher#failure_message)
31
+ def failure_message
32
+ message = super
33
+
34
+ messages = []
35
+
36
+ if @errors[:does_not_define_constants]
37
+ message <<
38
+ ", but #{@actual.inspect} does not respond to ::const_defined?"
39
+
40
+ return message
41
+ end # if
42
+
43
+ if @errors[:constant_is_not_defined]
44
+ message <<
45
+ ", but #{@actual.inspect} does not define constant #{@expected.inspect}"
46
+
47
+ return message
48
+ end # if
49
+
50
+ if hsh = @errors[:value_does_not_match]
51
+ messages <<
52
+ "constant #{@expected.inspect} has value #{hsh[:received].inspect}"
53
+ end # if
54
+
55
+ if hsh = @errors[:value_is_mutable]
56
+ messages <<
57
+ "the value of #{@expected.inspect} was mutable"
58
+ end # if
59
+
60
+ unless messages.empty?
61
+ tools = ::SleepingKingStudios::Tools::ArrayTools
62
+
63
+ message << ', but ' << tools.humanize_list(messages)
64
+ end # unless
65
+
66
+ message
67
+ end # method failure_message
68
+
69
+ # (see BaseMatcher#failure_message_when_negated)
70
+ def failure_message_when_negated
71
+ message = super
72
+
73
+ message <<
74
+ ", but #{@actual.inspect} defines constant #{@expected.inspect} with "\
75
+ "value #{actual.const_get(@expected).inspect}"
76
+
77
+ message
78
+ end # method failure_message
79
+
80
+ # Checks if the object has a constant :expected. Additionally, if a
81
+ # value expectation is set, compares the value of #expected to the
82
+ # specified value and checks the mutability of the constant.
83
+ #
84
+ # @param [Object] actual The object to check.
85
+ #
86
+ # @return [Boolean] true If the object has a constant :expected and matches
87
+ # the value and mutability expectations (if any); otherwise false.
88
+ def matches? actual
89
+ super
90
+
91
+ @errors = {}
92
+
93
+ return false unless has_constant?
94
+
95
+ matches_constant? :all?
96
+ end # method matches?
97
+
98
+ # (see BaseMatcher#does_not_match?)
99
+ def does_not_match? actual
100
+ super
101
+
102
+ @errors = {}
103
+
104
+ !has_constant?
105
+ end # method does_not_match?
106
+
107
+ # Sets a mutability expectation. The matcher will determine whether the
108
+ # value of the constant is mutable. Values of `nil`, `false`, `true` are
109
+ # always immutable, as are `Numeric` and `Symbol` primitives. `Array`
110
+ # values must be frozen and all array items must be immutable. `Hash`
111
+ # values must be frozen and all hash keys and values must be immutable.
112
+ #
113
+ # @return [HaveConstantMatcher] self
114
+ def immutable
115
+ @immutable = true
116
+
117
+ self
118
+ end # method immutable
119
+
120
+ # @return [Boolean] True if a mutability expectation is set, otherwise
121
+ # false.
122
+ def immutable?
123
+ !!@immutable
124
+ end # method immutable
125
+
126
+ # Sets a value expectation. The matcher will compare the value of the
127
+ # constant with the specified value.
128
+ #
129
+ # @param [Object] value The value to compare.
130
+ #
131
+ # @return [HaveConstantMatcher] self
132
+ def with value
133
+ @value = value
134
+ @value_set = true
135
+ self
136
+ end # method with
137
+ alias_method :with_value, :with
138
+
139
+ private
140
+
141
+ def has_constant?
142
+ unless actual.respond_to?(:const_defined?)
143
+ @errors[:does_not_define_constants] = true
144
+
145
+ return false
146
+ end # unless
147
+
148
+ unless actual.const_defined?(@expected)
149
+ @errors[:constant_is_not_defined] = true
150
+
151
+ return false
152
+ end # unless
153
+
154
+ true
155
+ end # method has_constant?
156
+
157
+ def immutable_value?
158
+ return true unless @immutable
159
+
160
+ actual_value = actual.const_get(@expected)
161
+
162
+ if mutable?(actual_value)
163
+ @errors[:value_is_mutable] = true
164
+
165
+ return false
166
+ end # if
167
+
168
+ true
169
+ end # method immutable_value
170
+
171
+ def matches_constant? filter
172
+ [ matches_constant_value?,
173
+ immutable_value?
174
+ ].send(filter) { |bool| bool }
175
+ end # method matches_constant?
176
+
177
+ def matches_constant_value?
178
+ return true unless @value_set
179
+
180
+ actual_value = actual.const_get(@expected)
181
+ match = (@value.respond_to?(:matches?) && @value.respond_to?(:description)) ?
182
+ @value.matches?(actual_value) :
183
+ @value == actual_value
184
+
185
+ unless match
186
+ @errors[:value_does_not_match] = {
187
+ :expected => @value,
188
+ :received => actual_value
189
+ } # end hash
190
+
191
+ return false
192
+ end # unless
193
+
194
+ true
195
+ end # method matches_constant_value?
196
+
197
+ def mutable? value
198
+ case value
199
+ when nil, false, true, Numeric, Symbol
200
+ false
201
+ when Array
202
+ return true unless value.frozen?
203
+
204
+ value.reduce(false) { |memo, item| memo || mutable?(item) }
205
+ when Hash
206
+ return true unless value.frozen?
207
+
208
+ (value.keys + value.values).reduce(false) { |memo, item| memo || mutable?(item) }
209
+ else
210
+ !value.frozen?
211
+ end # case
212
+ end # method mutable?
213
+
214
+ # Formats the expected value as a human-readable string. If the value looks
215
+ # like an RSpec matcher (it responds to :matches? and :description), calls
216
+ # value#description; otherwise calls value#inspect.
217
+ #
218
+ # @return [String] the value as a human-readable string.
219
+ def value_to_string
220
+ return @value.description if @value.respond_to?(:matches?) && @value.respond_to?(:description)
221
+
222
+ @value.inspect
223
+ end # method value_to_string
224
+ end # class
225
+ end # module
@@ -0,0 +1,11 @@
1
+ # lib/rspec/sleeping_king_studios/matchers/core/have_predicate.rb
2
+
3
+ require 'rspec/sleeping_king_studios/matchers/core/have_predicate_matcher'
4
+ require 'rspec/sleeping_king_studios/matchers/macros'
5
+
6
+ module RSpec::SleepingKingStudios::Matchers::Macros
7
+ # @see RSpec::SleepingKingStudios::Matchers::Core::HavePredicateMatcher#matches?
8
+ def have_predicate expected
9
+ RSpec::SleepingKingStudios::Matchers::Core::HavePredicateMatcher.new expected
10
+ end # method have_reader
11
+ end # module
@@ -0,0 +1,97 @@
1
+ # lib/rspec/sleeping_king_studios/matchers/core/have_predicate_matcher.rb
2
+
3
+ require 'rspec/sleeping_king_studios/matchers/base_matcher'
4
+ require 'rspec/sleeping_king_studios/matchers/core'
5
+ require 'rspec/sleeping_king_studios/matchers/core/be_boolean_matcher'
6
+ require 'rspec/sleeping_king_studios/matchers/shared/match_property'
7
+
8
+ module RSpec::SleepingKingStudios::Matchers::Core
9
+ # Matcher for testing whether an object has a specific predicate, e.g.
10
+ # responds to :property?.
11
+ #
12
+ # @since 2.2.0
13
+ class HavePredicateMatcher < RSpec::SleepingKingStudios::Matchers::BaseMatcher
14
+ include RSpec::SleepingKingStudios::Matchers::Shared::MatchProperty
15
+
16
+ # Generates a description of the matcher expectation.
17
+ #
18
+ # @return [String] The matcher description.
19
+ def description
20
+ "have predicate :#{@expected}"
21
+ end # method description
22
+
23
+ # @param [String, Symbol] expected The predicate to check for on the actual
24
+ # object.
25
+ def initialize expected
26
+ @expected = expected.to_s.gsub(/\?$/, '').intern
27
+
28
+ apply_boolean_expectation if strict_matching?
29
+ end # method initialize
30
+
31
+ # Checks if the object responds to #expected?. Additionally, if a value
32
+ # expectation is set, compares the value of #expected to the specified
33
+ # value.
34
+ #
35
+ # @param [Object] actual The object to check.
36
+ #
37
+ # @return [Boolean] true If the object responds to #expected and matches
38
+ # the value expectation (if any); otherwise false.
39
+ def matches? actual
40
+ super
41
+
42
+ responds_to_predicate? && matches_predicate_value?
43
+ end # method matches?
44
+
45
+ # Sets a value expectation. The matcher will compare the value from
46
+ # #property? with the specified value.
47
+ #
48
+ # @param [Object] value The value to compare.
49
+ #
50
+ # @return [HaveReaderMatcher] self
51
+ def with_value value
52
+ if strict_matching? && !(value === true || value === false)
53
+ raise ArgumentError.new 'predicate must return true or false'
54
+ end # if
55
+
56
+ @value = value
57
+ @value_set = true
58
+ self
59
+ end # method with
60
+ alias_method :with, :with_value
61
+
62
+ # (see BaseMatcher#failure_message)
63
+ def failure_message
64
+ message = "expected #{@actual.inspect} to respond to :#{@expected}?"
65
+ message << " and return #{value_to_string}" if @value_set
66
+
67
+ if !@matches_predicate
68
+ message << ", but did not respond to :#{@expected}?"
69
+ elsif !@matches_predicate_value
70
+ message << ", but returned #{@actual.send(:"#{@expected}?").inspect}"
71
+ end # if-elsif
72
+
73
+ message
74
+ end # method failure_message
75
+
76
+ # (see BaseMatcher#failure_message_when_negated)
77
+ def failure_message_when_negated
78
+ message = "expected #{@actual.inspect} not to respond to :#{@expected}?"
79
+ message << " and return #{value_to_string}" if @value_set
80
+ message
81
+ end # method failure_message
82
+
83
+ private
84
+
85
+ def apply_boolean_expectation
86
+ matcher = BeBooleanMatcher.new
87
+ aliased = RSpec::Matchers::AliasedMatcher.new matcher, ->(str) { 'true or false' }
88
+
89
+ @value = aliased
90
+ @value_set = true
91
+ end # method apply_boolean_expectation
92
+
93
+ def strict_matching?
94
+ RSpec.configure { |config| config.sleeping_king_studios.matchers }.strict_predicate_matching
95
+ end # method strict_matching?
96
+ end # class
97
+ end # module
@@ -1,110 +1,9 @@
1
1
  # lib/rspec/sleeping_king_studios/matchers/core/have_property.rb
2
2
 
3
- require 'rspec/sleeping_king_studios/matchers/base_matcher'
4
- require 'rspec/sleeping_king_studios/matchers/core'
5
- require 'rspec/sleeping_king_studios/matchers/shared/match_property'
3
+ require 'rspec/sleeping_king_studios/matchers/core/have_property_matcher'
4
+ require 'rspec/sleeping_king_studios/matchers/macros'
6
5
 
7
- module RSpec::SleepingKingStudios::Matchers::Core
8
- # Matcher for testing whether an object has a specific property, e.g.
9
- # responds to #property and #property= and has the specified value for
10
- # #property.
11
- #
12
- # @since 1.0.0
13
- class HavePropertyMatcher < RSpec::SleepingKingStudios::Matchers::BaseMatcher
14
- include RSpec::SleepingKingStudios::Matchers::Shared::MatchProperty
15
-
16
- # (see BaseMatcher#description)
17
- def description
18
- value_message = value_to_string
19
- "have property :#{@expected}#{@value_set ? " with value #{value_message}" : ''}"
20
- end # method description
21
-
22
- # @param [String, Symbol] expected The property to check for on the actual
23
- # object.
24
- def initialize expected
25
- @expected = expected.intern
26
- end # method initialize
27
-
28
- # (see BaseMatcher#does_not_match?)
29
- def does_not_match? actual
30
- super
31
-
32
- matches_property?(:none?)
33
- end # method does_not_match?
34
-
35
- # Checks if the object responds to #expected and #expected=. Additionally,
36
- # if a value expectation is set, compares the result of calling :expected
37
- # to the value.
38
- #
39
- # @param [Object] actual The object to check.
40
- #
41
- # @return [Boolean] true If the object responds to #expected and
42
- # #expected= and matches the value expectation (if any); otherwise false.
43
- def matches? actual
44
- super
45
-
46
- matches_property?(:all?)
47
- end # method matches?
48
-
49
- # Sets a value expectation. The matcher will compare the value to the
50
- # result of calling #property.
51
- #
52
- # @param [Object] value The value to set and then compare.
53
- #
54
- # @return [HavePropertyMatcher] self
55
- def with value
56
- @value = value
57
- @value_set = true
58
- self
59
- end # method with
60
- alias_method :with_value, :with
61
-
62
- # (see BaseMatcher#failure_message)
63
- def failure_message
64
- methods = []
65
- methods << ":#{@expected}" unless @matches_reader
66
- methods << ":#{@expected}=" unless @matches_writer
67
-
68
- message = "expected #{@actual.inspect} to respond to :#{@expected} and :#{@expected}="
69
- message << " and return #{value_to_string}" if @value_set
70
-
71
- errors = []
72
- errors << "did not respond to #{methods.join " or "}" unless methods.empty?
73
- errors << "returned #{@actual.send(@expected).inspect}" unless @matches_reader_value || !@value_set
74
-
75
- message << ", but #{errors.join(" and ")}"
76
- message
77
- end # failure_message
78
-
79
- # (see BaseMatcher#failure_message_when_negated)
80
- def failure_message_when_negated
81
- methods = []
82
- methods << ":#{@expected}" if @matches_reader
83
- methods << ":#{@expected}=" if @matches_writer
84
-
85
- message = "expected #{@actual.inspect} not to respond to :#{@expected} or :#{@expected}="
86
- message << " and return #{value_to_string}" if @value_set
87
-
88
- errors = []
89
- errors << "responded to #{methods.join " and "}" unless methods.empty?
90
- errors << "returned #{@actual.send(@expected).inspect}" if @matches_reader_value
91
-
92
- message << ", but #{errors.join(" and ")}"
93
- message
94
- end # failure_message_when_negated
95
-
96
- private
97
-
98
- def matches_property? filter
99
- [ responds_to_reader?,
100
- responds_to_writer?,
101
- matches_reader_value?
102
- ].send(filter) { |bool| bool }
103
- end # method matches_property?
104
- end # class
105
- end # module
106
-
107
- module RSpec::SleepingKingStudios::Matchers
6
+ module RSpec::SleepingKingStudios::Matchers::Macros
108
7
  # @see RSpec::SleepingKingStudios::Matchers::Core::HavePropertyMatcher#matches?
109
8
  def have_property expected
110
9
  RSpec::SleepingKingStudios::Matchers::Core::HavePropertyMatcher.new expected
@@ -0,0 +1,108 @@
1
+ # lib/rspec/sleeping_king_studios/matchers/core/have_property_matcher.rb
2
+
3
+ require 'rspec/sleeping_king_studios/matchers/base_matcher'
4
+ require 'rspec/sleeping_king_studios/matchers/core'
5
+ require 'rspec/sleeping_king_studios/matchers/shared/match_property'
6
+
7
+ module RSpec::SleepingKingStudios::Matchers::Core
8
+ # Matcher for testing whether an object has a specific property, e.g.
9
+ # responds to #property and #property= and has the specified value for
10
+ # #property.
11
+ #
12
+ # @since 1.0.0
13
+ class HavePropertyMatcher < RSpec::SleepingKingStudios::Matchers::BaseMatcher
14
+ include RSpec::SleepingKingStudios::Matchers::Shared::MatchProperty
15
+
16
+ # (see BaseMatcher#description)
17
+ def description
18
+ value_message = value_to_string
19
+ "have property :#{@expected}#{@value_set ? " with value #{value_message}" : ''}"
20
+ end # method description
21
+
22
+ # @param [String, Symbol] expected The property to check for on the actual
23
+ # object.
24
+ def initialize expected
25
+ @expected = expected.intern
26
+ end # method initialize
27
+
28
+ # (see BaseMatcher#does_not_match?)
29
+ def does_not_match? actual
30
+ super
31
+
32
+ matches_property?(:none?)
33
+ end # method does_not_match?
34
+
35
+ # Checks if the object responds to #expected and #expected=. Additionally,
36
+ # if a value expectation is set, compares the result of calling :expected
37
+ # to the value.
38
+ #
39
+ # @param [Object] actual The object to check.
40
+ #
41
+ # @return [Boolean] true If the object responds to #expected and
42
+ # #expected= and matches the value expectation (if any); otherwise false.
43
+ def matches? actual
44
+ super
45
+
46
+ matches_property?(:all?)
47
+ end # method matches?
48
+
49
+ # Sets a value expectation. The matcher will compare the value to the
50
+ # result of calling #property.
51
+ #
52
+ # @param [Object] value The value to set and then compare.
53
+ #
54
+ # @return [HavePropertyMatcher] self
55
+ def with value
56
+ @value = value
57
+ @value_set = true
58
+ self
59
+ end # method with
60
+ alias_method :with_value, :with
61
+
62
+ # (see BaseMatcher#failure_message)
63
+ def failure_message
64
+ methods = []
65
+ methods << ":#{@expected}" unless @matches_reader
66
+ methods << ":#{@expected}=" unless @matches_writer
67
+
68
+ message = "expected #{@actual.inspect} to respond to :#{@expected} and :#{@expected}="
69
+ message << " and return #{value_to_string}" if @value_set
70
+
71
+ errors = []
72
+ errors << "did not respond to #{methods.join " or "}" unless methods.empty?
73
+
74
+ if @matches_reader
75
+ errors << "returned #{@actual.send(@expected).inspect}" unless @matches_reader_value || !@value_set
76
+ end # if
77
+
78
+ message << ", but #{errors.join(" and ")}"
79
+ message
80
+ end # failure_message
81
+
82
+ # (see BaseMatcher#failure_message_when_negated)
83
+ def failure_message_when_negated
84
+ methods = []
85
+ methods << ":#{@expected}" if @matches_reader
86
+ methods << ":#{@expected}=" if @matches_writer
87
+
88
+ message = "expected #{@actual.inspect} not to respond to :#{@expected} or :#{@expected}="
89
+ message << " and return #{value_to_string}" if @value_set
90
+
91
+ errors = []
92
+ errors << "responded to #{methods.join " and "}" unless methods.empty?
93
+ errors << "returned #{@actual.send(@expected).inspect}" if @matches_reader_value
94
+
95
+ message << ", but #{errors.join(" and ")}"
96
+ message
97
+ end # failure_message_when_negated
98
+
99
+ private
100
+
101
+ def matches_property? filter
102
+ [ responds_to_reader?,
103
+ responds_to_writer?,
104
+ matches_reader_value?
105
+ ].send(filter) { |bool| bool }
106
+ end # method matches_property?
107
+ end # class
108
+ end # module
@@ -1,80 +1,9 @@
1
1
  # lib/rspec/sleeping_king_studios/matchers/core/have_reader.rb
2
2
 
3
- require 'rspec/sleeping_king_studios/matchers/base_matcher'
4
- require 'rspec/sleeping_king_studios/matchers/core'
5
- require 'rspec/sleeping_king_studios/matchers/shared/match_property'
3
+ require 'rspec/sleeping_king_studios/matchers/core/have_reader_matcher'
4
+ require 'rspec/sleeping_king_studios/matchers/macros'
6
5
 
7
- module RSpec::SleepingKingStudios::Matchers::Core
8
- # Matcher for testing whether an object has a specific property reader, e.g.
9
- # responds to :property.
10
- #
11
- # @since 1.0.0
12
- class HaveReaderMatcher < RSpec::SleepingKingStudios::Matchers::BaseMatcher
13
- include RSpec::SleepingKingStudios::Matchers::Shared::MatchProperty
14
-
15
- # (see BaseMatcher#description)
16
- def description
17
- value_message = value_to_string
18
- "have reader :#{@expected}#{@value_set ? " with value #{value_message}" : ''}"
19
- end # method description
20
-
21
- # @param [String, Symbol] expected The property to check for on the actual
22
- # object.
23
- def initialize expected
24
- @expected = expected.intern
25
- end # method initialize
26
-
27
- # Checks if the object responds to #expected. Additionally, if a value
28
- # expectation is set, compares the value of #expected to the specified
29
- # value.
30
- #
31
- # @param [Object] actual The object to check.
32
- #
33
- # @return [Boolean] true If the object responds to #expected and matches
34
- # the value expectation (if any); otherwise false.
35
- def matches? actual
36
- super
37
-
38
- responds_to_reader? && matches_reader_value?
39
- end # method matches?
40
-
41
- # Sets a value expectation. The matcher will compare the value from
42
- # #property with the specified value.
43
- #
44
- # @param [Object] value The value to compare.
45
- #
46
- # @return [HaveReaderMatcher] self
47
- def with value
48
- @value = value
49
- @value_set = true
50
- self
51
- end # method with
52
- alias_method :with_value, :with
53
-
54
- # (see BaseMatcher#failure_message)
55
- def failure_message
56
- message = "expected #{@actual.inspect} to respond to :#{@expected}"
57
- message << " and return #{value_to_string}" if @value_set
58
-
59
- if !@matches_reader
60
- message << ", but did not respond to :#{@expected}"
61
- elsif !@matches_reader_value
62
- message << ", but returned #{@actual.send(@expected).inspect}"
63
- end # if
64
-
65
- message
66
- end # method failure_message
67
-
68
- # (see BaseMatcher#failure_message_when_negated)
69
- def failure_message_when_negated
70
- message = "expected #{@actual.inspect} not to respond to :#{@expected}"
71
- message << " and return #{value_to_string}" if @value_set
72
- message
73
- end # method failure_message
74
- end # class
75
- end # module
76
-
77
- module RSpec::SleepingKingStudios::Matchers
6
+ module RSpec::SleepingKingStudios::Matchers::Macros
78
7
  # @see RSpec::SleepingKingStudios::Matchers::Core::HaveReaderMatcher#matches?
79
8
  def have_reader expected
80
9
  RSpec::SleepingKingStudios::Matchers::Core::HaveReaderMatcher.new expected