rspec-sleeping_king_studios 2.0.0.beta.0 → 2.0.0.beta.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +84 -13
  3. data/DEVELOPMENT.md +16 -0
  4. data/README.md +203 -100
  5. data/lib/rspec/sleeping_king_studios/all.rb +4 -0
  6. data/lib/rspec/sleeping_king_studios/configuration.rb +42 -0
  7. data/lib/rspec/sleeping_king_studios/examples/all.rb +5 -0
  8. data/lib/rspec/sleeping_king_studios/examples/property_examples.rb +58 -0
  9. data/lib/rspec/sleeping_king_studios/examples/rspec_matcher_examples.rb +105 -0
  10. data/lib/rspec/sleeping_king_studios/examples/shared_example_group.rb +62 -0
  11. data/lib/rspec/sleeping_king_studios/examples.rb +8 -0
  12. data/lib/rspec/sleeping_king_studios/matchers/active_model/all.rb +5 -0
  13. data/lib/rspec/sleeping_king_studios/matchers/active_model/have_errors/error_expectation.rb +0 -1
  14. data/lib/rspec/sleeping_king_studios/matchers/active_model/have_errors/message_expectation.rb +1 -2
  15. data/lib/rspec/sleeping_king_studios/matchers/active_model/have_errors.rb +75 -24
  16. data/lib/rspec/sleeping_king_studios/matchers/active_model.rb +6 -3
  17. data/lib/rspec/sleeping_king_studios/matchers/all.rb +5 -0
  18. data/lib/rspec/sleeping_king_studios/matchers/base_matcher.rb +20 -1
  19. data/lib/rspec/sleeping_king_studios/matchers/built_in/all.rb +5 -0
  20. data/lib/rspec/sleeping_king_studios/matchers/built_in/be_kind_of.rb +16 -10
  21. data/lib/rspec/sleeping_king_studios/matchers/built_in/include.rb +14 -9
  22. data/lib/rspec/sleeping_king_studios/matchers/built_in/respond_to.rb +45 -31
  23. data/lib/rspec/sleeping_king_studios/matchers/built_in.rb +5 -3
  24. data/lib/rspec/sleeping_king_studios/matchers/core/all.rb +5 -0
  25. data/lib/rspec/sleeping_king_studios/matchers/core/be_boolean.rb +11 -4
  26. data/lib/rspec/sleeping_king_studios/matchers/core/construct.rb +56 -32
  27. data/lib/rspec/sleeping_king_studios/matchers/core/have_property.rb +59 -29
  28. data/lib/rspec/sleeping_king_studios/matchers/core/have_reader.rb +31 -22
  29. data/lib/rspec/sleeping_king_studios/matchers/core/have_writer.rb +21 -55
  30. data/lib/rspec/sleeping_king_studios/matchers/core.rb +5 -3
  31. data/lib/rspec/sleeping_king_studios/matchers/shared/match_parameters.rb +1 -3
  32. data/lib/rspec/sleeping_king_studios/matchers/shared/match_property.rb +52 -0
  33. data/lib/rspec/sleeping_king_studios/matchers.rb +10 -3
  34. data/lib/rspec/sleeping_king_studios/version.rb +22 -1
  35. data/lib/rspec/sleeping_king_studios.rb +7 -1
  36. metadata +38 -16
  37. data/lib/rspec/sleeping_king_studios/matchers/active_model/have_errors/require.rb +0 -7
  38. data/lib/rspec/sleeping_king_studios/matchers/active_model/require.rb +0 -8
  39. data/lib/rspec/sleeping_king_studios/matchers/built_in/require.rb +0 -7
  40. data/lib/rspec/sleeping_king_studios/matchers/core/require.rb +0 -7
  41. data/lib/rspec/sleeping_king_studios/matchers/meta/fail_with_actual.rb +0 -107
  42. data/lib/rspec/sleeping_king_studios/matchers/meta/pass_with_actual.rb +0 -95
  43. data/lib/rspec/sleeping_king_studios/matchers/meta/require.rb +0 -7
  44. data/lib/rspec/sleeping_king_studios/matchers/meta.rb +0 -5
  45. data/lib/rspec/sleeping_king_studios/matchers/require.rb +0 -12
  46. data/lib/rspec/sleeping_king_studios/matchers/shared/require.rb +0 -7
  47. data/lib/rspec/sleeping_king_studios/require.rb +0 -7
