rspec-expectations 3.0.0 → 3.0.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 +6 -14
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/Changelog.md +10 -0
- data/README.md +22 -1
- data/lib/rspec/expectations.rb +0 -1
- data/lib/rspec/expectations/configuration.rb +5 -8
- data/lib/rspec/expectations/expectation_target.rb +4 -6
- data/lib/rspec/expectations/fail_with.rb +5 -8
- data/lib/rspec/expectations/handler.rb +2 -4
- data/lib/rspec/expectations/minitest_integration.rb +5 -4
- data/lib/rspec/expectations/syntax.rb +13 -13
- data/lib/rspec/expectations/version.rb +1 -1
- data/lib/rspec/matchers.rb +10 -11
- data/lib/rspec/matchers/built_in/all.rb +3 -5
- data/lib/rspec/matchers/built_in/base_matcher.rb +3 -4
- data/lib/rspec/matchers/built_in/be.rb +3 -6
- data/lib/rspec/matchers/built_in/be_instance_of.rb +0 -1
- data/lib/rspec/matchers/built_in/be_kind_of.rb +1 -1
- data/lib/rspec/matchers/built_in/change.rb +4 -4
- data/lib/rspec/matchers/built_in/compound.rb +5 -8
- data/lib/rspec/matchers/built_in/contain_exactly.rb +10 -9
- data/lib/rspec/matchers/built_in/eq.rb +0 -1
- data/lib/rspec/matchers/built_in/eql.rb +0 -1
- data/lib/rspec/matchers/built_in/equal.rb +2 -3
- data/lib/rspec/matchers/built_in/exist.rb +0 -4
- data/lib/rspec/matchers/built_in/include.rb +3 -3
- data/lib/rspec/matchers/built_in/match.rb +0 -1
- data/lib/rspec/matchers/built_in/operators.rb +7 -7
- data/lib/rspec/matchers/built_in/output.rb +1 -1
- data/lib/rspec/matchers/built_in/raise_error.rb +15 -12
- data/lib/rspec/matchers/built_in/respond_to.rb +5 -3
- data/lib/rspec/matchers/built_in/start_and_end_with.rb +0 -2
- data/lib/rspec/matchers/built_in/throw_symbol.rb +9 -5
- data/lib/rspec/matchers/built_in/yield.rb +14 -15
- data/lib/rspec/matchers/composable.rb +4 -2
- data/lib/rspec/matchers/dsl.rb +1 -3
- data/lib/rspec/matchers/matcher_delegator.rb +0 -1
- data/lib/rspec/matchers/pretty.rb +11 -11
- metadata +49 -56
- metadata.gz.sig +0 -0
@@ -87,8 +87,8 @@ module RSpec
|
|
87
87
|
end
|
88
88
|
|
89
89
|
def raise_block_syntax_error
|
90
|
-
raise SyntaxError,
|
91
|
-
"
|
90
|
+
raise SyntaxError, "The block passed to the `change` matcher must " \
|
91
|
+
"use `{ ... }` instead of do/end"
|
92
92
|
end
|
93
93
|
|
94
94
|
def positive_failure_reason
|
@@ -128,7 +128,7 @@ module RSpec
|
|
128
128
|
end
|
129
129
|
|
130
130
|
# @private
|
131
|
-
def does_not_match?(
|
131
|
+
def does_not_match?(_event_proc)
|
132
132
|
raise NotImplementedError, "`expect { }.not_to change { }.#{@relativity}()` is not supported"
|
133
133
|
end
|
134
134
|
|
@@ -281,7 +281,7 @@ module RSpec
|
|
281
281
|
end
|
282
282
|
|
283
283
|
# @private
|
284
|
-
def does_not_match?(
|
284
|
+
def does_not_match?(_event_proc)
|
285
285
|
raise NotImplementedError, "`expect { }.not_to change { }.to()` is not supported"
|
286
286
|
end
|
287
287
|
|
@@ -13,9 +13,9 @@ module RSpec
|
|
13
13
|
end
|
14
14
|
|
15
15
|
# @private
|
16
|
-
def does_not_match?(
|
17
|
-
raise NotImplementedError,
|
18
|
-
"
|
16
|
+
def does_not_match?(_actual)
|
17
|
+
raise NotImplementedError, "`expect(...).not_to " \
|
18
|
+
"matcher.#{conjunction} matcher` is not supported"
|
19
19
|
end
|
20
20
|
|
21
21
|
# @api private
|
@@ -68,7 +68,6 @@ module RSpec
|
|
68
68
|
# @api public
|
69
69
|
# Matcher used to represent a compound `and` expectation.
|
70
70
|
class And < self
|
71
|
-
|
72
71
|
# @api private
|
73
72
|
# @return [String]
|
74
73
|
def failure_message
|
@@ -83,7 +82,7 @@ module RSpec
|
|
83
82
|
|
84
83
|
private
|
85
84
|
|
86
|
-
def match(
|
85
|
+
def match(_expected, actual)
|
87
86
|
@matcher_1_matches = matcher_1.matches?(actual)
|
88
87
|
@matcher_2_matches = matcher_2.matches?(actual)
|
89
88
|
|
@@ -98,7 +97,6 @@ module RSpec
|
|
98
97
|
# @api public
|
99
98
|
# Matcher used to represent a compound `or` expectation.
|
100
99
|
class Or < self
|
101
|
-
|
102
100
|
# @api private
|
103
101
|
# @return [String]
|
104
102
|
def failure_message
|
@@ -107,7 +105,7 @@ module RSpec
|
|
107
105
|
|
108
106
|
private
|
109
107
|
|
110
|
-
def match(
|
108
|
+
def match(_expected, actual)
|
111
109
|
matcher_1.matches?(actual) || matcher_2.matches?(actual)
|
112
110
|
end
|
113
111
|
|
@@ -119,4 +117,3 @@ module RSpec
|
|
119
117
|
end
|
120
118
|
end
|
121
119
|
end
|
122
|
-
|
@@ -5,7 +5,6 @@ module RSpec
|
|
5
5
|
# Provides the implementation for `contain_exactly` and `match_array`.
|
6
6
|
# Not intended to be instantiated directly.
|
7
7
|
class ContainExactly < BaseMatcher
|
8
|
-
|
9
8
|
# @api private
|
10
9
|
# @return [String]
|
11
10
|
def failure_message
|
@@ -16,7 +15,7 @@ module RSpec
|
|
16
15
|
message += "the extra elements were: #{safe_sort(extra_items).inspect}\n" unless extra_items.empty?
|
17
16
|
message
|
18
17
|
else
|
19
|
-
"expected a collection that can be converted to an array with "
|
18
|
+
"expected a collection that can be converted to an array with " \
|
20
19
|
"`#to_ary` or `#to_a`, but got #{actual.inspect}"
|
21
20
|
end
|
22
21
|
end
|
@@ -35,8 +34,8 @@ module RSpec
|
|
35
34
|
|
36
35
|
private
|
37
36
|
|
38
|
-
def match(
|
39
|
-
|
37
|
+
def match(_expected, _actual)
|
38
|
+
return false unless convert_actual_to_an_array
|
40
39
|
match_when_sorted? || (extra_items.empty? && missing_items.empty?)
|
41
40
|
end
|
42
41
|
|
@@ -93,10 +92,10 @@ module RSpec
|
|
93
92
|
# some extra checks we don't need (e.g. to support nested data
|
94
93
|
# structures), and given that it's called N*M times here, it helps
|
95
94
|
# perf significantly to implement the matching bit ourselves.
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
95
|
+
next unless e === a || a == e
|
96
|
+
|
97
|
+
expected_matches[ei] << ai
|
98
|
+
actual_matches[ai] << ei
|
100
99
|
end
|
101
100
|
end
|
102
101
|
|
@@ -204,7 +203,9 @@ module RSpec
|
|
204
203
|
# @private
|
205
204
|
# Starting solution that is worse than any other real solution.
|
206
205
|
NullSolution = Class.new do
|
207
|
-
def self.worse_than?(
|
206
|
+
def self.worse_than?(_other)
|
207
|
+
true
|
208
|
+
end
|
208
209
|
end
|
209
210
|
|
210
211
|
def categorize_indexes(indexes_to_categorize, other_indexes)
|
@@ -5,7 +5,6 @@ module RSpec
|
|
5
5
|
# Provides the implementation for `equal`.
|
6
6
|
# Not intended to be instantiated directly.
|
7
7
|
class Equal < BaseMatcher
|
8
|
-
|
9
8
|
# @api private
|
10
9
|
# @return [String]
|
11
10
|
def failure_message
|
@@ -19,7 +18,7 @@ module RSpec
|
|
19
18
|
# @api private
|
20
19
|
# @return [String]
|
21
20
|
def failure_message_when_negated
|
22
|
-
|
21
|
+
<<-MESSAGE
|
23
22
|
|
24
23
|
expected not #{inspect_object(actual)}
|
25
24
|
got #{inspect_object(expected)}
|
@@ -60,7 +59,7 @@ MESSAGE
|
|
60
59
|
end
|
61
60
|
|
62
61
|
def detailed_failure_message
|
63
|
-
|
62
|
+
<<-MESSAGE
|
64
63
|
|
65
64
|
expected #{inspect_object(expected)}
|
66
65
|
got #{inspect_object(actual)}
|
@@ -37,13 +37,10 @@ module RSpec
|
|
37
37
|
"expected #{@actual.inspect} not to exist#{@test.validity_message}"
|
38
38
|
end
|
39
39
|
|
40
|
-
private
|
41
|
-
|
42
40
|
# @api private
|
43
41
|
# Simple class for memoizing actual/expected for this matcher
|
44
42
|
# and examining the match
|
45
43
|
class ExistenceTest < Struct.new(:actual, :expected)
|
46
|
-
|
47
44
|
# @api private
|
48
45
|
# @return [Boolean]
|
49
46
|
def valid_test?
|
@@ -83,7 +80,6 @@ module RSpec
|
|
83
80
|
@predicates ||= [:exist?, :exists?].select { |p| actual.respond_to?(p) }
|
84
81
|
end
|
85
82
|
end
|
86
|
-
|
87
83
|
end
|
88
84
|
end
|
89
85
|
end
|
@@ -78,9 +78,9 @@ module RSpec
|
|
78
78
|
end
|
79
79
|
|
80
80
|
def actual_hash_has_key?(expected_key)
|
81
|
-
# We check `
|
82
|
-
#
|
83
|
-
actual.
|
81
|
+
# We check `key?` first for perf:
|
82
|
+
# `key?` is O(1), but `any?` is O(N).
|
83
|
+
actual.key?(expected_key) ||
|
84
84
|
actual.keys.any? { |key| values_match?(expected_key, key) }
|
85
85
|
end
|
86
86
|
|
@@ -27,10 +27,10 @@ module RSpec
|
|
27
27
|
|
28
28
|
# @private
|
29
29
|
def get(klass, operator)
|
30
|
-
klass.ancestors.each
|
30
|
+
klass.ancestors.each do |ancestor|
|
31
31
|
matcher = registry[ancestor] && registry[ancestor][operator]
|
32
32
|
return matcher if matcher
|
33
|
-
|
33
|
+
end
|
34
34
|
|
35
35
|
nil
|
36
36
|
end
|
@@ -45,7 +45,7 @@ module RSpec
|
|
45
45
|
# @private
|
46
46
|
def self.use_custom_matcher_or_delegate(operator)
|
47
47
|
define_method(operator) do |expected|
|
48
|
-
if uses_generic_implementation_of?(operator) && matcher = OperatorMatcher.get(@actual.class, operator)
|
48
|
+
if uses_generic_implementation_of?(operator) && (matcher = OperatorMatcher.get(@actual.class, operator))
|
49
49
|
@actual.__send__(::RSpec::Matchers.last_expectation_handler.should_method, matcher.new(expected))
|
50
50
|
else
|
51
51
|
eval_match(@actual, operator, expected)
|
@@ -54,9 +54,9 @@ module RSpec
|
|
54
54
|
|
55
55
|
negative_operator = operator.sub(/^=/, '!')
|
56
56
|
if negative_operator != operator && respond_to?(negative_operator)
|
57
|
-
define_method(negative_operator) do |
|
57
|
+
define_method(negative_operator) do |_expected|
|
58
58
|
opposite_should = ::RSpec::Matchers.last_expectation_handler.opposite_should_method
|
59
|
-
raise "RSpec does not support `#{::RSpec::Matchers.last_expectation_handler.should_method} #{negative_operator} expected`. "
|
59
|
+
raise "RSpec does not support `#{::RSpec::Matchers.last_expectation_handler.should_method} #{negative_operator} expected`. " \
|
60
60
|
"Use `#{opposite_should} #{operator} expected` instead."
|
61
61
|
end
|
62
62
|
end
|
@@ -98,7 +98,7 @@ module RSpec
|
|
98
98
|
def __delegate_operator(actual, operator, expected)
|
99
99
|
if actual.__send__(operator, expected)
|
100
100
|
true
|
101
|
-
elsif ['==','===', '=~'].include?(operator)
|
101
|
+
elsif ['==', '===', '=~'].include?(operator)
|
102
102
|
fail_with_message("expected: #{expected.inspect}\n got: #{actual.inspect} (using #{operator})")
|
103
103
|
else
|
104
104
|
fail_with_message("expected: #{operator} #{expected.inspect}\n got: #{operator.gsub(/./, ' ')} #{actual.inspect}")
|
@@ -111,7 +111,7 @@ module RSpec
|
|
111
111
|
class NegativeOperatorMatcher < OperatorMatcher
|
112
112
|
def __delegate_operator(actual, operator, expected)
|
113
113
|
return false unless actual.__send__(operator, expected)
|
114
|
-
|
114
|
+
fail_with_message("expected not: #{operator} #{expected.inspect}\n got: #{operator.gsub(/./, ' ')} #{actual.inspect}")
|
115
115
|
end
|
116
116
|
end
|
117
117
|
end
|
@@ -26,8 +26,9 @@ module RSpec
|
|
26
26
|
self
|
27
27
|
end
|
28
28
|
|
29
|
+
# rubocop:disable MethodLength
|
29
30
|
# @private
|
30
|
-
def matches?(given_proc, negative_expectation
|
31
|
+
def matches?(given_proc, negative_expectation=false, &block)
|
31
32
|
@given_proc = given_proc
|
32
33
|
@block ||= block
|
33
34
|
@raised_expected_error = false
|
@@ -52,6 +53,7 @@ module RSpec
|
|
52
53
|
|
53
54
|
expectation_matched?
|
54
55
|
end
|
56
|
+
# rubocop:enable MethodLength
|
55
57
|
|
56
58
|
# @private
|
57
59
|
def does_not_match?(given_proc)
|
@@ -112,17 +114,18 @@ module RSpec
|
|
112
114
|
end
|
113
115
|
|
114
116
|
def prevent_invalid_expectations
|
115
|
-
if
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
117
|
+
what_to_raise = if expecting_specific_exception? && @expected_message
|
118
|
+
"`expect { }.not_to raise_error(SpecificErrorClass, message)`"
|
119
|
+
elsif expecting_specific_exception?
|
120
|
+
"`expect { }.not_to raise_error(SpecificErrorClass)`"
|
121
|
+
elsif @expected_message
|
122
|
+
"`expect { }.not_to raise_error(message)`"
|
123
|
+
end
|
124
|
+
|
125
|
+
return unless what_to_raise
|
126
|
+
|
127
|
+
specific_class_error = ArgumentError.new("#{what_to_raise} is not valid, use `expect { }.not_to raise_error` (with no args) instead")
|
128
|
+
raise specific_class_error
|
126
129
|
end
|
127
130
|
|
128
131
|
def expected_error
|
@@ -1,3 +1,5 @@
|
|
1
|
+
RSpec::Support.require_rspec_support "method_signature_verifier"
|
2
|
+
|
1
3
|
module RSpec
|
2
4
|
module Matchers
|
3
5
|
module BuiltIn
|
@@ -45,7 +47,7 @@ module RSpec
|
|
45
47
|
# @api private
|
46
48
|
# @return [String]
|
47
49
|
def failure_message
|
48
|
-
"expected #{@actual.inspect} to respond to #{@failing_method_names.
|
50
|
+
"expected #{@actual.inspect} to respond to #{@failing_method_names.map { |name| name.inspect }.join(', ')}#{with_arity}"
|
49
51
|
end
|
50
52
|
|
51
53
|
# @api private
|
@@ -82,8 +84,8 @@ module RSpec
|
|
82
84
|
end
|
83
85
|
|
84
86
|
def with_arity
|
85
|
-
|
86
|
-
|
87
|
+
return "" unless @expected_arity
|
88
|
+
" with #{@expected_arity} argument#{@expected_arity == 1 ? '' : 's'}"
|
87
89
|
end
|
88
90
|
|
89
91
|
def pp_names
|
@@ -52,7 +52,6 @@ module RSpec
|
|
52
52
|
# Provides the implementation for `start_with`.
|
53
53
|
# Not intended to be instantiated directly.
|
54
54
|
class StartWith < StartAndEndWith
|
55
|
-
|
56
55
|
private
|
57
56
|
|
58
57
|
def subset_matches?
|
@@ -68,7 +67,6 @@ module RSpec
|
|
68
67
|
# Provides the implementation for `end_with`.
|
69
68
|
# Not intended to be instantiated directly.
|
70
69
|
class EndWith < StartAndEndWith
|
71
|
-
|
72
70
|
private
|
73
71
|
|
74
72
|
def subset_matches?
|
@@ -7,12 +7,13 @@ module RSpec
|
|
7
7
|
class ThrowSymbol
|
8
8
|
include Composable
|
9
9
|
|
10
|
-
def initialize(expected_symbol
|
10
|
+
def initialize(expected_symbol=nil, expected_arg=nil)
|
11
11
|
@expected_symbol = expected_symbol
|
12
12
|
@expected_arg = expected_arg
|
13
13
|
@caught_symbol = @caught_arg = nil
|
14
14
|
end
|
15
15
|
|
16
|
+
# rubocop:disable MethodLength
|
16
17
|
# @private
|
17
18
|
def matches?(given_proc)
|
18
19
|
@block = given_proc
|
@@ -39,17 +40,18 @@ module RSpec
|
|
39
40
|
# Ruby 1.8 uses NameError with `symbol'
|
40
41
|
# Ruby 1.9 uses ArgumentError with :symbol
|
41
42
|
rescue NameError, ArgumentError => e
|
42
|
-
unless e.message
|
43
|
+
unless (match_data = e.message.match(/uncaught throw (`|\:)([a-zA-Z0-9_]*)(')?/))
|
43
44
|
other_exception = e
|
44
45
|
raise
|
45
46
|
end
|
46
|
-
@caught_symbol =
|
47
|
+
@caught_symbol = match_data.captures[1].to_sym
|
47
48
|
rescue => other_exception
|
48
49
|
raise
|
49
50
|
ensure
|
51
|
+
# rubocop:disable EnsureReturn
|
50
52
|
unless other_exception
|
51
53
|
if @expected_symbol.nil?
|
52
|
-
return
|
54
|
+
return !!@caught_symbol
|
53
55
|
else
|
54
56
|
if @expected_arg.nil?
|
55
57
|
return @caught_symbol == @expected_symbol
|
@@ -58,8 +60,10 @@ module RSpec
|
|
58
60
|
end
|
59
61
|
end
|
60
62
|
end
|
63
|
+
# rubocop:enable EnsureReturn
|
61
64
|
end
|
62
65
|
end
|
66
|
+
# rubocop:enable MethodLength
|
63
67
|
|
64
68
|
def does_not_match?(given_proc)
|
65
69
|
!matches?(given_proc) && Proc === given_proc
|
@@ -97,7 +101,7 @@ module RSpec
|
|
97
101
|
"got #{caught}"
|
98
102
|
end
|
99
103
|
|
100
|
-
def expected(symbol_desc
|
104
|
+
def expected(symbol_desc='a Symbol')
|
101
105
|
throw_description(@expected_symbol || symbol_desc, @expected_arg)
|
102
106
|
end
|
103
107
|
|
@@ -47,8 +47,8 @@ module RSpec
|
|
47
47
|
when 1 then true
|
48
48
|
when 0 then false
|
49
49
|
else
|
50
|
-
raise "The #{matcher_name} matcher is not designed to be used with a "
|
51
|
-
"method that yields multiple times. Use the yield_successive_args "
|
50
|
+
raise "The #{matcher_name} matcher is not designed to be used with a " \
|
51
|
+
"method that yields multiple times. Use the yield_successive_args " \
|
52
52
|
"matcher for that case."
|
53
53
|
end
|
54
54
|
end
|
@@ -61,16 +61,16 @@ module RSpec
|
|
61
61
|
|
62
62
|
def assert_used!
|
63
63
|
return if @used
|
64
|
-
raise "You must pass the argument yielded to your expect block on "
|
65
|
-
"to the method-under-test as a block. It acts as a probe that "
|
66
|
-
"allows the matcher to detect whether or not the method-under-test "
|
67
|
-
"yields, and, if so, how many times, and what the yielded arguments "
|
64
|
+
raise "You must pass the argument yielded to your expect block on " \
|
65
|
+
"to the method-under-test as a block. It acts as a probe that " \
|
66
|
+
"allows the matcher to detect whether or not the method-under-test " \
|
67
|
+
"yields, and, if so, how many times, and what the yielded arguments " \
|
68
68
|
"are."
|
69
69
|
end
|
70
70
|
|
71
71
|
def assert_valid_expect_block!
|
72
72
|
return if @block.arity == 1
|
73
|
-
raise "Your expect block must accept an argument to be used with this "
|
73
|
+
raise "Your expect block must accept an argument to be used with this " \
|
74
74
|
"matcher. Pass the argument as a block on to the method you are testing."
|
75
75
|
end
|
76
76
|
end
|
@@ -299,7 +299,7 @@ module RSpec
|
|
299
299
|
if !@probe.has_block?
|
300
300
|
"was not a block"
|
301
301
|
elsif all_args_match?
|
302
|
-
"yielded with expected arguments"
|
302
|
+
"yielded with expected arguments" \
|
303
303
|
"\nexpected not: #{surface_descriptions_in(@expected).inspect}" +
|
304
304
|
"\n got: #{@actual.inspect}"
|
305
305
|
else
|
@@ -313,8 +313,8 @@ module RSpec
|
|
313
313
|
return !@actual.empty?
|
314
314
|
end
|
315
315
|
|
316
|
-
unless match = all_args_match?
|
317
|
-
@positive_args_failure = "yielded with unexpected arguments"
|
316
|
+
unless (match = all_args_match?)
|
317
|
+
@positive_args_failure = "yielded with unexpected arguments" \
|
318
318
|
"\nexpected: #{surface_descriptions_in(@expected).inspect}" +
|
319
319
|
"\n got: #{@actual.inspect}"
|
320
320
|
end
|
@@ -384,20 +384,19 @@ module RSpec
|
|
384
384
|
def positive_failure_reason
|
385
385
|
return "was not a block" unless @probe.has_block?
|
386
386
|
|
387
|
-
"yielded with unexpected arguments"
|
388
|
-
"\nexpected: #{surface_descriptions_in(@expected).inspect}"
|
387
|
+
"yielded with unexpected arguments" \
|
388
|
+
"\nexpected: #{surface_descriptions_in(@expected).inspect}" \
|
389
389
|
"\n got: #{@actual.inspect}"
|
390
390
|
end
|
391
391
|
|
392
392
|
def negative_failure_reason
|
393
393
|
return "was not a block" unless @probe.has_block?
|
394
394
|
|
395
|
-
"yielded with expected arguments"
|
396
|
-
"\nexpected not: #{surface_descriptions_in(@expected).inspect}"
|
395
|
+
"yielded with expected arguments" \
|
396
|
+
"\nexpected not: #{surface_descriptions_in(@expected).inspect}" \
|
397
397
|
"\n got: #{@actual.inspect}"
|
398
398
|
end
|
399
399
|
end
|
400
400
|
end
|
401
401
|
end
|
402
402
|
end
|
403
|
-
|