rspec-expectations 2.13.0 → 2.14.0
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.
- data/Changelog.md +46 -0
- data/README.md +43 -87
- data/features/README.md +8 -9
- data/features/built_in_matchers/README.md +41 -41
- data/features/built_in_matchers/be_within.feature +3 -3
- data/features/built_in_matchers/expect_change.feature +6 -6
- data/features/built_in_matchers/expect_error.feature +2 -2
- data/features/built_in_matchers/start_with.feature +1 -1
- data/features/built_in_matchers/throw_symbol.feature +11 -11
- data/features/built_in_matchers/yield.feature +18 -3
- data/features/custom_matchers/define_diffable_matcher.feature +1 -1
- data/features/custom_matchers/define_matcher_outside_rspec.feature +6 -6
- data/features/custom_matchers/define_matcher_with_fluent_interface.feature +1 -1
- data/features/customized_message.feature +1 -1
- data/features/support/env.rb +10 -1
- data/features/syntax_configuration.feature +3 -0
- data/features/test_frameworks/test_unit.feature +15 -17
- data/lib/rspec/expectations/deprecation.rb +12 -33
- data/lib/rspec/expectations/differ.rb +25 -7
- data/lib/rspec/expectations/expectation_target.rb +7 -8
- data/lib/rspec/expectations/extensions/object.rb +2 -12
- data/lib/rspec/expectations/fail_with.rb +11 -1
- data/lib/rspec/expectations/handler.rb +11 -6
- data/lib/rspec/expectations/syntax.rb +2 -2
- data/lib/rspec/expectations/version.rb +1 -1
- data/lib/rspec/expectations.rb +1 -1
- data/lib/rspec/matchers/be_close.rb +1 -1
- data/lib/rspec/matchers/built_in/be.rb +2 -0
- data/lib/rspec/matchers/built_in/be_within.rb +1 -1
- data/lib/rspec/matchers/built_in/change.rb +9 -1
- data/lib/rspec/matchers/built_in/have.rb +20 -4
- data/lib/rspec/matchers/built_in/include.rb +2 -10
- data/lib/rspec/matchers/built_in/raise_error.rb +23 -7
- data/lib/rspec/matchers/built_in/yield.rb +78 -3
- data/lib/rspec/matchers/operator_matcher.rb +1 -1
- data/lib/rspec/matchers/pretty.rb +7 -1
- data/lib/rspec/matchers/test_unit_integration.rb +11 -0
- data/lib/rspec/matchers.rb +141 -143
- data/spec/rspec/expectations/differ_spec.rb +27 -5
- data/spec/rspec/expectations/expectation_target_spec.rb +10 -3
- data/spec/rspec/expectations/extensions/kernel_spec.rb +5 -5
- data/spec/rspec/expectations/fail_with_spec.rb +19 -0
- data/spec/rspec/expectations/handler_spec.rb +42 -21
- data/spec/rspec/expectations/syntax_spec.rb +45 -3
- data/spec/rspec/matchers/be_close_spec.rb +6 -6
- data/spec/rspec/matchers/be_spec.rb +36 -36
- data/spec/rspec/matchers/be_within_spec.rb +8 -0
- data/spec/rspec/matchers/change_spec.rb +17 -6
- data/spec/rspec/matchers/configuration_spec.rb +57 -89
- data/spec/rspec/matchers/description_generation_spec.rb +16 -2
- data/spec/rspec/matchers/exist_spec.rb +9 -9
- data/spec/rspec/matchers/has_spec.rb +1 -1
- data/spec/rspec/matchers/have_spec.rb +12 -2
- data/spec/rspec/matchers/include_matcher_integration_spec.rb +2 -2
- data/spec/rspec/matchers/include_spec.rb +4 -4
- data/spec/rspec/matchers/match_array_spec.rb +1 -1
- data/spec/rspec/matchers/match_spec.rb +1 -1
- data/spec/rspec/matchers/raise_error_spec.rb +189 -99
- data/spec/rspec/matchers/respond_to_spec.rb +4 -4
- data/spec/rspec/matchers/satisfy_spec.rb +1 -1
- data/spec/rspec/matchers/start_with_end_with_spec.rb +2 -2
- data/spec/rspec/matchers/yield_spec.rb +81 -4
- data/spec/spec_helper.rb +1 -1
- metadata +8 -7
data/features/support/env.rb
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
require 'aruba/cucumber'
|
|
2
2
|
|
|
3
|
+
timeouts = { 'java' => 60 }
|
|
4
|
+
|
|
3
5
|
Before do
|
|
4
|
-
@aruba_timeout_seconds = 15
|
|
6
|
+
@aruba_timeout_seconds = timeouts.fetch(RUBY_PLATFORM) { 15 }
|
|
5
7
|
end
|
|
8
|
+
|
|
9
|
+
Aruba.configure do |config|
|
|
10
|
+
config.before_cmd do |cmd|
|
|
11
|
+
set_env('JRUBY_OPTS', "-X-C #{ENV['JRUBY_OPTS']}") # disable JIT since these processes are so short lived
|
|
12
|
+
end
|
|
13
|
+
end if RUBY_PLATFORM == 'java'
|
|
14
|
+
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
Feature: Test::Unit integration
|
|
2
2
|
|
|
3
|
-
RSpec-expectations is a stand-alone gem that can be used without
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
syntax but prefer the test organization of another framework.
|
|
3
|
+
RSpec-expectations is a stand-alone gem that can be used without the rest of
|
|
4
|
+
RSpec. If you like the way Test::Unit (or MiniTest) organizes tests, but
|
|
5
|
+
prefer RSpec's approach to expressing expectations, you can have both.
|
|
7
6
|
|
|
8
|
-
|
|
7
|
+
The one downside is that failures are reported as errors with MiniTest.
|
|
8
|
+
|
|
9
|
+
Scenario: use rspec/expectations with Test::Unit
|
|
9
10
|
Given a file named "rspec_expectations_test.rb" with:
|
|
10
11
|
"""ruby
|
|
11
12
|
require 'test/unit'
|
|
@@ -17,30 +18,27 @@ Feature: Test::Unit integration
|
|
|
17
18
|
end
|
|
18
19
|
|
|
19
20
|
def be_an_int
|
|
20
|
-
|
|
21
|
+
# This is actually an internal rspec-expectations API, but is used
|
|
22
|
+
# here to demonstrate that deprecation warnings from within
|
|
23
|
+
# rspec-expectations work correcty without depending on rspec-core
|
|
24
|
+
RSpec.deprecate(:be_an_int, :replacement => :be_an_integer)
|
|
21
25
|
be_an_integer
|
|
22
26
|
end
|
|
23
27
|
|
|
24
28
|
def test_passing_expectation
|
|
25
|
-
|
|
26
|
-
x.should == 4
|
|
29
|
+
expect(1 + 3).to eq 4
|
|
27
30
|
end
|
|
28
31
|
|
|
29
32
|
def test_failing_expectation
|
|
30
|
-
|
|
31
|
-
array.should be_empty
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
def test_expect_matcher
|
|
35
|
-
expect { @a = 5 }.to change { @a }.from(nil).to(5)
|
|
33
|
+
expect([1,2]).to be_empty
|
|
36
34
|
end
|
|
37
35
|
|
|
38
|
-
def
|
|
39
|
-
1.
|
|
36
|
+
def test_custom_matcher_with_deprecation_warning
|
|
37
|
+
expect(1).to be_an_int
|
|
40
38
|
end
|
|
41
39
|
end
|
|
42
40
|
"""
|
|
43
41
|
When I run `ruby rspec_expectations_test.rb`
|
|
44
|
-
Then the output should contain "
|
|
42
|
+
Then the output should contain "3 tests, 0 assertions, 0 failures, 1 errors" or "3 tests, 0 assertions, 1 failures, 0 errors"
|
|
45
43
|
And the output should contain "expected empty? to return true, got false"
|
|
46
44
|
And the output should contain "be_an_int is deprecated"
|
|
@@ -1,38 +1,17 @@
|
|
|
1
1
|
module RSpec
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
#
|
|
5
|
-
#
|
|
6
|
-
#
|
|
7
|
-
def deprecate(
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
message
|
|
11
|
-
|
|
12
|
-
*****************************************************************
|
|
13
|
-
DEPRECATION WARNING: you are using deprecated behaviour that will
|
|
14
|
-
be removed from #{version_string}.
|
|
15
|
-
|
|
16
|
-
#{caller(0)[2]}
|
|
17
|
-
|
|
18
|
-
* #{method} is deprecated.
|
|
19
|
-
NOTICE
|
|
20
|
-
if alternate_method
|
|
21
|
-
message << <<-ADDITIONAL
|
|
22
|
-
* please use #{alternate_method} instead.
|
|
23
|
-
ADDITIONAL
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
message << "*****************************************************************"
|
|
27
|
-
warn_deprecation(message)
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
# Used internally by RSpec to display custom deprecation warnings. This
|
|
31
|
-
# is also defined in rspec-core, but we can't assume it's loaded since
|
|
32
|
-
# rspec-expectations should be usable w/o rspec-core.
|
|
33
|
-
def warn_deprecation(message)
|
|
34
|
-
warn(message)
|
|
2
|
+
module Expectations
|
|
3
|
+
module Deprecation
|
|
4
|
+
# @private
|
|
5
|
+
#
|
|
6
|
+
# Used internally to print deprecation warnings
|
|
7
|
+
def deprecate(deprecated, options={})
|
|
8
|
+
message = "DEPRECATION: #{deprecated} is deprecated."
|
|
9
|
+
message << " Use #{options[:replacement]} instead." if options[:replacement]
|
|
10
|
+
message << " Called from #{caller(0)[2]}."
|
|
11
|
+
warn message
|
|
35
12
|
end
|
|
36
13
|
end
|
|
37
14
|
end
|
|
15
|
+
|
|
16
|
+
extend(Expectations::Deprecation) unless respond_to?(:deprecate)
|
|
38
17
|
end
|
|
@@ -6,11 +6,11 @@ module RSpec
|
|
|
6
6
|
module Expectations
|
|
7
7
|
class Differ
|
|
8
8
|
# This is snagged from diff/lcs/ldiff.rb (which is a commandline tool)
|
|
9
|
-
def diff_as_string(
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
def diff_as_string(input_data_new, input_data_old)
|
|
10
|
+
output = matching_encoding("", input_data_old)
|
|
11
|
+
data_old = input_data_old.split(matching_encoding("\n", input_data_old)).map! { |e| e.chomp }
|
|
12
|
+
data_new = input_data_new.split(matching_encoding("\n", input_data_new)).map! { |e| e.chomp }
|
|
12
13
|
diffs = Diff::LCS.diff(data_old, data_new)
|
|
13
|
-
output = ""
|
|
14
14
|
return output if diffs.empty?
|
|
15
15
|
oldhunk = hunk = nil
|
|
16
16
|
file_length_difference = 0
|
|
@@ -33,16 +33,24 @@ module RSpec
|
|
|
33
33
|
hunk.unshift(oldhunk)
|
|
34
34
|
end
|
|
35
35
|
else
|
|
36
|
-
output << oldhunk.diff(format)
|
|
36
|
+
output << matching_encoding(oldhunk.diff(format).to_s, output)
|
|
37
37
|
end
|
|
38
38
|
ensure
|
|
39
39
|
oldhunk = hunk
|
|
40
|
-
output << "\n"
|
|
40
|
+
output << matching_encoding("\n", output)
|
|
41
41
|
end
|
|
42
42
|
end
|
|
43
43
|
#Handle the last remaining hunk
|
|
44
|
-
output << oldhunk.diff(format)
|
|
44
|
+
output << matching_encoding(oldhunk.diff(format).to_s,output)
|
|
45
|
+
output << matching_encoding("\n",output)
|
|
45
46
|
color_diff output
|
|
47
|
+
rescue Encoding::CompatibilityError
|
|
48
|
+
if input_data_new.encoding != input_data_old.encoding
|
|
49
|
+
"Could not produce a diff because the encoding of the actual string (#{input_data_old.encoding}) "+
|
|
50
|
+
"differs from the encoding of the expected string (#{input_data_new.encoding})"
|
|
51
|
+
else
|
|
52
|
+
"Could not produce a diff because of the encoding of the string (#{input_data_old.encoding})"
|
|
53
|
+
end
|
|
46
54
|
end
|
|
47
55
|
|
|
48
56
|
def diff_as_object(actual, expected)
|
|
@@ -108,6 +116,16 @@ module RSpec
|
|
|
108
116
|
PP.pp(object,"")
|
|
109
117
|
end
|
|
110
118
|
end
|
|
119
|
+
|
|
120
|
+
if String.method_defined?(:encoding)
|
|
121
|
+
def matching_encoding(string, source)
|
|
122
|
+
string.encode(source.encoding)
|
|
123
|
+
end
|
|
124
|
+
else
|
|
125
|
+
def matching_encoding(string, source)
|
|
126
|
+
string
|
|
127
|
+
end
|
|
128
|
+
end
|
|
111
129
|
end
|
|
112
130
|
|
|
113
131
|
end
|
|
@@ -7,8 +7,8 @@ module RSpec
|
|
|
7
7
|
# # used with `to`
|
|
8
8
|
# expect(actual).to eq(3)
|
|
9
9
|
#
|
|
10
|
-
# # with `
|
|
11
|
-
# expect(actual).
|
|
10
|
+
# # with `not_to`
|
|
11
|
+
# expect(actual).not_to eq(3)
|
|
12
12
|
class ExpectationTarget
|
|
13
13
|
class << self
|
|
14
14
|
attr_accessor :deprecated_should_enabled
|
|
@@ -36,29 +36,28 @@ module RSpec
|
|
|
36
36
|
|
|
37
37
|
# Runs the given expectation, passing if `matcher` returns false.
|
|
38
38
|
# @example
|
|
39
|
-
# expect(value).to_not eq(5)
|
|
40
39
|
# expect(value).not_to eq(5)
|
|
41
40
|
# @param [Matcher]
|
|
42
41
|
# matcher
|
|
43
42
|
# @param [String] message optional message to display when the expectation fails
|
|
44
43
|
# @return [Boolean] false if the negative expectation succeeds (else raises)
|
|
45
44
|
# @see RSpec::Matchers
|
|
46
|
-
def
|
|
47
|
-
prevent_operator_matchers(:
|
|
45
|
+
def not_to(matcher=nil, message=nil, &block)
|
|
46
|
+
prevent_operator_matchers(:not_to, matcher)
|
|
48
47
|
RSpec::Expectations::NegativeExpectationHandler.handle_matcher(@target, matcher, message, &block)
|
|
49
48
|
end
|
|
50
|
-
alias not_to
|
|
49
|
+
alias to_not not_to
|
|
51
50
|
|
|
52
51
|
def self.enable_deprecated_should
|
|
53
52
|
return if deprecated_should_enabled?
|
|
54
53
|
|
|
55
54
|
def should(*args)
|
|
56
|
-
RSpec.deprecate "`expect { }.should`", "`expect { }.to`"
|
|
55
|
+
RSpec.deprecate "`expect { }.should`", :replacement => "`expect { }.to`"
|
|
57
56
|
@target.should(*args)
|
|
58
57
|
end
|
|
59
58
|
|
|
60
59
|
def should_not(*args)
|
|
61
|
-
RSpec.deprecate "`expect { }.should_not`", "`expect { }.
|
|
60
|
+
RSpec.deprecate "`expect { }.should_not`", :replacement => "`expect { }.not_to`"
|
|
62
61
|
@target.should_not(*args)
|
|
63
62
|
end
|
|
64
63
|
|
|
@@ -6,17 +6,7 @@ module RSpec
|
|
|
6
6
|
def const_missing(name)
|
|
7
7
|
case name
|
|
8
8
|
when :Rspec, :Spec
|
|
9
|
-
RSpec.
|
|
10
|
-
*****************************************************************
|
|
11
|
-
DEPRECATION WARNING: you are using a deprecated constant that will
|
|
12
|
-
be removed from a future version of RSpec.
|
|
13
|
-
|
|
14
|
-
#{caller(0)[2]}
|
|
15
|
-
|
|
16
|
-
* #{name} is deprecated.
|
|
17
|
-
* RSpec is the new top-level module in RSpec-2
|
|
18
|
-
***************************************************************
|
|
19
|
-
WARNING
|
|
9
|
+
RSpec.deprecate(name.to_s, :replacement => "RSpec")
|
|
20
10
|
RSpec
|
|
21
11
|
else
|
|
22
12
|
begin
|
|
@@ -31,7 +21,7 @@ WARNING
|
|
|
31
21
|
|
|
32
22
|
# @deprecated (no replacement)
|
|
33
23
|
def differ=(ignore)
|
|
34
|
-
RSpec.deprecate("RSpec::Expectations.differ=(differ)"
|
|
24
|
+
RSpec.deprecate("RSpec::Expectations.differ=(differ)")
|
|
35
25
|
end
|
|
36
26
|
end
|
|
37
27
|
end
|
|
@@ -52,7 +52,17 @@ module RSpec
|
|
|
52
52
|
|
|
53
53
|
def coerce_to_string(string_or_array)
|
|
54
54
|
return string_or_array unless Array === string_or_array
|
|
55
|
-
string_or_array.join(
|
|
55
|
+
diffably_stringify(string_or_array).join("\n")
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def diffably_stringify(array)
|
|
59
|
+
array.map do |entry|
|
|
60
|
+
if Array === entry
|
|
61
|
+
entry.inspect
|
|
62
|
+
else
|
|
63
|
+
entry.to_s.gsub("\n", "\\n")
|
|
64
|
+
end
|
|
65
|
+
end
|
|
56
66
|
end
|
|
57
67
|
|
|
58
68
|
if String.method_defined?(:encoding)
|
|
@@ -2,13 +2,14 @@ module RSpec
|
|
|
2
2
|
module Expectations
|
|
3
3
|
|
|
4
4
|
class ExpectationHandler
|
|
5
|
-
def self.message_must_be_string(msg)
|
|
6
|
-
"WARNING: ignoring the provided expectation message argument " +
|
|
7
|
-
"(#{msg.inspect}) since it is not a string."
|
|
8
|
-
end
|
|
9
|
-
|
|
10
5
|
def self.check_message(msg)
|
|
11
|
-
|
|
6
|
+
unless msg.nil? || msg.respond_to?(:to_str) || msg.respond_to?(:call)
|
|
7
|
+
::Kernel.warn [
|
|
8
|
+
"WARNING: ignoring the provided expectation message argument (",
|
|
9
|
+
msg.inspect,
|
|
10
|
+
") since it is not a string or a proc."
|
|
11
|
+
].join
|
|
12
|
+
end
|
|
12
13
|
end
|
|
13
14
|
end
|
|
14
15
|
|
|
@@ -23,6 +24,8 @@ module RSpec
|
|
|
23
24
|
match = matcher.matches?(actual, &block)
|
|
24
25
|
return match if match
|
|
25
26
|
|
|
27
|
+
message = message.call if message.respond_to?(:call)
|
|
28
|
+
|
|
26
29
|
message ||= matcher.respond_to?(:failure_message_for_should) ?
|
|
27
30
|
matcher.failure_message_for_should :
|
|
28
31
|
matcher.failure_message
|
|
@@ -47,6 +50,8 @@ module RSpec
|
|
|
47
50
|
matcher.matches?(actual, &block)
|
|
48
51
|
return match unless match
|
|
49
52
|
|
|
53
|
+
message = message.call if message.respond_to?(:call)
|
|
54
|
+
|
|
50
55
|
message ||= matcher.respond_to?(:failure_message_for_should_not) ?
|
|
51
56
|
matcher.failure_message_for_should_not :
|
|
52
57
|
matcher.negative_failure_message
|
|
@@ -32,10 +32,10 @@ module RSpec
|
|
|
32
32
|
# `ExpectationTarget`.
|
|
33
33
|
# @example
|
|
34
34
|
# expect(actual).to eq(expected)
|
|
35
|
-
# expect(actual).
|
|
35
|
+
# expect(actual).not_to eq(expected)
|
|
36
36
|
# @return [ExpectationTarget]
|
|
37
37
|
# @see ExpectationTarget#to
|
|
38
|
-
# @see ExpectationTarget#
|
|
38
|
+
# @see ExpectationTarget#not_to
|
|
39
39
|
|
|
40
40
|
# @api private
|
|
41
41
|
# Determines where we add `should` and `should_not`.
|
data/lib/rspec/expectations.rb
CHANGED
|
@@ -37,7 +37,7 @@ module RSpec
|
|
|
37
37
|
# `eq.failure_message_for_should_not`.
|
|
38
38
|
#
|
|
39
39
|
# rspec-expectations ships with a standard set of useful matchers, and writing
|
|
40
|
-
# your own matchers is quite simple.
|
|
40
|
+
# your own matchers is quite simple.
|
|
41
41
|
#
|
|
42
42
|
# See [RSpec::Matchers](../RSpec/Matchers) for more information about the
|
|
43
43
|
# built-in matchers that ship with rspec-expectations, and how to write your
|
|
@@ -2,7 +2,7 @@ module RSpec
|
|
|
2
2
|
module Matchers
|
|
3
3
|
# @deprecated use +be_within+ instead.
|
|
4
4
|
def be_close(expected, delta)
|
|
5
|
-
RSpec.deprecate("be_close(#{expected}, #{delta})", "be_within(#{delta}).of(#{expected})")
|
|
5
|
+
RSpec.deprecate("be_close(#{expected}, #{delta})", :replacement => "be_within(#{delta}).of(#{expected})")
|
|
6
6
|
be_within(delta).of(expected)
|
|
7
7
|
end
|
|
8
8
|
end
|
|
@@ -39,7 +39,7 @@ MESSAGE
|
|
|
39
39
|
if @eval_before && !expected_matches_actual?(@expected_before, @actual_before)
|
|
40
40
|
"#{message} should have initially been #{@expected_before.inspect}, but was #{@actual_before.inspect}"
|
|
41
41
|
elsif @eval_after && !expected_matches_actual?(@expected_after, @actual_after)
|
|
42
|
-
"#{message} should have been changed to #{
|
|
42
|
+
"#{message} should have been changed to #{failure_message_for_expected_after}, but is now #{@actual_after.inspect}"
|
|
43
43
|
elsif @expected_delta
|
|
44
44
|
"#{message} should have been changed by #{@expected_delta.inspect}, but was changed by #{actual_delta.inspect}"
|
|
45
45
|
elsif @minimum
|
|
@@ -92,6 +92,14 @@ MESSAGE
|
|
|
92
92
|
|
|
93
93
|
private
|
|
94
94
|
|
|
95
|
+
def failure_message_for_expected_after
|
|
96
|
+
if RSpec::Matchers.is_a_matcher?(@expected_after)
|
|
97
|
+
@expected_after.description
|
|
98
|
+
else
|
|
99
|
+
@expected_after.inspect
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
|
|
95
103
|
def message
|
|
96
104
|
@message || "result"
|
|
97
105
|
end
|
|
@@ -2,6 +2,8 @@ module RSpec
|
|
|
2
2
|
module Matchers
|
|
3
3
|
module BuiltIn
|
|
4
4
|
class Have
|
|
5
|
+
QUERY_METHODS = [:size, :length, :count].freeze
|
|
6
|
+
|
|
5
7
|
def initialize(expected, relativity=:exactly)
|
|
6
8
|
@expected = case expected
|
|
7
9
|
when :no then 0
|
|
@@ -22,9 +24,19 @@ module RSpec
|
|
|
22
24
|
|
|
23
25
|
def matches?(collection_or_owner)
|
|
24
26
|
collection = determine_collection(collection_or_owner)
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
27
|
+
case collection
|
|
28
|
+
when enumerator_class
|
|
29
|
+
for query_method in QUERY_METHODS
|
|
30
|
+
next unless collection.respond_to?(query_method)
|
|
31
|
+
@actual = collection.__send__(query_method)
|
|
32
|
+
break unless @actual.nil?
|
|
33
|
+
end
|
|
34
|
+
raise not_a_collection if @actual.nil?
|
|
35
|
+
else
|
|
36
|
+
query_method = determine_query_method(collection)
|
|
37
|
+
raise not_a_collection unless query_method
|
|
38
|
+
@actual = collection.__send__(query_method)
|
|
39
|
+
end
|
|
28
40
|
case @relativity
|
|
29
41
|
when :at_least then @actual >= @expected
|
|
30
42
|
when :at_most then @actual <= @expected
|
|
@@ -46,7 +58,7 @@ module RSpec
|
|
|
46
58
|
end
|
|
47
59
|
|
|
48
60
|
def determine_query_method(collection)
|
|
49
|
-
|
|
61
|
+
QUERY_METHODS.detect {|m| collection.respond_to?(m)}
|
|
50
62
|
end
|
|
51
63
|
|
|
52
64
|
def not_a_collection
|
|
@@ -102,6 +114,10 @@ EOF
|
|
|
102
114
|
def relative_expectation
|
|
103
115
|
"#{relativities[@relativity]}#{@expected}"
|
|
104
116
|
end
|
|
117
|
+
|
|
118
|
+
def enumerator_class
|
|
119
|
+
RUBY_VERSION < '1.9' ? Enumerable::Enumerator : Enumerator
|
|
120
|
+
end
|
|
105
121
|
end
|
|
106
122
|
end
|
|
107
123
|
end
|
|
@@ -23,7 +23,7 @@ module RSpec
|
|
|
23
23
|
def diffable?
|
|
24
24
|
# Matchers do not diff well, since diff uses their inspect
|
|
25
25
|
# output, which includes their instance variables and such.
|
|
26
|
-
@expected.none? { |e| is_a_matcher?(e) }
|
|
26
|
+
@expected.none? { |e| RSpec::Matchers.is_a_matcher?(e) }
|
|
27
27
|
end
|
|
28
28
|
|
|
29
29
|
private
|
|
@@ -53,15 +53,7 @@ module RSpec
|
|
|
53
53
|
end
|
|
54
54
|
|
|
55
55
|
def comparing_with_matcher?(actual, expected)
|
|
56
|
-
actual.is_a?(Array) && is_a_matcher?(expected)
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
def is_a_matcher?(object)
|
|
60
|
-
return false if object.respond_to?(:i_respond_to_everything_so_im_not_really_a_matcher)
|
|
61
|
-
|
|
62
|
-
[:failure_message_for_should, :failure_message].any? do |msg|
|
|
63
|
-
object.respond_to?(msg)
|
|
64
|
-
end && object.respond_to?(:matches?)
|
|
56
|
+
actual.is_a?(Array) && RSpec::Matchers.is_a_matcher?(expected)
|
|
65
57
|
end
|
|
66
58
|
end
|
|
67
59
|
end
|
|
@@ -14,19 +14,31 @@ module RSpec
|
|
|
14
14
|
end
|
|
15
15
|
|
|
16
16
|
def matches?(given_proc, negative_expectation = false)
|
|
17
|
+
if negative_expectation && (expecting_specific_exception? || @expected_message)
|
|
18
|
+
what_to_deprecate = if expecting_specific_exception? && @expected_message
|
|
19
|
+
"`expect { }.not_to raise_error(SpecificErrorClass, message)`"
|
|
20
|
+
elsif expecting_specific_exception?
|
|
21
|
+
"`expect { }.not_to raise_error(SpecificErrorClass)`"
|
|
22
|
+
elsif @expected_message
|
|
23
|
+
"`expect { }.not_to raise_error(message)`"
|
|
24
|
+
end
|
|
25
|
+
RSpec.deprecate(what_to_deprecate, :replacement => "`expect { }.not_to raise_error()`")
|
|
26
|
+
end
|
|
17
27
|
@raised_expected_error = false
|
|
18
28
|
@with_expected_message = false
|
|
19
29
|
@eval_block = false
|
|
20
30
|
@eval_block_passed = false
|
|
31
|
+
unless given_proc.respond_to?(:call)
|
|
32
|
+
::Kernel.warn "`raise_error` was called with non-proc object #{given_proc.inspect}"
|
|
33
|
+
return false
|
|
34
|
+
end
|
|
21
35
|
begin
|
|
22
36
|
given_proc.call
|
|
23
|
-
rescue @expected_error => @actual_error
|
|
24
|
-
@raised_expected_error = true
|
|
25
|
-
@with_expected_message = verify_message
|
|
26
37
|
rescue Exception => @actual_error
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
38
|
+
if @actual_error == @expected_error || @expected_error === @actual_error
|
|
39
|
+
@raised_expected_error = true
|
|
40
|
+
@with_expected_message = verify_message
|
|
41
|
+
end
|
|
30
42
|
end
|
|
31
43
|
|
|
32
44
|
unless negative_expectation
|
|
@@ -79,7 +91,7 @@ module RSpec
|
|
|
79
91
|
def expected_error
|
|
80
92
|
case @expected_message
|
|
81
93
|
when nil
|
|
82
|
-
@expected_error
|
|
94
|
+
@expected_error.inspect
|
|
83
95
|
when Regexp
|
|
84
96
|
"#{@expected_error} with message matching #{@expected_message.inspect}"
|
|
85
97
|
else
|
|
@@ -101,6 +113,10 @@ module RSpec
|
|
|
101
113
|
*backtrace
|
|
102
114
|
].join("\n # ")
|
|
103
115
|
end
|
|
116
|
+
|
|
117
|
+
def expecting_specific_exception?
|
|
118
|
+
@expected_error != Exception
|
|
119
|
+
end
|
|
104
120
|
end
|
|
105
121
|
end
|
|
106
122
|
end
|
|
@@ -65,17 +65,92 @@ module RSpec
|
|
|
65
65
|
end
|
|
66
66
|
|
|
67
67
|
class YieldControl < BaseMatcher
|
|
68
|
+
def initialize
|
|
69
|
+
@expectation_type = nil
|
|
70
|
+
@expected_yields_count = nil
|
|
71
|
+
end
|
|
72
|
+
|
|
68
73
|
def matches?(block)
|
|
69
74
|
probe = YieldProbe.probe(block)
|
|
70
|
-
|
|
75
|
+
|
|
76
|
+
if @expectation_type
|
|
77
|
+
probe.num_yields.send(@expectation_type, @expected_yields_count)
|
|
78
|
+
else
|
|
79
|
+
probe.yielded_once?(:yield_control)
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def once
|
|
84
|
+
exactly(1)
|
|
85
|
+
self
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def twice
|
|
89
|
+
exactly(2)
|
|
90
|
+
self
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def exactly(number)
|
|
94
|
+
set_expected_yields_count(:==, number)
|
|
95
|
+
self
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def at_most(number)
|
|
99
|
+
set_expected_yields_count(:<=, number)
|
|
100
|
+
self
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def at_least(number)
|
|
104
|
+
set_expected_yields_count(:>=, number)
|
|
105
|
+
self
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def times
|
|
109
|
+
self
|
|
71
110
|
end
|
|
72
111
|
|
|
73
112
|
def failure_message_for_should
|
|
74
|
-
|
|
113
|
+
'expected given block to yield control'.tap do |failure_message|
|
|
114
|
+
failure_message << relativity_failure_message
|
|
115
|
+
end
|
|
75
116
|
end
|
|
76
117
|
|
|
77
118
|
def failure_message_for_should_not
|
|
78
|
-
|
|
119
|
+
'expected given block not to yield control'.tap do |failure_message|
|
|
120
|
+
failure_message << relativity_failure_message
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
private
|
|
125
|
+
|
|
126
|
+
def set_expected_yields_count(relativity, n)
|
|
127
|
+
@expectation_type = relativity
|
|
128
|
+
@expected_yields_count = case n
|
|
129
|
+
when Numeric then n
|
|
130
|
+
when :once then 1
|
|
131
|
+
when :twice then 2
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
def relativity_failure_message
|
|
136
|
+
return '' unless @expected_yields_count
|
|
137
|
+
" #{human_readable_expecation_type}#{human_readable_count}"
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
def human_readable_expecation_type
|
|
141
|
+
case @expectation_type
|
|
142
|
+
when :<= then 'at most '
|
|
143
|
+
when :>= then 'at least '
|
|
144
|
+
else ''
|
|
145
|
+
end
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
def human_readable_count
|
|
149
|
+
case @expected_yields_count
|
|
150
|
+
when 1 then "once"
|
|
151
|
+
when 2 then "twice"
|
|
152
|
+
else "#{@expected_yields_count} times"
|
|
153
|
+
end
|
|
79
154
|
end
|
|
80
155
|
end
|
|
81
156
|
|
|
@@ -91,7 +91,7 @@ module RSpec
|
|
|
91
91
|
if actual.__send__(operator, expected)
|
|
92
92
|
true
|
|
93
93
|
elsif ['==','===', '=~'].include?(operator)
|
|
94
|
-
fail_with_message("expected: #{expected.inspect}\n got: #{actual.inspect} (using #{operator})")
|
|
94
|
+
fail_with_message("expected: #{expected.inspect}\n got: #{actual.inspect} (using #{operator})")
|
|
95
95
|
else
|
|
96
96
|
fail_with_message("expected: #{operator} #{expected.inspect}\n got: #{operator.gsub(/./, ' ')} #{actual.inspect}")
|
|
97
97
|
end
|