@@ -0,0 +1,58 @@
1
+ # lib/rspec/sleeping_king_studios/examples/property_examples.rb
2
+
3
+ require 'rspec/sleeping_king_studios/examples'
4
+ require 'rspec/sleeping_king_studios/examples/shared_example_group'
5
+ require 'rspec/sleeping_king_studios/matchers/core/have_reader'
6
+ require 'rspec/sleeping_king_studios/matchers/core/have_writer'
7
+ require 'sleeping_king_studios/tools/object_tools'
8
+
9
+ module RSpec::SleepingKingStudios::Examples::PropertyExamples
10
+ extend RSpec::SleepingKingStudios::Examples::SharedExampleGroup
11
+
12
+ UNDEFINED_PROPERTY_EXPECTATION = Object.new.freeze
13
+
14
+ shared_examples 'has reader' do |property, expected_value = UNDEFINED_PROPERTY_EXPECTATION|
15
+ it "has reader :#{property}" do
16
+ object = defined?(instance) ? instance : subject
17
+
18
+ expect(object).to have_reader(property)
19
+
20
+ next if expected_value == UNDEFINED_PROPERTY_EXPECTATION
21
+
22
+ actual_value = instance.send property
23
+
24
+ if expected_value.is_a?(Proc)
25
+ args = [self, expected_value]
26
+ args.push actual_value unless 0 == expected_value.arity
27
+
28
+ expected_value = SleepingKingStudios::Tools::ObjectTools.apply *args
29
+ end # if
30
+
31
+ case expected_value
32
+ when ->(obj) { obj.respond_to?(:matches?) }
33
+ expect(actual_value).to expected_value
34
+ when true, false
35
+ expected_value
36
+ else
37
+ expect(actual_value).to be == expected_value
38
+ end # case
39
+ end # it
40
+ end # shared_examples
41
+ alias_shared_examples 'should have reader', 'has reader'
42
+
43
+ shared_examples 'has writer' do |property|
44
+ it "has writer :#{property}=" do
45
+ object = defined?(instance) ? instance : subject
46
+
47
+ expect(object).to have_writer(property)
48
+ end # it
49
+ end # shared_examples
50
+ alias_shared_examples 'should have writer', 'has writer'
51
+
52
+ shared_examples 'has property' do |property, expected_value = UNDEFINED_PROPERTY_EXPECTATION|
53
+ include_examples 'has reader', property, expected_value
54
+
55
+ include_examples 'has writer', property
56
+ end # shared_examples
57
+ alias_shared_examples 'should have property', 'has property'
58
+ end # module
@@ -0,0 +1,105 @@
1
+ # lib/rspec/sleeping_king_studios/examples/rspec_matcher_examples.rb
2
+
3
+ require 'rspec/sleeping_king_studios/examples'
4
+ require 'rspec/sleeping_king_studios/examples/shared_example_group'
5
+ require 'rspec/sleeping_king_studios/matchers/base_matcher'
6
+
7
+ module RSpec::SleepingKingStudios::Examples::RSpecMatcherExamples
8
+ extend RSpec::SleepingKingStudios::Examples::SharedExampleGroup
9
+
10
+ shared_examples 'passes with a positive expectation' do
11
+ let(:matcher_being_examined) { defined?(instance) ? instance : subject }
12
+
13
+ it 'passes with a positive expectation' do
14
+ expect(matcher_being_examined.matches? actual).to be true
15
+ end # it
16
+ end # shared_examples
17
+ alias_shared_examples 'should pass with a positive expectation', 'passes with a positive expectation'
18
+
19
+ shared_examples 'fails with a positive expectation' do
20
+ let(:matcher_being_examined) { defined?(instance) ? instance : subject }
21
+
22
+ it 'fails with a positive expectation' do
23
+ expect(matcher_being_examined.matches? actual).to be false
24
+ end # it
25
+
26
+ it 'has a failure message with a positive expectation' do
27
+ if defined?(failure_message)
28
+ matcher_being_examined.matches?(actual)
29
+
30
+ expected = failure_message.is_a?(String) ?
31
+ Regexp.new(Regexp.escape(failure_message)) :
32
+ failure_message
33
+
34
+ expect(matcher_being_examined.failure_message).to match expected
35
+ else
36
+ message = <<-MESSAGE
37
+ expected to match #{matcher_being_examined.class}#failure_message, but the expected
38
+ value was undefined. Define a failure message using
39
+ let(:failure_message) or set
40
+ config.handle_missing_failure_message_with to :ignore or :pending.
41
+ MESSAGE
42
+ message = message.split("\n").map(&:strip).join(' ')
43
+ case RSpec.configuration.sleeping_king_studios.examples.handle_missing_failure_message_with
44
+ when :pending
45
+ skip message
46
+ when :exception
47
+ raise StandardError.new message
48
+ end # case
49
+ end # if
50
+ end # it
51
+ end # shared_examples
52
+ alias_shared_examples 'should fail with a positive expectation', 'fails with a positive expectation'
53
+
54
+ shared_examples 'passes with a negative expectation' do
55
+ let(:matcher_being_examined) { defined?(instance) ? instance : subject }
56
+
57
+ it 'passes with a negative expectation' do
58
+ if matcher_being_examined.respond_to?(:does_not_match?)
59
+ expect(matcher_being_examined.does_not_match? actual).to be true
60
+ else
61
+ expect(matcher_being_examined.matches? actual).to be false
62
+ end # if-else
63
+ end # it
64
+ end # shared_examples
65
+ alias_shared_examples 'should pass with a negative expectation', 'passes with a negative expectation'
66
+
67
+ shared_examples 'fails with a negative expectation' do
68
+ let(:matcher_being_examined) { defined?(instance) ? instance : subject }
69
+
70
+ it 'fails with a negative expectation' do
71
+ if matcher_being_examined.respond_to?(:does_not_match?)
72
+ expect(matcher_being_examined.does_not_match? actual).to be false
73
+ else
74
+ expect(matcher_being_examined.matches? actual).to be true
75
+ end # if-else
76
+ end # it
77
+
78
+ it 'has a failure message with a negative expectation' do
79
+ if defined?(failure_message_when_negated)
80
+ matcher_being_examined.respond_to?(:does_not_match?) ? matcher_being_examined.does_not_match?(actual) : matcher_being_examined.matches?(actual)
81
+
82
+ expected = failure_message_when_negated.is_a?(String) ?
83
+ Regexp.new(Regexp.escape(failure_message_when_negated)) :
84
+ failure_message_when_negated
85
+
86
+ expect(matcher_being_examined.failure_message_when_negated).to match expected
87
+ else
88
+ message = <<-MESSAGE
89
+ expected to match #{matcher_being_examined.class}#failure_message_when_negated, but
90
+ the expected value was undefined. Define a failure message using
91
+ let(:failure_message_when_negated) or set
92
+ config.handle_missing_failure_message_with to :ignore or :pending.
93
+ MESSAGE
94
+ message = message.split("\n").map(&:strip).join(' ')
95
+ case RSpec.configuration.sleeping_king_studios.examples.handle_missing_failure_message_with
96
+ when :pending
97
+ skip message
98
+ when :exception
99
+ raise StandardError.new message
100
+ end # case
101
+ end # if
102
+ end # it
103
+ end # shared_examples
104
+ alias_shared_examples 'should fail with a negative expectation', 'fails with a negative expectation'
105
+ end # module
@@ -0,0 +1,62 @@
1
+ # lib/rspec/sleeping_king_studios/examples/shared_example_group.rb
2
+
3
+ require 'rspec/sleeping_king_studios/examples'
4
+
5
+ module RSpec::SleepingKingStudios::Examples
6
+ module SharedExampleGroup
7
+ # Aliases a defined shared example group, allowing it to be accessed using
8
+ # a new name. The example group must be defined in the current context
9
+ # using `shared_examples`. The aliases must be defined before including the
10
+ # module into an example group, or they will not be available in the
11
+ # example group.
12
+ #
13
+ # @param [String] new_name The new name to alias the shared example group
14
+ # as.
15
+ # @param [String] old_name The name under which the shared example group is
16
+ # currently defined.
17
+ def alias_shared_examples new_name, old_name
18
+ proc = shared_example_groups[self][old_name]
19
+
20
+ self.shared_examples new_name, &proc
21
+ end # method alias_shared_examples
22
+
23
+ # @api private
24
+ def included other
25
+ merge_shared_example_groups other
26
+ end # method included
27
+
28
+ # @overload shared_examples(name, &block)
29
+ # @param [String] name Identifer to use when looking up this shared group.
30
+ # @param block Used to create the shared example group definition.
31
+ # @overload shared_examples(name, metadata, &block)
32
+ # @param [String] name Identifer to use when looking up this shared group.
33
+ # @param metadata [Array<Symbol>, Hash] Metadata to attach to this group;
34
+ # any example group with matching metadata will automatically include
35
+ # this shared example group.
36
+ # @param block Used to create the shared example group definition.
37
+ #
38
+ # Defines a shared example group within the context of the current module.
39
+ # Unlike a top-level example group defined using RSpec#shared_examples,
40
+ # these examples are not globally available, and must be mixed into an
41
+ # example group by including the module. The shared examples must be
42
+ # defined before including the module, or they will not be available in the
43
+ # example group.
44
+ def shared_examples name, *metadata_args, &block
45
+ RSpec.world.shared_example_group_registry.add(self, name, *metadata_args, &block)
46
+ end # method shared_examples
47
+
48
+ private
49
+
50
+ # @api private
51
+ def merge_shared_example_groups other
52
+ shared_example_groups[self].each do |name, proc|
53
+ RSpec.world.shared_example_group_registry.add(other, name, &proc)
54
+ end # each
55
+ end # method merge_shared_example_groups
56
+
57
+ # @api private
58
+ def shared_example_groups
59
+ RSpec.world.shared_example_group_registry.send :shared_example_groups
60
+ end # method shared_example_groups
61
+ end # module
62
+ end # module
@@ -0,0 +1,8 @@
1
+ # lib/rspec/sleeping_king_studios/examples.rb
2
+
3
+ require 'rspec/sleeping_king_studios'
4
+
5
+ module RSpec::SleepingKingStudios
6
+ # Pregenerated example groups for use with RSpec.
7
+ module Examples; end
8
+ end # module
@@ -0,0 +1,5 @@
1
+ # lib/rspec/sleeping_king_studios/matchers/active_model/all.rb
2
+
3
+ Dir[File.join File.dirname(__FILE__), '*.rb'].each do |file|
4
+ require file
5
+ end # end each
@@ -1,6 +1,5 @@
1
1
  # lib/rspec/sleeping_king_studios/matchers/active_model/have_errors/error_expectation.rb
