rspec-sleeping_king_studios 2.0.0.beta.0 → 2.0.0.beta.1
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 +4 -4
- data/CHANGELOG.md +84 -13
- data/DEVELOPMENT.md +16 -0
- data/README.md +203 -100
- data/lib/rspec/sleeping_king_studios/all.rb +4 -0
- data/lib/rspec/sleeping_king_studios/configuration.rb +42 -0
- data/lib/rspec/sleeping_king_studios/examples/all.rb +5 -0
- data/lib/rspec/sleeping_king_studios/examples/property_examples.rb +58 -0
- data/lib/rspec/sleeping_king_studios/examples/rspec_matcher_examples.rb +105 -0
- data/lib/rspec/sleeping_king_studios/examples/shared_example_group.rb +62 -0
- data/lib/rspec/sleeping_king_studios/examples.rb +8 -0
- data/lib/rspec/sleeping_king_studios/matchers/active_model/all.rb +5 -0
- data/lib/rspec/sleeping_king_studios/matchers/active_model/have_errors/error_expectation.rb +0 -1
- data/lib/rspec/sleeping_king_studios/matchers/active_model/have_errors/message_expectation.rb +1 -2
- data/lib/rspec/sleeping_king_studios/matchers/active_model/have_errors.rb +75 -24
- data/lib/rspec/sleeping_king_studios/matchers/active_model.rb +6 -3
- data/lib/rspec/sleeping_king_studios/matchers/all.rb +5 -0
- data/lib/rspec/sleeping_king_studios/matchers/base_matcher.rb +20 -1
- data/lib/rspec/sleeping_king_studios/matchers/built_in/all.rb +5 -0
- data/lib/rspec/sleeping_king_studios/matchers/built_in/be_kind_of.rb +16 -10
- data/lib/rspec/sleeping_king_studios/matchers/built_in/include.rb +14 -9
- data/lib/rspec/sleeping_king_studios/matchers/built_in/respond_to.rb +45 -31
- data/lib/rspec/sleeping_king_studios/matchers/built_in.rb +5 -3
- data/lib/rspec/sleeping_king_studios/matchers/core/all.rb +5 -0
- data/lib/rspec/sleeping_king_studios/matchers/core/be_boolean.rb +11 -4
- data/lib/rspec/sleeping_king_studios/matchers/core/construct.rb +56 -32
- data/lib/rspec/sleeping_king_studios/matchers/core/have_property.rb +59 -29
- data/lib/rspec/sleeping_king_studios/matchers/core/have_reader.rb +31 -22
- data/lib/rspec/sleeping_king_studios/matchers/core/have_writer.rb +21 -55
- data/lib/rspec/sleeping_king_studios/matchers/core.rb +5 -3
- data/lib/rspec/sleeping_king_studios/matchers/shared/match_parameters.rb +1 -3
- data/lib/rspec/sleeping_king_studios/matchers/shared/match_property.rb +52 -0
- data/lib/rspec/sleeping_king_studios/matchers.rb +10 -3
- data/lib/rspec/sleeping_king_studios/version.rb +22 -1
- data/lib/rspec/sleeping_king_studios.rb +7 -1
- metadata +38 -16
- data/lib/rspec/sleeping_king_studios/matchers/active_model/have_errors/require.rb +0 -7
- data/lib/rspec/sleeping_king_studios/matchers/active_model/require.rb +0 -8
- data/lib/rspec/sleeping_king_studios/matchers/built_in/require.rb +0 -7
- data/lib/rspec/sleeping_king_studios/matchers/core/require.rb +0 -7
- data/lib/rspec/sleeping_king_studios/matchers/meta/fail_with_actual.rb +0 -107
- data/lib/rspec/sleeping_king_studios/matchers/meta/pass_with_actual.rb +0 -95
- data/lib/rspec/sleeping_king_studios/matchers/meta/require.rb +0 -7
- data/lib/rspec/sleeping_king_studios/matchers/meta.rb +0 -5
- data/lib/rspec/sleeping_king_studios/matchers/require.rb +0 -12
- data/lib/rspec/sleeping_king_studios/matchers/shared/require.rb +0 -7
- data/lib/rspec/sleeping_king_studios/require.rb +0 -7
@@ -1,46 +1,65 @@
|
|
1
1
|
# lib/rspec/sleeping_king_studios/matchers/built_in/respond_to.rb
|
2
2
|
|
3
3
|
require 'rspec/sleeping_king_studios/matchers/base_matcher'
|
4
|
-
require 'rspec/sleeping_king_studios/matchers/built_in
|
4
|
+
require 'rspec/sleeping_king_studios/matchers/built_in'
|
5
5
|
require 'rspec/sleeping_king_studios/matchers/shared/match_parameters'
|
6
|
+
require 'sleeping_king_studios/tools/enumerable_tools'
|
7
|
+
require 'sleeping_king_studios/tools/string_tools'
|
6
8
|
|
7
9
|
module RSpec::SleepingKingStudios::Matchers::BuiltIn
|
8
10
|
class RespondToMatcher < RSpec::Matchers::BuiltIn::RespondTo
|
9
11
|
include RSpec::SleepingKingStudios::Matchers::Shared::MatchParameters
|
12
|
+
include SleepingKingStudios::Tools::EnumerableTools
|
13
|
+
include SleepingKingStudios::Tools::StringTools
|
14
|
+
|
15
|
+
def initialize *expected
|
16
|
+
@include_all = [true, false].include?(expected.last) ? expected.pop : false
|
17
|
+
|
18
|
+
super(*expected)
|
19
|
+
end # constructor
|
20
|
+
|
21
|
+
# Generates a description of the matcher expectation.
|
22
|
+
#
|
23
|
+
# @return [String] The matcher description.
|
24
|
+
def description
|
25
|
+
expected_message = format_expected_arguments
|
26
|
+
"respond to #{pp_names}#{expected_message.empty? ? '' : " with #{expected_message}"}"
|
27
|
+
end # method description
|
10
28
|
|
11
29
|
# @overload with count
|
12
30
|
# Adds a parameter count expectation.
|
13
|
-
#
|
31
|
+
#
|
14
32
|
# @param [Integer, Range, nil] count (optional) The number of expected
|
15
33
|
# parameters.
|
16
|
-
#
|
34
|
+
#
|
17
35
|
# @return [RespondToMatcher] self
|
18
36
|
# @overload with *keywords
|
19
37
|
# Adds one or more keyword expectations (Ruby 2.0 only).
|
20
|
-
#
|
38
|
+
#
|
21
39
|
# @param [Array<String, Symbol>] keywords List of keyword arguments
|
22
40
|
# accepted by the method.
|
23
|
-
#
|
41
|
+
#
|
24
42
|
# @return [RespondToMatcher] self
|
25
43
|
# @overload with count, *keywords
|
26
44
|
# Adds a parameter count expectation and one or more keyword
|
27
45
|
# expectations (Ruby 2.0 only).
|
28
|
-
#
|
46
|
+
#
|
29
47
|
# @param [Integer, Range, nil] count (optional) The number of expected
|
30
48
|
# parameters.
|
31
49
|
# @param [Array<String, Symbol>] keywords List of keyword arguments
|
32
50
|
# accepted by the method.
|
33
|
-
#
|
51
|
+
#
|
34
52
|
# @return [RespondToMatcher] self
|
35
53
|
def with *keywords
|
36
54
|
@expected_arity = keywords.shift if Integer === keywords.first || Range === keywords.first
|
37
55
|
@expected_keywords = keywords
|
56
|
+
|
38
57
|
self
|
39
58
|
end # method with
|
40
59
|
|
41
60
|
# Adds a block expectation. The actual object will only match a block
|
42
61
|
# expectation if it expects a parameter of the form &block.
|
43
|
-
#
|
62
|
+
#
|
44
63
|
# @return [RespondToMatcher] self
|
45
64
|
def with_a_block
|
46
65
|
@expected_block = true
|
@@ -50,30 +69,32 @@ module RSpec::SleepingKingStudios::Matchers::BuiltIn
|
|
50
69
|
# @see BaseMatcher#failure_message
|
51
70
|
def failure_message
|
52
71
|
@failing_method_names ||= []
|
53
|
-
methods, messages = @
|
72
|
+
methods, messages = @failing_method_names, []
|
54
73
|
|
55
74
|
methods.map do |method|
|
56
75
|
message = "expected #{@actual.inspect} to respond to #{method.inspect}"
|
57
|
-
if @actual.respond_to?(method)
|
76
|
+
if @actual.respond_to?(method, @include_all)
|
58
77
|
message << " with arguments:\n#{format_errors_for_method method}"
|
59
78
|
end # if-else
|
60
79
|
messages << message
|
61
80
|
end # method
|
81
|
+
|
62
82
|
messages.join "\n"
|
63
83
|
end # method failure_message
|
64
84
|
|
65
85
|
# @see BaseMatcher#failure_message_when_negated
|
66
86
|
def failure_message_when_negated
|
67
87
|
@failing_method_names ||= []
|
68
|
-
methods, messages = @
|
88
|
+
methods, messages = @failing_method_names, []
|
69
89
|
|
70
90
|
methods.map do |method|
|
71
|
-
message
|
91
|
+
message = "expected #{@actual.inspect} not to respond to #{method.inspect}"
|
72
92
|
unless (formatted = format_expected_arguments).empty?
|
73
93
|
message << " with #{formatted}"
|
74
94
|
end # unless
|
75
95
|
messages << message
|
76
96
|
end # method
|
97
|
+
|
77
98
|
messages.join "\n"
|
78
99
|
end # method failure_message_when_negated
|
79
100
|
|
@@ -83,7 +104,7 @@ module RSpec::SleepingKingStudios::Matchers::BuiltIn
|
|
83
104
|
@actual = actual
|
84
105
|
@failing_method_reasons = {}
|
85
106
|
@failing_method_names = @names.__send__(filter_method) do |name|
|
86
|
-
@actual.respond_to?(name) &&
|
107
|
+
@actual.respond_to?(name, @include_all) &&
|
87
108
|
matches_arity?(actual, name) &&
|
88
109
|
matches_keywords?(actual, name) &&
|
89
110
|
matches_block?(actual, name)
|
@@ -121,7 +142,7 @@ module RSpec::SleepingKingStudios::Matchers::BuiltIn
|
|
121
142
|
raise error
|
122
143
|
end # if-else
|
123
144
|
end # method matches_keywords?
|
124
|
-
|
145
|
+
|
125
146
|
def matches_block? actual, name
|
126
147
|
return true unless @expected_block
|
127
148
|
|
@@ -135,32 +156,25 @@ module RSpec::SleepingKingStudios::Matchers::BuiltIn
|
|
135
156
|
|
136
157
|
def format_expected_arguments
|
137
158
|
messages = []
|
138
|
-
|
159
|
+
|
139
160
|
if !@expected_arity.nil?
|
140
|
-
messages << "#{@expected_arity.inspect}
|
161
|
+
messages << "#{@expected_arity.inspect} #{pluralize @expected_arity, 'argument', 'arguments'}"
|
141
162
|
end # if
|
142
163
|
|
143
164
|
if !(@expected_keywords.nil? || @expected_keywords.empty?)
|
144
|
-
messages << "keywords #{@expected_keywords.map(&:inspect)
|
165
|
+
messages << "#{pluralize @expected_keywords.count, 'keyword', 'keywords'} #{humanize_list @expected_keywords.map(&:inspect)}"
|
145
166
|
end # if
|
146
167
|
|
147
168
|
if @expected_block
|
148
169
|
messages << "a block"
|
149
170
|
end # if
|
150
171
|
|
151
|
-
|
152
|
-
when 0..1
|
153
|
-
messages.join(", ")
|
154
|
-
when 2
|
155
|
-
"#{messages[0]} and #{messages[1]}"
|
156
|
-
else
|
157
|
-
"#{messages[1..-1].join(", ")}, and #{messages[0]}"
|
158
|
-
end # case
|
172
|
+
humanize_list messages
|
159
173
|
end # method format_expected_arguments
|
160
174
|
|
161
175
|
def format_errors_for_method method
|
162
176
|
reasons, messages = @failing_method_reasons[method], []
|
163
|
-
|
177
|
+
|
164
178
|
if hsh = reasons.fetch(:not_enough_args, false)
|
165
179
|
messages << " expected at least #{hsh[:count]} arguments, but received #{hsh[:arity]}"
|
166
180
|
elsif hsh = reasons.fetch(:too_many_args, false)
|
@@ -168,11 +182,11 @@ module RSpec::SleepingKingStudios::Matchers::BuiltIn
|
|
168
182
|
end # if-elsif
|
169
183
|
|
170
184
|
if ary = reasons.fetch(:missing_keywords, false)
|
171
|
-
messages << " missing keywords #{ary.map(&:inspect)
|
185
|
+
messages << " missing #{pluralize ary.count, 'keyword', 'keywords'} #{humanize_list ary.map(&:inspect)}"
|
172
186
|
end # if
|
173
187
|
|
174
188
|
if ary = reasons.fetch(:unexpected_keywords, false)
|
175
|
-
messages << " unexpected keywords #{ary.map(&:inspect)
|
189
|
+
messages << " unexpected #{pluralize ary.count, 'keyword', 'keywords'} #{humanize_list ary.map(&:inspect)}"
|
176
190
|
end # if
|
177
191
|
|
178
192
|
if reasons.fetch(:expected_block, false)
|
@@ -180,13 +194,13 @@ module RSpec::SleepingKingStudios::Matchers::BuiltIn
|
|
180
194
|
end # if
|
181
195
|
|
182
196
|
messages.join "\n"
|
183
|
-
end # method format_errors_for_method
|
197
|
+
end # method format_errors_for_method
|
184
198
|
end # class
|
185
199
|
end # module
|
186
200
|
|
187
201
|
module RSpec::SleepingKingStudios::Matchers
|
188
202
|
# @see RSpec::SleepingKingStudios::Matchers::BuiltIn::RespondToMatcher#matches?
|
189
|
-
def respond_to expected
|
190
|
-
RSpec::SleepingKingStudios::Matchers::BuiltIn::RespondToMatcher.new expected
|
203
|
+
def respond_to *expected
|
204
|
+
RSpec::SleepingKingStudios::Matchers::BuiltIn::RespondToMatcher.new *expected
|
191
205
|
end # method respond_to
|
192
206
|
end # module
|
@@ -1,5 +1,7 @@
|
|
1
1
|
# lib/rspec/sleeping_king_studios/matchers/built_in.rb
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
3
|
+
require 'rspec/sleeping_king_studios/matchers'
|
4
|
+
|
5
|
+
module RSpec::SleepingKingStudios::Matchers
|
6
|
+
module BuiltIn; end
|
7
|
+
end # module
|
@@ -1,17 +1,24 @@
|
|
1
1
|
# lib/rspec/sleeping_king_studios/matchers/core/be_boolean.rb
|
2
2
|
|
3
3
|
require 'rspec/sleeping_king_studios/matchers/base_matcher'
|
4
|
-
require 'rspec/sleeping_king_studios/matchers/core
|
4
|
+
require 'rspec/sleeping_king_studios/matchers/core'
|
5
5
|
|
6
6
|
module RSpec::SleepingKingStudios::Matchers::Core
|
7
7
|
# Matcher for testing whether an object is true or false.
|
8
|
-
#
|
8
|
+
#
|
9
9
|
# @since 1.0.0
|
10
10
|
class BeBooleanMatcher < RSpec::SleepingKingStudios::Matchers::BaseMatcher
|
11
|
+
# Generates a description of the matcher expectation.
|
12
|
+
#
|
13
|
+
# @return [String] The matcher description.
|
14
|
+
def description
|
15
|
+
'be true or false'
|
16
|
+
end # method description
|
17
|
+
|
11
18
|
# Checks if the object is true or false.
|
12
|
-
#
|
19
|
+
#
|
13
20
|
# @param [Object] actual the object to check
|
14
|
-
#
|
21
|
+
#
|
15
22
|
# @return [Boolean] true if the object is true or false, otherwise false
|
16
23
|
def matches? actual
|
17
24
|
super
|
@@ -1,24 +1,35 @@
|
|
1
1
|
# spec/rspec/sleeping_king_studios/matchers/core/construct.rb
|
2
2
|
|
3
3
|
require 'rspec/sleeping_king_studios/matchers/base_matcher'
|
4
|
-
require 'rspec/sleeping_king_studios/matchers/core
|
5
|
-
|
4
|
+
require 'rspec/sleeping_king_studios/matchers/core'
|
6
5
|
require 'rspec/sleeping_king_studios/matchers/shared/match_parameters'
|
6
|
+
require 'sleeping_king_studios/tools/enumerable_tools'
|
7
|
+
require 'sleeping_king_studios/tools/string_tools'
|
7
8
|
|
8
9
|
module RSpec::SleepingKingStudios::Matchers::Core
|
9
10
|
# Matcher for checking whether an object can be constructed via #new and
|
10
11
|
# #initialize, and the parameters accepted by #initialize.
|
11
|
-
#
|
12
|
+
#
|
12
13
|
# @since 1.0.0
|
13
14
|
class ConstructMatcher < RSpec::SleepingKingStudios::Matchers::BaseMatcher
|
14
15
|
include RSpec::SleepingKingStudios::Matchers::Shared::MatchParameters
|
16
|
+
include SleepingKingStudios::Tools::EnumerableTools
|
17
|
+
include SleepingKingStudios::Tools::StringTools
|
18
|
+
|
19
|
+
# Generates a description of the matcher expectation.
|
20
|
+
#
|
21
|
+
# @return [String] The matcher description.
|
22
|
+
def description
|
23
|
+
expected_message = format_expected_arguments
|
24
|
+
"construct#{expected_message.empty? ? '' : " with #{expected_message}"}"
|
25
|
+
end # method description
|
15
26
|
|
16
27
|
# Checks if the object responds to :new. If so, allocates an instance and
|
17
28
|
# checks the parameters expected by #initialize against the expected
|
18
29
|
# parameters, if any.
|
19
|
-
#
|
30
|
+
#
|
20
31
|
# @param [Object] actual the object to check
|
21
|
-
#
|
32
|
+
#
|
22
33
|
# @return [Boolean] true if the object responds to :new and accepts the
|
23
34
|
# specified parameters for #initialize; otherwise false
|
24
35
|
def matches? actual
|
@@ -28,16 +39,33 @@ module RSpec::SleepingKingStudios::Matchers::Core
|
|
28
39
|
matches_arity?(actual) &&
|
29
40
|
matches_keywords?(actual)
|
30
41
|
end # method matches?
|
31
|
-
|
32
|
-
#
|
33
|
-
#
|
34
|
-
#
|
35
|
-
#
|
36
|
-
#
|
37
|
-
#
|
38
|
-
#
|
39
|
-
#
|
40
|
-
# @
|
42
|
+
|
43
|
+
# @overload with(count)
|
44
|
+
# Adds a parameter count expectation and removes any keyword expectations
|
45
|
+
# (Ruby 2.0+ only).
|
46
|
+
#
|
47
|
+
# @param [Integer, Range] count the number of expected parameters
|
48
|
+
#
|
49
|
+
# @return [ConstructMatcher] self
|
50
|
+
#
|
51
|
+
# @overload with(count, *keywords)
|
52
|
+
# Adds a parameter count expectation and one or more keyword expectations
|
53
|
+
# (Ruby 2.0 only).
|
54
|
+
#
|
55
|
+
# @param [Integer, Range] count the number of expected parameters
|
56
|
+
# @param [Array<String, Symbol>] keywords list of keyword arguments
|
57
|
+
# accepted by the method
|
58
|
+
#
|
59
|
+
# @return [ConstructMatcher] self
|
60
|
+
#
|
61
|
+
# @overload with(*keywords)
|
62
|
+
# Removes a parameter count expectation (if any) and adds one or more
|
63
|
+
# keyword expectations (Ruby 2.0 only).
|
64
|
+
#
|
65
|
+
# @param [Array<String, Symbol>] keywords list of keyword arguments
|
66
|
+
# accepted by the method
|
67
|
+
#
|
68
|
+
# @return [ConstructMatcher] self
|
41
69
|
def with *keywords
|
42
70
|
@expected_arity = keywords.shift if Integer === keywords.first || Range === keywords.first
|
43
71
|
@expected_keywords = keywords
|
@@ -45,11 +73,14 @@ module RSpec::SleepingKingStudios::Matchers::Core
|
|
45
73
|
end # method with
|
46
74
|
|
47
75
|
# Convenience method for more fluent specs. Does nothing and returns self.
|
48
|
-
#
|
76
|
+
#
|
49
77
|
# @return [ConstructMatcher] self
|
50
|
-
|
78
|
+
#
|
79
|
+
# @since 2.0.0
|
80
|
+
def argument
|
51
81
|
self
|
52
|
-
end # method
|
82
|
+
end # method argument
|
83
|
+
alias_method :arguments, :argument
|
53
84
|
|
54
85
|
# @see BaseMatcher#failure_message
|
55
86
|
def failure_message
|
@@ -62,7 +93,7 @@ module RSpec::SleepingKingStudios::Matchers::Core
|
|
62
93
|
def failure_message_when_negated
|
63
94
|
message = "expected #{@actual.inspect} not to construct"
|
64
95
|
unless (formatted = format_expected_arguments).empty?
|
65
|
-
message << " with #{formatted}"
|
96
|
+
message << " with #{formatted}"
|
66
97
|
end # unless
|
67
98
|
message
|
68
99
|
end # method failure_message_when_negated
|
@@ -71,7 +102,7 @@ module RSpec::SleepingKingStudios::Matchers::Core
|
|
71
102
|
|
72
103
|
def matches_arity? actual
|
73
104
|
return true unless @expected_arity
|
74
|
-
|
105
|
+
|
75
106
|
if result = check_method_arity(actual.allocate.method(:initialize), @expected_arity)
|
76
107
|
@failing_method_reasons.update result
|
77
108
|
return false
|
@@ -100,22 +131,15 @@ module RSpec::SleepingKingStudios::Matchers::Core
|
|
100
131
|
end # if
|
101
132
|
|
102
133
|
if !(@expected_keywords.nil? || @expected_keywords.empty?)
|
103
|
-
messages << "keywords #{@expected_keywords.map(&:inspect)
|
134
|
+
messages << "#{pluralize @expected_keywords.count, 'keyword', 'keywords'} #{humanize_list @expected_keywords.map(&:inspect)}"
|
104
135
|
end # if
|
105
136
|
|
106
|
-
|
107
|
-
when 0..1
|
108
|
-
messages.join(", ")
|
109
|
-
when 2
|
110
|
-
"#{messages[0]} and #{messages[1]}"
|
111
|
-
else
|
112
|
-
"#{messages[1..-1].join(", ")}, and #{messages[0]}"
|
113
|
-
end # case
|
137
|
+
humanize_list messages
|
114
138
|
end # method format_expected_arguments
|
115
139
|
|
116
140
|
def format_errors
|
117
141
|
reasons, messages = @failing_method_reasons, []
|
118
|
-
|
142
|
+
|
119
143
|
if hsh = reasons.fetch(:not_enough_args, false)
|
120
144
|
messages << " expected at least #{hsh[:count]} arguments, but received #{hsh[:arity]}"
|
121
145
|
elsif hsh = reasons.fetch(:too_many_args, false)
|
@@ -123,11 +147,11 @@ module RSpec::SleepingKingStudios::Matchers::Core
|
|
123
147
|
end # if-elsif
|
124
148
|
|
125
149
|
if ary = reasons.fetch(:missing_keywords, false)
|
126
|
-
messages << " missing keywords #{ary.map(&:inspect)
|
150
|
+
messages << " missing #{pluralize ary.count, 'keyword', 'keywords'} #{humanize_list ary.map(&:inspect)}"
|
127
151
|
end # if
|
128
152
|
|
129
153
|
if ary = reasons.fetch(:unexpected_keywords, false)
|
130
|
-
messages << " unexpected keywords #{ary.map(&:inspect)
|
154
|
+
messages << " unexpected #{pluralize ary.count, 'keyword', 'keywords'} #{humanize_list ary.map(&:inspect)}"
|
131
155
|
end # if
|
132
156
|
|
133
157
|
messages.join "\n"
|
@@ -1,77 +1,107 @@
|
|
1
1
|
# lib/rspec/sleeping_king_studios/matchers/core/have_property.rb
|
2
2
|
|
3
3
|
require 'rspec/sleeping_king_studios/matchers/base_matcher'
|
4
|
-
require 'rspec/sleeping_king_studios/matchers/core
|
4
|
+
require 'rspec/sleeping_king_studios/matchers/core'
|
5
|
+
require 'rspec/sleeping_king_studios/matchers/shared/match_property'
|
5
6
|
|
6
7
|
module RSpec::SleepingKingStudios::Matchers::Core
|
7
8
|
# Matcher for testing whether an object has a specific property, e.g.
|
8
9
|
# responds to :property and :property= and :property= updates the value of
|
9
10
|
# :property.
|
10
|
-
#
|
11
|
+
#
|
11
12
|
# @since 1.0.0
|
12
13
|
class HavePropertyMatcher < 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
|
+
value_message = value_to_string
|
21
|
+
"have property :#{@expected}#{@value_set ? " with value #{value_message}" : ''}"
|
22
|
+
end # method description
|
23
|
+
|
13
24
|
# @param [String, Symbol] expected the property to check for on the actual
|
14
25
|
# object
|
15
26
|
def initialize expected
|
16
27
|
@expected = expected.intern
|
17
28
|
end # method initialize
|
18
29
|
|
30
|
+
def does_not_match? actual
|
31
|
+
super
|
32
|
+
|
33
|
+
matches_property?(:none?)
|
34
|
+
end # method does_not_match?
|
35
|
+
|
19
36
|
# Checks if the object responds to :expected and :expected=. Additionally,
|
20
|
-
# if a value expectation is set,
|
21
|
-
#
|
22
|
-
#
|
37
|
+
# if a value expectation is set, compares the result of calling :expected
|
38
|
+
# to the value.
|
39
|
+
#
|
23
40
|
# @param [Object] actual the object to check
|
24
|
-
#
|
41
|
+
#
|
25
42
|
# @return [Boolean] true if the object responds to :expected and
|
26
43
|
# :expected= and matches the value expectation (if any); otherwise false
|
27
44
|
def matches? actual
|
28
45
|
super
|
29
46
|
|
30
|
-
|
31
|
-
@match_writer = @actual.respond_to? :"#{@expected}="
|
32
|
-
|
33
|
-
return false unless @match_reader && @match_writer
|
34
|
-
|
35
|
-
if @value_set
|
36
|
-
@actual.send :"#{@expected}=", @value
|
37
|
-
return false unless @actual.send(@expected) == @value
|
38
|
-
end # if
|
39
|
-
|
40
|
-
true
|
47
|
+
matches_property?(:all?)
|
41
48
|
end # method matches?
|
42
49
|
|
43
|
-
# Sets a value expectation. The matcher will
|
44
|
-
#
|
45
|
-
#
|
46
|
-
#
|
50
|
+
# Sets a value expectation. The matcher will compare the value to the
|
51
|
+
# result of calling :property.
|
52
|
+
#
|
47
53
|
# @param [Object] value the value to set and then compare
|
48
|
-
#
|
54
|
+
#
|
49
55
|
# @return [HavePropertyMatcher] self
|
50
56
|
def with value
|
51
57
|
@value = value
|
52
58
|
@value_set = true
|
53
59
|
self
|
54
60
|
end # method with
|
61
|
+
alias_method :with_value, :with
|
55
62
|
|
56
63
|
# @see BaseMatcher#failure_message
|
57
64
|
def failure_message
|
58
65
|
methods = []
|
59
|
-
methods << ":#{@expected}" unless @
|
60
|
-
methods << ":#{@expected}=" unless @
|
66
|
+
methods << ":#{@expected}" unless @matches_reader
|
67
|
+
methods << ":#{@expected}=" unless @matches_writer
|
68
|
+
|
69
|
+
message = "expected #{@actual.inspect} to respond to :#{@expected} and :#{@expected}="
|
70
|
+
message << " and return #{value_to_string}" if @value_set
|
61
71
|
|
62
|
-
|
72
|
+
errors = []
|
73
|
+
errors << "did not respond to #{methods.join " or "}" unless methods.empty?
|
74
|
+
errors << "returned #{@actual.send(@expected).inspect}" unless @matches_reader_value || !@value_set
|
63
75
|
|
64
|
-
"
|
65
|
-
|
66
|
-
"\n got: #{@actual.send(@expected).inspect}"
|
76
|
+
message << ", but #{errors.join(" and ")}"
|
77
|
+
message
|
67
78
|
end # failure_message
|
68
79
|
|
69
80
|
# @see BaseMatcher#failure_message_when_negated
|
70
81
|
def failure_message_when_negated
|
82
|
+
methods = []
|
83
|
+
methods << ":#{@expected}" if @matches_reader
|
84
|
+
methods << ":#{@expected}=" if @matches_writer
|
85
|
+
|
71
86
|
message = "expected #{@actual.inspect} not to respond to :#{@expected} or :#{@expected}="
|
72
|
-
message << "
|
87
|
+
message << " and return #{value_to_string}" if @value_set
|
88
|
+
|
89
|
+
errors = []
|
90
|
+
errors << "responded to #{methods.join " and "}" unless methods.empty?
|
91
|
+
errors << "returned #{@actual.send(@expected).inspect}" if @matches_reader_value
|
92
|
+
|
93
|
+
message << ", but #{errors.join(" and ")}"
|
73
94
|
message
|
74
95
|
end # failure_message_when_negated
|
96
|
+
|
97
|
+
private
|
98
|
+
|
99
|
+
def matches_property? filter
|
100
|
+
[ responds_to_reader?,
|
101
|
+
responds_to_writer?,
|
102
|
+
matches_reader_value?
|
103
|
+
].send(filter) { |bool| bool }
|
104
|
+
end # method matches_property?
|
75
105
|
end # class
|
76
106
|
end # module
|
77
107
|
|
@@ -1,14 +1,25 @@
|
|
1
1
|
# lib/rspec/sleeping_king_studios/matchers/core/have_reader.rb
|
2
2
|
|
3
3
|
require 'rspec/sleeping_king_studios/matchers/base_matcher'
|
4
|
-
require 'rspec/sleeping_king_studios/matchers/core
|
4
|
+
require 'rspec/sleeping_king_studios/matchers/core'
|
5
|
+
require 'rspec/sleeping_king_studios/matchers/shared/match_property'
|
5
6
|
|
6
7
|
module RSpec::SleepingKingStudios::Matchers::Core
|
7
8
|
# Matcher for testing whether an object has a specific property reader, e.g.
|
8
9
|
# responds to :property.
|
9
|
-
#
|
10
|
+
#
|
10
11
|
# @since 1.0.0
|
11
12
|
class HaveReaderMatcher < RSpec::SleepingKingStudios::Matchers::BaseMatcher
|
13
|
+
include RSpec::SleepingKingStudios::Matchers::Shared::MatchProperty
|
14
|
+
|
15
|
+
# Generates a description of the matcher expectation.
|
16
|
+
#
|
17
|
+
# @return [String] The matcher description.
|
18
|
+
def description
|
19
|
+
value_message = value_to_string
|
20
|
+
"have reader :#{@expected}#{@value_set ? " with value #{value_message}" : ''}"
|
21
|
+
end # method description
|
22
|
+
|
12
23
|
# @param [String, Symbol] expected the property to check for on the actual
|
13
24
|
# object
|
14
25
|
def initialize expected
|
@@ -18,50 +29,48 @@ module RSpec::SleepingKingStudios::Matchers::Core
|
|
18
29
|
# Checks if the object responds to :expected. Additionally, if a value
|
19
30
|
# expectation is set, compares the value of :expected to the specified
|
20
31
|
# value.
|
21
|
-
#
|
32
|
+
#
|
22
33
|
# @param [Object] actual the object to check
|
23
|
-
#
|
34
|
+
#
|
24
35
|
# @return [Boolean] true if the object responds to :expected and matches
|
25
36
|
# the value expectation (if any); otherwise false
|
26
37
|
def matches? actual
|
27
38
|
super
|
28
39
|
|
29
|
-
|
30
|
-
|
31
|
-
if @value_set
|
32
|
-
return false unless @match_value = @actual.send(@expected) == @value
|
33
|
-
end # if
|
34
|
-
|
35
|
-
true
|
40
|
+
responds_to_reader? && matches_reader_value?
|
36
41
|
end # method matches?
|
37
42
|
|
38
43
|
# Sets a value expectation. The matcher will compare the value from
|
39
44
|
# :property with the specified value.
|
40
|
-
#
|
45
|
+
#
|
41
46
|
# @param [Object] value the value to compare
|
42
|
-
#
|
47
|
+
#
|
43
48
|
# @return [HaveReaderMatcher] self
|
44
49
|
def with value
|
45
50
|
@value = value
|
46
51
|
@value_set = true
|
47
52
|
self
|
48
53
|
end # method with
|
54
|
+
alias_method :with_value, :with
|
49
55
|
|
50
56
|
# @see BaseMatcher#failure_message
|
51
57
|
def failure_message
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
58
|
+
message = "expected #{@actual} to respond to :#{@expected}"
|
59
|
+
message << " and return #{value_to_string}" if @value_set
|
60
|
+
|
61
|
+
if !@matches_reader
|
62
|
+
message << ", but did not respond to :#{@expected}"
|
63
|
+
elsif !@matches_reader_value
|
64
|
+
message << ", but returned #{@actual.send(@expected).inspect}"
|
65
|
+
end # if
|
66
|
+
|
67
|
+
message
|
59
68
|
end # method failure_message
|
60
69
|
|
61
70
|
# @see BaseMatcher#failure_message_when_negated
|
62
71
|
def failure_message_when_negated
|
63
|
-
message = "expected #{@actual} not to respond to
|
64
|
-
message << "
|
72
|
+
message = "expected #{@actual} not to respond to :#{@expected}"
|
73
|
+
message << " and return #{value_to_string}" if @value_set
|
65
74
|
message
|
66
75
|
end # method failure_message
|
67
76
|
end # class
|