2
2
 
3
- require 'rspec/sleeping_king_studios/matchers/base_matcher'
4
3
  require 'rspec/sleeping_king_studios/matchers/active_model/have_errors/message_expectation'
5
4
 
6
5
  module RSpec::SleepingKingStudios::Matchers::ActiveModel::HaveErrors
@@ -1,7 +1,6 @@
1
1
  # lib/rspec/sleeping_king_studios/matchers/active_model/have_errors/message_expectation.rb
2
2
 
3
- require 'rspec/sleeping_king_studios/matchers/base_matcher'
4
- require 'rspec/sleeping_king_studios/matchers/active_model/have_errors/require'
3
+ require 'rspec/sleeping_king_studios/matchers/active_model'
5
4
 
6
5
  module RSpec::SleepingKingStudios::Matchers::ActiveModel::HaveErrors
7
6
  # Stores an expectation of receiving a specified error message.
@@ -1,15 +1,19 @@
1
1
  # lib/rspec/sleeping_king_studios/matchers/active_model/have_errors.rb
2
2
 
3
3
  require 'rspec/sleeping_king_studios/matchers/base_matcher'
4
- require 'rspec/sleeping_king_studios/matchers/active_model/require'
4
+ require 'rspec/sleeping_king_studios/matchers/active_model'
5
5
  require 'rspec/sleeping_king_studios/matchers/active_model/have_errors/error_expectation'
6
+ require 'sleeping_king_studios/tools/enumerable_tools'
7
+ require 'sleeping_king_studios/tools/string_tools'
6
8
 
7
9
  module RSpec::SleepingKingStudios::Matchers::ActiveModel
8
10
  # Matcher for testing ActiveModel object validations.
9
- #
11
+ #
10
12
  # @since 1.0.0
11
13
  class HaveErrorsMatcher < RSpec::SleepingKingStudios::Matchers::BaseMatcher
12
14
  include RSpec::SleepingKingStudios::Matchers::ActiveModel::HaveErrors
15
+ include SleepingKingStudios::Tools::EnumerableTools
16
+ include SleepingKingStudios::Tools::StringTools
13
17
 
14
18
  def initialize
15
19
  super
@@ -19,12 +23,55 @@ module RSpec::SleepingKingStudios::Matchers::ActiveModel
19
23
  @error_expectations = []
20
24
  end # constructor
21
25
 
26
+ # Generates a description of the matcher expectation.
27
+ #
28
+ # @return [String] The matcher description.
29
+ def description
30
+ message = 'have errors'
31
+
32
+ attribute_messages = @error_expectations.select(&:expected).map do |expectation|
33
+ attribute_message = ":#{expectation.attribute}"
34
+
35
+ error_messages = expectation.messages.select(&:expected).map do |message_expectation|
36
+ %{"#{message_expectation.message}"}
37
+ end # map
38
+
39
+ unless error_messages.empty?
40
+ attribute_message << " with #{pluralize(error_messages.count, 'message', 'messages')} #{humanize_list error_messages}"
41
+ end # unless
42
+
43
+ attribute_message
44
+ end # each
45
+ message << " on #{attribute_messages.join(", and on ")}" unless attribute_messages.empty?
46
+
47
+ message
48
+ end # method description
49
+
50
+ # Checks if the object can be validated, whether the object is valid, and
51
+ # checks the errors on the object against the expected errors and messages
52
+ # from #on and #with_message, if any.
53
+ #
54
+ # @param [Object] actual the object to test against the matcher
55
+ #
56
+ # @return [Boolean] true if the object responds to :valid? and is valid
57
+ # or object.errors does not match the specified errors and messages (if
58
+ # any); otherwise false
59
+ #
60
+ # @see #matches?
61
+ def does_not_match? actual
62
+ @negative_expectation = true
63
+
64
+ return false unless @validates = actual.respond_to?(:valid?)
65
+
66
+ !matches?(actual)
67
+ end # method does_not_match?
68
+
22
69
  # Checks if the object can be validated, whether the object is valid, and
23
70
  # checks the errors on the object against the expected errors and messages
24
71
  # from #on and #with_message, if any.
25
- #
72
+ #
26
73
  # @param [Object] actual the object to test against the matcher
27
- #
74
+ #
28
75
  # @return [Boolean] true if the object responds to :valid?, is not valid,
29
76
  # and object.errors matches the specified errors and messages (if any);
30
77
  # otherwise false
@@ -39,55 +86,56 @@ module RSpec::SleepingKingStudios::Matchers::ActiveModel
39
86
 
40
87
  # Adds an error expectation. If the actual object does not have an error on
41
88
  # the specified attribute, #matches? will return false.
42
- #
89
+ #
43
90
  # @param [String, Symbol] attribute
44
- #
91
+ #
45
92
  # @return [HaveErrorsMatcher] self
46
- #
93
+ #
47
94
  # @example Setting an error expectation
48
95
  # expect(actual).to have_errors.on(:foo)
49
96
  def on attribute
50
97
  @error_expectations << ErrorExpectation.new(attribute)
51
-
98
+
52
99
  self
53
100
  end # method on
54
101
 
55
102
  # Adds a message expectation for the most recently added error attribute.
56
103
  # If the actual object does not have an error on the that attribute with
57
104
  # the specified message, #matches? will return false.
58
- #
105
+ #
59
106
  # @param [String, Regexp] message the expected error message. If a string,
60
107
  # matcher will check for an exact match; if a regular expression, matcher
61
108
  # will check if the message matches the regexp
62
- #
109
+ #
63
110
  # @raise [ArgumentError] if no error attribute has been added
64
- #
111
+ #
65
112
  # @return [HaveErrorsMatcher] self
66
- #
113
+ #
67
114
  # @example Setting an error and a message expectation
68
115
  # expect(actual).to have_errors.on(:foo).with("can't be blank")
69
- #
116
+ #
70
117
  # @see #on
71
118
  def with_message message
72
119
  raise ArgumentError.new "no attribute specified for error message" if
73
120
  @error_expectations.empty?
74
-
121
+
75
122
  @error_expectations.last.messages << MessageExpectation.new(message)
76
-
123
+
77
124
  self
78
125
  end # method with_message
79
126
 
80
127
  # Adds a set of message expectations for the most recently added error
81
128
  # attribute.
82
- #
129
+ #
83
130
  # @param [Array<String, Regexp>] messages
84
- #
131
+ #
85
132
  # @see #with_message
86
133
  def with_messages *messages
87
134
  messages.each do |message| self.with_message(message); end
88
-
135
+
89
136
  self
90
137
  end # method with_message
138
+ alias_method :with, :with_messages
91
139
 
92
140
  # @see BaseMatcher#failure_message
93
141
  def failure_message
@@ -109,14 +157,17 @@ module RSpec::SleepingKingStudios::Matchers::ActiveModel
109
157
  # @see BaseMatcher#failure_message_when_negated
110
158
  def failure_message_when_negated
111
159
  # Failure cases:
160
+ # * object is not a model ("to respond to valid")
112
161
  # * expected one or more errors, received one or more ("not to have
113
162
  # errors")
114
163
  # * expected one or more messages on attribute, received one or more
115
164
  # ("not to have errors on")
116
165
  # * expected specific messages on attribute, received all ("not to have
117
166
  # errors on")
118
-
119
- if expected_errors.empty?
167
+
168
+ if !@validates
169
+ "expected #{@actual.inspect} to respond to :valid?"
170
+ elsif expected_errors.empty?
120
171
  return "expected #{@actual.inspect} not to have errors#{received_errors_message}"
121
172
  else
122
173
  return "expected #{@actual.inspect} not to have errors#{expected_errors_message}#{received_errors_message}"
@@ -124,7 +175,7 @@ module RSpec::SleepingKingStudios::Matchers::ActiveModel
124
175
  end # method failure_message_when_negated
125
176
 
126
177
  private
127
-
178
+
128
179
  def attributes_have_errors?
129
180
  # Iterate through the received errors and match them against the expected
130
181
  # errors and messages.
@@ -155,7 +206,7 @@ module RSpec::SleepingKingStudios::Matchers::ActiveModel
155
206
  else
156
207
  error_expectation.messages << MessageExpectation.new(message, false, true)
157
208
  end # if-else
158
- end # each
209
+ end # each
159
210
  end # unless
160
211
  else
161
212
  error_expectation = ErrorExpectation.new attribute, false, true
@@ -175,7 +226,7 @@ module RSpec::SleepingKingStudios::Matchers::ActiveModel
175
226
  error_expectation.expected
176
227
  end # select
177
228
  end # method expected_errors
178
-
229
+
179
230
  def missing_errors
180
231
  @error_expectations.select do |error_expectation|
181
232
  error_expectation.expected && !error_expectation.received
@@ -197,7 +248,7 @@ module RSpec::SleepingKingStudios::Matchers::ActiveModel
197
248
  def expected_errors_message
198
249
  "\n expected errors:" + expected_errors.map do |error_expectation|
199
250
  "\n #{error_expectation.attribute}: " + (error_expectation.messages.empty? ?
200
- "(any)" :
251
+ "(#{@negative_expectation ? 'none' : 'any'})" :
201
252
  error_expectation.messages.expected.map(&:message).map(&:inspect).join(", "))
202
253
  end.join # map
203
254
  end # method expected_errors_message
@@ -1,5 +1,8 @@
1
1
  # lib/rspec/sleeping_king_studios/matchers/active_model.rb
2
2
 
3
- Dir[File.join File.dirname(__FILE__), 'active_model', '*.rb'].each do |file|
4
- require file
5
- end # end each
3
+ require 'rspec/sleeping_king_studios/matchers'
4
+
5
+ module RSpec::SleepingKingStudios::Matchers
6
+ # Matchers for ActiveModel object validation testing.
7
+ module ActiveModel; end
8
+ end # module
@@ -0,0 +1,5 @@
1
+ # lib/rspec/sleeping_king_studios/matchers/all.rb
2
+
3
+ %w(active_model built_in core).each do |dir_name|
4
+ require File.join File.dirname(__FILE__), dir_name, 'all'
5
+ end # each
@@ -1,6 +1,6 @@
1
1
  # lib/rspec/sleeping_king_studios/matchers/base_matcher.rb
2
2
 
3
- require 'rspec/sleeping_king_studios/matchers/require'
3
+ require 'rspec/sleeping_king_studios/matchers'
4
4
 
5
5
  module RSpec::SleepingKingStudios::Matchers
6
6
  # Minimal implementation of the RSpec matcher interface.
@@ -20,6 +20,17 @@ module RSpec::SleepingKingStudios::Matchers
20
20
  "#{name_to_sentence}#{to_sentence @expected}"
21
21
  end # method description
22
22
 
23
+ # Inverse of #matches? method.
24
+ #
25
+ # @param [Object] actual the object to test against the matcher
26
+ #
27
+ # @return [Boolean] false if the object matches, otherwise true
28
+ #
29
+ # @see #matches?
30
+ def does_not_match? actual
31
+ !matches?(actual)
32
+ end # method does_not_match?
33
+
23
34
  # Tests the actual object to see if it matches the defined condition(s).
24
35
  # Invoked by RSpec expectations.
25
36
  #
@@ -28,6 +39,7 @@ module RSpec::SleepingKingStudios::Matchers
28
39
  # @return [Boolean] true if the object matches, otherwise false
29
40
  def matches? actual
30
41
  @actual = actual
42
+
31
43
  true
32
44
  end # method matches?
33
45
 
@@ -42,5 +54,12 @@ module RSpec::SleepingKingStudios::Matchers
42
54
  def failure_message_when_negated
43
55
  "expected #{@actual.inspect} not to #{description}"
44
56
  end # method failure_message_when_negated
57
+
58
+ private
59
+
60
+ # @api private
61
+ def name_to_sentence
62
+ 'match'
63
+ end # method name_to_sentence
45
64
  end # class
46
65
  end # module
@@ -0,0 +1,5 @@
1
+ # lib/rspec/sleeping_king_studios/matchers/built_in/all.rb
2
+
3
+ Dir[File.join File.dirname(__FILE__), '*.rb'].each do |file|
4
+ require file
5
+ end # end each
@@ -1,17 +1,27 @@
1
1
  # lib/rspec/sleeping_king_studios/matchers/built_in/be_kind_of.rb
2
2
 
3
- require 'rspec/sleeping_king_studios/matchers/built_in/require'
3
+ require 'rspec/sleeping_king_studios/matchers/built_in'
4
+ require 'sleeping_king_studios/tools/enumerable_tools'
4
5
 
5
6
  module RSpec::SleepingKingStudios::Matchers::BuiltIn
6
7
  class BeAKindOfMatcher < RSpec::Matchers::BuiltIn::BeAKindOf
8
+ include SleepingKingStudios::Tools::EnumerableTools
9
+
10
+ # Generates a description of the matcher expectation.
11
+ #
12
+ # @return [String] The matcher description.
13
+ def description
14
+ message = "be #{type_string}"
15
+ end # method description
16
+
7
17
  # Checks if the object matches one of the specified types. Allows an
8
18
  # expected value of nil as a shortcut for expecting an instance of
9
19
  # NilClass.
10
- #
20
+ #
11
21
  # @param [Module, nil, Array<Module, nil>] expected the type or types to
12
22
  # check the object against
13
23
  # @param [Object] actual the object to check
14
- #
24
+ #
15
25
  # @return [Boolean] true if the object matches one of the specified types,
16
26
  # otherwise false
17
27
  def match expected, actual
@@ -22,14 +32,14 @@ module RSpec::SleepingKingStudios::Matchers::BuiltIn
22
32
  def failure_message
23
33
  "expected #{@actual.inspect} to be #{type_string}"
24
34
  end # method failure_message
25
-
35
+
26
36
  # @see BaseMatcher#failure_message_when_negated
27
37
  def failure_message_when_negated
28
38
  "expected #{@actual.inspect} not to be #{type_string}"
29
39
  end # method failure_message_when_negated
30
40
 
31
41
  private
32
-
42
+
33
43
  def match_type? expected
34
44
  case
35
45
  when expected.nil?
@@ -46,11 +56,7 @@ module RSpec::SleepingKingStudios::Matchers::BuiltIn
46
56
  when @expected.nil?
47
57
  @expected.inspect
48
58
  when @expected.is_a?(Enumerable) && 1 < @expected.count
49
- if 2 == expected.count
50
- "a #{expected.first.inspect} or #{expected.last.inspect}"
51
- else
52
- "a #{expected[0..-2].map(&:inspect).join(", ")}, or #{expected.last.inspect}"
53
- end # if-else
59
+ "a #{humanize_list @expected.map { |value| value.nil? ? 'nil' : value }, :last_separator => ' or '}"
54
60
  else
55
61
  "a #{expected}"
56
62
  end # case
@@ -1,12 +1,12 @@
1
1
  # lib/rspec/sleeping_king_studios/matchers/built_in/be_kind_of.rb
2
2
 
3
- require 'rspec/sleeping_king_studios/matchers/built_in/require'
3
+ require 'rspec/sleeping_king_studios/matchers/built_in'
4
4
 
5
5
  module RSpec::SleepingKingStudios::Matchers::BuiltIn
6
6
  class IncludeMatcher < RSpec::Matchers::BuiltIn::Include
7
7
  # @param [Array<Hash, Proc, Object>] expected the items expected to be
8
8
  # matched by the actual object
9
- #
9
+ #
10
10
  # @yield if a block is provided, the block is converted to a proc and
11
11
  # appended to the item expectations
12
12
  # @yieldparam [Object] item an item from the actual object; yield(item)
@@ -14,6 +14,7 @@ module RSpec::SleepingKingStudios::Matchers::BuiltIn
14
14
  # predicate
15
15
  def initialize *expected, &block
16
16
  expected << block if block_given?
17
+
17
18
  super *expected
18
19
  end # constructor
19
20
 
@@ -31,19 +32,27 @@ module RSpec::SleepingKingStudios::Matchers::BuiltIn
31
32
 
32
33
  # @see BaseMatcher#failure_message
33
34
  def failure_message
34
- return "expected #{@actual.inspect} to respond to :include?" if false === @includes
35
+ message = super
36
+
37
+ message << ", but it does not respond to `include?`" unless actual.respond_to?(:include?) || message =~ /does not respond to/
35
38
 
36
- super
39
+ message
37
40
  end # method failure_message_for_should
38
41
 
39
42
  # @see BaseMatcher#failure_message_when_negated
40
43
  def failure_message_when_negated
41
- super
44
+ message = super
45
+
46
+ message << ", but it does not respond to `include?`" unless actual.respond_to?(:include?) || message =~ /does not respond to/
47
+
48
+ message
42
49
  end # method
43
50
 
44
51
  private
45
52
 
46
53
  def perform_match(predicate, hash_subset_predicate)
54
+ return false unless actual.respond_to?(:include?)
55
+
47
56
  expected.__send__(predicate) do |expected_item|
48
57
  if comparing_proc?(expected_item)
49
58
  actual_matches_proc?(expected_item)
@@ -59,10 +68,6 @@ module RSpec::SleepingKingStudios::Matchers::BuiltIn
59
68
  end
60
69
  end
61
70
 
62
- def actual_collection_includes? expected_item
63
- (@includes = actual.respond_to?(:include?)) && super
64
- end # method actual_collection_includes?
65
-
66
71
  def actual_matches_proc? expected_item
67
72
  !!actual.detect(&expected_item)
68
73
  end # method actual_matches_proc?